Encryption TLS
Nous avons donc protégé l’accès à notre serveur MQTT, mais tout le trafic MQTT qui passe sur le réseau reste en clair. C’est à dire que si on mettait en place ce qu’on appelle un sniffer, on pourrait lire les données qui transitent par MQTT.
On va donc faire en sorte que tout ce qui transite au travers de MQTT soit encrypté. Pour cela, on va devoir mettre en place ce qu’on appelle une autorité de certification. Et grâce à elle, on va pouvoir générer un certificat et des clés de chiffrement que l’on utilisera pour sécuriser la connexion MQTT.
Autorité de certification
cd /etc
sudo mkdir certs
cd certs
sudo mkdir ca
cd ca
Maintenant qu’on a créé le répertoire, on va créer notre certificat.
sudo openssl req -new -x509 -days 3650 -extensions v3_ca -keyout ca.key -out ca.crt
Et on en arrive là
pi@rasp-test:/etc/certs/ca $ sudo openssl req -new -x509 -days 3650 -extensions v3_ca -keyout ca.key -out ca.crt
Generating a RSA private key
.....................................+++++
..+++++
writing new private key to 'ca.key'
Enter PEM pass phrase:
Il nous demande donc d’entrer un mot de passe. Ce mot de passe, il faudra très précieusement le mettre de côté car c’est ce qui nous permettra de signer ensuite les certificats.
Ensuite, il va te demander quelques informations. Il faudra là aussi faire attention à ce que tu entres. Il y a 2 éléments sensibles. Le premier, c’est “Organization Unit”. Ce champ nous permettra de mettre le rôle associé au certificat. Le second, c’est le champ “Common name”. Il faudra soit mettre le hostname soit son adresse IP. Donc si l’IP n’est pas fixe, préfère le hostname. Il ne faut pas que 2 certificats aient les mêmes informations, sinon, ça va foirer.
Country Name (2 letter code) [AU]:FR
State or Province Name (full name) [Some-State]:PARIS
Locality Name (eg, city) []:PARIS
Organization Name (eg, company) [Internet Widgits Pty Ltd]:COXPROD
Organizational Unit Name (eg, section) []:ca
Common Name (e.g. server FQDN or YOUR name) []:rasp-test
Email Address []:cedcox@nomail.com
Une fois fini, si tu listes les fichiers, tu devrais trouver ces fichiers
pi@rasp-test:/etc/certs/ca $ ls
ca.crt ca.key
pi@rasp-test:/etc/certs/ca $
Nous allons sécuriser ces 2 fichiers critiques
sudo chmod 600 ca.*
Certificat et clés pour notre serveur MQTT
Maintenant que nous avons notre autorité de certification, nous allons créer notre certificat pour notre serveur ainsi que la paire de clé nécessaire au chiffrement.
Commençons par créer un répertoire pour notre serveur MQTT
cd /etc/certs
sudo mkdir mosquitto
cd mosquitto
Ensuite, on crée la clé privée.
sudo openssl genrsa -out mosquitto.key 2048
voilà ce que ça donne :
pi@rasp-test:/etc/certs/mosquitto $ sudo openssl genrsa -out mosquitto.key 2048
Generating RSA private key, 2048 bit long modulus (2 primes)
.................+++++
.....................................................................................+++++
e is 65537 (0x010001)
pi@rasp-test:/etc/certs/mosquitto $ ls
mosquitto.key
pi@rasp-test:/etc/certs/mosquitto $
Faisons maintenant une demande de signature
sudo openssl req -out mosquitto.csr -key mosquitto.key -new
Comme tout à l’heure, il va falloir entrer quelques informations. Là aussi, il faudra bien faire attention aux 2 champs “Organization Name” et “Common name”. Par contre, ne rentre pas de “challenge password”. Tapes juste sur “Entrée”
Country Name (2 letter code) [AU]:FR
State or Province Name (full name) [Some-State]:PARIS
Locality Name (eg, city) []:PARIS
Organization Name (eg, company) [Internet Widgits Pty Ltd]:COXPROD
Organizational Unit Name (eg, section) []:mosquitto
Common Name (e.g. server FQDN or YOUR name) []:rasp-test
Email Address []:cedcox@nomail.com
Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:
Si on liste les fichiers, en plus de notre clé privée, il y a désormais notre demande de signature (fichier .csr).
pi@rasp-test:/etc/certs/mosquitto $ ls
mosquitto.csr mosquitto.key
pi@rasp-test:/etc/certs/mosquitto $
On soumet notre fichier de signature à l’autorité de certification
sudo openssl x509 -req -in mosquitto.csr -CA ../ca/ca.crt -CAkey ../ca/ca.key -CAcreateserial -out mosquitto.crt -days 3650
Une fois lancée, cette commande va te demander le mot de passe que tu as entré lorsque tu as généré ton autorité de certification
Signature ok
subject=C = FR, ST = PARIS, L = PARIS, O = COXPROD, OU = mosquitto, CN = rasp-test, emailAddress = cedcox@nomail.com
Getting CA Private Key
Enter pass phrase for ../ca/ca.key:
Si tu listes les fichiers, tu dois désormais avoir on fichier .crt qui est le certificat
pi@rasp-test:/etc/certs/mosquitto $ ls
mosquitto.crt mosquitto.csr mosquitto.key
pi@rasp-test:/etc/certs/mqtt $
Et on sécurise nos fichiers
sudo chmod 600 mosquitto*
Certificat et clés pour Rhasspy
Maintenant que nous avons un certificat pour notre serveur MQTT, il faudra générer un certificat pour chaque client MQTT, donc pour Rhasspy.
On commence donc par créer le répertoire qui va accueillir nos fichiers
cd /etc/certs
sudo mkdir rhasspy
cd rhasspy
On crée la clé privée
sudo openssl genrsa -out rhasspy.key 2048
Faisons maintenant une demande de signature
sudo openssl req -out rhasspy.csr -key rhasspy.key -new
On soumet notre demande de signature à l’autorité de certification
sudo openssl x509 -req -in rhasspy.csr -CA ../ca/ca.crt -CAkey ../ca/ca.key -CAcreateserial -out rhasspy.crt -days 3650
Comme pour mosquitto, on fait attention aux 2 champs critiques. Si notre client MQTT (Rhasspy) est sur un autre raspberry, on met le hostname de cet autre raspberry !
Country Name (2 letter code) [AU]:FR
State or Province Name (full name) [Some-State]:PARIS
Locality Name (eg, city) []:PARIS
Organization Name (eg, company) [Internet Widgits Pty Ltd]:COXPROD
Organizational Unit Name (eg, section) []:rhasspy
Common Name (e.g. server FQDN or YOUR name) []:rasp-test
Email Address []:cedcox@nomail.com
On fait signer par l’autorité de certification
sudo openssl x509 -req -in rhasspy.csr -CA ../ca/ca.crt -CAkey ../ca/ca.key -CAcreateserial -out rhasspy.crt -days 3650
On sécurise nos fichiers
sudo chmod 600 rhasspy*
N’oublie pas que tu devras générer ces fichiers pour chaque client qui devra se connecter au serveur MQTT comme nodered par exemple.
Configuration de mosquitto
On va déjà rappatrier les fichiers dans le répertoire de mosquitto
sudo cp -fr /etc/certs/mosquitto/* /etc/mosquitto/certs
sudo cp /etc/certs/ca/ca.crt /etc/mosquitto/certs/
sudo chown -R mosquitto /etc/mosquitto/certs
Ensuite, on édite notre fichier de configuration mosquitto
sudo nano /etc/mosquitto/mosquitto.conf
Et on colle ceci à la fin
## Si on veut autoriser aussi les connexions non chiffrees
listener 1883
## Activation des connexions chifrees par TLS
listener 8883
cafile /etc/mosquitto/certs/ca.crt
certfile /etc/mosquitto/certs/mosquitto.crt
keyfile /etc/mosquitto/certs/mosquitto.key
tls_version tlsv1.2
require_certificate true
Notre fichier de config est donc divisé en 2 parties.
La première c’est le listener sur le port TCP 1883. On peut si on le souhaite se garder la possibilité d’envoyer des messages MQTT non chiffré par des périphériques qui n’auraient pas la puissance de calcul pour le chiffrement.
La seconde partie c’est la mise en place du listener sur le port 8883. C’est le port utilisé pour le secure-MQTT. Dans cette partie, on y met les chemins vers les certificats nécessaires au chiffrement et à la vérification de signature des certificats clients.
Et on redémarre notre serveur MQTT
sudo systemctl restart mosquitto
Et un petit test de bon fonctionnement. Au préalable, on installe mosquitto-clients s’il n’est pas déjà là.
sudo apt-get install mosquitto-clients
Puis, on essaye de souscrire à notre serveur MQTT en utilisant TLS
sudo mosquitto_sub --cafile /etc/certs/ca/ca.crt \
-h rasp-test \
-t "#" -p 8883 -d \
--cert /etc/certs/rhasspy/rhasspy.crt \
--key /etc/certs/rhasspy/rhasspy.key \
-u rhasspy -P <ton_mot_de_passe_mosquitto>
Et voilà ce que tu devrais obtenir :
Client mosqsub|29427-rasp-test sending CONNECT
Client mosqsub|29427-rasp-test received CONNACK (0)
Client mosqsub|29427-rasp-test sending SUBSCRIBE (Mid: 1, Topic: #, QoS: 0)
Client mosqsub|29427-rasp-test received SUBACK
Subscribed (mid: 1): 0
Si ce n’est pas le cas… recommence à 0 en regénérant les certificats.
Configuration de Rhasspy
On rapatrie les fichiers nécessaires dans le répertoire de Rhasspy
mkdir /home/pi/.config/rhasspy/profiles/fr/certs
sudo cp -fr /etc/certs/rhasspy/* /home/pi/.config/rhasspy/profiles/fr/certs
sudo cp /etc/certs/ca/ca.crt /home/pi/.config/rhasspy/profiles/fr/certs
sudo chown -R pi /home/pi/.config/rhasspy/profiles/fr/certs
Il nous faut maintenant mettre à jour notre profil Rhasspy. Le problème c’est qu’à la date d’ajourd’hui, les champs TLS de l’interface de configuration sont non fonctionnels. Il va donc falloir aller modifier le fichier de configuration manuellement.
cd /home/pi/.config/rhasspy/profiles/fr
nano profile.json
Et là, il faut modifier la partie TLS pour qu’elle corresponde à ce qu’il y a ci-dessous :
"mqtt": {
"enabled": "true",
"host": "rasp-test",
"password": "ton_mot_de_passe_mqtt",
"port": "8883",
"site_id": "master",
"tls": {
"ca_certs": "/home/pi/.config/rhasspy/profiles/fr/certs/ca/ca.crt",
"certfile": "${RHASSPY_PROFILE_DIR}/certs/rhasspy.crt",
"enabled": true,
"keyfile": "${RHASSPY_PROFILE_DIR}/certs/rhasspy.key"
},
"username": "rhasspy"
},
Si tu as installé Rhasspy avec Docker, alors remplace cette ligne :
"ca_certs": "/home/pi/.config/rhasspy/profiles/fr/certs/ca/ca.crt",
Par celle-ci :
"ca_certs": "/profiles/fr/certs/ca/ca.crt",
On sauvegarde et on redémarre Rhasspy
sudo systemctl restart rhasspy
Merci pour cet article, c’est exactement ce qu’il me fallait ! Bravo ced pour tes articles, je les utilise beaucoup (je vais d’ailleurs bientôt passer de rhasspy docker à venv grâce à ton article, espérant corriger des difficultés audio)
Je n’ai pas été jusqu’au chiffrement TLS du MQTT car j’ai un des clients qui n’est pas (encore) compatible.
Sinon je vous renvoie vers le soft MQTT-Explorer (http://mqtt-explorer.com/). Dispo sur toutes les plateformes, il est compatible TLS et permet facilement de vérifier le bon fonctionnement, mais aussi de visualiser les messages simplement.
Bonjour Chris,
Si tu ajoutes
Listener 1883
juste avant la partieListener 8883
, mosquitto gardera aussi le port 1883 en non encrypté d’ouvert (comme à la page 4).Ça devrait te permettre de faire un test tout en gardant les clients non compatibles. 🙂
Après, c’est vrai que je préfère Rhasspy-watch quand il s’agit de regarder uniquement ce qui se passe au niveau MQTT pour Rhasspy. Mais si il y a d’autre chose en plus que Rhasspy sur MQTT, oui mqtt-explorer est sympa !
Ced