Let Mosquitto MQTT broker piggyback on Nginx's Let's Encrypt certificates
This article documents a method to let Mosquitto MQTT broker use the same certificates as Blocks with NGINX if deployed on the same server and accessed with the same domain name. This allows us to get the certificates automatically updated from the Lets Encrypt Nginx cert bot.
It assumes a working server with certificates handled by NGINX, as described in the Blocks "net-install" here, and Mosquitto installed on the server.
The article Add certificates for the Mosquitto MQTT broker secure connections describes the general setup to add TLS, and the article MQTT gives some context about MQTT and the Mosquitto broker.
Config file
We use a Mosquitto config file in /etc/mosquitto/conf.d with the following content:
user mosquitto password_file /etc/mosquitto/conf.d/pixi-pwd listener 1883 localhost listener 8883 keyfile /etc/mosquitto/certs/privkey.pem certfile /etc/mosquitto/certs/fullchain.pem cafile /etc/mosquitto/certs/fullchain.pem
Password file is described in the tls-article linked above and the 1883 listener is only required if one want the blocks server use local host with no encryption (probably a little bit more efficient)
Symlink the NGINX certs
To use the same certs as NGINX, symlink the relevant NGINX certs into /etc/mosquitto/certs like this:
The path to the Let's Encrypt certs will vary depending on the domain name in use.
ln -s /etc/letsencrypt/live/pixilab.net/cert.pem /etc/mosquitto/certs/cert.pem ln -s /etc/letsencrypt/live/pixilab.net/chain.pem /etc/mosquitto/certs/chain.pem ln -s /etc/letsencrypt/live/pixilab.net/fullchain.pem /etc/mosquitto/certs/fullchain.pem ln -s /etc/letsencrypt/live/pixilab.net/privkey.pem /etc/mosquitto/certs/privkey.pem
Once this is done, restart Mosquitto:
systemctl restart mosquitto
Automatically restart Mosquitto after any Certbot renewal
To achieve this, use Certbot’s deploy hooks.
Create a script in the deploy hook directory:
nano /etc/letsencrypt/renewal-hooks/deploy/restart-mosquitto.sh
Add the following shell script content:
#!/bin/bash echo "[+] Let's Encrypt certificate deployed. Restarting Mosquitto..." #Restart the Mosquitto service if systemctl restart mosquitto; then echo "[+] Mosquitto restarted successfully." else echo "[!] Failed to restart Mosquitto." >&2 exit 1 fi
Make the script executable:
chmod +x /etc/letsencrypt/renewal-hooks/deploy/restart-mosquitto.sh
Verify functionality
To verify that everything works, force Certbot to renew the certificates:
certbot renew --force-renewal
Then check that Mosquitto restarted automatically:
journalctl -u mosquitto --since "5 minutes ago"
You should see some startup logging from Mosquitto as a result.
After the process finishes, Mosquitto should continue to work with TLS connections.