Search code examples
amazon-eksnginx-ingressnlb

Client certificate authentication using NGINX Ingress behind AWS NLB


I'm attempting to secure some kubernetes ingress endpoints, and client certificate authentication would be ideal. I currently have NGINX Ingress deployed inside EKS, with an AWS NLB in front. The NLB is doing the TLS termination and NGINX is doing the actual routing to various services.

I've successfully used HTTP Basic Auth using annotations on the ingress resources. For example

nginx.ingress.kubernetes.io/auth-realm: Authentication Required
nginx.ingress.kubernetes.io/auth-secret: basic-auth
nginx.ingress.kubernetes.io/auth-type: basic
nginx.ingress.kubernetes.io/proxy-body-size: 8m
nginx.ingress.kubernetes.io/rewrite-target: /loki/$1text

Now if I switch to client cert auth I see that no authentication happens.

nginx.ingress.kubernetes.io/auth-tls-error-page: http://www.example.com/error-cert.html
nginx.ingress.kubernetes.io/auth-tls-pass-certificate-to-upstream: false
nginx.ingress.kubernetes.io/auth-tls-secret: default/ca-secret
nginx.ingress.kubernetes.io/auth-tls-verify-client: on
nginx.ingress.kubernetes.io/auth-tls-verify-depth: 1

From reading, it seems I need to combine this with the TLS negotiation/termination, but this is happening at the AWS NLB level. Is there a way to accomplish what I'm looking for?

I don't see a way to do client certificate authentication at the NLB level, nor to delay the TLS termination to the NGINX Ingress Controller.


Solution

  • Network Load Balancers do not support mutual TLS authentication (mTLS). For mTLS support, you need to create a TCP listener instead of a TLS listener. When configured this way, the load balancer will pass through the request as-is, allowing you to implement mTLS on the target, i.e. NGINX.