Multiple MQTT services with TCP router and no TLS

I'm trying to expose mosquito MQTT via Traefik. To do this I have an entrypoint for port 9001 which is exposed in my Traefik docker compose.

Looking at some other posts created a TCP router

labels:
     - "traefik.enable=true"
  #   - "traefik.tcp.routers.${CUSTOMER}_mqtt.tls=false" # expose without tls
     - "traefik.tcp.routers.${CUSTOMER}_mqtt.rule=HostSNI(`${CUSTOMER}.mqtt.domain.com`)"
     - "traefik.tcp.routers.${CUSTOMER}_mqtt.entrypoints=https, mqtt, mqtts, websocket"
     - "traefik.tcp.services.${CUSTOMER}_mqtt.loadbalancer.server.port=9001" # expose container port
     - "traefik.tcp.routers.${CUSTOMER}_mqtt.service=${CUSTOMER}_mqtt"
     - "traefik.tcp.routers.${CUSTOMER}_mqtt.tls.certresolver=cloudflare" # cert resolver. Set in traefik.yml
     - "traefik.tcp.routers.${CUSTOMER}_mqtt.tls.domains[0].main=mqtt.domain.com" # Main domain                           
     - "traefik.tcp.routers.${CUSTOMER}_mqtt.tls.domains[0].sans=*.mqtt.domain.com" # SANS domain

The problem is I don't want to use TLS from Traefik as I want to use self signed certs in MQTT as some of our clients require this. But if I disable TLS then HostSNI(${CUSTOMER}.mqtt.domain.com) doesn't work as it needs the TLS. But I can't use HostSNI(*) as I will have multiple instances of the MQTT service being exposed.

I have seen some posts about enabling passthrough but to my understanding that is too pass the Traefik TLS through to MQTT.

Is this something I can achieve?
If it's possible I could put my self signed certs in a file if I can use that file as a certresolver. However I don't think that's particularly great for mass deployment. I wanted to be able to deploy my docker compose and be done if possible. I can use ansible though.

Ideally, I'd like to pass multiple MQTT listener ports through. One for encrypted and one for unencrypted with auth required. To do this do I need another loadbalancer defined?

Thanks

Without Traefik having access to the certs, you can only use HostSNI(`*`). As soon as you put in a domain name,Traefik will check for a loaded TLS cert and will create a default cert if none is found.

If you really need to differentiate without certs, then you can only use different ports per customer.

Okay thanks,
So if I could make Traefik aware of my self signed certs then I could make it work?
Would I need to put them in my acme.json file? Or can I use a separate file for them and define it as a certresolver?
I could try and make one self signed cert for all instances.

Yes, you can use your custom certs in a dynamic config file (doc), which you load with providers.file in static config.

1 Like

Thanks, I'll give this a go when I get some time on it in the next few days