Introduction
In 2026, IoT architectures demand ultra-secure, scalable MQTT brokers. Mosquitto, the lightest and most performant open-source broker, leads with native MQTT 5.0 support, persistent storage, and inter-broker bridges. This expert tutorial guides you step-by-step to deploy a production-ready Mosquitto: Linux installation, advanced configuration with password authentication, granular ACLs, TLS 1.3 encryption, persistence, and Docker Compose orchestration.
Why it matters: In a zero-trust world, a poorly secured broker exposes your devices to MITM or DoS attacks. We provide complete, immediately testable configs while avoiding expert-level pitfalls. By the end, your broker will handle 100k+ QoS2 connections without breaking a sweat, ready for Kubernetes or edge computing. (142 words)
Prerequisites
- Ubuntu 24.04 LTS or Debian 12 server (4 GB RAM minimum for load testing).
- Advanced MQTT knowledge (QoS, topic wildcards, retained messages).
- OpenSSL 3+ installed (
sudo apt install openssl). - Docker 27+ and Docker Compose 2.29+ for containerized deployment.
- Tools:
mosquitto_pub/sub(installed with the broker),jqfor JSON parsing.
Installing Mosquitto
#!/bin/bash
sudo apt update
sudo apt install -y software-properties-common
dist="$(lsb_release -cs)"
wget -O - https://repo.eclipse.org/content/repositories/dev_mosquitto/com/eclipse-mosquitto/repo/${dist}-main/public.key | sudo tee /etc/apt/trusted.gpg.d/mosquitto-${dist}.asc > /dev/null
sudo add-apt-repository -y "deb https://repo.eclipse.org/content/repositories/dev_mosquitto/com/eclipse-mosquitto/repo/${dist}-main/ ${dist} main"
sudo apt update
sudo apt install -y mosquitto mosquitto-clients
sudo systemctl stop mosquitto
sudo systemctl disable mosquittoThis script installs the latest dev version of Mosquitto (2.0.18+ in 2026) from the official Eclipse repo for full MQTT 5.0 support. It disables the systemd service for manual configuration. Avoid outdated distro packages that lack features like shared subscriptions.
Basic Configuration and Listener
Now, test the bare broker. Run the installation code, then in one terminal use mosquitto_sub -h localhost -t test/topic, and publish with mosquitto_pub -h localhost -t test/topic -m 'Hello MQTT'. The broker listens on 1883 by default (unsecured).
Basic Mosquitto Configuration
persistence true
persistence_location /var/lib/mosquitto/
log_dest file /var/log/mosquitto/mosquitto.log
log_type all
log_timestamp true
log_timestamp_format %Y-%m-%dT%T%z
max_queued_messages 10000
max_queued_bytes 1048576
allow_anonymous false
listener 1883 localhost
listener 8883
protocol mqtt
max_connections 100000This config enables persistence (messages survive restarts), detailed logging with ISO timestamps, and two listeners: 1883 local-only for testing, 8883 for standard MQTT. Limit queues to prevent OOM under load. allow_anonymous false enforces auth from the start.
Starting and Basic Testing
Place the config in /etc/mosquitto/mosquitto.conf, create dirs with sudo mkdir -p /var/lib/mosquitto /var/log/mosquitto, and set ownership sudo chown -R mosquitto:mosquitto /var/{lib,log}/mosquitto. Start it: sudo -u mosquitto mosquitto -c /etc/mosquitto/mosquitto.conf. Test pub/sub – expect an auth error (that's good!).
Generating the Password File
#!/bin/bash
sudo mkdir -p /etc/mosquitto/auth
sudo touch /etc/mosquitto/auth/passwordfile
sudo chown mosquitto:mosquitto /etc/mosquitto/auth/passwordfile
sudo -u mosquitto mosquitto_passwd -c /etc/mosquitto/auth/passwordfile admin 'SecurePass2026!'
sudo -u mosquitto mosquitto_passwd /etc/mosquitto/auth/passwordfile iotdevice 'DeviceToken123'
sudo chmod 600 /etc/mosquitto/auth/passwordfileGenerates a hashed password file with mosquitto_passwd (SHA512 PBKDF2). Adds two users: admin (management) and iotdevice (publish/sub). Strict 600 permissions for security. Never store plaintext in production; rotate regularly.
Integrating Password Authentication
Update mosquitto.conf with password_file /etc/mosquitto/auth/passwordfile. Restart: pkill mosquitto ; sudo -u mosquitto mosquitto -c /etc/mosquitto/mosquitto.conf. Test: mosquitto_pub -h localhost -p 1883 -u iotdevice -P 'DeviceToken123' -t sensors/temp -m '23.5'. Success! Without creds, connection refused.
Advanced ACL Configuration
# ACL pour admin : full access
user admin
pattern readwrite %/
# IoT devices : publish sur sensors/, sub sur $SYS/ et actuators/
user iotdevice
pattern write sensors/+
pattern read $SYS/broker/#
p topic read actuators/#
# Groupe devices : wildcards
pattern write home/+/#
pattern read home/%u/#
# Deny all else
pattern readwrite $SYS
Hierarchical ACLs: admin gets full access via %/. iotdevice publishes to sensors/+ (one level), reads sysinfo and actuators. %u injects username for per-user topics. Test with mosquitto_sub -u iotdevice -P 'DeviceToken123' -t 'sensors/invalid' -v – denied! Add acl_file /etc/mosquitto/auth/aclfile to conf.
Applying ACLs and Testing
Add acl_file to mosquitto.conf, set ownership sudo chown mosquitto:mosquitto /etc/mosquitto/auth/aclfile, and restart. Expert tests:
- Admin pub/sub everywhere: OK.
- Iotdevice pub
sensors/temp: OK; pubhome/bad: denied.
/var/log/mosquitto/mosquitto.log for Access Refused.Generating Self-Signed TLS Certificates
#!/bin/bash
sudo mkdir -p /etc/mosquitto/certs
cd /etc/mosquitto/certs
sudo openssl req -newkey rsa:4096 -days 365 -nodes -x509 -keyout mosquitto.key -out mosquitto.crt -subj '/C=FR/ST=Paris/L=Paris/O=Learni/OU=IoT/CN=localhost'
sudo openssl dhparam -out dhparam.pem 4096
sudo chown -R mosquitto:mosquitto /etc/mosquitto/certs
sudo chmod 600 /etc/mosquitto/certs/{mosquitto.key,dhparam.pem}
sudo chmod 644 /etc/mosquitto/certs/mosquitto.crtGenerates a self-signed RSA 4096-bit CA (TLS 1.3 compatible) and DH params for Perfect Forward Secrecy. In production, use Let's Encrypt or EJBCA. Critical permissions: private key 600. Verify: openssl x509 -in mosquitto.crt -text -noout.
Enabling TLS on Listener 8883
Add to mosquitto.conf:
listener 8883
protocol mqtt
cafile /etc/mosquitto/certs/mosquitto.crt
certfile /etc/mosquitto/certs/mosquitto.crt
keyfile /etc/mosquitto/certs/mosquitto.key
dhparam /etc/mosquitto/certs/dhparam.pem
require_certificate false
use_identity_as_username true
Restart. Test TLS: mosquitto_pub -h localhost -p 8883 --capath /etc/ssl/certs -u iotdevice -P 'DeviceToken123' -t sensors/temp -m '24.0'. Check logs for TLS-PSK or cipher errors.
Bridge Configuration to Remote Broker
connection bridge-to-aws
address aws-iot-endpoint:8883
bridge_hostname mqtt-aws
bridge_username AWS_IOT_USER
bridge_password AWS_IOT_TOKEN
tls_version tlsv1.3
bridge_cafile /etc/mosquitto/certs/aws-ca.crt
bridge_certfile /etc/mosquitto/certs/client.crt
bridge_keyfile /etc/mosquitto/certs/client.key
remote_username mosq-aws
remote_password bridgepass
topic sensors/# out 1 bridge-mqtt-aws/ sensors/ {{"qos":1,"retain":true}}
topic actuators/# in 2 bridge-mqtt-aws/ actuators/Bridge out/in: forwards sensors/# to AWS IoT (QoS1, retain), subs actuators QoS2. Mutual TLS for security. Include via include_dir /etc/mosquitto/conf.d with sudo ln -s /etc/mosquitto/bridge.conf /etc/mosquitto/conf.d/. Scales for clustering.
Production Docker Deployment
For high availability, use Docker. Generate secrets via docker secret create mosquitto_pw /etc/mosquitto/auth/passwordfile.
Docker Compose for HA Mosquitto
version: '3.8'
services:
mosquitto:
image: eclipse-mosquitto:2.0
restart: always
ports:
- '1883:8883'
- '8883:8883'
volumes:
- ./mosquitto.conf:/mosquitto/config/mosquitto.conf:ro
- ./auth:/mosquitto/config/auth:ro
- ./certs:/mosquitto/config/certs:ro
- mosquitto_data:/mosquitto/data
- mosquitto_log:/mosquitto/log
environment:
- TZ=Europe/Paris
networks:
- iot-net
volumes:
mosquitto_data:
mosquitto_log:
networks:
iot-net:
driver: bridgeProduction Compose: persistent volumes, read-only configs, TZ for logs. Scale with replicas in Swarm. Run docker compose up -d. Monitor with Prometheus via Mosquitto plugin.
Best Practices
- Rotate credentials: Monthly cron script for
mosquitto_passwd+ ACL updates. - Monitoring: Enable
$SYS/broker/clients/active+ Prometheus exporter. - Load testing: Use
mqtt-benchmarkfor 10k conn/s. - Backup: Rsync
/var/lib/mosquitto+mosquitto_db_dump. - Zero-trust: Mutual TLS + PSK for low-power devices.
Common Errors to Avoid
- Forgetting
sudo chown mosquittoon configs: crashes with 'Permission denied'. - ACL without
userprefix: applies globally, exposes everything. - TLS without DH params: falls back to insecure ciphers (log: 'no shared cipher').
- No
max_connections: DoS via exhaustion (default 1000 too low).
Next Steps
Dive into MQTT 5.0 shared subscriptions with our Learni IoT training. Resources: Mosquitto Docs, MQTT Explorer for debugging, Eclipse GitHub repo for C plugins.