mutual TLS based on specific IP

4/15/2019

I'm trying to configure nginx-ingress for mutual TLS but only for specific remote address. I tried to use snippet but no success:

nginx.ingress.kubernetes.io/configuration-snippet: |
  if ($remote_addr = 104.214.x.x) {
    auth-tls-verify-client: on;
    auth-tls-secret: namespace/nginx-ca-secret;
    auth-tls-verify-depth: 1;
    auth-tls-pass-certificate-to-upstream: false;
  }

The auth-tls annotations work when applied as annotations, but inside the snippet they don't.

Any idea how to configure this or maybe a workaround to make it work?

-- vasilis
kubernetes
kubernetes-ingress
nginx-ingress

1 Answer

5/2/2019

The job of mTLS is basically restricting access to a service by requiring the client to present a certificate. If you expose a service and then require only clients with specific IP addresses to present a certificate, the entire rest of the world can still access your service without a certificate, which completely defeats the point of mTLS.

If you want more info, here is a good article that explains why TLS and mTLS exist and what is the difference between them.

There are two ways to make a sensible setup out of this:

  1. Just use regular TLS instead of mTLS
  2. Make a service in your cluster require mTLS to access it regardless of IP addresses

If you go for option 2, you need to configure the service itself to use mTLS, and then configure ingress to pass through the client certificate to the service. Here's a sample configuration for nginx ingress that will work with a service that expects mTLS:

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: mtls-sample
  annotations:
    nginx.ingress.kubernetes.io/backend-protocol: "https"
    nginx.ingress.kubernetes.io/auth-tls-pass-certificate-to-upstream: "true"
spec:
  rules:
    - http:
        paths:
          - path: /hello
            backend:
              serviceName: mtls-svc
              servicePort: 443
-- Shnatsel
Source: StackOverflow