Providing 2 endpoints for MQTT broker

I have the following issue: I use Traefik with Let's Encrypt in order to encrypt MQTT. Mosquitto is configured to listen on port 1883 and doesn't know about any certificates. So the route is:

MQTT client —TLS—> Traefik on port 443 —unencrypted—> Mosquitto on port 1883

This works flawlessly — unless you have a client that cannot deal with TLS. I therefore want to provide a second entrypoint with Traefik that does NOT encrypt anything but just forward the requests to MQTT. I'm trying this with the following configuration:

networks:
  web:
    external: true
  internal:
    external: false

volumes:
  mosquitto:

services:
  traefik:
    image: traefik:v2.5.5
    container_name: traefik
    restart: always
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
      - ${PWD}/config/traefik/traefik.toml:/traefik.toml
      - ${PWD}/config/traefik/traefik_dynamic.toml:/traefik_dynamic.toml
      - /home/till/docker-data/traefik/acme.json:/acme.json      
    ports:
      - "80:80"
      - "443:443"
      - "1883:1883"
    networks:
      - web

  mqtt:
    image: eclipse-mosquitto
    container_name: mosquitto
    networks:
      - web
    restart: always
    expose:
      - "1883"
    volumes:
      - "./config/mosquitto:/mosquitto/config/"
      - "mosquitto:/data"
    labels:
      - traefik.enable=true
      # This part works flawlessly.
      - traefik.tcp.services.mqtt.loadbalancer.server.port=1883
      - traefik.tcp.routers.mqtt.entrypoints=websecure
      - traefik.tcp.routers.mqtt.rule=HostSNI(`mq.example.com`)
      - traefik.tcp.routers.mqtt.service=mqtt
      - traefik.tcp.routers.mqtt.tls=true
      - traefik.tcp.routers.mqtt.tls.certresolver=lets-encrypt

      # This part should provide an unencrypted endpoint, but no client is able to connect. Why?
      - traefik.tcp.services.mqtt_insec.loadbalancer.server.port=1883
      - traefik.tcp.routers.mqtt_insecure.entrypoints=mqtt
      - traefik.tcp.routers.mqtt_insecure.rule=HostSNI(`mq2.example.com`)
      - traefik.tcp.routers.mqtt_insecure.service=mqtt_insec

The traefik.toml part looks like this:

[entryPoints]
  [entryPoints.web]
    address = ":80"
    [entryPoints.web.http.redirections.entryPoint]
      to = "websecure"
      scheme = "https"

  [entryPoints.websecure]
    address = ":443"

  [entryPoints.mqtt]
    address = ":1883"

This does not work. No client is able to connect to mq2.example.com on port 1883. I have checked that the port is open in the firewall. Any ideas why that is?

Thank you!

1 Like

The solution is: Because unencrypted TCP cannot transmit a hostname, Traefik is unable to know which subdomain is called. You have to set

- traefik.tcp.routers.mqtt_insecure.rule=HostSNI(`*`)

For this to work.

1 Like

This topic was automatically closed 3 days after the last reply. New replies are no longer allowed.