diff --git a/configuration/entrypoints.go b/configuration/entrypoints.go index 0d3e325805..5695f2da08 100644 --- a/configuration/entrypoints.go +++ b/configuration/entrypoints.go @@ -237,9 +237,11 @@ func makeEntryPointTLS(result map[string]string) (*tls.TLS, error) { files := tls.FilesOrContents{} files.Set(result["ca"]) optional := toBool(result, "ca_optional") + skipVerify := toBool(result, "ca_skipverify") configTLS.ClientCA = tls.ClientCA{ - Files: files, - Optional: optional, + Files: files, + Optional: optional, + SkipVerify: skipVerify, } } diff --git a/server/server.go b/server/server.go index d40c1719cd..6460839d74 100644 --- a/server/server.go +++ b/server/server.go @@ -17,7 +17,7 @@ import ( "sync" "time" - "github.com/armon/go-proxyproto" + proxyproto "github.com/armon/go-proxyproto" "github.com/containous/mux" "github.com/containous/traefik/cluster" "github.com/containous/traefik/configuration" @@ -461,9 +461,17 @@ func (s *Server) createTLSConfig(entryPointName string, tlsOption *traefiktls.TL } config.ClientCAs = pool if tlsOption.ClientCA.Optional { - config.ClientAuth = tls.VerifyClientCertIfGiven + if tlsOption.ClientCA.SkipVerify { + config.ClientAuth = tls.RequestClientCert + } else { + config.ClientAuth = tls.VerifyClientCertIfGiven + } } else { - config.ClientAuth = tls.RequireAndVerifyClientCert + if tlsOption.ClientCA.SkipVerify { + config.ClientAuth = tls.RequireAnyClientCert + } else { + config.ClientAuth = tls.RequireAndVerifyClientCert + } } } diff --git a/tls/tls.go b/tls/tls.go index ea56dc8ab8..e3ce19b6a8 100644 --- a/tls/tls.go +++ b/tls/tls.go @@ -16,8 +16,9 @@ const ( // ClientCA defines traefik CA files for a entryPoint // and it indicates if they are mandatory or have just to be analyzed if provided type ClientCA struct { - Files FilesOrContents - Optional bool + Files FilesOrContents + Optional bool + SkipVerify bool } // TLS configures TLS for an entry point diff --git a/types/types.go b/types/types.go index 52844053f1..49121135ac 100644 --- a/types/types.go +++ b/types/types.go @@ -17,7 +17,7 @@ import ( "github.com/containous/traefik/log" traefiktls "github.com/containous/traefik/tls" "github.com/mitchellh/hashstructure" - "github.com/ryanuber/go-glob" + glob "github.com/ryanuber/go-glob" ) // Backend holds backend configuration. @@ -510,6 +510,7 @@ func (b *Buckets) SetValue(val interface{}) { type ClientTLS struct { CA string `description:"TLS CA" json:"ca,omitempty"` CAOptional bool `description:"TLS CA.Optional" json:"caOptional,omitempty"` + CASkipVerify bool `description:"TLS CA.SkipVerify" json:"caSkipVerify,omitempty"` Cert string `description:"TLS cert" json:"cert,omitempty"` Key string `description:"TLS key" json:"key,omitempty"` InsecureSkipVerify bool `description:"TLS insecure skip verify" json:"insecureSkipVerify,omitempty"` @@ -537,10 +538,19 @@ func (clientTLS *ClientTLS) CreateTLSConfig() (*tls.Config, error) { if !caPool.AppendCertsFromPEM(ca) { return nil, fmt.Errorf("failed to parse CA") } + if clientTLS.CAOptional { - clientAuth = tls.VerifyClientCertIfGiven + if clientTLS.CASkipVerify { + clientAuth = tls.RequestClientCert + } else { + clientAuth = tls.VerifyClientCertIfGiven + } } else { - clientAuth = tls.RequireAndVerifyClientCert + if clientTLS.CASkipVerify { + clientAuth = tls.RequireAnyClientCert + } else { + clientAuth = tls.RequireAndVerifyClientCert + } } }