Esercitazione: Autorizzazione TLS, autenticazione client X.509 e controllo degli accessi in base all'attributo con il broker MQTT di Operazioni IoT di Azure
Questa esercitazione illustra come configurare il broker MQTT per le operazioni di Azure IoT con crittografia TLS e l'autenticazione client X.509. Include istruzioni dettagliate e script per la creazione di certificati sia per il broker che per i client. L'esercitazione illustra come configurare il broker MQTT con autorità di certificazione radice diverse per il client e il broker. Viene inoltre illustrata la configurazione di un criterio di autorizzazione ABAC (Attribute-Based Access Control) basato sulla catena di certificati client. Infine, l'esercitazione usa il client Mosquito per testare vari scenari per garantire il corretto funzionamento della configurazione.
L'esercitazione simula un ambiente in cui Azure IoT Operations è installato in una factory contoso, con i dispositivi prodotti da Fabrikam. Per rendere possibile l'autenticazione TLS e X.509:
- Broker MQTT per le operazioni IoT di Azure, installato in una factory contoso, deve considerare attendibile la CA radice di Fabrikam
- I sensori Fabrikam, ad esempio i termostati, devono considerare attendibile la CA radice contoso
- Ogni entità deve avere un proprio certificato foglia rilasciato dalla CA radice corretta
Prerequisiti
Per eseguire questa esercitazione, è necessario quanto segue:
- Un cluster Kubernetes con port forwarding abilitato per la porta 8883.
- Operazioni IoT di Azure distribuite senza un listener del servizio di bilanciamento del carico esistente.
- Accesso Kubectl al cluster per creare segreti e mappe di configurazione di Kubernetes.
- Il client Mosquitto deve pubblicare e sottoscrivere messaggi MQTT in esecuzione nello stesso computer del cluster Kubernetes per
localhost
l'accesso. Per non usarelocalhost
, vedere Facoltativo: usare un nome host o un indirizzo IP reale anziché lalocalhost
sezione . - Passaggio dell'interfaccia della riga di comando per creare i certificati.
Suggerimento
Per soddisfare questi requisiti, usare lo spazio di codice di avvio rapido. Lo spazio di codice di avvio rapido semplifica il processo di installazione fornendo questi componenti predefiniti.
Inoltre, è utile acquisire familiarità con la crittografia a chiave pubblica e i termini, ad esempio CA radice, chiave privata e certificati intermedi.
Facoltativo: usare un nome host o un indirizzo IP reale anziché localhost
Per semplificare questa esercitazione, viene usato localhost
per accedere al broker MQTT. Questo approccio garantisce che il certificato del server del broker abbia un nome alternativo soggetto (SAN) che corrisponda al nome host usato per accedere al broker. L'uso localhost
semplifica la configurazione perché la rete SAN è già impostata correttamente.
In uno scenario reale si userà il nome host o l'indirizzo IP esterno del broker anziché localhost
connettersi a esso da un altro dispositivo in rete. In questo caso, è necessario determinare il nome host o l'indirizzo IP corretto e usarlo come SAN durante la creazione del certificato del server:
- Se il nome host o l'indirizzo IP è già noto (ad esempio, tramite un record DNS o un indirizzo IP statico), usarlo come SAN durante la creazione del certificato del server. Connettersi quindi al broker usando tale nome host o IP anziché
localhost
. - Se il nome host o l'indirizzo IP non è già noto, è possibile usare un servizio segnaposto per determinare l'indirizzo IP esterno:
- Creare il servizio LoadBalancer su una porta non usata (ad esempio 8080):
kubectl create service loadbalancer placeholder-service --tcp=8080:8080
- Recuperare l'indirizzo IP esterno:
kubectl get svc placeholder-service
- Se l'indirizzo IP esterno:
- Mostra un valore simile
192.168.X.X
a : usare tale INDIRIZZO IP come SAN durante la creazione del certificato del server e del segreto. Connettersi quindi al broker usando tale INDIRIZZO IP anzichélocalhost
. - Mostra
<pending>
: la distribuzione di Kubernetes usata potrebbe non supportare l'assegnazione automatica di un indirizzo IP esterno. Per trovare l'indirizzo IP esterno, seguire la procedura descritta nella documentazione di Kubernetes per l'ambiente di distribuzione e host. Potrebbe anche essere necessario configurare il port forwarding o una VPN a seconda della configurazione di rete.
- Mostra un valore simile
- Dopo aver determinato l'indirizzo IP esterno, eliminare il servizio segnaposto:
kubectl delete svc placeholder-service
- Creare il servizio LoadBalancer su una porta non usata (ad esempio 8080):
Questo metodo garantisce che il certificato del server corrisponda all'indirizzo IP esterno, consentendo l'accesso sicuro al broker MQTT.
Preparare i certificati lato server e la catena completa
Creare prima di tutto una CA radice lato server. Questa CA è separata dalla CA radice lato client creata in un secondo momento. Per mantenere la separazione chiara, denominare tutto il lato server "Contoso". Per semplificare i passaggi successivi, si ignora la password per crittografare la chiave privata. Questa procedura è accettabile solo in un'impostazione di esercitazione.
step certificate create "Contoso Root CA" \
contoso_root_ca.crt contoso_root_ca.key \
--profile root-ca \
--no-password --insecure
Creare quindi una CA intermedia firmata da questa CA radice.
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
Infine, usare questa CA intermedia per firmare un certificato server per il front-end del broker MQTT. Di seguito è localhost
riportato il nome alternativo soggetto (SAN) usato per l'esercitazione.
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
Con il --bundle
flag , il certificato del server viene incluso nel certificato intermedio di firma. L'handshake TLS richiede che il bundle verifichi la catena completa.
Preparare i certificati lato client e la catena completa
Analogamente, creare la CA radice per Fabrikam e la CA intermedia.
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
Generare quindi i certificati client per un termostato, un hygrometer, un riscaldamento e una lampadina.
# 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
Configurare Kubernetes
Importare il certificato server appena generato e la chiave privata in un segreto Kubernetes. Questo segreto viene usato per configurare un listener TLS per il broker MQTT in un secondo momento.
kubectl create secret tls broker-server-cert -n azure-iot-operations \
--cert mqtts-endpoint.crt \
--key mqtts-endpoint.key
Creare anche una mappa di configurazione per contenere la CA radice Fabrikam (lato client). Questa mappa di configurazione è necessaria affinché il broker MQTT consideri attendibile per l'autenticazione X.509.
kubectl create configmap fabrikam-ca -n azure-iot-operations \
--from-file=client_ca.pem=fabrikam_root_ca.crt
Configurare il broker MQTT
I passaggi successivi configurano il broker MQTT con la crittografia TLS e l'autenticazione client X.509. L'esercitazione usa il portale di Azure per configurare il broker MQTT.
Autenticazione
Per consentire ai client di eseguire l'autenticazione usando certificati X.509 rilasciati dalla CA radice di Fabrikam, creare un criterio di autenticazione che consideri attendibile il certificato CA radice di Fabrikam ed esegue il mapping dei certificati client agli attributi di autorizzazione per il controllo degli accessi in base al ruolo.
Nella portale di Azure passare all'istanza di Operazioni IoT.
In Componenti selezionare MqTT Broker.
Seleziona la scheda Autenticazione.
Selezionare Crea criteri di autenticazione.
In Nome criterio immettere
x509-auth
.Aggiungere un nuovo metodo selezionando Aggiungi metodo.
Scegliere il tipo di metodo X.509 dall'elenco a discesa e quindi selezionare Aggiungi dettagli per configurare il metodo.
Nel riquadro dei dettagli dell'autenticazione X.509 specificare il nome
fabrikam-ca
ConfigMap del certificato CA attendibile Fabrikam e gli attributi.{ "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" } } } }
Selezionare Applica e quindi Aggiungi per salvare le modifiche.
Listener
Con i criteri di autenticazione applicati, creare un listener che usa i criteri di autenticazione X.509. Inoltre, poiché l'autenticazione X.509 richiede TLS, configurare il listener per l'uso del certificato del server Contoso e della chiave privata creata in precedenza.
Nella portale di Azure passare all'istanza di Operazioni IoT.
In Componenti selezionare MqTT Broker.
Selezionare il listener broker MQTT per LoadBalancer Create (Crea loadBalancer).> Immetti le impostazioni seguenti:
Impostazione Description Name Immetti mqtts-endpoint
.Nome servizio Nome del servizio Kubernetes. Lasciare vuoto per usare il nome mqtts-endpoint
del listener come nome del servizio.Tipo di servizio LoadBalancer già selezionato. In Porte immettere le impostazioni seguenti per la prima porta:
Impostazione Descrizione Porta Immettere 8883 Autenticazione Scegliere x509-auth Autorizzazione Scegliere Nessuna Protocollo Scegliere MQTT TLS Seleziona Aggiungi Nel riquadro configurazione TLS immettere le impostazioni seguenti:
Impostazione Descrizione Modalità TLS Scegliere Manuale Nome dell'autorità emittente Immetti broker-server-cert
Selezionare Applica e crea listener.
Dopo un minuto o due, viene creato il mqtts-endpoint
servizio LoadBalancer.
$ 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
Anziché usare l'indirizzo IP esterno, viene usato localhost
per l'esercitazione.
Suggerimento
La configurazione codespace configura automaticamente il port forwarding per 8883. Per configurare altri ambienti, vedere Usare il port forwarding.
Usare un singolo client Mosquito per pubblicare messaggi tramite TLS
Dalla stessa cartella dei file di certificato: contoso_root_ca.crt
, thermostat.crt
e thermostat.key
, usare il client Mosquito per pubblicare un messaggio. Il --cafile contoso_root_ca.crt
flag è che Mosquito esegua la verifica del certificato del server.
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 pubblicazione ha esito positivo perché Mosquito usa un certificato client radicato in fabrikam_root_ca.crt
. Il broker MQTT considera attendibile questo certificato perché i x509-auth
criteri di autenticazione creati in precedenza. Inoltre, il broker MQTT consente attualmente ai client autenticati di pubblicare in qualsiasi argomento.
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
Configurare l'autorizzazione per gli argomenti MQTT per più client che usano X.509
Per limitare l'accesso agli argomenti MQTT in base agli attributi del certificato client, creare un criterio di autorizzazione che esegue il mapping degli attributi del certificato client alle azioni consentite in argomenti specifici.
Nella portale di Azure passare all'istanza di Operazioni IoT.
In Componenti selezionare MqTT Broker.
Selezionare la scheda Autorizzazione.
Selezionare Crea criteri di autorizzazione.
In Nome criterio immettere
abac-authz
.In Regole immettere le regole seguenti:
[ { "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" ] } ] } ]
Selezionare Aggiungi per salvare le modifiche.
Aggiornare quindi il listener broker MQTT per usare i nuovi criteri di autorizzazione.
- Selezionare la scheda Listener .
- Selezionare il listener mqtts-endpoint .
- In Porte>8883>Autorizzazione scegliere abac-authz.
- Seleziona Salva.
Pubblicare messaggi in un argomento con restrizioni
In questa sezione vengono eseguiti i criteri di autorizzazione appena applicati.
Prima di tutto, connettersi e thermostat
provare a pubblicare nell'argomento 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
Poiché thermostat
fa parte di thermostat_group
, che non è autorizzato a pubblicare nell'argomento umidità, la pubblicazione ha esito negativo.
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.
Modificare per pubblicare in telemetry/temperature
, che è consentito e la pubblicazione ha esito positivo. Lasciare il comando in esecuzione.
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
Sottoscrivere messaggi su argomenti con restrizioni
In una sessione del terminale separata connettersi heater
a per sottoscrivere 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
Poiché heater
non è autorizzato a sottoscrivere l'argomento heartbeat, la sottoscrizione ha esito negativo. In questo caso, il codice 135 indica che non è autorizzato.
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
Passare all'argomento della sottoscrizione a telemetry/temperature
, a cui thermostat
vengono ancora inviati messaggi.
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
Ora heater
inizia a ricevere messaggi perché è autorizzato con il nome utente.
In un'altra sessione del terminale separata pubblicare messaggi in health/heartbeat
con 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 pubblicazione ha esito positivo perché lightbulb
dispone di un certificato intermedio con CN = Fabrikam Intermediate CA 1
, di cui viene eseguito il mapping all'attributo manufacturer=fabrikam
. I client con tale attributo possono pubblicare in health/heartbeat
. Quando il client inizia a inviare messaggi, heater
avviato in precedenza non riceve nulla.
Pulire le risorse
Per pulire le risorse create in questa esercitazione, eliminare il listener e i criteri di autenticazione e autorizzazione.
- Nella portale di Azure passare all'istanza di Operazioni IoT.
- In Componenti selezionare MqTT Broker.
- Selezionare la scheda Listener .
- Selezionare la casella di controllo accanto al listener mqtts-endpoint .
- Selezionare Elimina.
- Conferma l'eliminazione.
- Seleziona la scheda Autenticazione.
- Selezionare la casella di controllo accanto a x509-auth.
- Selezionare Elimina.
- Conferma l'eliminazione.
- Selezionare la scheda Autorizzazione.
- Selezionare la casella di controllo accanto a abac-authz.
- Selezionare Elimina.
- Conferma l'eliminazione.
Eliminare anche il segreto Kubernetes e la mappa di configurazione.
kubectl delete secret broker-server-cert -n azure-iot-operations
kubectl delete configmap fabrikam-ca -n azure-iot-operations
Eliminare infine i certificati e le chiavi generati in precedenza.
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