-
Notifications
You must be signed in to change notification settings - Fork 8.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[nginx] Support SSL for TCP #636
Comments
@od0 what's the benefit? Sorry to ask but I never used this option in the stream section. |
@aledbf I hadn't used it previously but discovered when trying to set up a SSL service on a port other than 443 (Elasticsearch in this case). I was curious if I could get it to work and discovered that NGINX supports it and it's as simple as adding a https://www.nginx.com/resources/admin-guide/nginx-tcp-ssl-termination/ |
Closing. Using ssl in nginx requires the ssl certificates. |
@aledbf We are trying to use nginx ingress for our What are your thoughts? Do you see issues? |
@naveensrinivasan why not use the ssl passthrough option and terminate ssl in the backend? |
@aledbf doing this dev/local where there aren't certs would be an issue. |
I have a similar use-case as @od0 and @naveensrinivasan, want to terminate a connection to an XMPP server listening on a TCP port for client connections. I have a certificate from letsencrypt stored in a k8s Secret, which is easy to configure for a bunch of REST endpoints, each application having a k8s Ingress where tls.secretName points to the letsencrypt secret. The non-encrypted XMPP port 5222 is easy to forward, however I'd like to have a TLS-version exposed instead, would be ideal to have the certificate and private key in a single Secret, which cert-manager can renew automatically. Or is there an easy workaround where you can terminate SSL on the backend using an existing Secret for the certificate? Examples? Update: In case anybody else needs this, got it working by using an stunnel docker image, https://hub.docker.com/r/dweomer/stunnel/, as a second container in my pod, configured similarly to https://github.com/PalmStoneGames/kube-cert-manager/blob/master/docs/consume-certificates.md to use the key + certificate. You can see which env variables are available to set here: https://github.com/dweomer/dockerfiles-stunnel/blob/master/stunnel.sh. Set |
Wish I found this thread before I opened an identical feature request the other day but commenting here because there's more traction. I realize I am the beggar in this situation but I strongly agree with @od0 and @naveensrinivasan, NGINX is used all over the world today for this exact purpose and I don't see why that functionality should not be exposed when it's deployed as an ingress controller in a Kubernetes cluster. Not every app can terminate |
@aledbf just wanted to share a similar use case as @stela, we are planning to move our XMPP application over to K8s and we need an SSL/TLS-over-TCP termination on the Ingress Controller. We looked at having the termination done on the backend (e.g. using an stunnel for example), but that is not a good fit for us for various reasons. We are now looking into running an haproxy ingress-controller side-by-side just for this application, as it seems to support that option (https://github.com/jcmoraisjr/haproxy-ingress#tcp-services-configmap) however we would prefer to have this in the nginx Ingress Controller and not introduce another piece to the mix. |
@aledbf given your previous statement that this enhancement might be considered, could we re-open the issue? to ensure we track this. Thanks! |
+1 I want to SSL terminate a bunch of services that are not http |
Also from my side the same. I want ingress-nginx able to terminate TLS for tcp (non-http) traffic. Very frustrated about this missing fuctionality |
Any update? Also struggling here. Just realized thsatt it is not working when trying to set it up. That's so basic that I even forgot to assume that it is not possible. |
I'm seeing a bunch of people, including myself, wanting the same thing which NGINX supports. Yet, there is this weird pushback from the maintainers of this project. Why is that? |
There is no such thing. Someone needs to work in this feature. Pull requests are always welcome. That said, in my previous comment.
Is hard to add this or any other additional feature with such restriction. This is the limitation. Also keep in mind Ingress is only about HTTP/HTTPS and the existence of TCP/UDP in this project is because there is no service type=LoadBalancer option in baremetal. I wish I could remove the TCP/UDP feature in a separate project, but sadly it's too late for that. |
Looking forward to seeing this feature, too. I think ingress-nginx should support this since Nginx does. |
What about an update? :-) |
Hey all, I was able to achieve this via a small(and quite bad) hack. --- a/helm-charts/nginx-ingress/nginx/nginx.tmpl
+++ b/helm-charts/nginx-ingress/nginx/nginx.tmpl
@@ -679,15 +679,15 @@ stream {
}
{{ range $address := $all.Cfg.BindAddressIpv4 }}
- listen {{ $address }}:{{ $tcpServer.Port }}{{ if $tcpServer.Backend.ProxyProtocol.Decode }} proxy_protocol{{ end }};
+ listen {{ $address }}:{{ $tcpServer.Port }}{{ if $tcpServer.Backend.ProxyProtocol.Decode }} proxy_protocol{{ end }} proxy_protocol ssl;
{{ else }}
- listen {{ $tcpServer.Port }}{{ if $tcpServer.Backend.ProxyProtocol.Decode }} proxy_protocol{{ end }};
+ listen {{ $tcpServer.Port }}{{ if $tcpServer.Backend.ProxyProtocol.Decode }} proxy_protocol{{ end }} proxy_protocol ssl;
{{ end }}
{{ if $IsIPV6Enabled }}
{{ range $address := $all.Cfg.BindAddressIpv6 }}
- listen {{ $address }}:{{ $tcpServer.Port }}{{ if $tcpServer.Backend.ProxyProtocol.Decode }} proxy_protocol{{ end }};
+ listen {{ $address }}:{{ $tcpServer.Port }}{{ if $tcpServer.Backend.ProxyProtocol.Decode }} proxy_protocol{{ end }} proxy_protocol ssl;
{{ else }}
- listen [::]:{{ $tcpServer.Port }}{{ if $tcpServer.Backend.ProxyProtocol.Decode }} proxy_protocol{{ end }};
+ listen [::]:{{ $tcpServer.Port }}{{ if $tcpServer.Backend.ProxyProtocol.Decode }} proxy_protocol{{ end }} proxy_protocol ssl;
{{ end }}
{{ end }}
proxy_timeout {{ $cfg.ProxyStreamTimeout }};
@@ -695,6 +695,21 @@ stream {
{{ if $tcpServer.Backend.ProxyProtocol.Encode }}
proxy_protocol on;
{{ end }}
+
+ proxy_protocol on;
+
+ ssl_protocols {{ $cfg.SSLProtocols }};
+ ssl_ciphers '{{ $cfg.SSLCiphers }}';
+ ssl_prefer_server_ciphers on;
+
+ # PEM sha: {{ $cfg.DefaultSSLCertificate.PemSHA }}
+ ssl_certificate {{ $cfg.DefaultSSLCertificate.PemFileName }};
+ ssl_certificate_key {{ $cfg.DefaultSSLCertificate.PemFileName }};
+
+
+ ssl_session_cache shared:SSL2:60m;
+ ssl_session_timeout 10h;
+ ssl_handshake_timeout 30s;
}
{{ end }} Reference: |
I've got another problem. I want SSL Passthrough to my mqtt broker but an error has occurred:
I can connect from inside cluster but I have a problem to do it from the outside. So I assume that this is related with NGINX. My config:
SOLUTION
|
I've got this to work based on @sedflix comment, but with some changes in the To get SSL Termination working for TCP backends, I needed to do the following:
Notes:
Reference: |
Please reopen or share the link to the feature request. |
@lmserrano any chance you could share extra details, I tried exactly the same steps as you posted here yet couldn't manage to make it work. Have you came across a different approach recently? thanks for reading. |
@mdiianni I've got it to work with the described steps. In fact it was after I managed to find a working solution that I then documented and organized it to make the post so that it could serve as future reference for myself and for everyone else experiencing the same issue. There are some thumbs ups so it leads me to believe it has been working for other people too. If you have have followed the configuration and it is not working now, it could be possible that the versions you are using could have changed since the time of the post. If you post more details about what you have, you may be able to get more help from the community. Some things worth checking:
If you are using a different cloud provider other than AWS you will also likely have to change some of the controller service annotations. Also, even for AWS, if you use AWS ACM for certificates you will need to configure the respective service annotations. Hope that helps. |
5 years later and this is not a standard feature? lol come on guys. http is not the only thing in the world. I think enough people said why they want to use this. As well, it is highly recommended not to carry ssl traffic through to an MQTT broker. with that said, don't you think this would be a nice feature. Kubernetes is for clusters and besides Redis and Mongo DB this is a pretty important cluster. |
Are we expecting this feature to be developped? @aledbf it could be as simple as having a format with a "-ssl" at the end like
to allow to keep using simple strings |
Alternatively I ended up using a stunnel container sidecar to do the TCP-TLS termination and proxy the connection to the container running the MQTT broker. |
Can you describe better this approach? It would be really appriciated. |
Sure no problem. Basically what happens is:
How to do it, example:
kind: ConfigMap
apiVersion: v1
metadata:
name: stunnel-conf
namespace: default
data:
start.sh: >
#!/bin/sh
apk update
apk add --no-cache ca-certificates stunnel
cat << EOF > /etc/stunnel/stunnel.conf
options = NO_SSLv2
options = NO_SSLv3
options = NO_TLSv1
options = NO_TLSv1.1
CApath = /conf/ssl/
pid = /var/run/stunnel.pid
foreground = yes
debug = 2
[service-tls-tcp]
CAfile = /conf/ssl/ca.crt
cert = /conf/ssl/tls.crt
key = /conf/ssl/tls.key
sslVersion = TLSv1.2
accept = 0.0.0.0:8443
connect = 127.0.0.1:8080
TIMEOUTbusy = 300
TIMEOUTclose = 60
TIMEOUTconnect = 10
TIMEOUTidle = 300
socket = l:SO_LINGER=1:60
retry = no
EOF
echo 'Starting Stunnel TLS termination for TCP Services...'
stunnel /etc/stunnel/stunnel.conf
extraContainers:
- name: stunnel
image: alpine:3.14.0
command: ["sh", "/opt/start.sh"]
volumeMounts:
- name: stunnel-conf
mountPath: /opt/
ports:
- containerPort: 8443
extraVolumes:
- name: stunnel-conf
configMap:
name: stunnel-conf
Sorry I cannot give a full working example right now but hopefully this gives you an idea. |
NGINX supports SSL for opened TCP ports – it would be great to be able to use this feature when specifying TCP ports in the
--tcp-services-configmap
ConfigMap.Right now the template looks like this:
Perhaps a new optional flag in the ConfigMap could be added and the template modified to something like this:
Happy to take a stab at implementing this and open a PR.
Thanks!
The text was updated successfully, but these errors were encountered: