Lab: running a Mosquitto MQTT broker
In short: MQTT is a lightweight publish and subscribe protocol used by many IoT devices. In this lab you install the Mosquitto broker, send and receive messages from the command line, and try wildcards, retained messages and quality of service levels on an isolated network.
Aim and what you need
The aim is to see how MQTT works by running your own broker. Devices publish messages to a topic such as lab/room1/temp; other clients subscribe to topics; the broker passes messages between them. This lab starts unauthenticated on purpose so you can see the basics, then the next lab locks it down.
- A Raspberry Pi set up as in the secure Pi lab, or any Debian or Ubuntu machine. Docker also works.
- Two terminal windows.
- An isolated lab or home network. Never expose port 1883 to the internet.
Steps
- Install the broker and clients and check the service is running.
- Mosquitto 2.x accepts only local connections until you configure a listener. Start by testing on the Pi itself.
- In terminal one subscribe to everything under
lab/; in terminal two publish a reading. - Try the single-level wildcard
+, a retained message and QoS 1. - To let LAN devices such as the ESP32 connect for this first test, add a listener on the Pi's LAN address, then allow only your LAN through the firewall.
sudo apt update
sudo apt install -y mosquitto mosquitto-clients
systemctl status mosquitto
# terminal 1
mosquitto_sub -h localhost -t 'lab/#' -v
# terminal 2
mosquitto_pub -h localhost -t lab/room1/temp -m 21.5
mosquitto_sub -h localhost -t 'lab/+/temp' -v
mosquitto_pub -h localhost -t lab/status -m online -r
mosquitto_pub -h localhost -t lab/room1/temp -m 22.0 -q 1
# /etc/mosquitto/conf.d/lab.conf (temporary, isolated lab only)
listener 1883 192.168.10.5
allow_anonymous true
sudo systemctl restart mosquitto
sudo ufw allow from 192.168.10.0/24 to any port 1883 proto tcp
# Docker alternative (put the same listener lines in ./mosquitto.conf, using 0.0.0.0)
docker run -d --name mosquitto -p 1883:1883 -v "$PWD/mosquitto.conf:/mosquitto/config/mosquitto.conf" eclipse-mosquitto:2
How to verify and troubleshoot
Each publish should appear instantly in the subscriber with its topic. Close and reopen a subscriber to lab/status: the retained online message arrives immediately, because the broker keeps the last retained value for new subscribers. sudo ss -tlnp | grep 1883 shows which address the broker listens on, and sudo journalctl -u mosquitto shows connections and errors.
- Connection refused from another machine: no LAN listener is configured, or the firewall blocks 1883.
- Not authorised:
allow_anonymousis false, which is the default once you add a listener in Mosquitto 2.x. - Broker will not start: run
mosquitto -c /etc/mosquitto/mosquitto.conf -vto see the config error. - Nothing received: topics are case-sensitive and must match exactly; quote wildcards in the shell.
Clean-up
Anonymous access is fine for ten minutes on an isolated network and wrong anywhere else, because anyone who can reach the port can read and inject messages. When you finish, clear the retained message with mosquitto_pub -h localhost -t lab/status -r -n, then either delete lab.conf and restart the broker, or go straight on to the passwords and TLS lab. For Docker, run docker rm -f mosquitto.
Practice
What is the difference between the + and # wildcards?
What does a retained message do?
Why does a fresh Mosquitto 2.x install refuse LAN connections?
Key takeaways
- MQTT is publish and subscribe through a central broker.
- Topics are hierarchical; + and # are wildcards.
- Retained messages give new subscribers the latest value.
- Mosquitto 2.x is local-only until you add a listener.
- Anonymous access is for short, isolated tests only.
Original content written by Mohamed Fayas for FM TecHub. © 2026 FM TecHub. You're welcome to share a link to this page; please don't copy the text elsewhere without permission.