### Install and configure Mosquitto™ on OpenWrt

The previous post was about MQTT security layers, the advantages of running a local MQTT server and how may a network of things be structured. The OpenWrt router should be ready to install and set up the server (broker) software. The software repositories contain two variants of the Eclipse Mosquitto software. One of them is built without SSL support. If you install that one, you won't be able to accept secure clients. The SSL enabled variant requires a bit more internal storage space and that's the main reason they provide both builds.

I'm using a router with Broadcom SoC and 16 MB of internal storage. There's still 86 percent free space after installing Mosquitto, the SSL enabled build. In this post I'll show you how to configure Mosquitto broker to listen to multiple ports and to accept clients with different security settings. This is because not all microcontrollers with network connectivity have enough processing power for TLS/SSL. And, as I said in the previous post, the devices in your local network are behind (at least one) firewall, and as long as no one else has physical access to the network, transport encryption between MQTT clients and server is not really needed. However, TLS/SSL is required for remote clients, over internet.

## Install on OpenWrt

Make sure OpenWrt itself as a network client can connect to the internet. Go to Network - Diagnostics. If you can't ping a valid domain, go to Network - DHCP and DNS and, at Server Settings - General Settings - DNS forwardings, add servers 8.8.8.8 and 8.8.4.4. DNS servers supplied via WAN do not reach LAN zone and that's why you have to set custom servers.

Go to System - Software - Actions. At first click on Update lists and after it finishes search for mosquitto. Look in the Available packages list for mosquitto-ssl and install it. The router itself can publish and receive MQTT packets to/from broker. To be able to do this install mosquitto-client-ssl. The installation can also be performed from the command line if you connect to the router via serial port or SSH over network.

opkg update
opkg install mosquitto-ssl
opkg install mosquitto-client-ssl libmosquitto-ssl

At this point, the server should be running. Go to Status - Processes and search for "mosquitto". If you can't find it, you need to get on the console, to enable and start it.

/etc/init.d/mosquitto enable
/etc/init.d/mosquitto restart

Use any client you like and test the connection to server. If you followed my previous post, the server address is the following:

• mqtt-broker.lan for devices that connect to OpenWrt router's network (a.k.a. the things network). This is not a multicast DNS address, it is resolved by router's DNS server;
• 192.168.1.222 (or whatever you have reserved in the DHCP server of the gateway) for devices that connect to broker from the home network (traffic routed via WAN port of OpenWrt router).

Test connection from outside of the things network. You can use MQTT Dash on your mobile device or MQTT.fx, MQTT Explorer on computers. By default, no TLS/SSL and no user/password are needed. Port is 1883.

## Edit configuration

To edit the configuration file stored on the router and upload certificate, you'll have to connect to it over SCP. I'm using WinSCP. It's free software for Windows, yet I run it in Wine, on Ubuntu, because I couldn't find a SCP GUI for Linux. Connect as a client in the LAN network of the OpenWrt router (the things network).

WinSCP connection settings

All the connection presets in left list of the screenshot above are valid. Although the first (root@192.168.1.222) is the WAN IP, it can be accessed from LAN too. With the current firewall settings, only from LAN. Some ports need to be opened on WAN side to allow access through WAN. The other two are the IP address of the router and the domain name that is resolved by router's DNS server to its own IP. As soon as you click Login, it will show you a warning. Accept it and click Yes/Update to start the connection over SCP.

You will work only on the right column. Browse to /etc/mosquitto and rename (even delete) mosquitto.conf. If you open it, you'll see it's just a template with no parameters in use. We'll make our own configuration, for the following scenario:

• Default listener: unsecured, on port 1883, for things that do not support TLS/SSL. Port is blocked for remote clients (over the internet).
• Secured listener: on port 8883, with CA, certificate and key, for remote access (local clients and things can use it too)
• Secured listener: on port 8884, with PSK (pre-shared key), for things. Port is blocked for remote clients (over the internet).

Next, I'll create the configuration for all these situations.

## Unsecured listener

For unsecured clients, the recommended port is 1883. First of all, some credentials should be created for clients. Connect to the router via SSH or serial port using PuTTY. WinSCP and PuTTY can be connected in the same time. Use this command to create passwd file with first user (username is "Thing01" in my example; can be replaced with any name you want):

mosquitto_passwd -c /etc/mosquitto/passwords.txt Thing01

Use this command to add more users:

mosquitto_passwd /etc/mosquitto/passwords.txt Thing02

Go ahead and open that file (/etc/mosquitto/passwords.txt) in WinSCP. You should see the (two) users added and the encrypted passwords. Let's configure the default listener. Open mosquitto.conf in WinSCP and paste the following configuration:

#Default listener
port 1883
allow_anonymous false
password_file /etc/mosquitto/passwords.txt

Stop Mosquitto from command line (PuTTY) using /etc/init.d/mosquitto stop. Now launch it with verbose on.

mosquitto -v -c /etc/mosquitto/mosquitto.conf

I tested the server with MQTT.fx and MQTT Explorer running on my Ubuntu local client. Here is how to configure the connection.

Connection settings in MQTT Explorer

Unsecured listener is ready. Generating the SSL certificates and keys for the secured listener is not a short topic. You can read about it in a future post.

## PSK secured listener

Using a pre-shared key (TLS PSK) to encrypt MQTT transmissions is recommended in performance constrained environments, like microcontrollers with limited CPU power. The key is made of digits and letter A to F (hexadecimal numbers). Both the server and the client must know this key.

PSK are stored in a text file, just like user credentials. We'll make that file in /etc/mosquitto. Using WinSCP, right click in that folder and choose New - File. Enter a name ("preshared.keys") and the text editor will open with this new file. The format is hint:key. The hint may be regarded as an username, while key is the password. How to generate a key? Since I'm on linux, I open the terminal (console) in any folder, and compute the md5sum of a file. These are the PSK entries for me:

Thing01:20a7da651a0743214cde51050398cffb
Thing02:eda7b5211a6e306c02de401900dc63bc

Save and close the editor. Go ahead and open mosquitto.conf. Settings for the default listener (from above) should already be there. The PSK file option is global, while usage of PSK encryption is per listener. Replace the contents with the following:

# Global
# Must be set before configuring listeners
per_listener_settings true

# Default listener
port 1883

# PSK listener
listener 8884
psk_hint "mqttbroker"

# Security
allow_anonymous false
psk_file /etc/mosquitto/preshared.keys


The order of the parameters in the configuration file should match the order in the original file. Otherwise, errors may occur. To test this configuration, I'm using mosquitto_pub.

mosquitto_pub -h mqtt-broker.lan -p 8884 -t test -m "Hello PSK" --psk-identity Thing01 --psk 20a7da651a0743214cde51050398cffb

If something is wrong, it will tell you that a TLS error occurred. Not very useful. The option use_identity_as_username set to true disables user/password authentication. It's not recommended to use multiple authentication methods. Disable default MQTT user/password authentication when using username identification from PSK hint.

At this point I have a MQTT broker running on OpenWrt router that listens on port 1883 for unsecured clients and on port 8884 for TLS PSK secured clients. In the next post I will add the certificate based TLS encryption and the server configuration is done. Various clients configuration follows (ESP8266, ESP32 etc.)

## References

The following pages were really helpful in creating this guide: