From b8f7ea05c4a93a244646a9a4b138a9296a995081 Mon Sep 17 00:00:00 2001 From: Arno Uhlig Date: Thu, 5 Oct 2017 13:26:07 +0200 Subject: [PATCH] configurable ssl_verify_client --- controllers/nginx/configuration.md | 7 +++++++ .../nginx/rootfs/etc/nginx/template/nginx.tmpl | 2 +- core/pkg/ingress/annotations/authtls/main.go | 17 +++++++++++++++++ examples/auth/client-certs/nginx/README.md | 1 + .../auth/client-certs/nginx/nginx-tls-auth.yaml | 1 + 5 files changed, 27 insertions(+), 1 deletion(-) diff --git a/controllers/nginx/configuration.md b/controllers/nginx/configuration.md index b76bf1955..f1f8d8f9a 100644 --- a/controllers/nginx/configuration.md +++ b/controllers/nginx/configuration.md @@ -47,6 +47,7 @@ The following annotations are supported: |[ingress.kubernetes.io/auth-url](#external-authentication)|string| |[ingress.kubernetes.io/auth-tls-secret](#certificate-authentication)|string| |[ingress.kubernetes.io/auth-tls-verify-depth](#certificate-authentication)|number| +|[ingress.kubernetes.io/auth-tls-verify-client](#certificate-authentication)|string| |[ingress.kubernetes.io/auth-tls-error-page](#certificate-authentication)|string| |[ingress.kubernetes.io/base-url-scheme](#rewrite)|string| |[ingress.kubernetes.io/client-body-buffer-size](#client-body-buffer-size)|string| @@ -155,6 +156,12 @@ ingress.kubernetes.io/auth-tls-verify-depth The validation depth between the provided client certificate and the Certification Authority chain. +``` +ingress.kubernetes.io/auth-tls-verify-client +``` + +Enables verification of client certificates. + ``` ingress.kubernetes.io/auth-tls-error-page ``` diff --git a/controllers/nginx/rootfs/etc/nginx/template/nginx.tmpl b/controllers/nginx/rootfs/etc/nginx/template/nginx.tmpl index bc99eb331..566d6e46a 100644 --- a/controllers/nginx/rootfs/etc/nginx/template/nginx.tmpl +++ b/controllers/nginx/rootfs/etc/nginx/template/nginx.tmpl @@ -636,7 +636,7 @@ stream { {{ if not (empty $server.CertificateAuth.CAFileName) }} # PEM sha: {{ $server.CertificateAuth.PemSHA }} ssl_client_certificate {{ $server.CertificateAuth.CAFileName }}; - ssl_verify_client on; + ssl_verify_client {{ $server.CertificateAuth.VerifyClient }}; ssl_verify_depth {{ $server.CertificateAuth.ValidationDepth }}; {{ if not (empty $server.CertificateAuth.ErrorPage)}} error_page 495 496 = {{ $server.CertificateAuth.ErrorPage }}; diff --git a/core/pkg/ingress/annotations/authtls/main.go b/core/pkg/ingress/annotations/authtls/main.go index 30a1a04fc..dd8885eb5 100644 --- a/core/pkg/ingress/annotations/authtls/main.go +++ b/core/pkg/ingress/annotations/authtls/main.go @@ -24,20 +24,28 @@ import ( ing_errors "k8s.io/ingress/core/pkg/ingress/errors" "k8s.io/ingress/core/pkg/ingress/resolver" "k8s.io/ingress/core/pkg/k8s" + "regexp" ) const ( // name of the secret annotationAuthTLSSecret = "ingress.kubernetes.io/auth-tls-secret" + annotationAuthVerifyClient = "ingress.kubernetes.io/auth-tls-verify-client" annotationAuthTLSDepth = "ingress.kubernetes.io/auth-tls-verify-depth" annotationAuthTLSErrorPage = "ingress.kubernetes.io/auth-tls-error-page" defaultAuthTLSDepth = 1 + defaultAuthVerifyClient = "on" +) + +var ( + authVerifyClientRegex = regexp.MustCompile(`on|off|optional|optional_no_ca`) ) // AuthSSLConfig contains the AuthSSLCert used for muthual autentication // and the configured ValidationDepth type AuthSSLConfig struct { resolver.AuthSSLCert + VerifyClient string `json:"verify_client"` ValidationDepth int `json:"validationDepth"` ErrorPage string `json:"errorPage"` } @@ -53,6 +61,9 @@ func (assl1 *AuthSSLConfig) Equal(assl2 *AuthSSLConfig) bool { if !(&assl1.AuthSSLCert).Equal(&assl2.AuthSSLCert) { return false } + if assl1.VerifyClient != assl2.VerifyClient { + return false + } if assl1.ValidationDepth != assl2.ValidationDepth { return false } @@ -89,6 +100,11 @@ func (a authTLS) Parse(ing *extensions.Ingress) (interface{}, error) { return &AuthSSLConfig{}, ing_errors.NewLocationDenied(err.Error()) } + tlsVerifyClient, err := parser.GetStringAnnotation(annotationAuthVerifyClient, ing) + if err != nil || !authVerifyClientRegex.MatchString(tlsVerifyClient) { + tlsVerifyClient = defaultAuthVerifyClient + } + tlsdepth, err := parser.GetIntAnnotation(annotationAuthTLSDepth, ing) if err != nil || tlsdepth == 0 { tlsdepth = defaultAuthTLSDepth @@ -108,6 +124,7 @@ func (a authTLS) Parse(ing *extensions.Ingress) (interface{}, error) { return &AuthSSLConfig{ AuthSSLCert: *authCert, + VerifyClient: tlsVerifyClient, ValidationDepth: tlsdepth, ErrorPage: errorpage, }, nil diff --git a/examples/auth/client-certs/nginx/README.md b/examples/auth/client-certs/nginx/README.md index d3da9d1a6..70e440e7c 100644 --- a/examples/auth/client-certs/nginx/README.md +++ b/examples/auth/client-certs/nginx/README.md @@ -31,6 +31,7 @@ Certificate Authentication is achieved through 2 annotations on the Ingress, as | --- | --- | --- | |ingress.kubernetes.io/auth-tls-secret|Sets the secret that contains the authorized CA Chain|string| |ingress.kubernetes.io/auth-tls-verify-depth|The verification depth Certificate Authentication will make|number (default to 1)| +|ingress.kubernetes.io/auth-tls-verify-client|Enables verification of client certificates|string (default to on)| |ingress.kubernetes.io/auth-tls-error-page|The page that user should be redirected in case of Auth error|string (default to empty| The following command instructs the controller to enable TLS authentication using the secret from the ``ingress.kubernetes.io/auth-tls-secret`` diff --git a/examples/auth/client-certs/nginx/nginx-tls-auth.yaml b/examples/auth/client-certs/nginx/nginx-tls-auth.yaml index c3ef92a8e..fe920a0f9 100644 --- a/examples/auth/client-certs/nginx/nginx-tls-auth.yaml +++ b/examples/auth/client-certs/nginx/nginx-tls-auth.yaml @@ -5,6 +5,7 @@ metadata: # Create this with kubectl create secret generic caingress --from-file=ca.crt --namespace=default ingress.kubernetes.io/auth-tls-secret: "default/caingress" ingress.kubernetes.io/auth-tls-verify-depth: "3" + ingress.kubernetes.io/auth-tls-verify-client: "on" auth-tls-error-page: "http://www.mysite.com/error-cert.html" kubernetes.io/ingress.class: "nginx" name: nginx-test