In this tutorial, I’ll guide you through setting up an MQTT broker using Open Source software Mosquitto on a Linux machine in the cloud. For this tutorial, I’ll assume you are using an Ubuntu 20.04 server hosted on AWS EC2, but you should be able to adapt this guide to other Linux distributions and cloud providers.
Before proceeding, ensure you have administrative (root) access to your Linux server.
First, you need to connect to your server. If you’re using an AWS EC2 Ubuntu instance, this is typically done using SSH. In your terminal, you can connect to your server using the following command (replace your-key.pem
and your-server-ip
with your details):
ssh -i your-key.pem ubuntu@your-server-ip
Before installing anything new, it’s always a good idea to make sure your system’s package list is up to date. You can do this with:
sudo apt-get update -y
sudo apt-get upgrade -y
The Mosquitto MQTT broker is available in the default Ubuntu repositories, so you can install it with:
sudo apt-get install mosquitto mosquitto-clients -y
The Mosquitto configuration file is located at /etc/mosquitto/mosquitto.conf
. You can edit this file using a text editor like nano:
sudo nano /etc/mosquitto/mosquitto.conf
By default, Mosquitto listens on port 1883. If you wish to change the port, you can do so by editing the following line in the configuration file:
listener 1883
You might also want to enable MQTT over websockets. You can do this by adding the following to your configuration file:
listener 9001
protocol websockets
To save and close the file in nano, press CTRL+X
, then Y
to confirm saving changes, and then ENTER
to confirm the filename.
Now you can start Mosquitto and enable it to start on boot using the following commands:
sudo systemctl start mosquitto
sudo systemctl enable mosquitto
For clients to be able to connect to your MQTT broker, you need to open the relevant ports in your cloud server’s firewall. On AWS, this is done in the security group associated with your EC2 instance. Add inbound rules to allow traffic on port 1883 and 9001.
At this point, you should have a working MQTT broker. You can test it using Mosquitto’s built-in clients. On your server, subscribe to a test topic:
mosquitto_sub -h localhost -t test
In a new terminal window, connect to your server again and publish a message to the test topic:
mosquitto_pub -h localhost -t test -m "hello world"
You should see “hello world” appear in the terminal where you ran mosquitto_sub
.
To make your MQTT broker more secure, you should set up user authentication. First, create a password file:
sudo mosquitto_passwd -c /etc/mosquitto/passwd username
Replace “username” with your desired username. You will be prompted to enter a password.
Then, open the Mosquitto configuration file again:
sudo nano /etc/mosquitto/mosquitto.conf
And add the following lines:
allow_anonymous false
password_file /etc/mosquitto/passwd
Then, restart Mosquitto:
sudo systemctl restart mosquitto
Now, when you test your broker, you will need to provide a username and password:
mosquitto_sub -h localhost -t test -u "username" -P "password"
mosquitto_pub -h localhost -t test -m "hello world" -u "username" -P "password"
That’s it! You now have a Mosquitto MQTT broker running on your Linux server in the cloud.
Now, let’s talk about securing our MQTT communication using TLS certificates. Transport Layer Security (TLS) is a protocol that provides secure communication over a computer network. When applied to MQTT, it ensures that the data being transmitted between the MQTT client and the broker is private and tamper-proof.
This process involves generating a Certificate Authority (CA), a server certificate, and client certificates, which are used to establish trusted communication.
We’ll use OpenSSL to create our certificates. It’s probably already installed, but if not, you can install it with:
sudo apt-get install openssl -y
We’ll start by creating a directory to store our certificates, and then move into that directory:
mkdir ~/certs
cd ~/certs
Now we’ll generate our CA private key:
openssl genrsa -out ca.key 2048
With the private key, we’ll generate the root certificate:
openssl req -new -x509 -days 3650 -key ca.key -out ca.crt
You’ll be asked for some information, which will be included in the certificate. The most important part is “Common Name”. It should be a name that identifies the CA.
First, create the server private key:
openssl genrsa -out server.key 2048
Now create a certificate signing request (CSR) with that key:
openssl req -new -key server.key -out server.csr
Again, you’ll be asked for some information. For the common name, you should use the IP address or hostname of your MQTT server.
Now, sign the CSR with the CA’s private key:
openssl x509 -req -in server.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out server.crt -days 3650
We’ll repeat a similar process for the client certificates:
openssl genrsa -out client.key 2048
openssl req -new -key client.key -out client.csr
Make sure the common name is different from the one you used for the server.
Now, sign the client CSR:
openssl x509 -req -in client.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out client.crt -days 3650
Now, we’ll tell Mosquitto to use these certificates for TLS. Open the Mosquitto configuration file:
sudo nano /etc/mosquitto/mosquitto.conf
And add the following lines:
listener 8883
cafile /home/ubuntu/certs/ca.crt
certfile /home/ubuntu/certs/server.crt
keyfile /home/ubuntu/certs/server.key
require_certificate true
The require_certificate true
line means that the server will require clients to provide a valid certificate.
Restart Mosquitto:
sudo systemctl restart mosquitto
Now, you can test the configuration with:
mosquitto_pub -h localhost -p 8883 --cafile ~/certs/ca.crt --cert ~/certs/client.crt --key ~/certs/client.key -t test -m "hello tls" -d
mosquitto_sub -h localhost -p 8883 --cafile ~/certs/ca.crt --cert ~/certs/client.crt --key ~/certs/client.key -t test -d
You should see the “hello tls” message arrive at the subscriber.
That’s it! Your MQTT broker is now secured with TLS certificates. Just make sure to distribute the client certificates and the CA certificate (not the CA key!) to your clients.
Remember, this is a basic setup, and for a production system, you would need a more robust configuration. For example, you might want to use separate client certificates for each client and revoke certificates when they’re not needed anymore. The specifics will depend on your use case.
If you get the error
Job for mosquitto.service failed because the control process exited with error code.
See "systemctl status mosquitto.service" and "journalctl -xeu mosquitto.service" for details.
This is likely a permission error on me and solved by mooving ca.crt server.crt and server.key to /etc/mosquittos/certs/ directory.
Gravio, the Node Computing Platform by Asteria Corporation is leveraging the potential of the MQTT protocol. Why not try it out now, you can connect your newly set up MQTT broker to Gravio’s PubSub functionalities and start connecting to and triggering all sorts of other software processes? You can connect MQTT to:
Get started with Gravio for free.
This article was originally published on our Medium blog, too: https://medium.com/gravio-edge-iot-platform/how-to-set-up-a-mosquitto-mqtt-broker-securely-using-client-certificates-82b2aaaef9c8