Ziel
Das Ziel ist es, auf einem Raspberry Pi einen MQTT-Server („Broker“) einzurichten, wie er bspw. für die Heimautomatisierung benötigt wird. In dieser Anleitung werde ich Mosquitto als Broker verwenden.
Voraussetzungen
Benötigt wird ein fertig eingerichteter Raspberry Pi, den man über SSH erreichen kann und für den man Root-Rechte hat. Hilfreich ist es, wenn man schon weiß, wie MQTT ungefähr funktioniert. Das kann man in der Anleitung aber auch nebenbei lernen.
Installation und Test
Zunächst loggt man sich auf dem Raspberry Pi ein und installiert den MQTT-Server und die Clients per apt:
sudo apt install mosquitto mosquitto-clients
Danach läuft der Server bereits und man kann ihn testen. Dazu ruft man einen Client auf und abonniert alle Topics:
mosquitto_sub -h localhost -v -t '#'
Dabei bedeutet „-h localhost“ dass man den Server auf dem gleichen Rechner benutzt (also den, den man gerade installiert hat), das „-v“ sorgt für eine umfangreichere Ausgabe und „-t ‚#’“ schließlich bedeutet, dass man bei allen Topics mithören möchte, die der Broker verarbeitet. Topics kann man sich vorstellen als Kanäle, über die man wie im Funkverkehr empfangen und senden kann, wenn man den passenden Kanal eingestellt hat. Man sendet hier allerdings nur an den Broker und der verteilt die Nachricht an alle weiter, die diesen Kanal bzw. dieses Topic empfangen möchten.
Da (vermutlich) noch kein anderer Client verbunden ist, wird man noch keine Ausgabe sehen. Zum weiteren Testen öffnet man deshalb ein weiteres Fenster, in dem man sich erneut mit dem Raspberry Pi verbindet. Dort veröffentlicht man dann eine Nachricht über den Broker:
mosquitto_pub -h localhost -t 'Test-Topic' -m 'Hallo Welt!'
Mit „-t“ wählt man dazu das Topic aus, unter dem man veröffentlichen will und mit „-m“ gibt man die Nachricht an. Im ersten Fenster sieht man dann die Ausgabe, die der Broker veröffentlicht hat:
Test-Topic Hallo Welt!
Der MQTT-Broker funktioniert also.
Konfiguration des Brokers
In der Grundkonfiguration gibt es keine Beschränkungen für den Zugriff auf den Broker. Jeder (aus dem Heimnetz) kann also Nachrichten veröffentlichen oder mitlesen. In einer minimalen Konfiguration wollen wir den Zugang nun einschränken. Dazu legen wir hier beispielhaft zwei User an, die jeweils ein Passwort bekommen.
Als erstes muss man eine Datei erzeugen, die die User/Passwort-Kombinationen enthält. Die erzeugt man, indem man sie schon gleich mit dem ersten User füllt, nennen wir ihn hier user1.
mosquitto_passwd -c passwords user1
Man wird nach dem Passwort für den User gefragt und muss dies noch einmal wiederholen. Dann wird die gewünschte Datei erzeugt, hier heißt sie passwords (wie hinter „-c“ angegeben).
Nun kann man noch beliebig viele weitere User hinzufügen:
mosquitto_passwd passwords user2
Wieder muss man das Passwort zweimal eingeben. Alternativ kann man auch die Option „-b“ verwenden und das Passwort in die Kommandozeile schreiben. Allerdings sollte man sich angewöhnen, nie Passwörter in Kommandos zu verwenden, denn diese werden dadurch auch für andere Benutzer auf dem gleichen Rechner sichtbar. Auch wenn man niemanden sonst auf seinen Rechner lässt, sollte man sich solche Unachtsamkeiten erst gar nicht angewöhnen.
Wir haben jetzt eine Datei passwords im aktuellen Verzeichnis liegen, also vermutlich in unserem Heim-Verzeichnis. Diese Datei verschieben wir nun ins passende Verzeichnis unter /etc. Und weil es sicher sein soll, überschreiben wir die Datei an den Benutzer root und gewähren nur ihm Schreibzugriff darauf:
sudo mv passwords /etc/mosquitto/conf.d/
sudo chown root:root /etc/mosquitto/conf.d/passwords
sudo chmod 644 /etc/mosquitto/conf.d/passwords
Jetzt brauchen wir noch eine Konfigurationsdatei, die diese Datei einbindet und die den anonymen Zugang unterbindet. Die legen wir im gleichen Verzeichnis ab wie die Passwort-Datei (also /etc/mosquitto/conf.d). Am besten macht man das gleich als root. Ich benutze meinen Lieblingseditor vim (eine beliebte Alternative ist nano):
sudo vim /etc/mosquitto/conf.d/auth.conf
Man fügt zwei Zeilen ein:
allow_anonymous false
password_file /etc/mosquitto/conf.d/passwords
Damit die neue Konfiguration greift, muss man den Dienst noch neu starten. Das muss man auch dann tun, wenn man nur die Datei mit den Passwörtern ändert.
sudo systemctl restart mosquitto
Danach kann man sich nur noch mit Mosquitto verbinden, wenn man einen der zuvor eingerichteten Zugänge benutzt. Eine anonyme Verbindung funktioniert nicht mehr und natürlich auch keine mit falschen Zugangsdaten.
Der Vollständigkeit halber möchte ich noch erwähnen, wie man ausprobieren kann, ob ein Zugang funktioniert, auch wenn man dazu das Passwort im Kommando angeben muss, was man ja nicht tun sollte! Hier geht es aber nicht anders:
mosquitto_pub -u user1 -P passwort1 -t 'Test-Topic' -m 'Ich bin drin!'
Wenn man ein falsches Passwort benutzt oder einen unbekannten Benutzernamen, wird der Broker die Verbindung nicht zulassen. Ebenso nicht, wenn man gar keine Zugangsdaten angibt.
Die Angabe des Host-Namens habe ich hier übrigens weggelassen, denn localhost ist der Default-Host.
Schauen wir zum Abschluss noch auf die beiden Direktiven allow_anonymous und password_file. Diese kann man auch jeweils weg lassen. Das ergibt vier Möglichkeiten, die alle zu einem unterschiedlichen Verhalten führen.
Fall 1: Wenn man keine der beiden Direktiven benutzt, kann man sich wie am Anfang anonym einloggen, also ohne Zugangsdaten. Man kann aber sogar beliebige Zugangsdaten benutzen, wenn man möchte.
Fall 2: Der Zustand, den wir zuletzt hatten, sowohl allow_anonymous false als auch password_file sind vorhanden. Dann kann man sich nicht mehr anonym verbinden und muss gültige Zugangsdaten angeben.
Fall 3: Es wird nur allow_anonymous false verwendet. Dann kann man sich nicht mehr anonym verbinden. Man kann sich allerdings mit beliebigen (!) Zugangsdaten verbinden.
Fall 4: Es wird nur password_file angegeben. Dann kann man sich anonym einloggen. Man kann aber auch Zugangsdaten angeben. Wenn man das tut, müssen diese allerdings zu einem hinterlegten Zugang passen. Man sollte dann aber explizit allow_anonymous true setzen. Benutzen kann man das mit weiteren Einstellungen um bspw. allen Usern lesenden Zugriff zu ermöglichen, das Schreiben aber zu beschränken.
Soweit eine erste Grundeinrichtung, die ohne viele Umstände funktioniert. Es gibt noch viele Konfigurationsmöglichkeiten, mit dem man Mosquitto weiter absichern kann.
Wichtig: Man sollte sich klar darüber sein, dass in der vorgestellten Grundkonfiguration die Zugangsdaten unverschlüsselt über die Leitung gehen! Das ist ein Problem, wenn jemand anderes im Heimnetz mitlesen kann. Im Zweifelsfall sollte man seinen Mosquitto besser noch per SSL absichern. Wie das geht, ist allerdings einen eigenen Artikel wert.