From 532150ab143134d03e6873f783c4819cbdaa5f2c Mon Sep 17 00:00:00 2001 From: Harry Bagdi Date: Tue, 18 Dec 2018 14:51:58 -0800 Subject: [PATCH] feat: add support for custom TLS certificate Following options have been added to work with custom TLS certificates, SNI names and to ignore a self-signed certificate: - `--admin-tls-skip-verify`: to skip validation of a certificate, this shouldn't be used in a production environment. - `--admin-tls-server-name`: use this if the FQDN of Kong's Admin API doesn't match the SNI name in the certificate. - `--admin-ca-cert-file`: use this to specify a custom CA cert which is not part of the bundled CA certs. --- cli/ingress-controller/flags.go | 11 +++++++++ cli/ingress-controller/main.go | 30 ++++++++++++++++++++++- internal/ingress/controller/controller.go | 8 +++++- 3 files changed, 47 insertions(+), 2 deletions(-) diff --git a/cli/ingress-controller/flags.go b/cli/ingress-controller/flags.go index 3f7086e4e2..abb0935254 100644 --- a/cli/ingress-controller/flags.go +++ b/cli/ingress-controller/flags.go @@ -111,6 +111,13 @@ The controller will set the endpoint records on the ingress using this address.` kongURL = flags.String("kong-url", "http://localhost:8001", "The address of the Kong Admin URL to connect to in the format of protocol://address:port") + kongTLSSkipVerify = flag.Bool("admin-tls-skip-verify", false, + "Disable verification of TLS certificate of Kong's Admin endpoint.") + kongTLSServerName = flag.String("admin-tls-server-name", "", + "SNI name to use to verify the certificate presented by Kong in TLS.") + kongCACert = flag.String("admin-ca-cert-file", "", + "Path to PEM-encoded CA certificate file to verify the Kong's Admin SSL certificate.") + kongHeaders headers ) @@ -156,6 +163,10 @@ The controller will set the endpoint records on the ingress using this address.` Kong: controller.Kong{ URL: *kongURL, Headers: kongHeaders, + + TLSServerName: *kongTLSServerName, + TLSSkipVerify: *kongTLSSkipVerify, + CACert: *kongCACert, }, APIServerHost: *apiserverHost, KubeConfigFile: *kubeConfigFile, diff --git a/cli/ingress-controller/main.go b/cli/ingress-controller/main.go index 6840103aff..a14669e278 100644 --- a/cli/ingress-controller/main.go +++ b/cli/ingress-controller/main.go @@ -17,8 +17,11 @@ limitations under the License. package main import ( + "crypto/tls" + "crypto/x509" "encoding/json" "fmt" + "io/ioutil" "math/rand" "net/http" "net/http/pprof" @@ -114,10 +117,35 @@ func main() { conf.KubeClient = kubeClient conf.KubeConf = kubeCfg + defaultTransport := http.DefaultTransport.(*http.Transport) + + var tlsConfig tls.Config + + if conf.Kong.TLSSkipVerify { + tlsConfig.InsecureSkipVerify = true + } + + if conf.Kong.TLSServerName != "" { + tlsConfig.ServerName = conf.Kong.TLSServerName + } + + if conf.Kong.CACert != "" { + certPool := x509.NewCertPool() + cert, err := ioutil.ReadFile(conf.Kong.CACert) + if err != nil { + glog.Fatalf("failed to read CACert: %s", conf.Kong.CACert) + } + ok := certPool.AppendCertsFromPEM([]byte(cert)) + if !ok { + glog.Fatalf("failed to load CACert: %s", conf.Kong.CACert) + } + tlsConfig.RootCAs = certPool + } + defaultTransport.TLSClientConfig = &tlsConfig c := http.DefaultClient c.Transport = &HeaderRoundTripper{ headers: conf.Kong.Headers, - rt: http.DefaultTransport, + rt: defaultTransport, } kongClient, err := kong.NewClient(kong.String(conf.Kong.URL), c) diff --git a/internal/ingress/controller/controller.go b/internal/ingress/controller/controller.go index 22287cda19..3da1f95bd1 100644 --- a/internal/ingress/controller/controller.go +++ b/internal/ingress/controller/controller.go @@ -42,9 +42,15 @@ const ( ) type Kong struct { - URL string + URL string + // Headers are injected into every request to Kong's Admin API + // to help with authorization/authentication. Headers []string Client *kong.Client + + TLSSkipVerify bool + TLSServerName string + CACert string } // Configuration contains all the settings required by an Ingress controller