Mosquitto MQTT and TLS without client HostSNI

Hello

I am trying to setup a mosquitto MQTT server behind Traefik. The problem is most clients lack the SNI feature (like mosquitto_pub used for testing !).

Here is my docker-compose file:

version: "3.0"
services:
  mosquitto:
    image: eclipse-mosquitto:latest
    container_name: mosquitto
    restart: always
    volumes:
      - ./config/mosquitto.conf:/mosquitto/config/mosquitto.conf
      - ./config/passwd:/mosquitto/passwd
      - ./data:/mosquitto/data
      - ./logs:/mosquitto/log
    expose:
      - 1883
    labels:
      - "traefik.enable=true"
      - "traefik.tcp.routers.mqtt.entrypoints=mqtt"
      - "traefik.tcp.routers.mqtt.rule=HostSNI(`*`)"
      - "traefik.tcp.routers.mqtt.service=mqtt-srv"
      - "traefik.tcp.routers.mqtts.entrypoints=mqttsecure"
      - "traefik.tcp.routers.mqtts.rule=HostSNI(`*`)"
      - "traefik.tcp.routers.mqtts.tls.certresolver=certs"
      - "traefik.tcp.routers.mqtts.tls.domains[0].main=*.example.com"
      - "traefik.tcp.routers.mqtts.tls.passthrough=false"
      - "traefik.tcp.routers.mqtts.tls.options=nonstrictsni@file"
      - "traefik.tcp.routers.mqtts.service=mqtt-srv"
      - "traefik.tcp.services.mqtt-srv.loadbalancer.server.port=1883"
    networks:
      - proxy

networks:
  proxy:
    external: true

with nonstrictsni dynamic configuration:

tls:
  options:
    nonstrictsni:
      sniStrict: false

Then I try to publish with this:

mosquitto_sub -L mqtts://user:password@mqtt.example.com/topic

I get an error:

Error: A network protocol error occurred when communicating with the broker.

Using a non secure protocol everything is fine. Connecting with openssl s_client works fine and I get my wildcard certificate.

I found similar topics and tryed many variations on my setup but found nothing working. Any idea?

Thanks

Share your full Traefik static and dynamic config, and docker-compose.yml if used.

If your client can’t do HostSNI, maybe it can’t do TLS 1.3, which is Traefik default. Check doc to change it.

Thanks

I have 3 majors clients:

  • ownTracks on Android - connection successful :+1:
  • ownTracks on iOS - connection successful :+1:
  • mosquitto MQTT itself in a bridged configuration. That one I was worried about because command line tools were not working but, surprisingly, it's OK :+1:

The only clients that are not working are mosquitto_pub and mosquitto_sub (v1.6.9, a bit old, that might explain, on an ubuntu 20.04) and I have no daily usage of those so I will not spend too much of my time on this issue (but lost some trying to test with those tools when everything was fine for other clients!)

Nevertheless here is my full config:

# docker-compose for traefik
version: "3.3"

secrets:
  gandi_api_key:
    file: "./secrets/gandi_api_key.secret"

services:
  traefik:
    image: "traefik:v2.11"
    container_name: "traefik"
    ports:
      - "80:80"
      - "443:443"                                                                                                          
      - "1883:1883"
      - "8883:8883"
    secrets:
      - "gandi_api_key"
    volumes:
      - "/var/run/docker.sock:/var/run/docker.sock:ro"
      - "/srv/traefik/acme.json:/acme.json"
      - "/srv/traefik/services:/etc/traefik/services"
      - "/srv/traefik/traefik.yaml:/etc/traefik/traefik.yaml"
    environment:
      - "GANDIV5_PERSONAL_ACCESS_TOKEN_FILE=/run/secrets/gandi_api_key"
    restart: always
    labels:
      - "traefik.enable=true"
      - "traefik.http.middlewares.auth.basicauth.users=admin:<edited>"
      - "traefik.http.routers.traefikapi.entrypoints=websecure,web"
      - "traefik.http.routers.traefikapi.middlewares=auth"
      - "traefik.http.routers.traefikapi.rule=Host(`traefik.example.com`)"
      - "traefik.http.routers.traefikapi.service=api@internal"
      - "traefik.http.routers.traefikapi.tls=true"
      - "traefik.http.routers.traefikapi.tls.certresolver=certs"
      - "traefik.http.routers.traefikapi.tls.domains[0].main=*.example.com"
    networks:
      - proxy

networks:
  proxy:
    name: "proxy
# traefik.yaml
entryPoints:
  web:
    address: ":80"
    http:
      redirections:
        entryPoint:
          to: websecure
          scheme: https
          priority: 1000000
  websecure:
    address: ":443"
  mqtt:
    address: ":1883"
  mqttsecure:
    address: ":8883"

api:
  dashboard: true

log:
  level: WARN

providers:
  docker:
    exposedByDefault: false
  file:
    directory: "/etc/traefik/services"

certificatesResolvers:
  certs:
    acme:
      email: "letsencrypt@example.com"
      storage: acme.json
      dnsChallenge:
        provider: gandiv5

Dynamic file for SNI already provided but from another thread it seems to be the default configuration.

Docker compose for starting mosquitto already provided!