Tutorial: TLS, X.509-Clientauthentifizierung und attributbasierte Zugriffssteuerungsautorisierung mit dem MQTT-Broker von Azure IoT Einsatz
In diesem Tutorial erfahren Sie, wie Sie den MQTT-Broker von Azure IoT Einsatz mit TLS-Verschlüsselung und X.509-Clientauthentifizierung einrichten. Es enthält außerdem Schritt-für-Schritt-Anleitungen und Skripts zum Erstellen von Zertifikaten für den Broker und die Clients. Im Tutorial wird erläutert, wie Sie den MQTT-Broker mit verschiedenen Stammzertifizierungsstellen für den Client und den Broker konfigurieren. Außerdem wird die Einrichtung einer Autorisierungsrichtlinie für die attributbasierte Zugriffssteuerung basierend auf der Clientzertifikatkette behandelt. Zuletzt werden in diesem Tutorial mit dem Mosquito-Client verschiedene Szenarios getestet, um sicherzustellen, dass das Setup ordnungsgemäß funktioniert.
Im Tutorial wird eine Umgebung simuliert, in der Azure IoT Einsatz in einer Contoso-Fabrik mit von Fabrikam hergestellten Geräten installiert ist. So richten Sie TLS und die X.509-Authentifizierung ein:
- Der in einer Contoso-Factory installierte MQTT-Broker von Azure IoT Einsatz muss der Fabrikam-Stammzertifizierungsstelle vertrauen.
- Fabrikam-Sensoren wie Thermostate, müssen ebenfalls der Contoso-Stammzertifizierungsstelle vertrauen.
- Jede Entität muss über ein eigenes Blattzertifikat verfügen, das von der richtigen Stammzertifizierungsstelle ausgestellt wurde.
Voraussetzungen
Für dieses Tutorial benötigen Sie Folgendes:
- Einen Kubernetes-Cluster mit aktivierter Portweiterleitung für Port 8883
- Azure IoT Einsatz-Instanz ohne bestehenden Lastenausgleichslistener
- Kubectl-Zugriff auf den Cluster zum Erstellen von Kubernetes-Geheimnissen und -ConfigMaps
- Den Mosquitto-Client zum Veröffentlichen und Abonnieren von MQTT-Nachrichten, die für den
localhost
-Zugriff auf demselben Computer wie der Kubernetes-Cluster ausgeführt werden. Wenn Sielocalhost
nicht verwenden möchten, lesen Sie Optional: Verwenden eines echten Hostnamens oder einer echten IP-Adresse anstelle vonlocalhost
. - Die step CLI zum Erstellen von Zertifikaten
Tipp
Um diese Anforderungen zu erfüllen, verwenden Sie den Schnellstartcodespace. Der Schnellstartcodespace vereinfacht den Einrichtungsprozess, indem diese Komponenten sofort bereitgestellt werden.
Vertrautheit mit Kryptografie mit öffentlichen Schlüsseln und Ausdrücken wie Stammzertifizierungsstelle, private Schlüssel und Zwischenzertifikaten ist von Vorteil.
Optional: Verwenden eines echten Hostnamens oder einer echten IP-Adresse anstelle von localhost
Um dieses Tutorial einfach zu halten, greifen wir mit localhost
auf den MQTT-Broker zu. Dieser Ansatz stellt sicher, dass das Serverzertifikat des Brokers über einen alternativen Antragstellernamen (Subject Alternative Name, SAN) verfügt, der dem Hostnamen entspricht, der für den Zugriff auf den Broker verwendet wird. Die Verwendung von localhost
vereinfacht das Setup, da der SAN bereits ordnungsgemäß festgelegt ist.
In einem realen Szenario würden Sie den Hostnamen oder die externe IP des Brokers anstelle von localhost
verwenden und von einem anderen Gerät im Netzwerk aus eine Verbindung herstellen. In diesem Fall müssen Sie den richtigen Hostnamen oder die richtige IP-Adresse ermitteln und die entsprechende Zeichenfolge beim Erstellen des Serverzertifikats als SAN verwenden:
- Wenn der Hostname oder die IP-Adresse bereits bekannt ist (z. B. aus einem DNS-Eintrag oder der statischen IP), verwenden Sie die Zeichenfolge beim Erstellen des Serverzertifikats als SAN. Stellen Sie dann eine Verbindung mit dem Broker her, und verwenden Sie dabei diesen Hostnamen oder diese IP anstelle von
localhost
. - Wenn der Hostname oder die IP-Adresse noch nicht bekannt ist, können Sie die externe IP-Adresse mit einem Platzhalterdienst ermitteln:
- Erstellen Sie den LoadBalancer-Dienst auf einem nicht verwendeten Port (z. B. 8080):
kubectl create service loadbalancer placeholder-service --tcp=8080:8080
- Rufen Sie die externe IP-Adresse ab:
kubectl get svc placeholder-service
- Wenn die externe IP:
- einen Wert wie
192.168.X.X
aufweist, verwenden Sie diese IP bei der Erstellung des Serverzertifikats und des Geheimnisses als SAN. Stellen Sie dann eine Verbindung zum Broker her, wobei Sie diese IP anstelle vonlocalhost
verwenden. <pending>
aufweist, bietet Ihre Kubernetes-Distribution möglicherweise keine Unterstützung für die automatische Zuweisung einer externen IP-Adresse. Um die externe IP-Adresse zu ermitteln, führen Sie die Schritte in der Kubernetes-Dokumentation Ihrer Distribution und Hostumgebung aus. Je nach Netzwerksetup müssen Sie unter Umständen auch eine Portweiterleitung oder ein VPN konfigurieren.
- einen Wert wie
- Löschen Sie nach dem Ermitteln der externen IP den Platzhalterdienst:
kubectl delete svc placeholder-service
- Erstellen Sie den LoadBalancer-Dienst auf einem nicht verwendeten Port (z. B. 8080):
Diese Methode stellt sicher, dass das Serverzertifikat mit der externen IP-Adresse übereinstimmt und einen sicheren Zugriff auf den MQTT-Broker ermöglicht.
Vorbereiten der serverseitigen Zertifikate und vollständigen Kette
Erstellen Sie zunächst eine serverseitige Stammzertifizierungsstelle. Diese Zertifizierungsstelle besteht unabhängig von der clientseitigen Stammzertifizierungsstelle, die später erstellt wird. Um die Trennung der Zertifizierungsstellen zu verdeutlichen, werden alle serverseitigen Ressourcen mit „Contoso“ benannt. Um spätere Schritte zu vereinfachen, überspringen wir das Kennwort zum Verschlüsseln des privaten Schlüssels. Diese Vorgehensweise ist nur in einem Tutorial zulässig.
step certificate create "Contoso Root CA" \
contoso_root_ca.crt contoso_root_ca.key \
--profile root-ca \
--no-password --insecure
Erstellen Sie dann eine Zwischenzertifizierungsstelle, die von dieser Stammzertifizierungsstelle signiert ist.
step certificate create "Contoso Intermediate CA 1" \
contoso_intermediate_ca.crt contoso_intermediate_ca.key \
--profile intermediate-ca \
--ca ./contoso_root_ca.crt --ca-key ./contoso_root_ca.key \
--no-password --insecure
Verwenden Sie schließlich diese Zwischenzertifizierungsstelle, um ein Serverzertifikat für das Broker-Front-End des MQTT-Brokers zu signieren. In diesem Tutorial wird localhost
als SAN verwendet.
step certificate create mqtts-endpoint \
mqtts-endpoint.crt mqtts-endpoint.key \
--profile leaf \
--ca ./contoso_intermediate_ca.crt --ca-key ./contoso_intermediate_ca.key \
--bundle \
--san localhost \
--not-after 2400h --no-password --insecure
Mit dem --bundle
-Flag wird das Serverzertifikat mit dem signierenden Zwischenzertifikat gebündelt. Der TLS-Handshake erfordert, dass das Bundle die vollständige Kette verifiziert.
Vorbereiten der clientseitigen Zertifikate und vollständigen Kette
Erstellen Sie auf ähnliche Weise die Stammzertifizierungsstelle für Fabrikam und die Zwischenzertifizierungsstelle.
step certificate create --profile root-ca "Fabrikam Root CA" \
fabrikam_root_ca.crt fabrikam_root_ca.key \
--no-password --insecure
step certificate create "Fabrikam Intermediate CA 1" \
fabrikam_intermediate_ca.crt fabrikam_intermediate_ca.key \
--profile intermediate-ca \
--ca ./fabrikam_root_ca.crt --ca-key ./fabrikam_root_ca.key \
--no-password --insecure
Generieren Sie dann Clientzertifikate für einen Thermostat, ein Hygrometer, ein Heizgerät und eine Glühbirne.
# Create a client certificate for the thermostat
step certificate create thermostat thermostat.crt thermostat.key \
--ca ./fabrikam_intermediate_ca.crt --ca-key ./fabrikam_intermediate_ca.key --bundle \
--not-after 2400h --no-password --insecure
# Create a client certificate for the hygrometer
step certificate create hygrometer hygrometer.crt hygrometer.key \
--ca ./fabrikam_intermediate_ca.crt --ca-key ./fabrikam_intermediate_ca.key --bundle \
--not-after 2400h --no-password --insecure
# Create a client certificate for the heater
step certificate create heater heater.crt heater.key \
--ca ./fabrikam_intermediate_ca.crt --ca-key ./fabrikam_intermediate_ca.key --bundle \
--not-after 2400h --no-password --insecure
# Create a client certificate for the lightbulb
step certificate create lightbulb lightbulb.crt lightbulb.key \
--ca ./fabrikam_intermediate_ca.crt --ca-key ./fabrikam_intermediate_ca.key --bundle \
--not-after 2400h --no-password --insecure
Konfigurieren von Kubernetes
Importieren Sie das neu generierte Serverzertifikat und den privaten Schlüssel in ein Kubernetes-Geheimnis. Dieses Geheimnis wird verwendet, um später einen TLS-Listener für den MQTT-Broker zu konfigurieren.
kubectl create secret tls broker-server-cert -n azure-iot-operations \
--cert mqtts-endpoint.crt \
--key mqtts-endpoint.key
Erstellen Sie außerdem eine ConfigMap, die die (clientseitige) Fabrikam-Stammzertifizierungsstelle enthält. Diese ConfigMap ist erforderlich, damit der MQTT-Broker der Zertifizierungsstelle bei der X.509-Authentifizierung vertraut.
kubectl create configmap fabrikam-ca -n azure-iot-operations \
--from-file=client_ca.pem=fabrikam_root_ca.crt
Konfigurieren des MQTT-Brokers
In den nächsten Schritten wird der MQTT-Broker mit TLS-Verschlüsselung und X.509-Clientauthentifizierung konfiguriert. In diesem Tutorial wird das Azure-Portal für die Konfiguration des MQTT-Brokers verwendet.
Authentifizierung
Damit Clients sich mit X.509-Zertifikaten authentifizieren können, die von der Fabrikam-Stammzertifizierungsstelle ausgestellt wurden, müssen Sie eine Authentifizierungsrichtlinie erstellen, die dem Zertifikat der Fabrikam-Stammzertifizierungsstelle vertraut und die Clientzertifikate den Autorisierungsattributen der attributbasierten Zugriffssteuerung zuordnet.
Navigieren Sie im Azure-Portal zu Ihrer IoT Einsatz-Instanz.
Wählen Sie unter Komponenten den MQTT-Broker aus.
Wählen Sie die Registerkarte Authentifizierung aus.
Wählen Sie Authentifizierungsrichtlinie erstellen aus.
Geben Sie unter Richtlinienname
x509-auth
ein.Fügen Sie eine neue Methode hinzu, indem Sie Methode hinzufügen auswählen.
Wählen Sie in der Dropdownliste den Methodentyp X.509 aus, und wählen Sie dann Details hinzufügen aus, um die Methode zu konfigurieren.
Geben Sie im Bereich X.509-Authentifizierungsdetails den ConfigMap-Namen des Zertifikats der vertrauenswürdigen Fabrikam-Stammzertifizierungsstelle
fabrikam-ca
im JSON-Format an.{ "trustedClientCaCert": "fabrikam-ca", "authorizationAttributes": { "thermostat": { "subject": "CN = thermostat", "attributes": { "group": "thermostat_group" } }, "hygrometer": { "subject": "CN = hygrometer", "attributes": { "group": "hygrometer_group" } }, "intermediate": { "subject": "CN = Fabrikam Intermediate CA 1", "attributes": { "manufacturer": "fabrikam" } } } }
Wählen Sie dann Anwenden und Hinzufügen aus, um die Änderungen zu speichern.
Listener
Erstellen Sie nach der Einrichtung der Authentifizierungsrichtlinie einen Listener, der die X.509-Authentifizierungsrichtlinie verwendet. Da die X.509-Authentifizierung TLS erfordert, müssen Sie den Listener zudem so konfigurieren, dass er das Contoso-Serverzertifikat und den privaten Schlüssel verwendet, die Sie zuvor erstellt haben.
Navigieren Sie im Azure-Portal zu Ihrer IoT Einsatz-Instanz.
Wählen Sie unter Komponenten den MQTT-Broker aus.
Wählen Sie MQTT-Brokerlistener für LoadBalancer>Erstellen aus. Geben Sie folgende Einstellungen ein:
Einstellung BESCHREIBUNG Name Geben Sie mqtts-endpoint
ein.Dienstname Name des Kubernetes-Diensts Lassen Sie das Feld leer, um den Listenernamen mqtts-endpoint
als Dienstnamen zu verwenden.Diensttyp LoadBalancer ist bereits ausgewählt. Geben Sie unter Ports die folgenden Einstellungen für den ersten Port ein:
Einstellung BESCHREIBUNG Port Geben Sie 8883 ein. Authentifizierung Wählen Sie x509-auth aus. Autorisierung Wählen Sie die Option Keine aus. Protokoll Wählen Sie MQTT aus. TLS Wählen Sie Hinzufügen aus. Geben Sie im Bereich TLS-Konfiguration erstellen die folgenden Einstellungen ein:
Einstellung Beschreibung TLS-Modus Wählen Sie Manuell aus. Issuer name Geben Sie broker-server-cert
einWählen Sie Anwenden und Listener erstellen aus.
Nach einer oder zwei Minuten ist der LoadBalancer-Dienst mqtts-endpoint
erstellt.
$ kubectl get service mqtts-endpoint -n azure-iot-operations
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
mqtts-endpoint LoadBalancer 10.43.28.140 XXX.XX.X.X 8883:30988/TCP 104s
Anstatt die externe IP zu verwenden, verwenden wir localhost
für dieses Tutorial.
Tipp
Die Konfiguration des Codespace richtet die Portweiterleitung automatisch auf Port 8883 ein. Informationen zum Einrichten anderer Umgebungen finden Sie unter Verwenden der Portweiterleitung.
Verwenden eines einzelnen Mosquito-Clients zum Veröffentlichen von Nachrichten über TLS
Verwenden Sie im demselben Ordner wie die Zertifikatdateien contoso_root_ca.crt
, thermostat.crt
und thermostat.key
den Mosquito-Client, um eine Nachricht zu veröffentlichen. Das --cafile contoso_root_ca.crt
-Flag weist den Mosquito-Client an, das Serverzertifikat zu verifizieren.
mosquitto_pub -t "example/topic" -m "example temperature measurement" -i thermostat \
-q 1 -V mqttv5 -d \
-h localhost \
--key thermostat.key \
--cert thermostat.crt \
--cafile contoso_root_ca.crt
Die Veröffentlichung ist erfolgreich, weil der Mosquito-Client ein Clientzertifikat verwendet, dessen Stamm fabrikam_root_ca.crt
ist. Der MQTT-Broker vertraut diesem Zertifikat aufgrund der zuvor erstellten x509-auth
-Authentifizierungsrichtlinie. Darüber hinaus lässt der MQTT-Broker derzeit zu, dass authentifizierte Clients Nachrichten in jedem Thema veröffentlichen.
Client thermostat sending CONNECT
Client thermostat received CONNACK (0)
Client thermostat sending PUBLISH (d0, q1, r0, m1, 'example/topic', ... (31 bytes))
Client thermostat received PUBACK (Mid: 1, RC:0)
Client thermostat sending DISCONNECT
Konfigurieren der Autorisierung in MQTT-Themen für mehrere Clients mit X.509
Um den Zugriff auf MQTT-Themen auf Basis der Clientzertifikatattribute einzuschränken, müssen Sie eine Autorisierungsrichtlinie erstellen, die den Clientzertifikatattributen zulässige Aktionen in bestimmten Themen zuordnet.
Navigieren Sie im Azure-Portal zu Ihrer IoT Einsatz-Instanz.
Wählen Sie unter Komponenten den MQTT-Broker aus.
Wählen Sie die Registerkarte Autorisierung.
Wählen Sie Autorisierungsrichtlinie erstellen aus.
Geben Sie unter Richtlinienname
abac-authz
ein.Geben Sie unter Regeln die folgenden Regeln ein:
[ { "principals": { "attributes": [ { "group": "thermostat_group" } ] }, "brokerResources": [ { "method": "Connect" }, { "method": "Publish", "topics": [ "telemetry/temperature" ] } ] }, { "principals": { "attributes": [ { "group": "hygrometer_group" } ] }, "brokerResources": [ { "method": "Connect" }, { "method": "Publish", "topics": [ "telemetry/humidity" ] } ] }, { "principals": { "attributes": [ { "manufacturer": "fabrikam" } ] }, "brokerResources": [ { "method": "Connect" }, { "method": "Publish", "topics": [ "health/heartbeat" ] } ] }, { "principals": { "usernames": [ "heater" ] }, "brokerResources": [ { "method": "Connect" }, { "method": "Subscribe", "topics": [ "telemetry/temperature", "telemetry/humidity" ] } ] } ]
Wählen Sie Hinzufügen aus, um die Änderungen zu speichern.
Aktualisieren Sie dann den MQTT-Brokerlistener, sodass dieser die neue Autorisierungsrichtlinie verwendet.
- Öffnen Sie die Registerkarte Listener.
- Wählen Sie den Listener mqtts-endpoint aus.
- Wählen Sie unter Ports>8883>Autorisierung den Wert abac-authz aus.
- Wählen Sie Speichern.
Veröffentlichen von Nachrichten in einem eingeschränkten Thema
In diesem Abschnitt testen wir die neu angewendeten Autorisierungsrichtlinien.
Stellen Sie zunächst eine Verbindung zu thermostat
her, und versuchen Sie, eine Nachricht im Thema telemetry/humidity
zu veröffentlichen:
mosquitto_pub -t "telemetry/humidity" -m "example temperature measurement" -i thermostat \
-q 1 -V mqttv5 -d \
-h localhost \
--key thermostat.key \
--cert thermostat.crt \
--cafile contoso_root_ca.crt
Da thermostat
zu thermostat_group
gehört und „thermostat_group“ nicht berechtigt ist, im Thema „humidity“ zu veröffentlichen, schlägt die Veröffentlichung fehl.
Client thermostat sending CONNECT
Client thermostat received CONNACK (0)
Client thermostat sending PUBLISH (d0, q1, r0, m1, 'telemetry/humidity', ... (6 bytes))
Client thermostat received PUBACK (Mid: 1, RC:135)
Warning: Publish 1 failed: Not authorized.
Nehmen Sie die Veröffentlichung stattdessen in telemetry/temperature
vor, was zulässig ist und die Veröffentlichung ist erfolgreich. Brechen Sie die Ausführung des Befehls nicht ab.
mosquitto_pub -t "telemetry/temperature" -m "example temperature measurement" -i thermostat \
-q 1 -V mqttv5 -d \
-h localhost \
--repeat 10000 \
--repeat-delay 3 \
--key thermostat.key \
--cert thermostat.crt \
--cafile contoso_root_ca.crt
Abonnieren von Nachrichten in eingeschränkten Themen
Stellen Sie in einer separaten Terminalsitzung eine Verbindung mit heater
her, um health/heartbeat
zu abonnieren.
mosquitto_sub -q 1 -t "health/heartbeat" -d -V mqttv5 \
-i heater \
-h localhost \
--key heater.key \
--cert heater.crt \
--cafile contoso_root_ca.crt
Da heater
nicht autorisiert ist, das Heartbeatthema zu abonnieren, schlägt das Abonnement fehl. Code 135 bedeutet in diesem Fall nicht autorisiert.
Client heater sending CONNECT
Client heater received CONNACK (0)
Client heater sending SUBSCRIBE (Mid: 1, Topic: health/heartbeat, QoS: 1, Options: 0x00)
Client heater received SUBACK
Subscribed (mid: 1): 135
Stellen Sie das zu abonnierende Thema auf telemetry/temperature
um, in das thermostat
weiterhin Nachrichten sendet.
mosquitto_sub -q 1 -t "telemetry/temperature" -d -V mqttv5 \
-i heater \
-h localhost \
--key heater.key \
--cert heater.crt \
--cafile contoso_root_ca.crt
heater
empfängt nun Nachrichten, da es mit seinem Benutzernamen autorisiert ist.
Veröffentlichen Sie in einer anderen separaten Terminalsitzung mit lightbulb
Nachrichten in health/heartbeat
:
mosquitto_pub -q 1 -t "health/heartbeat" -m "example heartbeat" -d -V mqttv5 \
-i lightbulb \
-h localhost \
--repeat 100 \
--repeat-delay 3 \
--key lightbulb.key \
--cert lightbulb.crt \
--cafile contoso_root_ca.crt
Die Veröffentlichung ist erfolgreich, weil lightbulb
ein Zwischenzertifikat mit CN = Fabrikam Intermediate CA 1
hat, das dem Attribut manufacturer=fabrikam
zugeordnet ist. Clients mit diesem Attribut können in health/heartbeat
veröffentlichen. Wenn der Client mit dem Senden von Nachrichten beginnt, empfängt heater
(zuvor gestartet) nichts.
Bereinigen von Ressourcen
Um die in diesem Tutorial erstellten Ressourcen zu bereinigen, löschen Sie den Listener sowie die Authentifizierungs- und Autorisierungsrichtlinien.
- Navigieren Sie im Azure-Portal zu Ihrer IoT Einsatz-Instanz.
- Wählen Sie unter Komponenten den MQTT-Broker aus.
- Öffnen Sie die Registerkarte Listener.
- Aktivieren Sie das Kontrollkästchen neben dem Listener mqtts-endpoint.
- Klicken Sie auf Löschen.
- Bestätigen Sie den Löschvorgang.
- Wählen Sie die Registerkarte Authentifizierung aus.
- Aktivieren Sie das Kontrollkästchen neben x509-auth.
- Klicken Sie auf Löschen.
- Bestätigen Sie den Löschvorgang.
- Wählen Sie die Registerkarte Autorisierung.
- Aktivieren Sie das Kontrollkästchen neben abac-authz.
- Klicken Sie auf Löschen.
- Bestätigen Sie den Löschvorgang.
Löschen Sie außerdem das Kubernetes-Geheimnis und die ConfigMap.
kubectl delete secret broker-server-cert -n azure-iot-operations
kubectl delete configmap fabrikam-ca -n azure-iot-operations
Löschen Sie schließlich die zuvor generierten Zertifikate und Schlüssel.
rm contoso_root_ca.crt contoso_root_ca.key contoso_intermediate_ca.crt contoso_intermediate_ca.key mqtts-endpoint.crt mqtts-endpoint.key
rm fabrikam_root_ca.crt fabrikam_root_ca.key fabrikam_intermediate_ca.crt fabrikam_intermediate_ca.key thermostat.crt thermostat.key hygrometer.crt hygrometer.key heater.crt heater.key lightbulb.crt lightbulb.key