Comment installer et sécuriser le courtier de messagerie Mosquitto MQTT sur Debian 8

De Get Docs
Aller à :navigation, rechercher

Introduction

MQTT est un protocole de messagerie de machine à machine, conçu pour fournir une communication légère de publication/abonnement aux appareils « Internet des objets ». Il est couramment utilisé pour le suivi géographique des flottes de véhicules, la domotique, les réseaux de capteurs environnementaux et la collecte de données à grande échelle.

Mosquitto est un serveur MQTT populaire (ou courtier, dans le langage MQTT) qui bénéficie d'un excellent support communautaire et est facile à installer et à configurer.

Dans ce didacticiel, nous allons installer Mosquitto, récupérer les certificats SSL de Let's Encrypt et configurer notre courtier pour qu'il utilise SSL pour sécuriser nos communications MQTT protégées par mot de passe.

Conditions préalables

Avant de commencer ce tutoriel, vous aurez besoin de :

Étape 1 - Installation de Mosquitto

Le paquet mosquitto de Debian ne prend pas en charge certaines des fonctionnalités dont nous avons besoin, nous allons donc installer à partir d'un référentiel plus à jour fourni par le projet Mosquitto. Tout d'abord, téléchargez leur clé de signature de référentiel.

wget http://repo.mosquitto.org/debian/mosquitto-repo.gpg.key

Installez ensuite la clé avec apt-key.

sudo apt-key add mosquitto-repo.gpg.key

Cela permet à apt-get de vérifier l'intégrité de tout logiciel que vous installez à partir du nouveau référentiel.

Indiquez maintenant à apt-get où trouver le logiciel en ajoutant l'URL du référentiel à un fichier dans /etc/apt/sources.list.d/.

sudo nano /etc/apt/sources.list.d/mosquitto.list

Cela ouvrira un nouveau fichier vierge. Collez la ligne suivante dans le fichier.

/etc/apt/sources.list.d/mosquitto.list

deb http://repo.mosquitto.org/debian jessie main

Enregistrez et fermez l'éditeur, puis mettez à jour avec apt-get pour extraire les nouvelles informations de package.

sudo apt-get update

Et enfin, installez le package mosquitto et son logiciel client.

sudo apt-get install mosquitto mosquitto-clients

Par défaut, Debian démarrera le service Mosquitto après l'installation. Testons la configuration par défaut. Nous utiliserons l'un des clients que nous venons d'installer pour nous abonner à un sujet sur notre courtier.

Les Topics sont des libellés auxquels vous publiez des messages et auxquels vous vous abonnez. Ils sont organisés en hiérarchie, vous pouvez donc avoir sensors/outside/temp et sensors/outside/humidity, par exemple. La façon dont vous organisez les sujets dépend de vous et de vos besoins. Tout au long de ce didacticiel, nous utiliserons un sujet de test simple pour tester nos modifications de configuration.

Connectez-vous une deuxième fois à votre serveur, vous avez donc deux terminaux côte à côte. Dans le nouveau terminal, utilisez mosquitto_sub pour vous abonner au sujet de test :

mosquitto_sub -h localhost -t test

L'indicateur -h spécifie le nom d'hôte du serveur MQTT et -t est le nom du sujet. Vous ne verrez aucune sortie après avoir appuyé sur ENTER car mosquitto_sub attend l'arrivée des messages. Revenez sur votre autre terminal et publiez un message :

mosquitto_pub -h localhost -t test -m "hello world"

Les options pour mosquitto_pub sont les mêmes que pour mosquitto_sub, bien que cette fois nous utilisons l'option supplémentaire -m pour spécifier notre message. Appuyez sur ENTER, et vous devriez voir hello world apparaître dans l'autre terminal. Vous avez envoyé votre premier message MQTT !

Appuyez sur CTRL+C dans le deuxième terminal pour sortir de mosquitto_sub, mais gardez la connexion au serveur ouverte. Nous l'utiliserons à nouveau pour un autre test à l'étape 5.

Ensuite, nous allons sécuriser notre installation avec SSL en utilisant Certbot, le nouveau client Let's Encrypt.

Étape 2 - Installation de Certbot pour les certificats Let's Encrypt

Let's Encrypt est un nouveau service offrant des certificats SSL gratuits via une API automatisée. De nombreux clients peuvent communiquer avec l'API, et Debian inclut le client officiel dans son référentiel par défaut, mais il est un peu obsolète et manque d'une fonctionnalité importante dont nous avons besoin.

Au lieu de cela, nous installerons le client à partir du référentiel backports de Debian. Il s'agit d'un référentiel officiel qui rend les nouvelles versions de certains logiciels disponibles pour les versions déjà publiées de Debian. Nous devons ajouter le référentiel à notre liste de sources APT, comme nous l'avons fait à l'étape précédente.

Commencez par ouvrir un nouveau fichier dans /etc/apt/sources.list.d/.

sudo nano /etc/apt/sources.list.d/backports.list

Collez la ligne suivante dans le fichier :

/etc/apt/sources.list.d/backports.list

deb http://mirrors.digitalocean.com/debian jessie-backports main

Enregistrez le fichier et fermez l'éditeur. Ensuite, mettez à jour les informations sur le package.

sudo apt-get update

Et enfin, installez le client officiel Let's Encrypt, appelé Certbot, indiquant à APT d'utiliser jessie-backports comme source :

sudo apt-get install certbot -t jessie-backports

Maintenant que Certbot est installé, exécutons-le pour obtenir notre certificat.

Étape 3 - Exécution de Certbot

Certbot doit répondre à un défi cryptographique émis par l'API Let's Encrypt afin de prouver que nous contrôlons notre domaine. Il utilise les ports 80 (HTTP) et/ou 443 (HTTPS) pour y parvenir. Nous n'utiliserons que le port 80, donc autorisez le trafic entrant sur ce port.

sudo ufw allow http
OutputRule added
Rule added (v6)

Nous pouvons maintenant exécuter Certbot pour obtenir notre certificat. Nous utiliserons l'option --standalone pour indiquer à Certbot de gérer lui-même la demande de challenge HTTP, et --standalone-supported-challenges http-01 limite la communication au port 80. -d spécifie le domaine pour lequel vous souhaitez un certificat et certonly indique à Certbot de simplement récupérer le certificat sans effectuer aucune autre étape de configuration.

sudo certbot certonly --standalone --standalone-supported-challenges http-01 -d mqtt.example.com

Lors de l'exécution de la commande, vous serez invité à saisir une adresse e-mail et à accepter les conditions d'utilisation. Après cela, vous verrez un message vous indiquant que le processus a réussi et où vos certificats sont stockés.

Nous avons nos certificats. Nous devons maintenant nous assurer que Certbot les renouvelle automatiquement lorsqu'ils sont sur le point d'expirer.

Étape 4 - Configuration des renouvellements automatiques de Certbot

Les certificats de Let's Encrypt ne sont valables que pendant quatre-vingt-dix jours. Il s'agit d'encourager les utilisateurs à automatiser leur processus de renouvellement de certificat. Nous devrons configurer une commande qui vérifie régulièrement les certificats arrivant à expiration et les renouvelle automatiquement.

Pour exécuter la vérification de renouvellement quotidiennement, nous utiliserons cron, un service système standard pour exécuter des tâches périodiques. Nous disons à cron quoi faire en ouvrant et en éditant un fichier appelé crontab.

sudo crontab -e

Vous serez invité à sélectionner un éditeur de texte. Choisissez votre favori, et vous serez présenté avec le crontab par défaut qui contient un texte d'aide. Collez la ligne suivante à la fin du fichier, puis enregistrez-la et fermez-la.

crontab

. . .
15 3 * * * certbot renew --noninteractive --post-hook "systemctl restart mosquitto"

La partie 15 3 * * * de cette ligne signifie "exécuter la commande suivante à 3h15, tous les jours". La commande renew pour Certbot vérifiera tous les certificats installés sur le système et mettra à jour ceux qui doivent expirer dans moins de trente jours. --noninteractive indique à Certbot de ne pas attendre l'entrée de l'utilisateur.

--post-hook "systemctl restart mosquitto" redémarrera Mosquitto pour récupérer le nouveau certificat, mais uniquement si le certificat a été renouvelé. Cette fonctionnalité post-hook est ce qui manquait aux anciennes versions du client Let's Encrypt, et pourquoi nous avons installé à partir de backports au lieu du référentiel Debian par défaut. Sans cela, nous devions redémarrer Mosquitto tous les jours, même si aucun certificat n'était réellement mis à jour. Bien que vos clients MQTT doivent être configurés pour se reconnecter automatiquement, il est sage d'éviter de les interrompre quotidiennement sans raison valable.

Maintenant que le renouvellement automatique du certificat est défini, nous allons revenir à la configuration de Mosquitto pour qu'il soit plus sécurisé.

Étape 5 - Configuration des mots de passe MQTT

Configurons Mosquitto pour utiliser des mots de passe afin que nous puissions contrôler qui peut publier des messages. Mosquitto inclut un utilitaire pour générer un fichier de mot de passe spécial appelé mosquitto_passwd. Cette commande vous invitera à entrer un mot de passe pour le nom d'utilisateur spécifié et placera les résultats dans /etc/mosquitto/passwd.

sudo mosquitto_passwd -c /etc/mosquitto/passwd sammy

Créez maintenant un nouveau fichier de configuration pour Mosquitto et dites-lui d'utiliser ce fichier de mot de passe pour exiger des connexions pour toutes les connexions.

sudo nano /etc/mosquitto/conf.d/default.conf

Cela devrait ouvrir un fichier vide. Collez ce qui suit :

/etc/mosquitto/conf.d/default.conf

allow_anonymous false
password_file /etc/mosquitto/passwd

allow_anonymous false désactive toutes les connexions non authentifiées et la ligne password_file indique à Mosquitto où rechercher les informations d'utilisateur et de mot de passe. Enregistrez et quittez le fichier.

Vous devez maintenant redémarrer Mosquitto et tester vos modifications.

sudo systemctl restart mosquitto

Tout d'abord, essayez de publier un message sans mot de passe.

mosquitto_pub -h localhost -t "test" -m "hello world"

Le message doit être rejeté :

OutputConnection Refused: not authorised.
Error: The connection was refused.

Avant de réessayer avec le mot de passe, revenez à votre deuxième fenêtre de terminal et abonnez-vous au sujet test, en utilisant cette fois le nom d'utilisateur et le mot de passe :

mosquitto_sub -h localhost -t test -u "sammy" -P "password"

Il devrait se connecter et s'asseoir, en attendant les messages. Vous pouvez laisser ce terminal ouvert et connecté pour le reste du didacticiel, car nous lui enverrons périodiquement des messages de test.

Publiez maintenant un message avec votre autre terminal, en utilisant à nouveau le nom d'utilisateur et le mot de passe.

mosquitto_pub -h localhost -t "test" -m "hello world" -u "sammy" -P "password"

Le message devrait passer comme à l'étape 1. Nous avons ajouté avec succès la protection par mot de passe à Mosquitto. Malheureusement, nous envoyons des mots de passe non cryptés sur Internet. Nous allons résoudre ce problème en ajoutant le cryptage SSL à Mosquitto.

Étape 6 - Configuration de SSL MQTT

Pour activer le cryptage SSL, nous devons indiquer à Mosquitto où nos certificats Let's Encrypt sont stockés. Ouvrez le fichier de configuration que nous avons précédemment démarré.

sudo nano /etc/mosquitto/conf.d/default.conf

Collez ce qui suit à la fin du fichier, en laissant les deux lignes que nous avons déjà ajoutées :

/etc/mosquitto/conf.d/default.conf

. . .
listener 1883 localhost

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

Nous ajoutons deux blocs listener distincts à la configuration. Le premier, listener 1883 localhost, met à jour l'écouteur MQTT par défaut sur le port 1883, auquel nous nous sommes connectés jusqu'à présent. 1883 est le port MQTT non chiffré standard. La partie localhost de la ligne indique à Mosquitto de ne lier ce port qu'à l'interface localhost, il n'est donc pas accessible de l'extérieur. Les requêtes externes auraient de toute façon été bloquées par notre pare-feu, mais il est bon d'être explicite.

listener 8883 configure un écouteur chiffré sur le port 8883. Il s'agit du port standard pour MQTT + SSL, souvent appelé MQTTS. Les trois lignes suivantes, certfile, cafile et keyfile, pointent toutes Mosquitto vers les fichiers Let's Encrypt appropriés pour configurer les connexions cryptées.

Enregistrez et quittez le fichier, puis redémarrez Mosquitto pour mettre à jour les paramètres.

sudo systemctl restart mosquitto

Mettez à jour le pare-feu pour autoriser les connexions au port 8883.

sudo ufw allow 8883
OutputRule added
Rule added (v6)

Maintenant, testez à nouveau en utilisant mosquitto_pub, avec quelques options différentes pour SSL :

mosquitto_pub -h mqtt.example.com -t test -m "hello again" -p 8883 --capath /etc/ssl/certs/ -u "sammy" -P "password"

Notez que nous utilisons le nom d'hôte complet au lieu de localhost. Étant donné que notre certificat SSL est émis pour mqtt.example.com, si nous tentons une connexion sécurisée à localhost, nous obtiendrons une erreur indiquant que le nom d'hôte ne correspond pas au nom d'hôte du certificat (même s'ils pointent tous les deux vers le même serveur Mosquitto).

--capath /etc/ssl/certs/ active SSL pour mosquitto_pub et lui indique où rechercher les certificats racine. Ceux-ci sont généralement installés par votre système d'exploitation, le chemin est donc différent pour macOS, Windows, etc. mosquitto_pub utilise le certificat racine pour vérifier que le certificat du serveur Mosquitto a été correctement signé par l'autorité de certification Let's Encrypt. Il est important de noter que mosquitto_pub et mosquitto_sub ne tenteront pas une connexion SSL sans cette option (ou l'option similaire --cafile), même si vous vous connectez au protocole sécurisé standard. port de 8883.

Si tout se passe bien avec le test, vous verrez hello again apparaître dans l'autre terminal mosquitto_sub. Cela signifie que votre serveur est entièrement configuré ! Si vous souhaitez étendre le protocole MQTT pour qu'il fonctionne avec les websockets, vous pouvez suivre la dernière étape.

Étape 7 - Configuration de MQTT sur Websockets (facultatif)

Afin de parler MQTT en utilisant JavaScript à partir de navigateurs Web, le protocole a été adapté pour fonctionner sur des websockets standard. Si vous n'avez pas besoin de cette fonctionnalité, vous pouvez ignorer cette étape.

Nous devons ajouter un autre bloc listener à notre configuration Mosqiutto.

sudo nano /etc/mosquitto/conf.d/default.conf

À la fin du fichier, ajoutez ce qui suit :

/etc/mosquitto/conf.d/default.conf

. . .
listener 8083
protocol websockets
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

C'est essentiellement le même que le bloc précédent, à l'exception du numéro de port et de la ligne protocol websockets. Il n'y a pas de port standardisé officiel pour MQTT sur les websockets, mais 8083 est le plus courant.

Enregistrez et quittez le fichier, puis redémarrez Mosquitto.

sudo systemctl restart mosquitto

Maintenant, ouvrez le port 8083 dans le pare-feu.

sudo ufw allow 8083

Pour tester cette fonctionnalité, nous utiliserons un client MQTT public basé sur un navigateur. Il y en a quelques-uns, mais mqtt-admin est simple et direct. Ouvrez mqtt-admin dans votre navigateur. Vous verrez ce qui suit :

Remplissez les informations de connexion comme suit :

  • Protocole doit être wss (qui signifie websocket secure).
  • Host doit être le domaine de votre serveur Mosquitto, mqtt.example.com.
  • Port doit être 8083.
  • User doit être votre nom d'utilisateur Mosquitto ; ici, nous avons utilisé sammy.
  • Password doit être le mot de passe que vous avez choisi.
  • ClientId peut être laissé à la valeur par défaut, mqtt-admin.

Après avoir appuyé sur Enregistrer les paramètres, mqtt-admin se connectera à votre serveur Mosquitto. Dans l'écran suivant, remplissez Topic en tant que test, saisissez n'importe quel message pour Payload, puis appuyez sur Publish. Le message s'affichera dans le terminal mosquitto_sub.

Conclusion

Nous avons maintenant mis en place un serveur MQTT sécurisé et protégé par mot de passe, avec des certificats SSL à renouvellement automatique du service Let's Encrypt. Cela servira de plate-forme de messagerie robuste et sécurisée pour tous les projets que vous imaginez. Certains logiciels et matériels populaires qui fonctionnent bien avec le protocole MQTT incluent :

  • OwnTracks, une application de géolocalisation open source que vous pouvez installer sur votre téléphone. OwnTracks rapportera périodiquement des informations de position à votre serveur MQTT, que vous pourrez ensuite stocker et afficher sur une carte, ou créer des alertes et activer le matériel IoT en fonction de votre emplacement.
  • Node-RED est une interface graphique basée sur un navigateur pour "câbler ensemble" l'Internet des objets. Vous faites glisser la sortie d'un nœud vers l'entrée d'un autre et pouvez acheminer les informations à travers des filtres, entre différents protocoles, dans des bases de données, etc. MQTT est très bien supporté par Node-RED.
  • Le ESP8266 est un microcontrôleur wifi peu coûteux avec des capacités MQTT. Vous pouvez en connecter un pour publier des données de température sur un sujet, ou peut-être vous abonner à un sujet sur la pression barométrique et faire retentir un buzzer lorsqu'une tempête arrive !

Ce ne sont là que quelques exemples populaires de l'écosystème MQTT. Il y a beaucoup plus de matériel et de logiciels qui parlent le protocole. Si vous avez déjà une plate-forme matérielle préférée ou un langage logiciel, il a probablement des capacités MQTT. Amusez-vous à faire parler vos « choses » !