ingress-nginx: Nginx doesn't support AEAD-CHACHA20-POLY1305-SHA256 cipher
What happened:
When integrating NGINX with the pinniped (https://pinniped.dev) supervisor, I receive a 502 bad gateway when doing HTTPS to the backend. The logs from the ingress-controller pod shows:
2022/12/04 12:57:24 [error] 102#102: *291951 SSL_do_handshake() failed (SSL: error:1409442E:SSL routines:ssl3_read_bytes:tlsv1 alert protocol version:SSL alert number 70) while SSL handshaking to upstream, client: 127.0.0.1, server: pinniped-supervisor.blog.tremolo.dev, request: "GET / HTTP/2.0", upstream: "https://10.42.0.10:10250/", host: "pinniped-supervisor.blog.tremolo.dev"
2022/12/04 12:57:24 [error] 102#102: *291951 SSL_do_handshake() failed (SSL: error:1409442E:SSL routines:ssl3_read_bytes:tlsv1 alert protocol version:SSL alert number 70) while SSL handshaking to upstream, client: 127.0.0.1, server: pinniped-supervisor.blog.tremolo.dev, request: "GET / HTTP/2.0", upstream: "https://10.42.2.8:10250/", host: "pinniped-supervisor.blog.tremolo.dev"
2022/12/04 12:57:24 [error] 102#102: *291951 SSL_do_handshake() failed (SSL: error:1409442E:SSL routines:ssl3_read_bytes:tlsv1 alert protocol version:SSL alert number 70) while SSL handshaking to upstream, client: 127.0.0.1, server: pinniped-supervisor.blog.tremolo.dev, request: "GET / HTTP/2.0", upstream: "https://10.42.0.10:10250/", host: "pinniped-supervisor.blog.tremolo.dev"
127.0.0.1 - - [04/Dec/2022:12:57:24 +0000] "GET / HTTP/2.0" 502 150 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:107.0) Gecko/20100101 Firefox/107.0" 17 0.005 [pinniped-supervisor-pinniped-supervisor-api-443] [] 10.42.0.10:10250, 10.42.2.8:10250, 10.42.0.10:10250 0, 0, 0 0.003, 0.001, 0.001 502, 502, 502 64ae7a27872728869f931bf68ce46404
What you expected to happen:
HTTPS to the supervisor
NGINX Ingress controller version (exec into the pod and run nginx-ingress-controller --version.):
-------------------------------------------------------------------------------
NGINX Ingress controller
Release: v1.5.1
Build: d003aae913cc25f375deb74f898c7f3c65c06f05
Repository: https://github.com/kubernetes/ingress-nginx
nginx version: nginx/1.21.6
-------------------------------------------------------------------------------
Kubernetes version (use kubectl version
):
Client Version: version.Info{Major:"1", Minor:"25", GitVersion:"v1.25.4", GitCommit:"872a965c6c6526caa949f0c6ac028ef7aff3fb78", GitTreeState:"clean", BuildDate:"2022-11-09T13:28:30Z", GoVersion:"go1.19.3", Compiler:"gc", Platform:"darwin/arm64"}
Kustomize Version: v4.5.7
Server Version: version.Info{Major:"1", Minor:"23", GitVersion:"v1.23.6+k3s1", GitCommit:"418c3fa858b69b12b9cefbcff0526f666a6236b9", GitTreeState:"clean", BuildDate:"2022-04-28T22:16:18Z", GoVersion:"go1.17.5", Compiler:"gc", Platform:"linux/amd64"}
Environment:
- Cloud provider or hardware configuration: Civo
- OS (e.g. from /etc/os-release): N/A
- Kernel (e.g.
uname -a
): N/A - Install tools: Civo
- Basic cluster related info:
kubectl version
kubectl get nodes -o wide
NAME STATUS ROLES AGE VERSION INTERNAL-IP EXTERNAL-IP OS-IMAGE KERNEL-VERSION CONTAINER-RUNTIME
k3s-civo-auth-pinniped-6502-9ec1d5-node-pool-33cd-h3zf4 Ready <none> 36h v1.23.6+k3s1 192.168.1.5 <none> Alpine Linux v3.16 5.15.78-0-virt containerd://1.5.11-k3s2
k3s-civo-auth-pinniped-6502-9ec1d5-node-pool-33cd-xyoyo Ready <none> 36h v1.23.6+k3s1 192.168.1.4 <none> Alpine Linux v3.16 5.15.78-0-virt containerd://1.5.11-k3s2
k3s-civo-auth-pinniped-6502-9ec1d5-node-pool-33cd-kkxy6 Ready <none> 36h v1.23.6+k3s1 192.168.1.3 <none> Alpine Linux v3.16 5.15.78-0-virt containerd://1.5.11-k3s2
-
How was the ingress-nginx-controller installed: Civo marketplace
-
Current State of the controller:
kubectl describe ingressclasses
Name: nginx
Labels: app.kubernetes.io/component=controller
app.kubernetes.io/instance=ingress-nginx
app.kubernetes.io/name=ingress-nginx
app.kubernetes.io/part-of=ingress-nginx
app.kubernetes.io/version=1.5.1
Annotations: <none>
Controller: k8s.io/ingress-nginx
Events: <none>
ingress object:
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
annotations:
kubernetes.io/ingress.class: nginx
nginx.ingress.kubernetes.io/backend-protocol: https
name: pinniped-supervisor
namespace: pinniped-supervisor
spec:
rules:
- host: pinniped-supervisor.blog.tremolo.dev
http:
paths:
- backend:
service:
name: pinniped-supervisor-api
port:
number: 443
path: /
pathType: ImplementationSpecific
tls:
- hosts:
- pinniped-supervisor-api.blog.tremolo.dev
secretName: tls-pinniped-supervisor-api-doesnotexist
- Others:
Here’s the certificate and openssl s_client from pinnped:
CONNECTED(00000005)
depth=0
verify error:num=20:unable to get local issuer certificate
verify return:1
depth=0
verify error:num=21:unable to verify the first certificate
verify return:1
write W BLOCK
---
Certificate chain
0 s:
i:/CN=Pinniped Supervisor Aggregation CA
---
Server certificate
-----BEGIN CERTIFICATE-----
MIIBsjCCAVigAwIBAgIQPUSXuHk1E2n7YHkSZ1/GMTAKBggqhkjOPQQDAjAtMSsw
KQYDVQQDEyJQaW5uaXBlZCBTdXBlcnZpc29yIEFnZ3JlZ2F0aW9uIENBMB4XDTIy
MTIwMzAxMDE1OVoXDTIzMTIwMzAxMDY1OVowADBZMBMGByqGSM49AgEGCCqGSM49
AwEHA0IABLUB2pmk9pHrwcEKsYyXw8qIT73889TdkYBahzbRp+E0TlQN8Vc0Oktr
vrsDfWZv2OrjZTn3fBfL7MZzqoSxAHejgYYwgYMwEwYDVR0lBAwwCgYIKwYBBQUH
AwEwDAYDVR0TAQH/BAIwADAfBgNVHSMEGDAWgBQ7JmbAfML1UU84CC/2sNCuNmJ4
8zA9BgNVHREBAf8EMzAxgi9waW5uaXBlZC1zdXBlcnZpc29yLWFwaS5waW5uaXBl
ZC1zdXBlcnZpc29yLnN2YzAKBggqhkjOPQQDAgNIADBFAiEAvQEb7XU2lFja4/V4
h6TwDtNG6aS6G99mAHO98s+ZHdICIDh3AUJxdpp89Ulu5udbU0N1qxCxGu5SeozU
ds5trUc5
-----END CERTIFICATE-----
subject=
issuer=/CN=Pinniped Supervisor Aggregation CA
---
No client certificate CA names sent
Server Temp Key: ECDH, X25519, 253 bits
---
SSL handshake has read 952 bytes and written 381 bytes
---
New, TLSv1/SSLv3, Cipher is AEAD-CHACHA20-POLY1305-SHA256
Server public key is 256 bit
Secure Renegotiation IS NOT supported
Compression: NONE
Expansion: NONE
No ALPN negotiated
SSL-Session:
Protocol : TLSv1.3
Cipher : AEAD-CHACHA20-POLY1305-SHA256
Session-ID:
Session-ID-ctx:
Master-Key:
Start Time: 1670121814
Timeout : 7200 (sec)
Verify return code: 21 (unable to verify the first certificate)
---
How to reproduce this issue:
- Deploy ingress-nginx w/LoadBalancer
- Deploy pinniped supervisor - kubectl apply -f https://get.pinniped.dev/v0.20.0/install-pinniped-supervisor.yaml
- Create the above Ingress rule
- Access the host
Anything else we need to know:
I tried to get nginx to recognize the AEAD-CHACHA20-POLY1305-SHA256
cipher by setting:
ssl-ciphers: ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:AEAD-CHACHA20-POLY1305-SHA256
in the ingress-nginx-controller ConfigMap
, but didn’t help
About this issue
- Original URL
- State: closed
- Created 2 years ago
- Comments: 16 (8 by maintainers)
Thanks @bmv126 !!! that did the trick. I tried
nginx.ingress.kubernetes.io/proxy-ssl-protocols: "TLSv1.3"
but that didn’t make any change to the result.Hi @mlbiam
From the errors in description, the issue is because of using invalid tls version when communicating to backend pod.
As below is set in ingress resource, communication to backend happens via tls
By default nginx uses older tls v1 version to communicate, as per http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_ssl_protocols
You can update the ingress resource to use supported backend tls versions: I think below should work.
@mlbiam Yes. That is because the tmpl which generates the nginx.conf expects CA file to be provided and does not render only the ssl-protocols.
https://github.com/kubernetes/ingress-nginx/blob/3474c33e15d809ba401b38891a2ed3c4080b751e/rootfs/etc/nginx/template/nginx.tmpl#L1000
This logic can be improved to separate the proxy-protocols from the proxy-ssl-verify requirements.
ingress-nginx --> piniped using HTTPS fails, user sees a 502 from nginx and the log messages from the beginning of this issue appear in the nginx logs.
This is a very confusing statement. I’ve been working with ingress-nginx for five years and have never had to explicitly trust a certificate. Regardless of if the cert is self signed or the CA is self signed. The documentation is pretty clear on this too, that you need to explicitly enable ca verification.
Again, based on my own experience of five years with multiple production deployments and the ingress-nginx docs, this is not a correct statement. So unless this is a new, breaking change something is very off on these statements.
I see that you need to get this working, but I don’t see real clear descriptive data on what is the problem with the ingress-nginx-controller that needs to be fixed.
Other related info I can think of, I have already stated. I can put a certificate from letsencrypt in a pod made from nginx:alpine and it works just fine.
I think the problem is not described well.
ssl-passthrough
. I already saw that you want to terminate on the ingress-nginx-controller so once you have TLS to the app from outside the cluster, you could consider plain-text traffic from ingress-nginx-controller to the pod (if the app offers that)backend-protocol: HTTPS
, then neither the ingress-controller-pod nor any other pod nor any other host has your CA cert inside it to recognize your self-signed cert/assign
And if your backend app requires to terminate TLS then you can try the ssl-passthrough annotation as well. Terminating on the ingress-controller and then using backend-protocol HTTPS means that the pinniped pod or any other pod expecting TLS connections should have a cert with a well known CA as well. Self-signed cert in the backend pod means the CA will not be known outside that pod