Close

Secure MQTT Broker setup

A project log for Secure ESP8266 MQTT p.o.c.

Secure ESP8266 MQTT proof of concept

w-taylorW. Taylor 02/01/2019 at 22:576 Comments

MQTT Broker secure setup

Copyright (c) 2019-2023 Warren Taylor.

Here are the basics of how to install, configure, and secure the “Mosquitto” MQTT Broker on an already properly configured and running installation of OpenWRT. However, the MQTT Broker can run on any computer on a local area network (LAN). You could even run it on a Raspberry PI if performance isn’t a strict requirement. So the following instruction should be adaptable to most modern operating systems.

Disclaimer

The following documentation in no way guarantees a secure system.

Install Mosquitto Broker and Client

With ssh (or similar) log into your OpenWRT router.

ssh root@your-router-hostname
opkg install mosquitto-ssl mosquitto-client-ssl libmosquitto-ssl

Create "mosquitto" user if it does not already exist

useradd -M mosquitto
usermod -L mosquitto

Create a directory to securely hold your certificates

(Keys and Certificates can be generate on any computer as long as the required files are securely copied to the server and all keys are securely stored.)

mkdir /root/mosquitto
chmod go-rwx /root/mosquitto
chown mosquitto:mosquitto /root/mosquitto
cd /root/mosquitto

Creating the MQTT Keys and Certificates

The documentation below talks a lot about Keys, Certificates, Certificate Authorities, etc... Rather than trying to rewrite the very good documentation others have already put a great deal of effort into, I refer you to some of their work:

NEVER use the same key and certificate to secure more than one device. If one device becomes compromised then all devices secured with the same key and certificate are also compromised. When generating your credentials it is important to use different subject parameters for your CA, server and client certificates. Every time you are prompted for the CN (Common Name), enter your same server hostname. If you don't know your exact hostname then run something like:

uci show system

Create an X509 CA key and certificate for self-signing

(Determine and securely store a PEM Pass Phrase, which is used to protect your CA Key)

openssl req -new -x509 -days 365 -extensions v3_ca -keyout mosq_ca.key -out mosq_ca.crt -subj "/C=CA/ST=BC/L=your-city/O=ca.your-domain.com/OU=ca/CN=your-hostname/emailAddress=your@email.com"

Subject Parameters:

To verify:

openssl x509 -in mosq_ca.crt -noout -text

Generate the MQTT Server private key

openssl genrsa -out mosq_serv.key 2048

Generate the MQTT Server self-signed certificate

openssl req -new -key mosq_serv.key -out mosq_serv.csr -subj "/C=your-country/ST=your-state/L=your-city/O=server.your-domain.com/OU=server/CN=your-hostname/emailAddress=your@email.com"

Generate the CA signed certificate to use in the MQTT Mosquitto Server

openssl x509 -req -in mosq_serv.csr -CA mosq_ca.crt -CAkey mosq_ca.key -CAcreateserial -out mosq_serv.crt -days 365

Generate the MQTT Client private key

openssl genrsa -out mosq_client.key 2048

Generate the MQTT Client self-signed certificate

openssl req -new -key mosq_client.key -out mosq_client.csr -subj "/C=your-country/ST=your-state/L=your-city/O=client.your-domain.com/OU=client/CN=your-hostname/emailAddress=your@email.com"

Generate the CA signed certificate to use in the MQTT Client

openssl x509 -req -in mosq_client.csr -CA mosq_ca.crt -CAkey mosq_ca.key -CAcreateserial -out mosq_client.crt -days 365

Increase the security of the files just created

chmod go-rwx /root/mosquitto/*
chown mosquitto:mosquitto /root/mosquitto/*

Mosquitto server config

/etc/mosquitto/mosquitto.conf

port 8883
cafile /etc/mosquitto/mosq_ca.crt
keyfile /etc/mosquitto/mosq_serv.key
certfile /etc/mosquitto/mosq_serv.crt
protocol mqtt
tls_version tlsv1.2
require_certificate true

Copy the necessary certificates and key

cp /root/mosquitto/mosq_ca.crt   /etc/mosquitto/mosq_ca.crt
cp /root/mosquitto/mosq_serv.key /etc/mosquitto/mosq_serv.key
cp /root/mosquitto/mosq_serv.crt /etc/mosquitto/mosq_serv.crt

Restart the Mosquitto Broker

service mosquitto stop
service mosquitto start

Run a quick test

The following command should turn on zone 2 for 2 minutes (i.e. 120 seconds). Try running it now, even if the MQTT client has not yet been setup, in order to check for any errors that may occur on the server side.

mosquitto_pub -h your-hostname -p 8883 --cafile mosq_ca.crt --cert mosq_serv.crt --key mosq_serv.key --debug --topic irrigation/zone/on -m "2 120"

Error: The connection was refused.
If you are using a newer version of the Mosquitto Broker
you may get the following error messages:

Client (null) sending CONNECT
Client (null) received CONNACK (5)
Connection error: Connection Refused: not authorised.
Error: The connection was refused.

The quick solution is to update mosquitto.conf with the following line and then Restart the Mosquitto Broker:

allow_anonymous true

However, this solution is a "double edge sword". Sure, it gets things running but you may now be less secure than you require. A more complicated configuration could include:

...
allow_anonymous false
use_identity_as_username true
...

Or even require user name and password in addition to using security certificates and keys.

There are many more Mosquitto Security related configuration settings but I cannot tell you what to do because everyones security requirements are different and these are getting into complicated configurations that are beyond the scope of this project.

MQTT Server References

Discussions

Mitchell Tuckness wrote 04/06/2021 at 11:36 point

I am trying to get MQTT working with Weewx Weather app and I use this method, all I get is:

1617708945: Error: Unable to load CA certificates. Check cafile "/etc/mosquitto/certs/mosq_serv.key".
1617708945: OpenSSL Error[0]: error:0B084088:x509 certificate routines:X509_load_cert_crl_file:no certificate or crl found

Is there a reason for this issue?


  Are you sure? yes | no

W. Taylor wrote 09/08/2023 at 04:03 point

The documentation above describes the file being in "/root/mosquitto/mosq_serv.key". Check your configuration settings and confirm the files are in the correct directory.

  Are you sure? yes | no

Darlan Dieterich wrote 11/14/2020 at 12:13 point

Hi! 

How I can resolve this message on publish/subscribe in my Broker:

`SSL_connect returned=1 errno=0 state=error: certificate verify failed (self signed certificate)`

What I doing wrong?

  Are you sure? yes | no

W. Taylor wrote 09/08/2023 at 04:05 point

I have updated the above documentation. Search for the section containing "allow_anonymous true". Also make sure that you are correctly referencing the mosq_ca.crt file.

  Are you sure? yes | no

David Viana wrote 10/07/2020 at 17:14 point

Very good, thanks! Please, can you show a example using client certificates? How mqtt client subscrible or publication can use the client certificate?

Thanks!

  Are you sure? yes | no

W. Taylor wrote 09/08/2023 at 04:12 point

Go to https://hackaday.io/project/163666/log/159166-secure-esp8266-mqtt-client and refer to the "secure_credentials.h" section.

Or you can open a command shell and go to your directory containing your certificates and keys. Then try running:

mosquitto_sub -h your-hostname -p 8883 --tls-version tlsv1.2 --topic irrigation/zone/on --cafile mosq_ca.crt --cert mosq_client.crt --key mosq_client.key

And then from another shell:

mosquitto_pub -h your-hostname -p 8883 --tls-version tlsv1.2 --topic irrigation/zone/on -m "1 5" --cafile mosq_ca.crt --cert mosq_client.crt --key mosq_client.key

Obviously, replacing "your-hostname" with the actual host name you used when creating the keys and certificates.

  Are you sure? yes | no