From fa60fb9366beb9349b97750f5b6ebbd51419380b Mon Sep 17 00:00:00 2001 From: Sam Lai Date: Thu, 21 Oct 2021 22:44:39 +0100 Subject: [PATCH] fix(inputs/kube_inventory): set TLS server name config properly The TLS config currently always sets the ServerName to the same as the baseURL. A URL is not a valid value, e.g. `https://kubernetes.example.com:6443` is not a valid ServerName value; the matching ServerName value should be `kubernetes.example.com`. This results in an error like - ``` 2021-10-21T12:15:40Z E! [inputs.kube_inventory] Error in plugin: Get "https://kubernetes.example.com:6443/apis/apps/v1/namespaces/default/deployments": x509: certificate is valid for kubernetes, kubernetes.default, kubernetes.default.svc, kubernetes.default.svc.cluster.local, localhost, kubernetes.example.com, not https://kubernetes.example.com:6443 ``` The ServerName value is not read from config, so I'm not sure why this currently works for anyone, unless they disable TLS verification through the `insecure_skip_verify` setting. The fix is to set ServerName to the `tls_server_name` config value if set, otherwise leave it blank, in which case, it will automatically use the hostname (https://github.com/kubernetes/client-go/blob/master/rest/config.go#L219). I can confirm that the inputs/kubernetes plugin does this (although it doesn't use the k8s client-go library), and it works properly by passing through the `tls_server_name` value or leaving it blank. --- plugins/inputs/kube_inventory/README.md | 2 ++ plugins/inputs/kube_inventory/client.go | 2 +- plugins/inputs/kube_inventory/kube_state.go | 1 + 3 files changed, 4 insertions(+), 1 deletion(-) diff --git a/plugins/inputs/kube_inventory/README.md b/plugins/inputs/kube_inventory/README.md index 7803d4fc4e9eb..06e6020c5f8d1 100644 --- a/plugins/inputs/kube_inventory/README.md +++ b/plugins/inputs/kube_inventory/README.md @@ -74,6 +74,8 @@ avoid cardinality issues: # tls_cert = "/path/to/certfile" ## Used for TLS client certificate authentication # tls_key = "/path/to/keyfile" + ## Send the specified TLS server name via SNI + # tls_server_name = "kubernetes.example.com" ## Use TLS but skip chain & host verification # insecure_skip_verify = false diff --git a/plugins/inputs/kube_inventory/client.go b/plugins/inputs/kube_inventory/client.go index 66455b004f918..da03c643283fe 100644 --- a/plugins/inputs/kube_inventory/client.go +++ b/plugins/inputs/kube_inventory/client.go @@ -23,7 +23,7 @@ type client struct { func newClient(baseURL, namespace, bearerToken string, timeout time.Duration, tlsConfig tls.ClientConfig) (*client, error) { c, err := kubernetes.NewForConfig(&rest.Config{ TLSClientConfig: rest.TLSClientConfig{ - ServerName: baseURL, + ServerName: tlsConfig.ServerName, Insecure: tlsConfig.InsecureSkipVerify, CAFile: tlsConfig.TLSCA, CertFile: tlsConfig.TLSCert, diff --git a/plugins/inputs/kube_inventory/kube_state.go b/plugins/inputs/kube_inventory/kube_state.go index 24db993dd39bb..f2e1ce6280a25 100644 --- a/plugins/inputs/kube_inventory/kube_state.go +++ b/plugins/inputs/kube_inventory/kube_state.go @@ -80,6 +80,7 @@ var sampleConfig = ` # tls_ca = "/path/to/cafile" # tls_cert = "/path/to/certfile" # tls_key = "/path/to/keyfile" + # tls_server_name = "kubernetes.example.com" ## Use TLS but skip chain & host verification # insecure_skip_verify = false `