From 1096813bf9a425e2aa4ac755b6c991b626dfab50 Mon Sep 17 00:00:00 2001 From: Matt Butcher Date: Wed, 15 Nov 2017 10:16:29 -0700 Subject: [PATCH] fix(tiller): add stricter certificate verification The older version of Tiller allowed a weaker set of certificate checks than we intended. This version requires a client certificate, and then requires that that certificate be signed by a known CA. This works around the situation where a user could provide a self-signed certificate. --- cmd/tiller/tiller.go | 6 +++++- docs/helm/helm_get_hooks.md | 9 +++++++-- docs/helm/helm_get_manifest.md | 9 +++++++-- docs/helm/helm_get_values.md | 11 ++++++++--- docs/tiller_ssl.md | 29 ++++++++++++++++++++++++++++- 5 files changed, 55 insertions(+), 9 deletions(-) diff --git a/cmd/tiller/tiller.go b/cmd/tiller/tiller.go index fadf8dd3a..f9ec0d4fc 100644 --- a/cmd/tiller/tiller.go +++ b/cmd/tiller/tiller.go @@ -232,7 +232,11 @@ func tlsOptions() tlsutil.Options { opts := tlsutil.Options{CertFile: *certFile, KeyFile: *keyFile} if *tlsVerify { opts.CaCertFile = *caCertFile - opts.ClientAuth = tls.VerifyClientCertIfGiven + + // We want to force the client to not only provide a cert, but to + // provide a cert that we can validate. + // http://www.bite-code.com/2015/06/25/tls-mutual-auth-in-golang/ + opts.ClientAuth = tls.RequireAndVerifyClientCert } return opts } diff --git a/docs/helm/helm_get_hooks.md b/docs/helm/helm_get_hooks.md index 3db1b8d55..a2fb36acd 100644 --- a/docs/helm/helm_get_hooks.md +++ b/docs/helm/helm_get_hooks.md @@ -18,7 +18,12 @@ helm get hooks [flags] RELEASE_NAME ### Options ``` - --revision int32 get the named release with revision + --revision int32 get the named release with revision + --tls enable TLS for request + --tls-ca-cert string path to TLS CA certificate file (default "$HELM_HOME/ca.pem") + --tls-cert string path to TLS certificate file (default "$HELM_HOME/cert.pem") + --tls-key string path to TLS key file (default "$HELM_HOME/key.pem") + --tls-verify enable TLS for request and verify remote ``` ### Options inherited from parent commands @@ -35,4 +40,4 @@ helm get hooks [flags] RELEASE_NAME ### SEE ALSO * [helm get](helm_get.md) - download a named release -###### Auto generated by spf13/cobra on 7-Nov-2017 +###### Auto generated by spf13/cobra on 15-Nov-2017 diff --git a/docs/helm/helm_get_manifest.md b/docs/helm/helm_get_manifest.md index 11597716d..1cf712d9b 100644 --- a/docs/helm/helm_get_manifest.md +++ b/docs/helm/helm_get_manifest.md @@ -20,7 +20,12 @@ helm get manifest [flags] RELEASE_NAME ### Options ``` - --revision int32 get the named release with revision + --revision int32 get the named release with revision + --tls enable TLS for request + --tls-ca-cert string path to TLS CA certificate file (default "$HELM_HOME/ca.pem") + --tls-cert string path to TLS certificate file (default "$HELM_HOME/cert.pem") + --tls-key string path to TLS key file (default "$HELM_HOME/key.pem") + --tls-verify enable TLS for request and verify remote ``` ### Options inherited from parent commands @@ -37,4 +42,4 @@ helm get manifest [flags] RELEASE_NAME ### SEE ALSO * [helm get](helm_get.md) - download a named release -###### Auto generated by spf13/cobra on 7-Nov-2017 +###### Auto generated by spf13/cobra on 15-Nov-2017 diff --git a/docs/helm/helm_get_values.md b/docs/helm/helm_get_values.md index fe23e6819..1e57a2303 100644 --- a/docs/helm/helm_get_values.md +++ b/docs/helm/helm_get_values.md @@ -16,8 +16,13 @@ helm get values [flags] RELEASE_NAME ### Options ``` - -a, --all dump all (computed) values - --revision int32 get the named release with revision + -a, --all dump all (computed) values + --revision int32 get the named release with revision + --tls enable TLS for request + --tls-ca-cert string path to TLS CA certificate file (default "$HELM_HOME/ca.pem") + --tls-cert string path to TLS certificate file (default "$HELM_HOME/cert.pem") + --tls-key string path to TLS key file (default "$HELM_HOME/key.pem") + --tls-verify enable TLS for request and verify remote ``` ### Options inherited from parent commands @@ -34,4 +39,4 @@ helm get values [flags] RELEASE_NAME ### SEE ALSO * [helm get](helm_get.md) - download a named release -###### Auto generated by spf13/cobra on 7-Nov-2017 +###### Auto generated by spf13/cobra on 15-Nov-2017 diff --git a/docs/tiller_ssl.md b/docs/tiller_ssl.md index ab2b6ba54..59d653e26 100644 --- a/docs/tiller_ssl.md +++ b/docs/tiller_ssl.md @@ -4,6 +4,8 @@ This document explains how to create strong SSL/TLS connections between Helm and Tiller. The emphasis here is on creating an internal CA, and using both the cryptographic and identity functions of SSL. +> Support for TLS-based auth was introduced in Helm 2.3.0 + Configuring SSL is considered an advanced topic, and knowledge of Helm and Tiller is assumed. @@ -16,6 +18,10 @@ also verifies Tiller's identity by certificate authority. There are numerous possible configurations for setting up certificates and authorities, but the method we cover here will work for most situations. +> As of Helm 2.7.2, Tiller _requires_ that the client certificate be validated +> by its CA. In prior versions, Tiller used a weaker validation strategy that +> allowed self-signed certificates. + In this guide, we will show how to: - Create a private CA that is used to issue certificates for Tiller clients and @@ -69,7 +75,7 @@ very important. The key in particular should be handled with particular care. Often, you will want to generate an intermediate signing key. For the sake of brevity, we will be signing keys with our root CA. -## Generating Certificates +### Generating Certificates We will be generating two certificates, each representing a type of certificate: @@ -256,6 +262,27 @@ $ cp helm.key.pem $(helm home)/key.pem With this, you can simply run `helm ls --tls` to enable TLS. +### Troubleshooting + +*Running a command, I get `Error: transport is closing`* + +This is almost always due to a configuration error in which the client is missing +a certificate (`--tls-cert`) or the certificate is bad. + +*I'm using a certificate, but get `Error: remote error: tls: bad certificate`* + +This means that Tiller's CA cannot verify your certificate. In the examples above, +we used a single CA to generate both the client and server certificates. In these +examples, the CA has _signed_ the client's certificate. We then load that CA +up to Tiller. So when the client certificate is sent to the server, Tiller +checks the client certificate against the CA. + +*If I use `--tls-verify` on the client, I get `Error: x509: certificate is valid for tiller-server, not localhost`* + +If you plan to use `--tls-verify` on the client, you will need to make sure that +the host name that Helm connects to matches the host name on the certificate. In +some cases this is awkward, since Helm will connect over localhost, or the FQDN is +not available for public resolution. ## References