SSL Passthrough via Kubernetes Ingress

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:

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.

--

--

Passionate about Software Engineering. Go evangelist.

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store