Users and access control in the Mosquitto MQTT server
A while ago, I blogged about how to setup an MQTT server with Mosquitto. In this one, I want to talk about how to setup multiple user accounts and how to implement access control.
In this post, I'll assume that you've already followed my previous post to which I've linked above.
User accounts
User accounts are a great security measure, as they prevent anyone without a password from accessing your MQTT server. Thankfully, they are pretty easy to do too - you just need a user / password file, and a directive in the main mosquitto.conf
file to get it to read from it.
First, let's create a new users file:
sudo touch /etc/mosquitto/mosquitto_users
sudo chown mosquitto:mosquitto /etc/mosquitto/mosquitto_users
sudo chmod 0640 /etc/mosquitto/mosquitto_users
Then you can create new users like this:
sudo mosquitto_passwd /etc/mosquitto/mosquitto_users new_username_1
...replacing new_username_1
with the username of the new account you want to create. Upon executing the above, it will prompt you to enter a new password. Personally I use Keepass2 for this purpose, but you can create good passwords on the command line directly too:
dd if=/dev/urandom bs=1 count=20 | base64 | tr -d '+/='
Now that we have a users file, we can tell mosquitto about it. Add the following to your /etc/mosquitto/mosquitto.conf
file:
# Require a username / password to connect
allow_anonymous false
# ....which are stored in the following file
password_file /etc/mosquitto/mosquitto_users
This disables anonymous access, and tells mosquitto where the the username / password file.
In future if you want to delete a user, do that like this:
sudo mosquitto_passwd /etc/mosquitto/mosquitto_users -D new_username_1
Access control
Access control is similar to user accounts. First, we need an access control file - which describes who can access what - and then we need a directive in the mosquitto.conf
file to tell Mosquitto about it. Let's start with that access control file. Mine is located at /etc/mosquitto/mosquitto_acls
.
# Directives here affect anonymous users, but we've disabled anonymous access
user username_here
topic readwrite foo/#
user bob
topic read rockets/status
There are 2 parts to the ACL file. First, the user
directive sets the current user for which any following topic
directives apply.
The topic
directive allows the current user to read, write, or readwrite (both at the same time) a given topic. MQTT as a protocol is built on the idea of publishing (writing) to or subscribing (reading from) topics. Mosquitto assumes that a user has no access at all unless 1 or more topic
directives are present to allow access.
The topic directive is comprised of 3 parts. First, the word topic
is the name of the directive.
Next, any 1 of the following words declares what kind of access is being granted:
read
: Read-only accesswrite
: Write-only accessreadwrite
: Both read and write access
Finally, the name of the topic that is being affected by the access rule is given. This may include a hash symbol (#
) as a wildcard. For example, rockets/status
would affect only that specific topic, but space/#
would affect all topics that start with space/
.
Here are some more examples:
# Allow read access to "my_app/news"
topic read my_app/news
# Allow write access to "rockets/status"
topic write rockets/status
# Allow read and write access to everything under "another_app/"
topic readwrite another_app/#
Once you've created your ACL file, add this to your mosquitto.conf
(being careful to put it before any listener
directives if you have TLS / MQTTS support enabled):
acl_file /etc/mosquitto/mosquitto_acls
This will tell Mosquitto about your new access control file.
Reloading changes
After making changes above, you'll want to tell Mosquitto to reload the configuration file. Do that like this:
sudo systemctl reload mosquitto-mqtt.service
If your systemd service file doesn't support reloading, then a restart will do. Alternatively, add this to your systemd service file to the [Service]
section:
ExecReload=/bin/kill -s HUP $MAINPID
Conclusion
In this tutorially-kinda post, I've talked through how to manage user accounts for the Mosquitto MQTT. I've also talked about how to enable and manage access control lists too.
This should make your MQTT server more secure. The other thing you can do to make your MQTT server more secure is enable TLS encryption. I'm going to hold off on showing that in this file because I'm still unsure about the best way of doing it (getting Mosquitto to do it vs using Nginx as a reverse proxy - I'm currently testing the former), but if there's the demand I'll post about it in the future.