IoT-Tutorials

Python MQTT TLS: Sichere Verbindungen auf Port 8883 mit paho-mqtt

Verschlüsseln Sie Ihren Python-MQTT-Verkehr mit paho-mqtt und TLS auf Port 8883: System-CA-Speicher nutzen, Hostnamenprüfung aktiv lassen, typische Zertifikatsfehler beheben und über sicheres WebSocket verbinden, wenn nur Web-Ports offen sind.

Vorhängeschloss über einem Python-Skript, das eine Python-MQTT-TLS-Verbindung zu einem Broker auf Port 8883 zeigt
Probieren Sie es auf Ihrem eigenen MQTT-Broker ausHolen Sie sich im Free-Tarif einen privaten, verwalteten MQTT-Broker und starten Sie mit fertigen Codebeispielen.
Kostenlos testen Codebeispiele Keine Kreditkarte erforderlich

Python MQTT TLS entscheidet darüber, ob Ihr Benutzername, Ihr Passwort und Ihre Sensordaten im Klartext oder verschlüsselt und authentifiziert durch das Internet reisen. In diesem Tutorial konfigurieren Sie paho-mqtt so, dass es sich mit den vertrauenswürdigen CA-Zertifikaten Ihres Betriebssystems auf Port 8883 verbindet, lassen die Hostnamenprüfung eingeschaltet und beheben die Zertifikatsfehler, an denen die meisten scheitern. Alle Beispiele verbinden sich mit broker.connectmq.com, der ein öffentlich vertrauenswürdiges Let's-Encrypt-Zertifikat ausliefert, sodass keine eigenen CA-Dateien nötig sind.

Was TLS für MQTT leistet

MQTT selbst hat keine Verschlüsselung. Auf Port 1883 läuft alles, einschließlich des CONNECT-Pakets mit Ihren Zugangsdaten, als lesbare Bytes. TLS umhüllt die TCP-Verbindung und gibt Ihnen drei Garantien:

  1. Vertraulichkeit: Niemand auf dem Netzwerkpfad kann Payloads oder Passwörter lesen.
  2. Integrität: Niemand kann Nachrichten unterwegs unbemerkt verändern.
  3. Server-Authentifizierung: Ihr Client prüft, dass er wirklich mit dem angefragten Broker spricht und nicht mit einem Betrüger.

Der dritte Punkt ist derjenige, den man versehentlich deaktiviert. Verschlüsselung ohne Prüfung schützt vor passiven Lauschern, aber nicht vor einem aktiven Angreifer, der sein eigenes Zertifikat präsentiert. In Industrie-4.0-Umgebungen ist das keine Kür: Rahmenwerke wie IEC 62443 und die NIS2-Richtlinie erwarten Schutzmaßnahmen für Vertraulichkeit und Integrität der Kommunikation, auch wenn ein Edge-Gateway nur Maschinendaten aus der Halle sendet. Der Leitfaden zu MQTT-Security-Best-Practices behandelt das Gesamtbild; dieser Artikel konzentriert sich darauf, die Client-Seite richtig aufzusetzen.

ConnectMQ stellt auf jedem Broker diese Ports bereit:

Port Transport Verschlüsselt Verwendung aus Python
1883 MQTT über TCP Nein Nur lokale Tests
8883 MQTT über TLS Ja Standard für die Produktion
8083 MQTT über WebSocket Nein Aus Python selten nötig
8084 MQTT über sicheres WebSocket, Pfad /mqtt Ja Wenn nur Web-Ports erlaubt sind

Voraussetzungen

python -m venv .venv
source .venv/bin/activate          # Windows: .venv\Scripts\activate
pip install "paho-mqtt>=2.0"

Prüfen Sie, ob das Zertifikat des Brokers auf Ihrem Rechner validiert wird, bevor Sie Python-Code schreiben. Dieser Befehl zeigt die Kette und das Prüfergebnis:

openssl s_client -connect broker.connectmq.com:8883 -servername broker.connectmq.com -brief </dev/null

Achten Sie auf Verification: OK. Wenn OpenSSL schon hier scheitert, liegt das Problem am CA-Speicher Ihres Systems oder am Netzwerk, nicht an Ihrem Code.

Der minimale Python-MQTT-TLS-Client

Speichern Sie dies als tls_client.py und ersetzen Sie k7f3q2 durch Ihre eigene zufällige Zeichenfolge:

import ssl
import time
import uuid

import paho.mqtt.client as mqtt

BROKER = "broker.connectmq.com"
PORT = 8883
TOPIC = "connectmq/demo/k7f3q2/secure"


def on_connect(client, userdata, flags, reason_code, properties):
    if reason_code.is_failure:
        print(f"Connect failed: {reason_code}")
        return
    sock = client.socket()
    print(f"Connected over {sock.version()} using {sock.cipher()[0]}")
    client.subscribe(TOPIC, qos=1)


def on_message(client, userdata, msg):
    print(f"{msg.topic}: {msg.payload.decode()}")


client = mqtt.Client(mqtt.CallbackAPIVersion.VERSION2, client_id=f"tls-{uuid.uuid4().hex[:8]}")
client.on_connect = on_connect
client.on_message = on_message

# Vertrauenswürdige CAs des Betriebssystems nutzen, ein gültiges Zertifikat verlangen
# und prüfen, dass es zu BROKER passt. Das ist der sichere Standard.
client.tls_set(cert_reqs=ssl.CERT_REQUIRED, tls_version=ssl.PROTOCOL_TLS_CLIENT)

client.connect(BROKER, PORT, keepalive=60)
client.loop_start()
time.sleep(2)
client.publish(TOPIC, "hello over TLS", qos=1)
time.sleep(2)
client.disconnect()
client.loop_stop()

Führen Sie es aus, und Sie sollten etwas wie Connected over TLSv1.3 using TLS_AES_256_GCM_SHA384 sehen, gefolgt von Ihrer zurückkommenden Nachricht.

Was tls_set() tut

Ohne ca_certs-Argument aufgerufen, erstellt tls_set() einen SSL-Kontext, der die standardmäßig vertrauenswürdigen Zertifikate der Plattform lädt, vom Server ein gültiges Zertifikat verlangt und prüft, ob der Name im Zertifikat zum Host passt, den Sie an connect() übergeben haben. Die expliziten Argumente cert_reqs und tls_version oben sind die Standardwerte, ausgeschrieben, damit die Absicht für den nächsten Leser offensichtlich ist.

Wenn Sie volle Kontrolle bevorzugen, erstellen Sie den Kontext selbst und übergeben ihn:

context = ssl.create_default_context()
context.minimum_version = ssl.TLSVersion.TLSv1_2
client.tls_set_context(context)

ssl.create_default_context() aktiviert Hostnamen- und Zertifikatsprüfung, und eine Mindestversion lehnt veraltete Protokolle ab. Verwenden Sie entweder tls_set() oder tls_set_context(), nicht beides.

Zugangsdaten für einen privaten Broker hinzufügen

TLS schützt die Zugangsdaten, die Sie senden, kombinieren Sie also immer beides. Mit einem im ConnectMQ-Portal erstellten Broker:

client = mqtt.Client(mqtt.CallbackAPIVersion.VERSION2, client_id="YOUR_CLIENT_ID")
client.username_pw_set("YOUR_USERNAME", "YOUR_PASSWORD")
client.tls_set()
client.connect("broker.connectmq.com", 8883, keepalive=60)

Verwenden Sie den Hostnamen und die Client-ID aus dem Portal; der Broker bindet Client-IDs an die von ihm ausgestellten Zugangsdaten. Laden Sie Geheimnisse aus Umgebungsvariablen (os.environ["MQTT_PASSWORD"]), statt sie in die Versionsverwaltung einzuchecken.

Sicheres WebSocket aus Python

Manche Netzwerke blockieren alles außer den Standard-Web-Ports. paho kann MQTT über sicheres WebSocket auf Port 8084 tunneln, mit derselben TLS-Prüfung:

client = mqtt.Client(
    mqtt.CallbackAPIVersion.VERSION2,
    client_id=f"wss-{uuid.uuid4().hex[:8]}",
    transport="websockets",
)
client.ws_set_options(path="/mqtt")
client.tls_set()
client.connect("broker.connectmq.com", 8084, keepalive=60)

Alles andere, also Callbacks, Abonnements und Publishing, bleibt gleich. Der Artikel MQTT über WebSocket erklärt, wann dieser Transport sinnvoll ist.

Häufige TLS-Fehler beheben

Die meisten TLS-Fehler haben eine Handvoll Ursachen. Ordnen Sie Ihre Fehlermeldung dieser Tabelle zu:

Fehler Wahrscheinliche Ursache Lösung
CERTIFICATE_VERIFY_FAILED: unable to get local issuer certificate Python findet keine vertrauenswürdigen CAs Siehe die Lösungen zum CA-Speicher unten
Hostname mismatch, certificate is not valid for '...' Verbindung per IP-Adresse oder Alias Mit dem exakten Hostnamen des Brokers verbinden
certificate is not yet valid oder certificate has expired Die Uhr des Geräts geht falsch Zeit vor dem Verbinden per NTP synchronisieren
WRONG_VERSION_NUMBER TLS-Client spricht mit dem unverschlüsselten Port 1883 Port 8883 verwenden
Verbindung hängt und läuft dann in einen Timeout Unverschlüsselter Client spricht mit TLS-Port 8883, oder Port blockiert tls_set() aufrufen oder Port 8084 versuchen

Einen fehlenden CA-Speicher beheben

  • macOS mit Python von python.org: Diese Python-Version hat keinen Zugriff auf den System-Schlüsselbund. Führen Sie das Skript "Install Certificates.command" im Python-Anwendungsordner aus oder verweisen Sie paho auf certifi: pip install certifi, dann client.tls_set(ca_certs=certifi.where()).
  • Schlanke Docker-Images: Installieren Sie das CA-Bundle, zum Beispiel apt-get install -y ca-certificates bei Debian-basierten Images.
  • Unternehmens- und Werksnetze mit TLS-Inspektion: Ein Proxy ersetzt Zertifikate womöglich durch eigene. Fragen Sie die IT nach der Root-CA des Unternehmens und übergeben Sie sie mit ca_certs=, statt die Prüfung zu deaktivieren.
  • Embedded Linux: Aktualisieren Sie das CA-Bundle; sehr alte Images enthalten möglicherweise nicht das ISRG-Root-X1-Zertifikat, auf das Let's Encrypt verweist.

TLS niemals durch Abschalten der Prüfung "reparieren"

Sie werden auf Ratschläge stoßen, client.tls_insecure_set(True) aufzurufen oder cert_reqs=ssl.CERT_NONE zu übergeben. Beides lässt den Fehler verschwinden, indem jedes Zertifikat von jedem akzeptiert wird, was die Server-Authentifizierung stillschweigend entfernt. Nutzen Sie das nur für eine schnelle Diagnose in Ihrem eigenen Labornetz, niemals in ausgeliefertem Code.

Vermeiden Sie außerdem, das Leaf-Zertifikat des Brokers in Ihrem Client zu pinnen. Let's-Encrypt-Zertifikate werden regelmäßig erneuert, ein gepinntes Zertifikat bricht also bei der nächsten Erneuerung. Vertrauen Sie stattdessen der CA, genau das tut der Standardspeicher.

Checkliste für die Produktion

Bevor Sie einen Python-Client mit TLS ausrollen, bestätigen Sie jeden Punkt:

  1. Überall wird Port 8883 (oder 8084 mit WebSocket) verwendet; nichts fällt auf 1883 zurück.
  2. tls_set() oder tls_set_context() wird ohne tls_insecure_set(True) aufgerufen.
  3. Der Client verbindet sich per Hostname, niemals per IP-Adresse.
  4. Das Gerät hat eine genaue Uhrzeit, beim Booten per NTP synchronisiert.
  5. Das CA-Bundle auf dem Gerät wird gepflegt und mit dem Betriebssystem aktualisiert.
  6. Zugangsdaten stammen aus Umgebungsvariablen oder einem Secrets-Store.
  7. Eine Reconnect-Logik ist vorhanden; der Leitfaden zu paho-mqtt-Reconnects zeigt ein robustes Muster.

Wie es weitergeht

Wenn Sie neu bei paho sind, behandelt das paho-mqtt-Python-Tutorial die Grundlagen von Publish und Subscribe, und der Leitfaden zu aiomqtt und asyncio zeigt, wie Sie einem asynchronen Client einen tls_context übergeben. Für Clients in anderen Sprachen vergleicht die Übersicht der MQTT-Client-Bibliotheken die TLS-Unterstützung in verschiedenen Ökosystemen. Die Dokumentation des Python-ssl-Moduls ist die Referenz für jede hier verwendete Kontextoption.

Sichern Sie Ihren MQTT-Verkehr mit ConnectMQ

ConnectMQ ist ein verwalteter MQTT-Broker mit TLS auf 8883 und sicherem WebSocket auf 8084, standardmäßig aktiviert und gestützt auf ein automatisch verwaltetes Let's-Encrypt-Zertifikat, sodass Ihre Python-Clients den Broker mit dem CA-Speicher prüfen, den sie bereits haben. Testen Sie auf dem öffentlichen MQTT-Broker, der für Tests und Prototypen gedacht ist, und wechseln Sie dann zu einem privaten Cloud-MQTT-Broker mit generierten Zugangsdaten. Erstellen Sie Ihren kostenlosen Broker im Serverless-Plan, ohne Kreditkarte.

Häufig gestellte Fragen

Muss ich ein CA-Zertifikat herunterladen, um mich per TLS zu verbinden?

Nein. Der Broker nutzt ein Let's-Encrypt-Zertifikat, dessen Kette zu einer Root führt, der aktuelle Betriebssysteme vertrauen, daher funktioniert tls_set() mit dem Standard-CA-Speicher.

Welchen Port verwendet MQTT über TLS?

Der Standardport ist 8883. ConnectMQ bietet zusätzlich MQTT über sicheres WebSocket auf Port 8084 mit dem Pfad /mqtt.

Warum schlägt Python MQTT TLS fehl, wenn ich mich per IP-Adresse verbinde?

Die Hostnamenprüfung vergleicht den Namen im Zertifikat mit dem Host, mit dem Sie sich verbunden haben. Eine IP-Adresse passt nicht zum Namen des Brokers, die Prüfung schlägt also absichtlich fehl; verwenden Sie den Hostnamen.

Reicht TLS aus, um meinen MQTT-Client abzusichern?

TLS schützt die Verbindung, Sie benötigen aber dennoch starke, gerätespezifische Zugangsdaten und ein durchdachtes Topic-Design. Kombinieren Sie TLS mit eindeutigen Zugangsdaten aus dem Broker-Portal.

Verwandte Artikel

Die besten MQTT-CLI-Tools zum Testen, Skripten und Debuggen

Ein praxisnaher Vergleich von mosquitto_pub/sub, MQTTX CLI, HiveMQ MQTT CLI, der MQTT.js-CLI, curl und mqttui – mit demselben Test gegen broker.connectmq.com, damit Sie das richtige Tool zum Skripten und Debuggen wählen.

8 Min. Lesezeit

Alle Artikel →

Ihr privater MQTT-Broker ist nur wenige Klicks entfernt

Konto anlegen, Broker-Zugangsdaten erhalten und das erste Gerät verbinden — ohne Server, die installiert, gepatcht oder skaliert werden müssen.