Question
I'm currently playing with NGINX ingress controller in my k8s cluster. I was trying to make end-to-end encryption work and I was able to make the connection secure all the way to the pod.
In order to achieve HTTPS all the way till pod, I had to use annotation
nginx.ingress.kubernetes.io/backend-protocol: "HTTPS"
Sample Ingress:
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: foo-api-ingress
annotations:
kubernetes.io/ingress.class: "nginx"
nginx.ingress.kubernetes.io/backend-protocol: "HTTPS"
spec:
tls:
- hosts:
- foo.example.com
secretName: foo-cert
rules:
- host: foo.example.com
http:
paths:
- path: /path1
backend:
serviceName: foo-api-path1-service
servicePort: 443
- path: /path2
backend:
serviceName: foo-api-path2-service
servicePort: 443
I'm confused in terms of how exactly this happens because when we encrypt the connection path also get encrypted then how NGINX does path-based routing? does it decrypt the connection at ingress and re-encrypt it? also, does performance get affected by using this method?
Answer
TL;DR
does it decrypt the connection at ingress and re-encrypt it?
In short, yes. Please see the explanation below.
Explanation
The path that a request is travelling to get to a Pod
can be seen as:
Assuming that we have an Ingress controller
(nginx-ingress
) in place of an
Ingress
you can have several ways to connect your client with a Pod
(simplified):
- Unencrypted:
client
-- (HTTP) -->Ingress controller
-- (HTTP) -->Service
---->Pod
- Encrypted at the
Ingress controller
(withnginx.ingress.kubernetes.io/backend-protocol: "HTTPS"
)client
-- (HTTP) -->Ingress controller
-- (HTTP S ) -->Service
---->Pod
- Encrypted and decrypted at the
Ingress controller
where TLS Termination happens:client
-- (HTTP S ) -->Ingress controller
(TLS Termination) -- (HTTP) -->Service
---->Pod
Your setup:
- Encrypted and decrypted at the
Ingress
controller where TLS Termination happens and encrypted once again when connecting with a HTTPS backend bynginx.ingress.kubernetes.io/backend-protocol: "HTTPS"
:client
-- (HTTP S ) -->Ingress controller
(TLS Termination) -- (HTTP S ) -->Service
---->Pod
- Encrypted and decrypted at the
Pod
whereIngress controller
is configured with SSL Passthrough:client
-- (HTTP S ) -->Ingress controller
-- (HTTP S ) -->Service
---->Pod
Disclaimer!
This is only a simplified explanation. For more reference you can look at this comment:
there is a missing detail here, the SSL Passthrough traffic never reaches NGINX in the ingress controller. There is a go listener for TLS connections that just pipes the traffic to the service defined in the ingress.
For more reference you can look on the similar question (with an answer):
You can also check this article with example setup similar to yours:
Additional resources: