Tutoriel : TLS, authentification client X.509 et autorisation de contrôle d'accès basé sur les attributs (ABAC) avec le courtier MQTT d'Opérations Azure IoT
Ce tutoriel vous guide tout au long de la configuration du répartiteur MQTT Opérations Azure IoT avec le chiffrement TLS et l’authentification du client X.509. Il inclut des instructions et des scripts pas à pas pour la création de certificats pour le répartiteur et les clients. Le tutoriel explique comment configurer le répartiteur MQTT avec différentes autorités de certification racine pour le client et le répartiteur. Il couvre également la configuration d’une stratégie d’autorisation de contrôle d’accès basé sur des attributs (ABAC) basée sur la chaîne de certificats client. Enfin, le tutoriel utilise le client Mosquito pour tester différents scénarios pour vérifier que l’installation fonctionne correctement.
Le tutoriel simule un environnement où Opérations Azure IoT est installé dans une fabrique Contoso, avec des appareils fabriqués par Fabrikam. Pour que l’authentification TLS et X.509 fonctionnent :
- Le répartiteur MQTT Opérations Azure IoT, installé dans une fabrique Contoso, doit approuver l’autorité de certification racine Fabrikam
- Les capteurs Fabrikam, comme les thermostats, doivent approuver l’autorité de certification racine Contoso
- Chaque entité doit avoir son propre certificat feuille émis par l’autorité de certification racine correcte
Prérequis
Pour suivre ce didacticiel, vous avez besoin des éléments suivants :
- Un cluster Kubernetes avec transfert de port activé pour le port 8883.
- Opérations Azure IoT déployées sans écouteur d’équilibreur de charge existant.
- Kubectl accède au cluster pour créer des secrets Kubernetes et des mappages de configuration.
- Client Mosquitto pour publier et s’abonner aux messages MQTT s’exécutant sur le même ordinateur que le cluster Kubernetes pour
localhost
accès. Pour ne pas utiliserlocalhost
, consultez Facultatif : Utilisez un nom d’hôte réel ou une adresse IP au lieu delocalhost
section. - Étape CLI pour créer des certificats.
Conseil
Pour répondre à ces exigences, utilisez le codespace de démarrage rapide. Le codespace de démarrage rapide simplifie le processus d’installation en fournissant ces composants en dehors de la boîte de dialogue.
En plus, connaissance du chiffrement par clé publique et des termes tels que l’autorité de certification racine, la clé privée et les certificats intermédiaires est utile.
Facultatif : Utilisez un nom d’hôte réel ou une adresse IP au lieu de localhost
Pour simplifier ce didacticiel, nous utilisons localhost
pour accéder au répartiteur MQTT. Cette approche garantit que le certificat de serveur du répartiteur a un autre nom d’objet (SAN) qui correspond au nom d’hôte utilisé pour accéder au répartiteur. L’utilisation de localhost
simplifie la configuration, car le SAN est déjà défini correctement.
Dans un scénario réel, vous utiliseriez le nom d’hôte ou l’adresse IP externe du répartiteur au lieu de localhost
et vous y connecter à partir d’un autre appareil sur le réseau. Dans ce cas, vous devez déterminer le nom d’hôte ou l’adresse IP approprié et l’utiliser comme SAN lors de la création du certificat de serveur :
- Si le nom d’hôte ou l’adresse IP est déjà connu (par exemple, par le biais d’un enregistrement DNS ou d’une adresse IP statique), utilisez-le comme SAN lors de la création du certificat de serveur. Ensuite, connectez-vous au répartiteur à l’aide de ce nom d’hôte ou de cette adresse IP au lieu de
localhost
. - Si le nom d’hôte ou l’adresse IP n’est pas déjà connu, vous pouvez utiliser un service d’espace réservé pour déterminer l’adresse IP externe :
- Créez le service LoadBalancer sur un port qui n’est pas utilisé (comme 8080) :
kubectl create service loadbalancer placeholder-service --tcp=8080:8080
- Récupérez l’adresse IP externe :
kubectl get svc placeholder-service
- Si l'IP externe :
- Affiche une valeur telle que
192.168.X.X
: utilisez cette adresse IP comme SAN lors de la création du certificat de serveur et du secret. Ensuite, connectez-vous au répartiteur à l’aide de cette adresse IP au lieu delocalhost
. - Affiche
<pending>
: la distribution Kubernetes que vous utilisez peut ne pas prendre en charge l’attribution automatique d’une adresse IP externe. Pour rechercher l’adresse IP externe, suivez les étapes de la documentation Kubernetes pour votre environnement de distribution et d’hôte. Vous devrez peut-être également configurer réacheminement de port ou un VPN en fonction de la configuration du réseau.
- Affiche une valeur telle que
- Après avoir déterminé l’adresse IP externe, supprimez le service d’espace réservé :
kubectl delete svc placeholder-service
- Créez le service LoadBalancer sur un port qui n’est pas utilisé (comme 8080) :
Cette méthode garantit que le certificat de serveur correspond à l’adresse IP externe, ce qui permet un accès sécurisé au répartiteur MQTT.
Préparer des certificats côté serveur et une chaîne complète
Tout d’abord, créez une autorité de certification racine côté serveur. Cette autorité de certification est distincte de l’autorité de certification racine côté client qui est créée ultérieurement. Pour que la séparation soit claire, nous nommons tout le côté serveur « Contoso ». Pour faciliter les étapes ultérieures, nous ignorons le mot de passe pour chiffrer la clé privée. Cette pratique n’est acceptable que dans un paramètre de didacticiel.
step certificate create "Contoso Root CA" \
contoso_root_ca.crt contoso_root_ca.key \
--profile root-ca \
--no-password --insecure
Ensuite, créez une autorité de certification intermédiaire signée par cette autorité de certification racine.
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
Enfin, utilisez cette autorité de certification intermédiaire pour signer un certificat de serveur pour le serveur frontal du répartiteur MQTT. Ici, localhost
est l’autre nom de l’objet (SAN) utilisé pour le tutoriel.
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
Avec l’indicateur --bundle
, le certificat de serveur est groupé avec le certificat intermédiaire de signature. L’établissement d'une liaison TLS nécessite l’offre groupée pour vérifier la chaîne complète.
Préparer des certificats côté lient et une chaîne complète
De même, créez l’autorité de certification racine pour Fabrikam et l’autorité de certification intermédiaire.
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
Ensuite, générez des certificats clients pour un thermostat, un hygromètre, un chauffage et une ampoule.
# 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
Configurer Kubernetes
Importez le certificat de serveur nouvellement généré et la clé privée dans un secret Kubernetes. Ce secret est utilisé pour configurer un écouteur TLS pour le répartiteur MQTT ultérieurement.
kubectl create secret tls broker-server-cert -n azure-iot-operations \
--cert mqtts-endpoint.crt \
--key mqtts-endpoint.key
Créez également un mappage de configuration pour contenir l’autorité de certification racine Fabrikam (côté client). Ce mappage de configuration est requis pour que le répartiteur MQTT l’approuve pour l’authentification X.509.
kubectl create configmap fabrikam-ca -n azure-iot-operations \
--from-file=client_ca.pem=fabrikam_root_ca.crt
Configurer l’Agent MQTT
Les étapes suivantes configurent le répartiteur MQTT avec le chiffrement TLS et l’authentification du client X.509. Le tutoriel utilise le portail Azure pour configurer le répartiteur MQTT.
Authentification
Pour permettre aux clients de s’authentifier à l’aide de certificats X.509 émis par l’autorité de certification racine Fabrikam, créez une stratégie d’authentification qui approuve le certificat d’autorité de certification racine Fabrikam et mappe les certificats clients aux attributs d’autorisation pour ABAC.
Dans le portail Azure, accédez à votre instance Opérations IoT.
Sous Composants, sélectionnez Agent MQTT.
Sélectionnez l’onglet Authentification.
Sélectionnez Créer une stratégie d’authentification.
Pour Nom de stratégie, entrez
x509-auth
.Ajoutez une nouvelle méthode en sélectionnant Ajouter une méthode.
Choisissez le type de méthode X.509 dans la liste déroulante, puis sélectionnez Ajouter des détails pour configurer la méthode.
Dans le volet des détails de l'authentification X.509, spécifiez le nom ConfigMap du certificat de l'autorité de certification de Fabrikam
fabrikam-ca
et les attributs.{ "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" } } } }
Sélectionnez Appliquer, puis Ajouter pour enregistrer les modifications.
Port d'écoute
Avec la stratégie d’authentification en place, créez un écouteur qui utilise la stratégie d’authentification X.509. En outre, étant donné que l’authentification X.509 nécessite TLS, configurez l’écouteur pour utiliser le certificat de serveur Contoso et la clé privée créés précédemment.
Dans le portail Azure, accédez à votre instance Opérations IoT.
Sous Composants, sélectionnez Agent MQTT.
Sélectionnez Écouteur de l’Agent MQTT pour LoadBalancer>Créer. Entrez les paramètres suivants :
Setting Description Nom Entrez mqtts-endpoint
.Nom du service Nom du service Kubernetes. Laissez-le vide pour utiliser le nom de l’écouteur mqtts-endpoint
en tant que nom de service.Type de service LoadBalancer déjà sélectionné. Sous Ports, entrez les paramètres suivants pour le premier port :
Setting Description Port Entrez 8883 Authentification Choisissez x509-auth Autorisation Choisissez Aucun(e) Protocol Choisir MQTT TLS Sélectionnez Ajouter Dans le volet Configuration TLS, entrez les paramètres suivants :
Setting Description Mode TLS Choisissez Manuel Nom de l'émetteur Entrez broker-server-cert
Sélectionnez Appliquer et Créer un écouteur.
Après une minute ou deux, le service mqtts-endpoint
LoadBalancer est créé.
$ 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
Au lieu d’utiliser l’adresse IP externe, nous utilisons localhost
pour le tutoriel.
Conseil
La configuration de l’espace de code configure automatiquement le réacheminement de port pour 8883. Pour configurer d’autres environnements, consultez Utiliser le réacheminement de port.
Utiliser un seul client Mosquito pour publier des messages via TLS
À partir du même dossier que les fichiers de certificat : contoso_root_ca.crt
, thermostat.crt
et thermostat.key
, utilisez le client Mosquito pour publier un message. L’indicateur --cafile contoso_root_ca.crt
est destiné à Mosquito pour effectuer la vérification des certificats de serveur.
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
La publication réussit, car Mosquito utilise un certificat client racine dans fabrikam_root_ca.crt
. Le répartiteur MQTT approuve ce certificat, car la stratégie d’authentification x509-auth
créée précédemment. En outre, le répartiteur MQTT permet actuellement aux clients authentifiés de publier sur n’importe quelle rubrique.
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
Configurer l’autorisation sur les rubriques MQTT pour plusieurs clients à l’aide de X.509
Pour restreindre l’accès aux rubriques MQTT en fonction des attributs de certificat client, créez une stratégie d’autorisation qui mappe les attributs de certificat client aux actions autorisées sur des rubriques spécifiques.
Dans le portail Azure, accédez à votre instance Opérations IoT.
Sous Composants, sélectionnez Agent MQTT.
Sélectionnez l’onglet Autorisation.
Sélectionnez Créer la stratégie d’autorisation
Pour Nom de stratégie, entrez
abac-authz
.Sous Règles, entrez les règles suivantes :
[ { "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" ] } ] } ]
Sélectionnez Ajouter pour enregistrer les modifications.
Ensuite, mettez à jour l’écouteur broker MQTT pour utiliser la nouvelle stratégie d’autorisation.
- Sélectionnez l’onglet Écouteurs
- Sélectionnez l’écouteur mqtts-endpoint.
- Sous Ports>8883>Autorisation, choisissez abac-authz.
- Cliquez sur Enregistrer.
Publier des messages dans une rubrique restreinte
Dans cette section, nous testons les stratégies d’autorisation nouvellement appliquées.
Tout d’abord, connectez-vous à thermostat
et essayez de publier sur la rubrique telemetry/humidity
:
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
Étant donné que thermostat
fait partie de thermostat_group
, qui n’est pas autorisé à publier dans la rubrique d’humidité, la publication échoue.
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.
Modifiez la publication sur telemetry/temperature
, qui est autorisée et la publication réussit. Laissez la commande en cours d’exécution.
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
S’abonner à des messages sur des rubriques restreintes
Dans une session de terminal distincte, connectez-vous avec heater
pour vous abonner à health/heartbeat
.
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
Étant donné que heater
n’est pas autorisé(e) à s’abonner à la rubrique pulsation, l’abonnement échoue. Ici, le code 135 signifie non autorisé(e).
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
Basculez la rubrique d’abonnement vers telemetry/temperature
, auquel thermostat
envoie toujours des messages.
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
Maintenant heater
commence à recevoir des messages, car il est autorisé avec son nom d’utilisateur.
Dans une autre session de terminal distincte, publiez des messages sur health/heartbeat
avec lightbulb
:
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
La publication réussit, car lightbulb
a un certificat intermédiaire avec CN = Fabrikam Intermediate CA 1
, qui est mappé à l’attribut manufacturer=fabrikam
. Les clients avec cet attribut peuvent publier sur health/heartbeat
. Lorsque le client commence à envoyer des messages, heater
démarré précédemment ne reçoit rien.
Nettoyer les ressources
Pour nettoyer les ressources créées dans ce tutoriel, supprimez l’écouteur et les stratégies d’authentification et d’autorisation.
- Dans le portail Azure, accédez à votre instance Opérations IoT.
- Sous Composants, sélectionnez Agent MQTT.
- Sélectionnez l’onglet Écouteurs
- Cochez la case en regard de l’écouteur mqtts-endpoint.
- Sélectionnez Supprimer.
- Confirmez la suppression.
- Sélectionnez l’onglet Authentification.
- Cochez la case en regard de x509-auth.
- Sélectionnez Supprimer.
- Confirmez la suppression.
- Sélectionnez l’onglet Autorisation.
- Cochez la case à côté de abac-authz.
- Sélectionnez Supprimer.
- Confirmez la suppression.
Supprimez également le secret Kubernetes et la carte de configuration.
kubectl delete secret broker-server-cert -n azure-iot-operations
kubectl delete configmap fabrikam-ca -n azure-iot-operations
Enfin, supprimez les certificats et clés générés précédemment.
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