Mit einem selbstsignierten Zertifikat für MQTT können Sie einen Labor- oder Offline-Broker ohne öffentliche Zertifizierungsstelle verschlüsseln. Naiv umgesetzt scheitert es entweder bei jedem Client an der Prüfung oder verleitet dazu, die Prüfung ganz abzuschalten. Dieses Tutorial zeigt das richtige Muster, eine kleine private CA mit OpenSSL, konfiguriert dann Mosquitto auf Port 8883, verbindet Python- und Kommandozeilen-Clients und erklärt, wann Ihnen ein öffentlich vertrauenswürdiges Zertifikat die Mühe erspart.
Selbstsigniertes Zertifikat vs. private CA
Der Begriff „selbstsigniertes Zertifikat“ wird für zwei unterschiedliche Setups verwendet:
- Ein einzelnes selbstsigniertes Serverzertifikat: Das Zertifikat des Brokers signiert sich selbst. Clients müssen genau diesem Zertifikat vertrauen. Läuft es ab oder ändert es sich, muss jeder Client aktualisiert werden.
- Eine private CA: Sie erstellen Ihr eigenes Root-CA-Zertifikat (selbstsigniert) und signieren damit das Broker-Zertifikat. Clients vertrauen der CA, sodass Sie das Broker-Zertifikat beliebig neu ausstellen können, solange die CA gleich bleibt.
Der Ansatz mit privater CA ist fast immer das, was Sie wollen. Er kostet zwei zusätzliche OpenSSL-Befehle und erspart Ihnen, das Vertrauen bei jeder Änderung des Serverzertifikats neu zu verteilen.
Wann ein selbstsigniertes Zertifikat für MQTT sinnvoll ist
| Szenario | Selbstsigniert / private CA | Öffentlich vertrauenswürdiges Zertifikat |
|---|---|---|
| Tests auf dem Laptop oder im Labor | Passt gut | Möglich, aber unnötig |
| Abgeschottetes Fabriknetzwerk ohne öffentliches DNS | Oft die einzige Option | Ohne öffentliches DNS nicht möglich |
Interner Broker, erreichbar per IP oder .local-Name |
Machbar | Öffentliche CAs können für diese Namen nicht ausstellen |
| Aus dem Internet erreichbarer Broker für Geräte und Apps | Vermeiden | Klar zu bevorzugen |
| Browser-Dashboards über WSS | Mühsam (Browserwarnungen) | Funktioniert sofort |
| Clients von Drittanbietern, die Sie nicht kontrollieren | Mühsam (sie müssen Ihre CA installieren) | Funktioniert sofort |
Im industriellen Umfeld ist der zweite Fall häufig: OT-Netze in Werken sind nach dem Zonen- und Conduit-Modell der IEC 62443 vom Internet getrennt, und der lokale Broker neben SPS, Edge-Gateways und SCADA hat weder öffentliches DNS noch Internetzugang. Hier ist eine private CA, idealerweise die bestehende Unternehmens-PKI statt einer Insellösung pro Halle, oft die sauberste Wahl. Wichtig ist dann ein dokumentierter Prozess für Ausstellung, Erneuerung und Sperrung, denn auch Regelwerke wie NIS2 erwarten nachvollziehbare Abläufe für kryptografische Schlüssel.
Schritt 1: Die private CA erstellen
Legen Sie ein Arbeitsverzeichnis sowie einen CA-Schlüssel und ein CA-Zertifikat an. Schützen Sie ca.key: Wer ihn besitzt, kann sich als Ihr Broker ausgeben.
mkdir -p ~/mqtt-ca && cd ~/mqtt-ca
openssl genrsa -out ca.key 4096
openssl req -x509 -new -nodes -key ca.key -sha256 -days 3650 \
-subj "/O=Example Lab/CN=Example Lab MQTT CA" -out ca.crt
Schritt 2: Das Broker-Zertifikat mit SAN erstellen
Moderne TLS-Clients ignorieren bei der Hostname-Prüfung den Common Name des Zertifikats und betrachten nur den Subject Alternative Name (SAN). Ein fehlender SAN ist der häufigste Grund, warum ein selbstsigniertes MQTT-Setup an der Prüfung scheitert. Nehmen Sie jeden Namen und jede IP-Adresse auf, die Clients verwenden werden.
openssl genrsa -out broker.key 2048
openssl req -new -key broker.key \
-subj "/O=Example Lab/CN=mqtt.lab.local" -out broker.csr
cat > broker.ext <<'EOF'
basicConstraints = CA:FALSE
keyUsage = digitalSignature, keyEncipherment
extendedKeyUsage = serverAuth
subjectAltName = DNS:mqtt.lab.local, DNS:localhost, IP:192.168.1.50
EOF
openssl x509 -req -in broker.csr -CA ca.crt -CAkey ca.key -CAcreateserial \
-days 397 -sha256 -extfile broker.ext -out broker.crt
Prüfen Sie das Ergebnis, bevor Sie es verwenden:
openssl x509 -in broker.crt -noout -subject -issuer -dates -ext subjectAltName
openssl verify -CAfile ca.crt broker.crt
Der zweite Befehl sollte broker.crt: OK ausgeben. Ersetzen Sie die Namen und die IP-Adresse durch Ihre eigenen.
Schritt 3: Mosquitto für TLS konfigurieren
Kopieren Sie die Dateien auf den Broker und legen Sie eine Listener-Konfiguration an:
sudo mkdir -p /etc/mosquitto/certs
sudo cp ca.crt broker.crt broker.key /etc/mosquitto/certs/
sudo chown mosquitto: /etc/mosquitto/certs/broker.key
sudo chmod 600 /etc/mosquitto/certs/broker.key
# /etc/mosquitto/conf.d/tls.conf
listener 8883
cafile /etc/mosquitto/certs/ca.crt
certfile /etc/mosquitto/certs/broker.crt
keyfile /etc/mosquitto/certs/broker.key
# Zusätzlich MQTT-Zugangsdaten verlangen
allow_anonymous false
password_file /etc/mosquitto/passwd
Legen Sie einen Benutzer mit sudo mosquitto_passwd -c /etc/mosquitto/passwd labuser an, starten Sie dann mit sudo systemctl restart mosquitto neu und prüfen Sie journalctl -u mosquitto auf Fehler wie nicht lesbare Schlüsseldateien.
Schritt 4: Clients verbinden
Jeder Client braucht ca.crt, niemals den CA-Schlüssel. Mit den mosquitto-Tools:
mosquitto_sub -h mqtt.lab.local -p 8883 --cafile ca.crt \
-u labuser -P 'your-password' -i lab-sub-1 -t "lab/#" -v
mosquitto_pub -h mqtt.lab.local -p 8883 --cafile ca.crt \
-u labuser -P 'your-password' -i lab-pub-1 -t "lab/test" -m "hello private CA"
In Python mit paho-mqtt 2.x:
import paho.mqtt.client as mqtt
client = mqtt.Client(mqtt.CallbackAPIVersion.VERSION2, client_id="lab-python-1")
client.tls_set(ca_certs="ca.crt") # nur der privaten CA vertrauen
client.username_pw_set("labuser", "your-password")
client.connect("mqtt.lab.local", 8883)
client.loop_start()
client.publish("lab/test", "verified against private CA", qos=1).wait_for_publish()
client.loop_stop()
client.disconnect()
In Node.js übergeben Sie ca: fs.readFileSync("ca.crt") in den MQTT.js-Optionen. Auf einem ESP32 betten Sie den Inhalt von ca.crt ein und rufen setCACert() auf. Beachten Sie, dass die Prüfung in jedem Beispiel vollständig aktiv bleibt: Der Client vertraut einfach Ihrer CA statt einer öffentlichen. Wenn Prüffehler auftreten, listet unser Leitfaden zu SSL CERTIFICATE_VERIFY_FAILED bei MQTT die üblichen Ursachen auf.
Der privaten CA systemweit vertrauen
--cafile an jedes Tool zu übergeben, wird auf Laborrechnern schnell lästig. Auf einer Linux-Workstation können Sie die CA zum Store des Betriebssystems hinzufügen, sodass Tools, die ihn nutzen, etwa mosquitto_sub --capath /etc/ssl/certs, curl und die meisten Laufzeitumgebungen, dem Labor-Broker automatisch vertrauen:
# Debian / Ubuntu / Raspberry Pi OS
sudo cp ca.crt /usr/local/share/ca-certificates/example-lab-mqtt-ca.crt
sudo update-ca-certificates
Unter Windows importieren Sie ca.crt in einer Eingabeaufforderung mit Administratorrechten mit certutil -addstore -f Root ca.crt in den Speicher „Vertrauenswürdige Stammzertifizierungsstellen“; unter macOS fügen Sie es dem System-Schlüsselbund hinzu und markieren es als vertrauenswürdig. Gehen Sie dabei bewusst vor. Alles, was von Ihrer Labor-CA signiert ist, wird von diesem Rechner für jeden Zweck als vertrauenswürdig eingestuft, nicht nur für MQTT. Schützen Sie den CA-Schlüssel also entsprechend und entfernen Sie die CA von Rechnern, die das Labor verlassen. Beachten Sie, dass certifi-basierte Python-Clients und Node.js den Store des Betriebssystems ohne entsprechende Konfiguration ignorieren und daher weiterhin die CA-Datei brauchen.
Fallstricke, die Sie vermeiden sollten
- Fehlender SAN: Die Hostname-Prüfung scheitert, obwohl die Kette gültig ist.
- Die falsche Datei verteilen: Clients brauchen
ca.crt, nichtbroker.crtund niemalsca.key. - Prüfung deaktivieren:
--insecure,tls_insecure_set(True)oderrejectUnauthorized: falsemachen das Zertifikat sinnlos. - Ablauf vergessen: Tragen Sie das Ablaufdatum des Broker-Zertifikats in einen Kalender ein und automatisieren Sie die Erneuerung, wenn möglich. Ein abgelaufenes Zertifikat nimmt alle Clients auf einmal offline.
- Zu lange Gültigkeit des Serverzertifikats: Langlebige Zertifikate sind bequem, vergrößern aber die Folgen eines geleakten Schlüssels. Halten Sie die CA langlebig und das Broker-Zertifikat kürzer.
- CA-Schlüssel auf dem Broker: Bewahren Sie den CA-Schlüssel offline auf. Der Broker braucht nur seinen eigenen Schlüssel und sein Zertifikat.
- Uhrzeitprobleme: Geräte ohne genaue Uhrzeit lehnen gültige Zertifikate ab. Stellen Sie in abgeschotteten Werksnetzen einen internen NTP-Server bereit, den auch SPS und Edge-Gateways nutzen.
Dieselbe private CA kann auch Client-Zertifikate signieren, wenn Sie Mutual TLS wünschen; siehe MQTT mTLS mit X.509-Client-Zertifikaten.
Das Broker-Zertifikat erneuern
Da die private CA gleich bleibt, betrifft die Erneuerung nur den Broker. Erzeugen Sie einen neuen Schlüssel (oder verwenden Sie den alten weiter, wenn Ihre Richtlinie das erlaubt), erstellen Sie einen neuen CSR, signieren Sie ihn mit derselben CA und derselben Datei broker.ext und ersetzen Sie die Dateien auf dem Broker:
openssl genrsa -out broker-new.key 2048
openssl req -new -key broker-new.key -subj "/O=Example Lab/CN=mqtt.lab.local" -out broker-new.csr
openssl x509 -req -in broker-new.csr -CA ca.crt -CAkey ca.key -CAcreateserial \
-days 397 -sha256 -extfile broker.ext -out broker-new.crt
sudo cp broker-new.crt /etc/mosquitto/certs/broker.crt
sudo cp broker-new.key /etc/mosquitto/certs/broker.key
sudo systemctl restart mosquitto
Die Clients ändern sich nicht, weil sie ca.crt vertrauen, nicht dem Broker-Zertifikat. Das ist der Vorteil des Musters mit privater CA gegenüber einem einzelnen selbstsignierten Zertifikat, bei dem jeder Client die neue Datei bräuchte. Ein einfacher Cronjob, der Sie einen Monat vor Ablauf warnt, lohnt sich:
openssl x509 -checkend 2592000 -noout -in /etc/mosquitto/certs/broker.crt \
|| echo "MQTT broker certificate expires within 30 days"
Die Betriebskosten, über die niemand spricht
Eine private CA ist am ersten Tag einfach. Die Kosten zeigen sich später: ca.crt an jeden neuen Client verteilen, Browserwarnungen erklären, wenn jemand ein WSS-Dashboard öffnet, das Broker-Zertifikat vor dem Ablauf erneuern, die CA selbst nach einem Jahrzehnt oder einer Schlüsselkompromittierung ersetzen und alles für die nächste Ingenieurin oder den nächsten Ingenieur dokumentieren. Bei einem aus dem Internet erreichbaren System erkaufen Sie mit diesem Aufwand nichts, was ein öffentlich vertrauenswürdiges Zertifikat nicht ohnehin bietet.
Das ist der Hauptgrund, für aus dem Internet erreichbare Produktionssysteme einen verwalteten MQTT-Broker zu nutzen. ConnectMQ präsentiert ein Let's-Encrypt-Zertifikat, dem Betriebssysteme, Browser, Python und Node.js bereits vertrauen, und erneuert es automatisch. Clients verbinden sich auf Port 8883 oder per Secure WebSocket auf 8084, ohne dass CA-Dateien verteilt werden müssen, abgesehen vom Einbetten einer standardmäßigen öffentlichen Root auf Mikrocontrollern. Das können Sie in Sekunden auf dem kostenlosen öffentlichen MQTT-Broker bestätigen:
mosquitto_sub -h broker.connectmq.com -p 8883 --capath /etc/ssl/certs \
-i pubca-test-3e8b -t "connectmq/demo/3e8b/#" -v
Einen Vergleich der Hosting-Modelle finden Sie in unserem Leitfaden zum Cloud-MQTT-Broker, und die vollständige Liste der Härtungsschritte unter MQTT-TLS-Konfiguration.
Starten Sie mit ConnectMQ
Verzichten Sie für Ihren Produktions-Broker auf die private CA. Registrieren Sie sich bei ConnectMQ unter app.connectmq.com, wählen Sie den kostenlosen Serverless-Plan ohne Kreditkarte, erstellen Sie einen Broker und verbinden Sie sich auf Port 8883 mit dem generierten Benutzernamen, Passwort und der Client ID. ConnectMQ kümmert sich um Zertifikate und Erneuerungen; Ihr selbstsigniertes Setup bleibt im Labor, wo es hingehört.
Häufig gestellte Fragen
Kann ich ein selbstsigniertes Zertifikat in einer MQTT-Produktionsumgebung verwenden?
In geschlossenen Netzwerken, in denen Sie jeden Client kontrollieren, ja, sofern Sie eine ordentliche private CA betreiben und Erneuerungen verwalten. Bei aus dem Internet erreichbaren Brokern ist ein öffentlich vertrauenswürdiges Zertifikat einfacher und erspart es, das Vertrauen an jeden Client zu verteilen.
Warum lehnt mein Client das Zertifikat trotz CA-Datei ab?
Der häufigste Grund ist ein fehlender oder falscher Subject Alternative Name. Prüfen Sie ihn mit openssl x509 -noout -ext subjectAltName -in broker.crt und stellen Sie sicher, dass er den Hostnamen enthält, den die Clients verwenden.
Kann ich ein Let's-Encrypt-Zertifikat für einen internen Broker bekommen?
Nur für einen öffentlichen Domainnamen, den Sie kontrollieren, per DNS-Validierung. Öffentliche CAs stellen keine Zertifikate für private IP-Adressen oder .local-Namen aus.
Muss ich Mosquitto nach der Erneuerung des Zertifikats neu starten?
Mosquitto lädt Zertifikate beim Start. Planen Sie also nach der Erneuerung einen Neustart oder ein Reload ein und testen Sie anschließend mit openssl s_client.



