So installierst und sicherst du den Mosquitto MQTT Messaging Broker unter Ubuntu 20.04

Mosquitto ist ein Open-Source Message Broker, der das Message Queuing Telemetry Transport(MQTT) Protokoll verwendet. Das Protokoll wurde entwickelt, um eine leichtgewichtige Kommunikation mit Geräten im Internet der Dinge(IoT) zu ermöglichen. Es wird häufig für die GPS-Ortung von Fahrzeugen, die Hausautomatisierung, Umweltsensoren und groß angelegte Datenerhebungen verwendet.

Das MQTT-Protokoll läuft auf dem TCP/IP-Modell. Da es leichtgewichtig ist, kannst du dank seines kleinen Code-Fußabdrucks Anwendungen für Geräte mit minimalen Ressourcen erstellen. Es basiert auf dem Publish/Subscribe-Modell. Bei diesem Modell verbindet sich der Client mit dem Mosquitto-Server, der als Broker fungiert, um Informationen an andere Clients zu senden, die einen Kanal abonniert haben.

In diesem Lernprogramm wirst du Mosquitto installieren und den Broker so einrichten, dass er SSL zum Schutz der Kommunikation verwendet.

Voraussetzungen

  • Ein Ubuntu 20.04-Server mit einem Nicht-Root-Benutzer mit sudo-Rechten.
  • Ein Domainname (myqtt.example.com), der auf deinen Server zeigt.

Schritt 1 – Installiere Mosquitto Server und Client

Ubuntu wird mit der älteren Version 1.6 von Mosquitto ausgeliefert. Um die neueste Version zu installieren, füge das offizielle Mosquitto-Repository hinzu.

$ sudo add-apt-repository ppa:mosquitto-dev/mosquitto-ppa

Installiere den Mosquitto Server und den Client.

$ sudo apt install mosquitto mosquitto-clients

Überprüfe den Status des Servers.

$ sudo systemctl status mosquitto
? mosquitto.service - Mosquitto MQTT Broker
     Loaded: loaded (/lib/systemd/system/mosquitto.service; enabled; vendor preset: enabled)
     Active: active (running) since Tue 2022-01-25 09:18:40 UTC; 25s ago
       Docs: man:mosquitto.conf(5)
             man:mosquitto(8)
   Main PID: 119694 (mosquitto)
      Tasks: 1 (limit: 2274)
     Memory: 1.0M
     CGroup: /system.slice/mosquitto.service
             ??119694 /usr/sbin/mosquitto -c /etc/mosquitto/mosquitto.conf

Jan 25 09:18:39 <userid> systemd[1]: Starting Mosquitto MQTT Broker...
Jan 25 09:18:40 <userid> systemd[1]: Started Mosquitto MQTT Broker.

Schritt 2 – MQTT-Passwort-Authentifizierung konfigurieren

Mosquitto wird mit einem Dienstprogramm geliefert, das eine Passwortdatei namens mosquitto_passwd erstellt. Mosquitto speichert alle Konfigurationen in dem Verzeichnis /etc/mosquitto.

Führe den folgenden Befehl aus, um eine verschlüsselte Passwortdatei unter /etc/mosquitto/passwd für den Benutzernamen username zu erzeugen. Gib ein Passwort deiner Wahl ein.

$ sudo mosquitto_passwd -c /etc/mosquitto/passwd username
Password:
Reenter password:

Als Nächstes erstellst du eine Datei default.conf im Verzeichnis /etc/mosquitto/conf.d und öffnest sie zur Bearbeitung.

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

Füge die folgenden Zeilen ein, um den Speicherort der Passwortdatei anzugeben. Wenn du das Listener-Feld weglässt, wird die Verbindung immer anonym hergestellt, unabhängig von der Konfiguration.

listener 1883
password_file /etc/mosquitto/passwd

Speichere die Datei, indem du Strg + X drückst und Y eingibst, wenn du dazu aufgefordert wirst.

Starte den Mosquitto-Server neu, um die Änderung zu übernehmen.

$ sudo systemctl restart mosquitto

Schritt 3 – Mosquitto Client testen

Je nach Anwendungsfall kannst du den Mosquitto-Client nutzen, um Nachrichten zu verschiedenen Themen zu senden und zu empfangen. Ein Client ist entweder ein Abonnent oder ein Herausgeber.

Der nächste Schritt besteht darin, ein Topic zu abonnieren. Im MQTT-Protokoll bezieht sich ein Topic auf einen String, der vom Server/Broker verwendet wird, um Nachrichten für die verbundenen Clients zu filtern. Hier sind einige Beispielthemen, die du in einer Hausautomatisierungsanwendung verwenden kannst.

  • home/lights/sitting_room
  • home/lights/kitchen
  • home/lights/master_bedroom
  • home/lights/kids_bedroom

Um ein Thema zu abonnieren, führst du den Befehl mosquitto_sub -t gefolgt von dem Thema aus. Um zum Beispiel das Thema home/lights/kitchen zu abonnieren, führe den folgenden Befehl aus.

$ mosquitto_sub -u username -P YOUR_PASSWORD -t "home/lights/kitchen"

Schließe das bestehende Fenster nicht. Öffne ein neues Terminalfenster, um mit dem folgenden Befehl eine Nachricht an das Thema home/lights/kitchen zu veröffentlichen.

$ mosquitto_pub -u username -P YOUR_PASSWORD -m "ON" -t "home/lights/kitchen"

Wenn du zum ersten Terminalfenster zurückkehrst, erhältst du die Nutzlast von ON.

ON

Als Nächstes schickst du vom zweiten Terminal aus die Nachricht OFF an dasselbe Thema.

$ mosquitto_pub -u username -P YOUR_PASSWORD -m "OFF" -t "home/lights/kitchen"

Auf dem ersten Terminal wird die neu veröffentlichte Nachricht angezeigt.

ON
OFF

Wenn du versuchst, einen unauthentifizierten Kommentar zu senden, schlägt dies fehl. Probiere zum Beispiel den folgenden Befehl aus.

$ mosquitto_sub -t "home/lights/sitting_room"
Connection error: Connection Refused: not authorised.

Es wird nicht empfohlen, aber du musst die folgende Zeile in die Datei /etc/mosquitto/conf.d/default.conf einfügen, wenn du die Befehle ohne Authentifizierung ausführen willst.

allow_anonymous true

Schritt 4 – SSL installieren

Um ein SSL-Zertifikat mit Let’s Encrypt zu installieren, müssen wir das Tool Certbot herunterladen. Dazu verwenden wir den Snapd-Paketinstaller.

Installiere den Snap-Installer.

$ sudo apt install snapd

Vergewissere dich, dass deine Version von Snapd auf dem neuesten Stand ist.

$ sudo snap install core 
$ sudo snap refresh core

Installiere Certbot.

$ sudo snap install --classic certbot

Stelle mit dem folgenden Befehl sicher, dass der Certbot-Befehl ausgeführt wird, indem du einen symbolischen Link auf das Verzeichnis /usr/bin erstellst.

$ sudo ln -s /snap/bin/certbot /usr/bin/certbot

Erstelle ein SSL-Zertifikat.

$ sudo certbot certonly --standalone --agree-tos --no-eff-email --staple-ocsp --preferred-challenges http -m name@example.com -d mqtt.example.com

Mit dem obigen Befehl wird ein Zertifikat in das Verzeichnis /etc/letsencrypt/live/mqtt.example.com auf deinem Server heruntergeladen.

Erstelle ein Diffie-Hellman-Gruppenzertifikat.

$ sudo openssl dhparam -out /etc/ssl/certs/dhparam.pem 2048

Erstelle ein Challenge-Web-Root-Verzeichnis für die automatische Erneuerung von Let’s Encrypt.

$ sudo mkdir -p /var/lib/letsencrypt

Erstelle einen Cron Job zur Erneuerung des SSL-Zertifikats. Er wird jeden Tag ausgeführt, um das Zertifikat zu überprüfen und bei Bedarf zu erneuern. Erstelle dazu zunächst die Datei /etc/cron.daily/certbot-renew und öffne sie zur Bearbeitung.

$ sudo nano /etc/cron.daily/certbot-renew

Füge den folgenden Code ein.

#!/bin/sh
certbot renew --cert-name mqtt.example.com --webroot -w /var/lib/letsencrypt/

Speichere die Datei, indem du Strg + X drückst und Y eingibst, wenn du dazu aufgefordert wirst.

Ändere die Berechtigungen für die Aufgabendatei, um sie ausführbar zu machen.

$ sudo chmod +x /etc/cron.daily/certbot-renew

Schritt 5 – MQTT SSL konfigurieren

Jetzt, wo wir die SSL-Zertifikate bereit haben, müssen wir Mosquitto den Zugriff auf sie ermöglichen. Dazu müssen wir die Zertifikate an einen Ort kopieren, von dem aus Mosquitto auf sie zugreifen kann.

$ sudo cp /etc/letsencrypt/live/mqtt.example.com/fullchain.pem /etc/mosquitto/certs/server.pem
$ sudo cp /etc/letsencrypt/live/mqtt.example.com/privkey.pem /etc/mosquitto/certs/server.key

Ändere die Eigentümerschaft des Verzeichnisses /etc/mosquitto/certs auf den während der Installation angelegten Benutzer mosquitto.

$ sudo chown mosquitto: /etc/mosquitto/certs

Der nächste Schritt, um die SSL-Verschlüsselung für Mosquitto zu aktivieren, besteht darin, den Speicherort der SSL-Zertifikate anzugeben. Öffne die Konfigurationsdatei zum Bearbeiten.

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

Füge den folgenden Code am Ende der Datei ein.

. . .
listener 8883
certfile /etc/mosquitto/certs/server.pem
cafile  /etc/ssl/certs/ISRG_Root_X1.pem
keyfile /etc/mosquitto/certs/server.key
dhparamfile /etc/ssl/certs/dhparam.pem

Speichere die Datei, indem du Strg + X drückst und Y eingibst, wenn du dazu aufgefordert wirst. Achte darauf, dass du am Ende der Datei einen Zeilenumbruch einfügst.

Der Teil listener 8883 richtet den verschlüsselten Listener ein. Das ist der Standardport für MQTT + SSL, auch MQTTS genannt. In den nächsten vier Zeilen wird der Speicherort der SSL-Dateien angegeben.

Starte Mosquitto neu, um die Einstellungen zu aktualisieren.

$ sudo systemctl restart mosquitto

Du musst die Firewall aktualisieren, um Verbindungen zu Port 8883 zuzulassen.

$ sudo ufw allow 8883

Als Nächstes müssen wir die Funktionalität mit dem Befehl mosquitto_pub testen.

$ mosquitto_pub -h mqtt.example.com -t "home/lights/kitchen" -m "hello" -p 8883 --capath /etc/ssl/certs/ -u username -P YOUR_PASSWORD

Wie du sehen kannst, haben wir einige zusätzliche Parameter angegeben, darunter die Portnummer und den Pfad zu den SSL-Zertifikaten. Wenn du SSL verwenden willst, musst du immer den vollständigen Hostnamen angeben, d.h. mqtt.example.com statt localhost, da sonst ein Fehler auftreten würde.

Außerdem musst du jedes Mal die Direktive --capath hinzufügen. Sie sagt dem Mosquitto-Client, dass er nach Root-Zertifikaten suchen soll, die vom Betriebssystem installiert wurden.

Schritt 6 – SSL-Erneuerung konfigurieren

Certbot wird dein Zertifikat automatisch erneuern, bevor es abläuft. Allerdings muss es angewiesen werden, die erneuerten Zertifikate in das Verzeichnis /etc/mosquitto/certs zu kopieren und den Mosquitto-Dienst neu zu starten.

Dazu erstellen wir ein Shell-Skript. Erstelle eine Datei mosquitto-copy.sh im Verzeichnis /etc/letsencrypt/renewal-hooks/deploy.

$ sudo nano /etc/letsencrypt/renewal-hooks/deploy/mosquitto-copy.sh

Füge den folgenden Code darin ein. Ersetze den Wert der Variable MY_DOMAIN durch deine Domain. Die Variable ${RENEWED_LINEAGE} verweist bei der Erneuerung auf das Verzeichnis /etc/letsencrypt/live/mqtt.example.com.

# Set which domain this script will be run for
MY_DOMAIN=mqtt.example.com
# Set the directory that the certificates will be copied to.
CERTIFICATE_DIR=/etc/mosquitto/certs

if [ "${RENEWED_DOMAINS}" = "${MY_DOMAIN}" ]; then
	# Copy new certificate to Mosquitto directory
	cp ${RENEWED_LINEAGE}/fullchain.pem ${CERTIFICATE_DIR}/server.pem
	cp ${RENEWED_LINEAGE}/privkey.pem ${CERTIFICATE_DIR}/server.key

	# Set ownership to Mosquitto
	chown mosquitto: ${CERTIFICATE_DIR}/server.pem ${CERTIFICATE_DIR}/server.key

	# Ensure permissions are restrictive
	chmod 0600 ${CERTIFICATE_DIR}/server.pem ${CERTIFICATE_DIR}/server.key

	# Tell Mosquitto to reload certificates and configuration
	pkill -HUP -x mosquitto
fi

Speichere die Datei, indem du Strg + X drückst und Y eingibst, wenn du dazu aufgefordert wirst.

Mache die Datei ausführbar.

$ sudo chmod +x /etc/letsencrypt/renewal-hooks/deploy/mosquitto-copy.sh

Dieses Skript wird bei jeder erfolgreichen Erneuerung des Zertifikats automatisch ausgeführt.

Wenn du Mosquitto und einen Webserver wie Nginx verwendest, musst du Certbot anweisen, den Server vor der Erneuerung anzuhalten und ihn nach der Erneuerung wieder zu starten. Dazu öffnest du die Datei etc/letsencrypt/renewal/mqtt.example.com.conf.

$ sudo nano /etc/letsencrypt/renewal/mqtt.example.com.conf

Füge die folgenden Zeilen am Ende der Datei ein. Ändere die Befehle entsprechend dem Webserver, den du verwendest.

pre_hook = systemctl stop nginx
post_hook = systemctl start nginx

Speichere die Datei, indem du Strg + X drückst und Y eingibst, wenn du dazu aufgefordert wirst.

Führe einen Certbot-Probelauf durch, um sie zu überprüfen.

$ sudo certbot renew --dry-run

Wenn du keine Fehler siehst, bedeutet das, dass alles eingestellt ist.

Schritt 7 – Websockets konfigurieren

Mit der Websockets-Funktion kannst du Mosquitto so konfigurieren, dass es das MQTT-Protokoll von Browsern aus mit Javascript verwendet. Um sie zu aktivieren, öffne die Konfigurationsdatei.

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

Füge die folgenden Zeilen am Ende der Datei ein.

. . .
listener 8083
protocol websockets
certfile /etc/mosquitto/certs/server.pem
cafile  /etc/ssl/certs/ISRG_Root_X1.pem
keyfile /etc/mosquitto/certs/server.key
dhparamfile /etc/ssl/certs/dhparam.pem

Speichere die Datei, indem du Strg + X drückst und Y eingibst, wenn du dazu aufgefordert wirst.

Wie du siehst, ist es derselbe Block wie der, den wir für die Aktivierung von SSL verwendet haben, mit Ausnahme der Felder für die Portnummer und das Protokoll. 8083 ist der gängigste Port, der von MQTT für die Kommunikation über WebSockets verwendet wird.

Starte den Mosquitto-Dienst neu.

$ sudo systemctl restart mosquitto

Öffne Port 8083.

$ sudo ufw allow 8083

Wir müssen einen browserbasierten MQTT-Client verwenden, um die WebSockets-Funktionalität zu testen. Es gibt viele Clients, aber wir werden den HiveMQ Websocket Client für unseren Zweck verwenden. Starte den Client in deinem Browser und du wirst folgendes sehen.

HiveMQ Websockets Client

Wie auf dem Screenshot oben zu sehen, füllst du die Felder wie abgebildet aus.

  • Der Host sollte die Domain deines Mosquitto-Servers sein, mqtt.example.com.
  • Der Port sollte 8083 sein.
  • Das Feld ClientID kann so belassen werden, wie es ist.
  • Der Benutzername sollte dein Mosquitto-Benutzername sein.
  • Das Passwort sollte das Passwort sein, das du oben erstellt hast.
  • Aktiviere das SSL-Kästchen.

Klicke auf die Schaltfläche Verbinden und der HiveMQ-Client wird mit deinem Mosquitto-Server verbunden.

Sobald die Verbindung steht, gibst du home/lights/kitchen als Thema ein, gibst eine beliebige Nachricht ein und drückst auf Veröffentlichen.

Mosquitto Websocket veröffentlichen

Die Nachricht wird in deinem mosquitto_sub Terminalfenster angezeigt und bestätigt die erfolgreiche Verbindung.

Mosquitto Websockets Terminal Antwort

Dies zeigt, dass die Websockets-Implementierung erfolgreich ist.

Fazit

Damit ist unsere Einrichtung eines sicheren, passwortgeschützten und SSL-verschlüsselten MQTT-Servers auf einem Ubuntu 20.04 basierten Rechner abgeschlossen. Wenn du Fragen hast, schreibe sie unten in die Kommentare.

Das könnte dich auch interessieren …