Eine MQTT ACL (Access Control List, Zugriffskontrollliste) ist der Regelsatz, mit dem ein Broker entscheidet, welcher authentifizierte Client auf welche Topics publizieren oder welche Topics er abonnieren darf. Dieser Artikel erklärt die Konzepte, zeigt am Beispiel von Mosquitto, wie sie in einer echten Broker-Konfiguration aussehen, beschreibt, was bei einer Ablehnung passiert, und stellt Muster für das Topic-Design vor, die die Autorisierung einfach halten, egal ob Sie feingranulare ACLs oder Isolation auf Mandantenebene nutzen.
Authentifizierung und Autorisierung
Die beiden Begriffe werden leicht verwechselt, und Broker behandeln sie in unterschiedlichen Phasen:
- Authentifizierung beantwortet die Frage „Wer bist du?". Sie findet einmal beim CONNECT statt, mit Benutzername und Passwort, einem Client-Zertifikat oder einem Token. Details finden Sie unter MQTT-Authentifizierung mit Benutzername und Passwort.
- Autorisierung beantwortet die Frage „Was darfst du?". Sie wird bei jedem SUBSCRIBE und, je nach Broker, bei jedem PUBLISH geprüft. ACLs sind die gängigste Art, sie auszudrücken.
Ein authentifizierter Client ohne Autorisierungsregeln kann in der Regel alles lesen und schreiben, was sein Broker oder Mandant zulässt. ACLs schränken das pro Benutzer, pro Client ID oder pro Rolle ein.
Woraus eine MQTT-ACL-Regel besteht
Unabhängig von der Syntax eines Brokers kombiniert jede Regel dieselben Elemente:
| Element | Beispiele |
|---|---|
| Subjekt | Ein Benutzername, eine Client ID, eine Rolle oder „alle" |
| Aktion | Lesen (abonnieren und empfangen), Schreiben (publizieren) oder beides |
| Topic-Filter | factory/line1/#, devices/+/cmd, devices/%u/# |
| Entscheidung | Erlauben oder verweigern |
Regeln werden mit dem Topic jeder Operation abgeglichen. Bei Subscriptions prüfen viele Broker den angeforderten Filter selbst, sodass ein Client, der devices/sensor-01/# lesen darf, keine breitere Subscription auf devices/# an der Prüfung vorbeischmuggeln kann.
Beispiel für eine Mosquitto MQTT ACL
Mosquitto eignet sich gut als Referenz, weil seine dateibasierte ACL kurz und gut lesbar ist. Authentifizierung und ACL-Datei werden in mosquitto.conf aktiviert:
# mosquitto.conf
listener 8883
certfile /etc/mosquitto/certs/server.crt
keyfile /etc/mosquitto/certs/server.key
allow_anonymous false
password_file /etc/mosquitto/passwd
acl_file /etc/mosquitto/acl
Die ACL-Datei selbst:
# /etc/mosquitto/acl
# Regeln vor der ersten "user"-Zeile gelten für anonyme Clients (hier keine)
# Ein Backend-Dienst, der alle Telemetrie liest und Befehle sendet
user backend
topic read factory/+/+/telemetry/#
topic write factory/+/+/cmd/#
# Ein Dashboard, das nur lesen darf
user dashboard
topic read factory/#
# Pattern-Regeln gelten für jeden Benutzer.
# %u = Benutzername, %c = Client ID
pattern write factory/+/%c/telemetry/#
pattern read factory/+/%c/cmd/#
pattern write factory/+/%c/status
Mit diesen Regeln kann ein Gerät, das sich mit der Client ID cnc-07 verbindet, auf factory/line2/cnc-07/telemetry/spindle publizieren und factory/line2/cnc-07/cmd/stop empfangen, aber weder die Befehle einer anderen Maschine lesen noch im Namen einer anderen Maschine publizieren. Die Pattern-Regeln skalieren auf Tausende Geräte ohne einen Eintrag pro Gerät, und genau das ist der Hauptgrund, die Client ID in den Topic-Pfad aufzunehmen. Mosquitto unterstützt außerdem topic deny-Zeilen und ein Dynamic-Security-Plugin mit Rollen und Gruppen; die Mosquitto-Dokumentation beschreibt beides.
Laden Sie den Broker nach dem Bearbeiten der Datei neu und testen Sie anschließend:
# Erlaubt: cnc-07 publiziert seine eigene Telemetrie
mosquitto_pub -h localhost -p 8883 --cafile ca.crt -V mqttv5 \
-i cnc-07 -u cnc-07 -P "$PW" -t 'factory/line2/cnc-07/telemetry/spindle' -m 1200 -q 1
# Verweigert: cnc-07 publiziert als cnc-08
mosquitto_pub -h localhost -p 8883 --cafile ca.crt -V mqttv5 \
-i cnc-07 -u cnc-07 -P "$PW" -t 'factory/line2/cnc-08/telemetry/spindle' -m 1200 -q 1
Was passiert, wenn ein Client abgelehnt wird
Abgelehnte Operationen erzeugen nicht immer einen offensichtlichen Fehler, weshalb ACL-Probleme als besonders schwer zu debuggen gelten.
| Operation | MQTT 3.1.1 | MQTT 5.0 |
|---|---|---|
| SUBSCRIBE abgelehnt | SUBACK-Return-Code 0x80 (Fehler) | SUBACK-Reason-Code 0x87 Not authorized |
| PUBLISH QoS 0 abgelehnt | Stillschweigend verworfen | Stillschweigend verworfen |
| PUBLISH QoS 1/2 abgelehnt | Meist bestätigt und verworfen | PUBACK/PUBREC kann 0x87 enthalten, abhängig vom Broker |
Praktische Tipps zur Fehlersuche:
- SUBACK-Codes immer prüfen. Viele Bibliotheken stellen sie in einem Callback bereit; protokollieren Sie sie beim Start.
- Beim Testen MQTT 5 und QoS 1 verwenden. Reason Codes in Bestätigungen machen Ablehnungen sichtbar.
- Mit der Identität des Geräts testen. Ein Test mit einem Admin-Konto sagt nichts über die Regeln des Geräts aus.
- Das Broker-Log prüfen. Die meisten Broker protokollieren abgelehnte Publishes und Subscriptions auf Debug-Ebene.
Topic-Namespaces für einfache Autorisierung entwerfen
Gute ACLs beginnen mit guten Topics. Sind Identität und Richtung im Topic-Pfad sichtbar, schrumpfen die Regeln auf wenige Muster. Sind sie es nicht, landen Sie bei einer langen Liste von Sonderfällen.
Identität in den Pfad aufnehmen
Platzieren Sie die Client ID oder Geräte-ID auf einer festen Ebene: factory/<line>/<deviceId>/.... Pattern-Regeln wie %c funktionieren nur, wenn die Identität eine vollständige Topic-Ebene ist.
Richtungen trennen
Verwenden Sie getrennte Zweige für aufwärts fließende Daten und abwärts fließende Befehle: .../telemetry, .../status, .../cmd. Geräte erhalten Schreibrechte auf die ersten beiden und Leserechte auf den dritten.
Mandanten oder Kunden ganz oben trennen
Bedient ein Broker mehrere Kunden, machen Sie den Kunden zur ersten Ebene: <tenant>/.... Die Zugangsdaten jedes Mandanten sind dann auf einen Teilbaum beschränkt.
Gemeinsame Daten in einem klar benannten Zweig halten
Konfiguration, die an alle Geräte verteilt wird, gehört nach broadcast/... oder config/..., mit reinem Lesezugriff für Geräte.
Den Unified Namespace (UNS) nach ISA-95 als Gerüst nutzen
In Industrie-4.0-Projekten liefert der UNS die Struktur, an der sich auch die Autorisierung orientiert. Sein Topic-Baum folgt der Equipment-Hierarchie nach ISA-95 (IEC 62264): Enterprise → Site → Area → Line → Cell, etwa acme/werk-stuttgart/montage/linie-1/zelle-3/temperatur. Jede Ebene ist eine natürliche Grenze für Regeln: Ein Werks-Dashboard liest acme/werk-stuttgart/#, ein Linien-Gateway schreibt nur unterhalb von .../linie-1/, und ein MES-Dienst erhält Schreibrechte ausschließlich auf die Befehlszweige seines Bereichs. Damit passt das ACL-Design auch zu Zonenkonzepten nach IEC 62443. Mehr zur UNS-Struktur lesen Sie im Beitrag zu Sparkplug B und Unified Namespace.
Der Artikel mit Beispielen für MQTT-Topic-Hierarchien zeigt vollständige Bäume, die auf diesen Prinzipien aufbauen.
Checkliste für das ACL-Design
- Standardmäßig verweigern; nur erlauben, was jede Rolle braucht.
- Geräten Schreibrechte auf ihre eigene Telemetrie und ihren Status geben, Leserechte auf ihre eigenen Befehle, sonst nichts.
- Dashboards nur Lesezugriff geben.
- Backend-Diensten Schreibrechte auf Befehlszweige geben und prüfen, wer diese Zugangsdaten besitzt.
- Niemals
#an Gerätezugangsdaten vergeben. - Regeldatei oder Rollendefinitionen versionieren und Änderungen reviewen.
- Jede Rolle nach jeder Änderung mit ihren echten Zugangsdaten testen.
Autorisierung bei ConnectMQ
ConnectMQ bietet keine ACLs pro Topic. Die Isolation bei ConnectMQ funktioniert auf Mandantenebene: Der Broker-Traffic jedes Kunden ist von allen anderen Mandanten isoliert, Zugangsdaten werden pro Broker generiert, und Client IDs sind an den ausgestellten Benutzernamen und das Passwort gebunden, sodass ein Client nicht die Identität eines anderen Clients annehmen kann. Quotas pro Plan, Flood Protection und IP-Sperre nach wiederholten fehlgeschlagenen Logins begrenzen, was ein fehlerhafter Client anrichten kann.
Was das für das Design bedeutet:
- Getrennte Broker als Sicherheitsgrenze nutzen. Wenn zwei Gruppen von Clients niemals die Daten der jeweils anderen sehen dürfen, legen Sie sie auf unterschiedliche Broker, statt sich auf Topic-Regeln zu verlassen. Ein Dedicated-Plan bietet Ihnen einen isolierten Cluster, wenn diese Grenze auch physisch sein muss.
- Nicht vertrauenswürdige Clients vom Broker fernhalten. Browser-Nutzer und Dritte sollten mit Ihrem Backend kommunizieren, das die Broker-Zugangsdaten hält und entscheidet, was in ihrem Namen publiziert wird.
- Topics so entwerfen, als könnten ACLs später kommen. Identität im Pfad und getrennte Befehlszweige kosten jetzt nichts und halten Ihnen Optionen offen, falls Sie einen Teil des Systems auf einen Broker mit Topic-Regeln verlagern.
- Befehle auf dem Gerät validieren. Ein Gerät sollte prüfen, ob ein Befehl korrekt aufgebaut und erwartet ist, bevor es handelt, unabhängig davon, wie der Broker autorisiert.
Diese Kombination aus Mandantenisolation und Topic-Disziplin deckt viele Flotten gut ab. Wenn Ihr Projekt Topic-Beschränkungen pro Gerät innerhalb eines gemeinsamen Namespace erfordert, planen Sie für diesen Teil des Systems einen Broker ein, der ACLs auf Topic-Ebene unterstützt. Für das Gesamtbild lesen Sie Best Practices für MQTT-Sicherheit und Ist MQTT sicher?.
Starten Sie mit ConnectMQ
Betreiben Sie Ihre Geräte auf einem verwalteten MQTT-Broker mit Mandantenisolation, TLS, generierten und an Client IDs gebundenen Zugangsdaten sowie IP-Sperre bei fehlgeschlagenen Logins. Erstellen Sie unter app.connectmq.com einen kostenlosen Serverless-Broker, ganz ohne Kreditkarte, und testen Sie Topic-Designs zuerst auf dem öffentlichen MQTT-Broker, der für Tests gedacht ist und keine Produktionsdaten transportieren sollte.
Häufig gestellte Fragen
Was ist eine MQTT ACL?
Eine Liste von Regeln, die einem Broker sagt, welche Benutzer oder Clients auf welche Topic-Filter publizieren oder sie abonnieren dürfen. Sie wird geprüft, nachdem sich der Client authentifiziert hat.
Unterstützt ConnectMQ ACLs pro Topic?
Nein. ConnectMQ isoliert Mandanten voneinander und bindet Client IDs an die ausgestellten Zugangsdaten aus Benutzername und Passwort, erzwingt aber keine Lese- und Schreibregeln pro Topic innerhalb eines Brokers.
Warum liefert mein abgelehnter Publish keinen Fehler?
In MQTT 3.1.1 hat der Broker keine Möglichkeit, einen abgelehnten Publish zu melden, daher wird er stillschweigend verworfen. MQTT-5-Broker können bei Bestätigungen für QoS 1 und 2 den Reason Code 0x87 zurückgeben.
Sollten ACL-Regeln den Benutzernamen oder die Client ID verwenden?
Verwenden Sie den Bezeichner, der pro Gerät eindeutig ist und vom Client nicht frei gewählt werden kann. Bindet der Broker Client IDs an Zugangsdaten, funktioniert beides; andernfalls ist der Benutzername vorzuziehen.



