From 262c326dd25c5725fe24052be85784c9ec8c0852 Mon Sep 17 00:00:00 2001 From: Alexander Yastrebov Date: Mon, 21 Oct 2024 18:23:24 +0200 Subject: [PATCH] skipper: add TLS client authentication config (#3281) Add an option and a flag to configure TLS Client Authentication policy of the Server. Fixes https://github.com/zalando/skipper/issues/3280 Signed-off-by: Alexander Yastrebov --- config/config.go | 22 +++++++++++++++++++++- skipper.go | 5 +++++ 2 files changed, 26 insertions(+), 1 deletion(-) diff --git a/config/config.go b/config/config.go index aaaf4f45c0..ca22edfe35 100644 --- a/config/config.go +++ b/config/config.go @@ -217,7 +217,8 @@ type Config struct { Certificates []tls.Certificate `yaml:"-"` // TLS version - TLSMinVersion string `yaml:"tls-min-version"` + TLSMinVersion string `yaml:"tls-min-version"` + TLSClientAuth tls.ClientAuthType `yaml:"tls-client-auth"` // Exclude insecure cipher suites ExcludeInsecureCipherSuites bool `yaml:"exclude-insecure-cipher-suites"` @@ -523,6 +524,9 @@ func NewConfig() *Config { // TLS version flag.StringVar(&cfg.TLSMinVersion, "tls-min-version", defaultMinTLSVersion, "minimal TLS Version to be used in server, proxy and client connections") + flag.Func("tls-client-auth", "TLS client authentication policy for server, one of: "+ + "NoClientCert, RequestClientCert, RequireAnyClientCert, VerifyClientCertIfGiven or RequireAndVerifyClientCert. "+ + "See https://pkg.go.dev/crypto/tls#ClientAuthType for details.", cfg.setTLSClientAuth) // Exclude insecure cipher suites flag.BoolVar(&cfg.ExcludeInsecureCipherSuites, "exclude-insecure-cipher-suites", false, "excludes insecure cipher suites") @@ -727,6 +731,7 @@ func (c *Config) ToOptions() skipper.Options { DebugListener: c.DebugListener, CertPathTLS: c.CertPathTLS, KeyPathTLS: c.KeyPathTLS, + TLSClientAuth: c.TLSClientAuth, CipherSuites: c.filterCipherSuites(), MaxLoopbacks: c.MaxLoopbacks, DefaultHTTPStatus: c.DefaultHTTPStatus, @@ -1047,6 +1052,21 @@ func (c *Config) getMinTLSVersion() uint16 { return tlsVersionTable[defaultMinTLSVersion] } +func (c *Config) setTLSClientAuth(s string) error { + var ok bool + c.TLSClientAuth, ok = map[string]tls.ClientAuthType{ + "NoClientCert": tls.NoClientCert, + "RequestClientCert": tls.RequestClientCert, + "RequireAnyClientCert": tls.RequireAnyClientCert, + "VerifyClientCertIfGiven": tls.VerifyClientCertIfGiven, + "RequireAndVerifyClientCert": tls.RequireAndVerifyClientCert, + }[s] + if !ok { + return fmt.Errorf("unsupported TLS client authentication type") + } + return nil +} + func (c *Config) filterCipherSuites() []uint16 { if !c.ExcludeInsecureCipherSuites { return nil diff --git a/skipper.go b/skipper.go index e0a3fc8f31..19e24f027f 100644 --- a/skipper.go +++ b/skipper.go @@ -617,6 +617,10 @@ type Options struct { // multiple keys, the order must match the one given in CertPathTLS KeyPathTLS string + // TLSClientAuth sets the policy the server will follow for + // TLS Client Authentication, see [tls.ClientAuthType] + TLSClientAuth tls.ClientAuthType + // TLS Settings for Proxy Server ProxyTLS *tls.Config @@ -1198,6 +1202,7 @@ func (o *Options) tlsConfig(cr *certregistry.CertRegistry) (*tls.Config, error) config := &tls.Config{ MinVersion: o.TLSMinVersion, + ClientAuth: o.TLSClientAuth, } if o.CipherSuites != nil {