Condividi tramite


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

Diagramma che mostra la relazione di trust delle radici dell'autorità di certificazione lato client e del server.

Prerequisiti

Per eseguire questa esercitazione, è necessario quanto segue:

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:
    1. Creare il servizio LoadBalancer su una porta non usata (ad esempio 8080):
      kubectl create service loadbalancer placeholder-service --tcp=8080:8080
      
    2. Recuperare l'indirizzo IP esterno:
      kubectl get svc placeholder-service
      
    3. 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.
    4. Dopo aver determinato l'indirizzo IP esterno, eliminare il servizio segnaposto:
      kubectl delete svc placeholder-service
      

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.

  1. Nella portale di Azure passare all'istanza di Operazioni IoT.

  2. In Componenti selezionare MqTT Broker.

  3. Seleziona la scheda Autenticazione.

  4. Selezionare Crea criteri di autenticazione.

  5. In Nome criterio immettere x509-auth.

  6. Aggiungere un nuovo metodo selezionando Aggiungi metodo.

  7. Scegliere il tipo di metodo X.509 dall'elenco a discesa e quindi selezionare Aggiungi dettagli per configurare il metodo.

  8. 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"
          }
        }
      }
    }
    
  9. Selezionare Applica e quindi Aggiungi per salvare le modifiche.

Screenshot che mostra come usare portale di Azure per creare il metodo di autenticazione X.509 del broker MQTT.

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.

  1. Nella portale di Azure passare all'istanza di Operazioni IoT.

  2. In Componenti selezionare MqTT Broker.

  3. 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.
  4. 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
  5. Nel riquadro configurazione TLS immettere le impostazioni seguenti:

    Impostazione Descrizione
    Modalità TLS Scegliere Manuale
    Nome dell'autorità emittente Immetti broker-server-cert
  6. Selezionare Applica e crea listener.

Screenshot che mostra portale di Azure metodo per impostare un listener con la porta TLS.

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.crte 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.

  1. Nella portale di Azure passare all'istanza di Operazioni IoT.

  2. In Componenti selezionare MqTT Broker.

  3. Selezionare la scheda Autorizzazione.

  4. Selezionare Crea criteri di autorizzazione.

  5. In Nome criterio immettere abac-authz.

  6. 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"
            ]
          }
        ]
      }
    ]
    
  7. Selezionare Aggiungi per salvare le modifiche.

Screenshot che mostra portale di Azure per la configurazione di un criterio di autorizzazione.

Aggiornare quindi il listener broker MQTT per usare i nuovi criteri di autorizzazione.

  1. Selezionare la scheda Listener .
  2. Selezionare il listener mqtts-endpoint .
  3. In Porte>8883>Autorizzazione scegliere abac-authz.
  4. Seleziona Salva.

Screenshot che mostra portale di Azure per il collegamento di una porta a un criterio di autorizzazione.

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.

  1. Nella portale di Azure passare all'istanza di Operazioni IoT.
  2. In Componenti selezionare MqTT Broker.
  3. Selezionare la scheda Listener .
  4. Selezionare la casella di controllo accanto al listener mqtts-endpoint .
  5. Selezionare Elimina.
  6. Conferma l'eliminazione.
  7. Seleziona la scheda Autenticazione.
  8. Selezionare la casella di controllo accanto a x509-auth.
  9. Selezionare Elimina.
  10. Conferma l'eliminazione.
  11. Selezionare la scheda Autorizzazione.
  12. Selezionare la casella di controllo accanto a abac-authz.
  13. Selezionare Elimina.
  14. 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