In a previous post we described howto setup Traefik 2 on Kubernetes, please check it out if you are not familiair with Traefik’s custom CRD’s like IngressRoutes etc.
This is part 2 of the series, it will focus on TCP TLS support using Letsencrypt. We will create a simple TCP service in an isolated namespace and expose this service in Traefik securely with TLS.
A major feature of Treafik 2 is it’s support for TCP TLS. This is exciting because Traefik will manage the certificates required for valid TLS connections and offload the secure TLS connection to a normal TCP based service like a NodeJS backend. No more reloads for daemons to activate a new certificate, yay! And finally easy gRPC and HTTP2 connections without the complexity of TLS.
Let’s see how we can create a simple service and then add TLS support for this service using Traefik 2.
In this example we will use Mosquitto as a simple TCP based service, a MQTT broker that works as a pub/sub system for IoT metrics and such. Easy to setup and it does support TLS, however in this case we secure it via Traefik 2 and skip all that hassle.
Step 1) Deploy mosquitto in a namespace
kubectl create namespace mosquitto kubectl -n mosquitto create deployment mosquitto --image=eclipse-mosquitto
Step 2) Expose the mosquitto deployment
We’ll expose the deployment in the namespace.
kubectl -n mosquitto create service clusterip mosquitto --tcp=1883:1883
Step 3) Create an IngressRouteTCP object for Traefik
Save the contents below to a file named mosquitto-traefik-ingress.yaml and apply to the correct namespace. It will create an IngressRouteTCP object for Traefik2 and also apply TLSoptions required for normal operation.
Please note that the TLSoptions are bound to a namespace, so in this example we refer to this object as you can see.
Make sure you change the HostSNI below to a valid hostname that can be used for SSL. As you can see we enable this service on an entrypoint named “mqtt”, make sure you specify this entrypoint in your Traefik deployment!
apiVersion: traefik.containo.us/v1alpha1 kind: IngressRouteTCP metadata: name: mosquitto spec: entryPoints: - mqtt routes: - match: HostSNI(`mqtt.canhaz.domain`) services: - name: mosquitto port: 1883 tls: passthrough: false options: name: default namespace: mosquitto --- apiVersion: traefik.containo.us/v1alpha1 kind: TLSOption metadata: name: default spec: cipherSuites: - TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 - TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305 - TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305 - TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 - TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 minVersion: VersionTLS13 sniStrict: true
Step 4) Test the configuration
In one window run this command to subscribe to the wildcard “#” channel using TLS. Remember to give Traefik some time to generate the certificates.
mosquitto_sub -h mqtt.canhaz.domain -t \# -V mqttv5 -v -p 8883 --capath /etc/ssl/certs
In another window run the following command to publish random payloads to the mqtt broker, which should appear in the other window.
while :; do mosquitto_pub -h mqtt.canhaz.domain -p 8883 -t $RANDOM/$RANDOM/$RANDOM \ -V mqttv5 -m $RANDOM --capath /etc/ssl/certs; sleep 2; done
Treafik 2 TLS with Mosquitto
That’s it, you now have a working setup using Traefik 2 and Mosquitto. It’s secured with the latest TLS1.3 ciphers without ever touching a single .csr, .crt or .pem file!
You can easily test another service with the same approach, the basics are the same, just remember that entrypoints in Traefik are attached to ports and can be configured using the IngressRouteTCP object.
Next post will dive deeper into Traefik with network policies.