diff --git a/vertical-pod-autoscaler/pkg/admission-controller/README.md b/vertical-pod-autoscaler/pkg/admission-controller/README.md index e0ee63a199b..9e8b67c5b93 100644 --- a/vertical-pod-autoscaler/pkg/admission-controller/README.md +++ b/vertical-pod-autoscaler/pkg/admission-controller/README.md @@ -32,6 +32,8 @@ up the changes: ```sudo systemctl restart kubelet.service``` for pods on their creation & updates. 1. You can specify a path for it to register as a part of the installation process by setting `--register-by-url=true` and passing `--webhook-address` and `--webhook-port`. +1. You can specify a minimum TLS version with `--min-tls-version` with acceptable values being `tls1_2` (default), or `tls1_3`. +1. You can also specify a comma or colon separated list of ciphers for the server to use with `--tls-ciphers` if `--min-tls-version` is set to `tls1_2`. ## Implementation diff --git a/vertical-pod-autoscaler/pkg/admission-controller/config.go b/vertical-pod-autoscaler/pkg/admission-controller/config.go index fc6f143d0d4..231d7772bfd 100644 --- a/vertical-pod-autoscaler/pkg/admission-controller/config.go +++ b/vertical-pod-autoscaler/pkg/admission-controller/config.go @@ -19,6 +19,8 @@ package main import ( "context" "crypto/tls" + "fmt" + "strings" "time" admissionregistration "k8s.io/api/admissionregistration/v1" @@ -31,14 +33,43 @@ const ( webhookConfigName = "vpa-webhook-config" ) -func configTLS(serverCert, serverKey []byte) *tls.Config { +func configTLS(serverCert, serverKey []byte, minTlsVersion, ciphers string) *tls.Config { + var tlsVersion uint16 + var ciphersuites []uint16 + reverseCipherMap := make(map[string]uint16) sCert, err := tls.X509KeyPair(serverCert, serverKey) if err != nil { klog.Fatal(err) } + + for _, c := range tls.CipherSuites() { + reverseCipherMap[c.Name] = c.ID + } + for _, c := range strings.Split(strings.ReplaceAll(ciphers, ",", ":"), ":") { + cipher, ok := reverseCipherMap[c] + if ok { + ciphersuites = append(ciphersuites, cipher) + } + } + if len(ciphersuites) == 0 { + ciphersuites = nil + } + + switch minTlsVersion { + case "": + fallthrough + case "tls1_2": + tlsVersion = tls.VersionTLS12 + case "tls1_3": + tlsVersion = tls.VersionTLS13 + default: + klog.Fatal(fmt.Errorf("Unable to determine value for --min-tls-version (%s), must be either tls1_2 or tls1_3", minTlsVersion)) + } + return &tls.Config{ - MinVersion: tls.VersionTLS12, + MinVersion: tlsVersion, Certificates: []tls.Certificate{sCert}, + CipherSuites: ciphersuites, } } diff --git a/vertical-pod-autoscaler/pkg/admission-controller/main.go b/vertical-pod-autoscaler/pkg/admission-controller/main.go index dd060c98563..7dde2245d62 100644 --- a/vertical-pod-autoscaler/pkg/admission-controller/main.go +++ b/vertical-pod-autoscaler/pkg/admission-controller/main.go @@ -59,6 +59,8 @@ var ( tlsCertFile: flag.String("tls-cert-file", "/etc/tls-certs/serverCert.pem", "Path to server certificate PEM file."), tlsPrivateKey: flag.String("tls-private-key", "/etc/tls-certs/serverKey.pem", "Path to server certificate key PEM file."), } + ciphers = flag.String("tls-ciphers", "", "A comma-separated or colon-separated list of ciphers to accept. Only works when min-tls-version is set to tls1_2.") + minTlsVersion = flag.String("min-tls-version", "tls1_2", "The minimum TLS version to accept. Must be set to either tls1_2 (default) or tls1_3.") port = flag.Int("port", 8000, "The port to listen on.") address = flag.String("address", ":8944", "The address to expose Prometheus metrics.") @@ -131,7 +133,7 @@ func main() { }) server := &http.Server{ Addr: fmt.Sprintf(":%d", *port), - TLSConfig: configTLS(certs.serverCert, certs.serverKey), + TLSConfig: configTLS(certs.serverCert, certs.serverKey, *minTlsVersion, *ciphers), } url := fmt.Sprintf("%v:%v", *webhookAddress, *webhookPort) go func() {