mosquitto + mysql auth + let’s encrypt

Installer mosquitto (mqtt broker) avec une authentification via (mariadb (mysql)

On considère que mariadb (mysql) est installé et configuré.

apt -y install mosquitto

On installe le plugin pour l’authentification

apt -y install mosquitto-auth-plugin

On va créer un utilisateur et une base de données spécifique (isoler les problèmes)

CREATE DATABASE mosquitto;
CREATE USER 'mosquitto'@'localhost' IDENTIFIED BY 'mosquitto_password';
GRANT ALL PRIVILEGES ON mosquitto.* TO 'mosquitto'@'localhost';
FLUSH PRIVILEGES;

On créé une table pour l’authentification des utilisateurs : id, login, password et super si l’utilisateur doit être un « super-utilisateur ».

CREATE TABLE `users` (
`userID` int(10) unsigned NOT NULL AUTO_INCREMENT,
`userLogin` tinytext NOT NULL,
`userPassword` tinytext NOT NULL,
`userSuper` int(1) unsigned NOT NULL,
PRIMARY KEY (`userID`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

On créé une table pour lier les droits des utilisateurs vis à vis des topics. On va donc avoir un id, login, topic et les droits associés (1= read only, 2 = read write)

DROP TABLE IF EXISTS `acls`; CREATE TABLE `acls` (
`aclID` int(10) unsigned NOT NULL AUTO_INCREMENT,
`aclLogin` tinytext NOT NULL,
`aclTopic` tinytext NOT NULL,
`aclRW` int(1) unsigned NOT NULL, PRIMARY KEY (`aclID`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

on va créer un fichier dans /etc/mosquitto/conf.d donc nano /etc/mosquitto/conf.d/sql-auth.conf avec comme contenu

auth_plugin /usr/lib/mosquitto-auth-plugin/auth-plugin.so
auth_opt_backends mysql
auth_opt_host localhost
auth_opt_port 3306
auth_opt_dbname mosquitto
auth_opt_user mosquitto
auth_opt_pass mosquitto_password
auth_opt_userquery SELECT userPassword FROM users WHERE userLogin = '%s'
auth_opt_superquery SELECT COUNT(*) FROM users WHERE userLogin = '%s' AND userSuper = 1
auth_opt_aclquery SELECT aclTopic FROM acls WHERE (aclLogin = '%s') AND (aclRW >= %d)

On peut maintenant redémarrer le daemon pour la prise en compte des modifications.

Il faut rajouter des mots de passe en PBKDF2. Un utilitaire est fourni de base dans le système, il s’agit de np. On exécute donc np, on donne le mot de passe voulut, on confirme et le système donne le hash à mémoriser en base.

Pour les topics, il suffit de récupérer l’utilisateur, lui assigner le bon topic et les droits et le tour est joué.

On va maintenant installer un certificat SSL via Let’s Encrypt pour protéger nos échanges.

apt -y install certbot

On pense à désactiver les serveurs web du système le temps de récupérer le certificat

J’ai créé un fichier /opt/renew.sh avec le contenu

#!/bin/sh
certbot certonly \
--non-interactive \
--email user@domain.com \
--preferred-challenges http \
--standalone \
--agree-tos \
--renew-by-default \
-d domain.com

On lance /opt/renew.sh (et on peut l’associer à un crontab pour les mises à jour)

On se rajoute un fichier dans la configuration de Mosquitto

nano /etc/mosquitto/conf.d/letsencrypt.conf
listener 8883
certfile /etc/letsencrypt/live/mqtt.example.com/cert.pem
cafile /etc/letsencrypt/live/mqtt.example.com/chain.pem
keyfile /etc/letsencrypt/live/mqtt.example.com/privkey.pem

On relance et c’est parti.

Attention, dans cette configuration, seul le port 8883 est utilisé via SSL, donc le port par défaut 1883 ne répond plus.