SSL Passthrough via Kubernetes Ingress

Arun Barua
2 min readJan 24, 2023
Photo by Franck on Unsplash

Your microservice is ready to ship to your Kubernetes cluster. It supports mutual TLS (mTLS) via x509 certificates. Perhaps you’re using SPIFFE and Spire to obtain your TLS certificates.

You also want your service to be available from outside your cluster; and that’s OK because of the security provided via mTLS.

Creating a LoadBalancer service is a fine option. But, perhaps you’re limited by your infrastructure — perhaps LoadBalancer is not supported, perhaps you’re restricted in the number of IP addresses available to support the port of your choice, perhaps configuring DNS to the allocated IP is a tedious process and something you’re keen to avoid.

That leaves us with Ingress. All that is now needed is for ingress to passthrough SSL. Otherwise, ingress will terminate SSL and initiate it’s own connection preventing the service from validating the originating app via x509.

This requires 2 steps:

  1. Configure SSL passthrough on the ingress controller.
  2. Annotate your service with ssl-passthrough.

Step #1 is a one-time activity. Perhaps this is already done and you can skip straight through to step #2.

NGINX Ingress Controller — enabling SSL passthrough

Check your nginx ingress controller:

$ kubectl -n ingress-nginx get deployment/ingress-nginx-controller -o yaml

You’re looking for `— enable-ssl-passthrough` to be passed through to the controller as an argument:

apiVersion: apps/v1
kind: Deployment
...
spec:
template:
spec:
containers:
- args:
...
- --enable-ssl-passthrough

If that’s not the case, you can add that in by editing the deployment inline or patching the deployment:

$ kubectl -n ingress-nginx patch deployment/ingress-nginx-controller --patch-file patch.yml
spec:
template:
spec:
containers:
- name: controller
args:
- /nginx-ingress-controller
- --publish-service=$(POD_NAMESPACE)/ingress-nginx-controller
- --election-id=ingress-nginx-leader
- --controller-class=k8s.io/ingress-nginx
- --ingress-class=nginx
- --configmap=$(POD_NAMESPACE)/ingress-nginx-controller
- --validating-webhook=:8443
- --validating-webhook-certificate=/usr/local/certificates/cert
- --validating-webhook-key=/usr/local/certificates/key
- --enable-ssl-passthrough

Note: Patch replaces the args, so be sure to check the existing args and make a perfect copy if needed before adding the enable-ssl-passthrough flag.

Annotating the Ingress service

The service that fronts your microservice needs to be annotated to ask the ingress controller to passthrough SSL for the appropriate domain.

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: your-ingress-name
namespace: your-namespace
annotations:
nginx.ingress.kubernetes.io/backend-protocol: "HTTPS"
nginx.ingress.kubernetes.io/ssl-passthrough: "true"
nginx.ingress.kubernetes.io/ssl-redirect: "true"
spec:
ingressClassName: nginx
rules:
- host: your-domain-name
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: your-service-name
port:
number: 443

Summary

This post is a recipe on enabling ssl-passthrough for your service, should you need it.

The usecase for mTLS is highlighted; but perhaps you have your own reasons. Do share in the comments.

The post focuses on nginx which is probably the most common ingress controller. Please leave comments if you’d like to see corresponding configurations for other controller technologies.

--

--

Arun Barua

Passionate about Software Engineering. Go evangelist.