Mosquitto is an open-source message broker that implements the MQTT protocol.

Let’s get Mosquitto up and running for your IoT devices. We’ll focus on a basic, secure setup.

First, installation. On Debian/Ubuntu systems, it’s straightforward:

sudo apt update
sudo apt install mosquitto mosquitto-clients

This installs the broker itself and some handy client tools for testing. For other systems, check the official Mosquitto downloads page.

Next, we need to configure it. The main configuration file is usually at /etc/mosquitto/mosquitto.conf. It’s a good idea to make a backup before you start:

sudo cp /etc/mosquitto/mosquitto.conf /etc/mosquitto/mosquitto.conf.bak

Now, let’s edit the file. Open it with your favorite editor:

sudo nano /etc/mosquitto/mosquitto.conf

By default, Mosquitto might allow anonymous connections. For any real-world IoT deployment, this is a no-go. We need authentication. The simplest way for a small setup is to use username/password authentication.

First, create a password file. Mosquitto uses a specific format for this. We’ll use the mosquitto_passwd utility for this:

sudo mosquitto_passwd -c /etc/mosquitto/passwd your_mqtt_username

This command creates a new password file (-c) and adds a user named your_mqtt_username. You’ll be prompted to enter and confirm a password for this user. If you want to add more users later, omit the -c flag:

sudo mosquitto_passwd /etc/mosquitto/passwd another_username

Now, tell Mosquitto to use this password file and to require authentication. Add these lines to your mosquitto.conf:

password_file /etc/mosquitto/passwd
allow_anonymous false

The allow_anonymous false line is crucial. It disables unauthenticated access.

For basic security, we should also enable TLS/SSL encryption so your messages aren’t sent in plain text over the network. This involves generating or obtaining SSL certificates. For a quick self-signed certificate for testing, you can use openssl:

sudo openssl req -new -x509 -keyout /etc/mosquitto/mosquitto.key -out /etc/mosquitto/mosquitto.crt -days 365 -nodes

You’ll be prompted for information like Country Name, State, etc. For testing, you can fill these in with dummy data. The -nodes flag means we won’t encrypt the private key with a passphrase, which is convenient for a simple setup but not recommended for production.

Now, configure Mosquitto to use these certificates. Add these lines to mosquitto.conf:

# TLS settings
listener 8883
protocol mqtts
certfile /etc/mosquitto/mosquitto.crt
keyfile /etc/mosquitto/mosquitto.key

This tells Mosquitto to listen on port 8883 (the standard for MQTT over TLS) using the mqtts protocol, and points to our certificate and key files.

We also want to keep the default MQTT port (1883) open for unencrypted communication if we decide to allow it later, or for specific internal uses. However, for a secure setup, we usually want to restrict this or disable it. For now, let’s ensure it’s configured:

# Default MQTT listener
listener 1883

After making these changes, save the mosquitto.conf file and restart the Mosquitto service for them to take effect:

sudo systemctl restart mosquitto

You can check its status to ensure it started without errors:

sudo systemctl status mosquitto

Now, let’s test it. On one terminal, subscribe to a topic:

mosquitto_sub -h localhost -t "my/test/topic" -u "your_mqtt_username" -P "your_mqtt_password" --tls-version tlsv1.2

Note the --tls-version tlsv1.2 flag. This is important when connecting via TLS. If you’re connecting to the unencrypted port 1883, you’d omit the --tls-version flag and change -h localhost to -h localhost -p 1883.

In another terminal, publish a message:

mosquitto_pub -h localhost -t "my/test/topic" -m "Hello from Mosquitto!" -u "your_mqtt_username" -P "your_mqtt_password" --tls-version tlsv1.2

If everything is configured correctly, you should see "Hello from Mosquitto!" appear in your subscriber terminal.

A common pitfall is firewall rules. If you’re running Mosquitto on a server accessible from the internet, ensure ports 1883 (unencrypted) and 8883 (TLS) are open in your firewall. For example, using ufw:

sudo ufw allow 1883/tcp
sudo ufw allow 8883/tcp
sudo ufw enable

The core mechanic that often trips people up with TLS is that the client must explicitly tell Mosquitto it’s using TLS, even if the broker is configured for it. This is why the --tls-version flag on the client is essential. Without it, the client will try to connect using plain MQTT, and the TLS handshake will fail, leading to connection errors.

The next hurdle you’ll face is managing persistent sessions and Quality of Service (QoS) levels for reliable message delivery.

Want structured learning?

Take the full Mqtt course →