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.
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.
Die Nachricht wird in deinem mosquitto_sub
Terminalfenster angezeigt und bestätigt die erfolgreiche Verbindung.
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.