Question about E2E Encryption with NGF #3977
Replies: 7 comments
-
Hey @EmekaNnaji, thanks for opening this discussion. I was doing some digging around and I think that if you follow the HTTPS termination guide, and set up your NLB to be TCP, that should enable e2e encryption. To avoid the TLS being terminated on the NLB, having it be TCP makes it so the NLB doesn't touch anything related to the TLS, however the TLS handshake should continue from Client(tls) -> NLB(TCP just forwards request, data should stay encrypted) -> NGINX(Terminate TLS) -> backend. I'm think this solution still enables e2e encryption, basically off loading the tls configuration onto NGF and the gateway api resources instead of on the NLB. Please try it out and let me know if it works, or if you have any other questions. Here's a stackoverflow link that is related: https://stackoverflow.com/questions/67210192/aws-network-load-balancer-ssl-passthrough. |
Beta Was this translation helpful? Give feedback.
-
Hey, Thanks for the quick reply. For reason's outside my control, I'm stuck with using self signed certs currently. Since those would be untrusted by the browser, I'm trying to circumvent that by slapping an ACM cert on the NLB. |
Beta Was this translation helpful? Give feedback.
-
@EmekaNnaji, ok I've looked into it a bit more and from some responses from GPT and this similar stackoverflow link https://stackoverflow.com/questions/70677589/how-to-use-aws-nlb-with-nginx-ingress-controller-for-ssl. I think you can keep the ACM cert on the NLB, though this will result in a tls termination on the NLB. The NLB will then have to open a second tls session to the NGINX Service and I think you can do this by putting the following annotations on the NGINX Service.
Or something similar to the above. You can provide these annotations to the NGINX Service by modifying the This is starting to move outside of my knowledge, but I hope some of this is looking familiar to you and you can build a solution similar to what I provided. |
Beta Was this translation helpful? Give feedback.
-
@bjee19 - Thanks for the pointers. I should note I've done that part. apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
name: cafe-gateway
namespace: nginx-gateway
spec:
gatewayClassName: nginx
infrastructure:
annotations:
service.beta.kubernetes.io/aws-load-balancer-backend-protocol: "ssl"
service.beta.kubernetes.io/aws-load-balancer-nlb-target-type: "ip"
service.beta.kubernetes.io/aws-load-balancer-ssl-cert: arn:aws:acm:us-east-1:xxxxxxxx
listeners:
- name: https
port: 443
protocol: HTTPS
hostname: '*.example.com'
allowedRoutes:
namespaces:
from: All
tls:
mode: Terminate
certificateRefs:
- kind: Secret
name: bootstrap-ingress-gateway-cert
namespace: nginx-gateway apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: argocdv2
namespace: nginx-gateway
spec:
hostnames:
- argocd.example.com
parentRefs:
- name: cafe-gateway
namespace: nginx-gateway
sectionName: https
rules:
- matches:
- path:
type: PathPrefix
value: /
backendRefs:
- name: argocd-server
port: 80
namespace: argocd The problem is specifically comms between the NLB and Nginx. Terminating SSL on the NLB then re-encrypting and passing to the Nginx pod is where the breakdown is. SNI gets dropped at the NLB (My assumption), so all traffic from the NLB to the Nginx Pod match the default server block that then drops the traffic because of server {
listen 443 ssl default_server;
listen [::]:443 ssl default_server;
ssl_reject_handshake on;
} I wondering if there's a sane way to make updates to the nginx config besides my current solution of going into the nginx pod and manually updating that problematic block from what it is above to: server {
listen 443 ssl default_server;
ssl_certificate /etc/nginx/secrets/ssl_keypair_nginx-gateway_bootstrap-ingress-gateway-cert.pem;
ssl_certificate_key /etc/nginx/secrets/ssl_keypair_nginx-gateway_bootstrap-ingress-gateway-cert.pem;
listen [::]:443 ssl default_server;
return 444;
} |
Beta Was this translation helpful? Give feedback.
-
@EmekaNnaji, ok I'm starting to understand more. Just verifying, what version of NGF are you running? If it is 2.X+, you shouldn't be able to modify the nginx conf like such, so I'm wondering how you're doing that. We have a better way of injecting nginx conf through the use of SnippetsFilters, but that doesn't have the ability to remove nginx conf (or rewrite that default_server block). Could you also paste the full nginx conf that makes your traffic flow? |
Beta Was this translation helpful? Give feedback.
-
@bjee19 - I'm running version 2.1.2:
here's the modified conf that works:
Main difference between the 2 being what I pointed out prior. Here's what I'm seeing in the logs: |
Beta Was this translation helpful? Give feedback.
-
Hey @EmekaNnaji, thanks for posting the full nginx conf, this helps a lot. I'm wondering in the fixed version, how traffic actually reaches the backend. From the information I gathered online, when the nlb terminates ssl from the client and re-encrypts it to nginx the sni should be getting dropped (what you were already thinking). So when the request reaches nginx it should never reach the argocd block you posted:
But should instead always hit the default_server block you modified:
Since you modified it to include the ssl cert/key and return 444, the tls handshake will work and pass, however traffic won't get proxied to any upstream. It'll just drop it there. If, in the case some traffic does make it to the upstream, that means it must have somehow had the server_name
Should work since it won't go into the default_server block. With your modified nginx conf, are you seeing traffic reach your argocd backend? |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
-
How can I enable E2E encryption in AWS EKS using NGF? I've tried using a TLS listener with a cert with a TLS TG to the Nginx Pod. Basically, I want Client (TLS) -> NLB (TLS) -> Nginx (Terminate TLS) -> Backend.I keep seeing client closed connection while SSL handshaking, client: x.x.x.x, server: 0.0.0.0:443. I'm able to get my flow working my editing the generated Nginx Conf, specifically this block from:
to
Then disabling SNI:
I feel like there's definitely a better way to accomplish this, just not sure how.
Beta Was this translation helpful? Give feedback.
All reactions