Condividi tramite


Configurare TLS con la gestione manuale dei certificati per proteggere le comunicazioni MQTT nell'anteprima mq di Azure IoT

Importante

Anteprima delle operazioni di Azure IoT: abilitata da Azure Arc è attualmente disponibile in ANTEPRIMA. Non è consigliabile usare questo software di anteprima negli ambienti di produzione.

Vedere le condizioni per l'utilizzo supplementari per le anteprime di Microsoft Azure per termini legali aggiuntivi che si applicano a funzionalità di Azure in versione beta, in anteprima o in altro modo non ancora disponibili a livello generale.

È possibile configurare TLS per proteggere la comunicazione MQTT tra il broker MQTT e il client usando una risorsa BrokerListener. È possibile configurare TLS con la gestione manuale o automatica dei certificati.

Per configurare manualmente l'anteprima mq di Azure IoT per l'uso di un certificato TLS specifico, specificarlo in una risorsa BrokerListener con un riferimento a un segreto Kubernetes. Quindi distribuirlo usando kubectl. Questo articolo illustra un esempio per configurare TLS con certificati autofirmato per il test.

Creare un'autorità di certificazione con l'interfaccia della riga di comando passaggio

Il passaggio è un gestore certificati che consente di iniziare rapidamente a funzionare durante la creazione e la gestione della propria CA privata.

  1. Installare l'interfaccia della riga di comando del passaggio e creare un certificato e una chiave dell'autorità di certificazione radice.

    step certificate create --profile root-ca "Example Root CA" root_ca.crt root_ca.key
    
  2. Creare un certificato ca intermedio e una chiave firmati dalla CA radice.

    step certificate create --profile intermediate-ca "Example Intermediate CA" intermediate_ca.crt intermediate_ca.key \
    --ca root_ca.crt --ca-key root_ca.key
    

Creare un certificato server

Usare l'interfaccia della riga di comando del passaggio per creare un certificato server dall'autorità di certificazione intermedia firmata.

step certificate create mqtts-endpoint mqtts-endpoint.crt mqtts-endpoint.key \
--profile leaf \
--not-after 8760h \
--san mqtts-endpoint \
--san localhost \
--ca intermediate_ca.crt --ca-key intermediate_ca.key \
--no-password --insecure

mqtts-endpoint In questo caso, e localhost sono i nomi alternativi del soggetto (SAN) per il front-end broker di Azure IoT MQ rispettivamente in Kubernetes e nei client locali. Per connettersi tramite Internet, aggiungere un oggetto --san con un indirizzo IP esterno. I --no-password --insecure flag vengono usati per il test per ignorare le richieste di password e disabilitare la protezione password per la chiave privata perché è archiviata in un segreto Kubernetes. Per l'ambiente di produzione, usare una password e archiviare la chiave privata in una posizione sicura, ad esempio Azure Key Vault.

Requisiti dell'algoritmo di chiave del certificato

Sono supportate sia le chiavi EC che RSA, ma tutti i certificati nella catena devono usare lo stesso algoritmo di chiave. Se si importano certificati CA personalizzati, assicurarsi che il certificato del server usi lo stesso algoritmo di chiave delle ca.

Importare la catena di certificati server come segreto Kubernetes

  1. Creare una catena di certificati server completa, in cui l'ordine dei certificati è importante: il certificato del server è il primo nel file, il secondo è il secondo.

    cat  mqtts-endpoint.crt intermediate_ca.crt  > server_chain.pem
    
  2. Creare un segreto Kubernetes con la catena di certificati del server e la chiave del server usando kubectl.

    kubectl create secret tls server-cert-secret -n azure-iot-operations \
    --cert server_chain.crt \
    --key mqtts-endpoint.key
    

Abilitare TLS per un listener

Modificare l'impostazione tls in una risorsa BrokerListener per specificare la configurazione TLS manuale che fa riferimento al segreto Kubernetes. Prendere nota del nome del segreto usato per il certificato del server TLS (server-cert-secret nell'esempio precedente).

apiVersion: mq.iotoperations.azure.com/v1beta1
kind: BrokerListener
metadata:
  name: manual-tls-listener
  namespace: azure-iot-operations
spec:
  brokerRef: broker
  authenticationEnabled: false # If true, BrokerAuthentication must be configured
  authorizationEnabled: false
  serviceType: loadBalancer # Optional, defaults to clusterIP
  serviceName: mqtts-endpoint # Match the SAN in the server certificate
  port: 8885 # Avoid port conflict with default listener at 8883
  tls:
    manual:
      secretName: server-cert-secret

Dopo aver creato la risorsa BrokerListener, l'operatore crea automaticamente un servizio Kubernetes e distribuisce il listener. È possibile controllare lo stato del servizio eseguendo kubectl get svc.

Connessione al broker con TLS

Per testare la connessione TLS con il client mosquitto, pubblicare un messaggio e passare il certificato CA radice nel parametro --cafile.

$ mosquitto_pub -d -h localhost -p 8885 -i "my-client" -t "test-topic" -m "Hello" --cafile root_ca.crt
Client my-client sending CONNECT
Client my-client received CONNACK (0)
Client my-client sending PUBLISH (d0, q0, r0, m1, 'test-topic', ... (5 bytes))
Client my-client sending DISCONNECT

Suggerimento

Per usare localhost, la porta deve essere disponibile nel computer host. Ad esempio: kubectl port-forward svc/mqtts-endpoint 8885:8885 -n azure-iot-operations. Con alcune distribuzioni kubernetes come K3d, è possibile aggiungere una porta inoltrata con k3d cluster edit $CLUSTER_NAME --port-add 8885:8885@loadbalancer.

Nota

Per connettersi al broker è necessario distribuire la radice di attendibilità ai client, nota anche come bundle di attendibilità. In questo caso, la radice dell'attendibilità è l'interfaccia della riga di comando del passaggio creata dall'autorità di certificazione radice autofirmato. Per verificare la catena di certificati server, è necessaria la distribuzione della radice di attendibilità. Se i client MQTT sono carichi di lavoro nel cluster Kubernetes, è necessario creare anche un oggetto ConfigMap con la CA radice e montarlo nel pod.

Ricordarsi di specificare nome utente, password e così via se l'autenticazione MQ è abilitata.

Usare l'indirizzo IP esterno per il certificato del server

Per connettersi con TLS tramite Internet, il certificato server di Azure IoT MQ deve avere il nome host esterno come SAN. Nell'ambiente di produzione, si tratta in genere di un nome DNS o di un indirizzo IP noto. Tuttavia, durante lo sviluppo/test, è possibile che non si conosca il nome host o l'indirizzo IP esterno assegnato prima della distribuzione. Per risolvere questo problema, distribuire prima il listener senza il certificato del server, quindi creare il certificato del server e il segreto con l'INDIRIZZO IP esterno e infine importare il segreto nel listener.

Se si tenta di distribuire il listener manual-tls-listener TLS di esempio ma il segreto server-cert-secret Kubernetes a cui si fa riferimento non esiste, il servizio associato viene creato, ma i pod non vengono avviati. Il servizio viene creato perché l'operatore deve riservare l'indirizzo IP esterno per il listener.

$ kubectl get svc mqtts-endpoint -n azure-iot-operations
NAME                   TYPE           CLUSTER-IP      EXTERNAL-IP   PORT(S)             AGE
mqtts-endpoint         LoadBalancer   10.43.93.6      172.18.0.2    8885:30674/TCP      1m15s

Tuttavia, questo comportamento è previsto ed è possibile lasciarlo così mentre si importa il certificato del server. I log di Health Manager indicano che Azure IoT MQ è in attesa del certificato del server.

$ kubectl logs -l app=health-manager -n azure-iot-operations
...
<6>2023-11-06T21:36:13.634Z [INFO] [1] - Server certificate server-cert-secret not found. Awaiting creation of secret.

Nota

In genere, in un sistema distribuito, i log dei pod non sono deterministici e devono essere usati con cautela. Il modo giusto per visualizzare informazioni come questa è tramite gli eventi Kubernetes e lo stato delle risorse personalizzate, che si trova nel backlog. Considerare il passaggio precedente come soluzione alternativa temporanea.

Anche se i pod front-end non sono aggiornati, l'indirizzo IP esterno è già disponibile.

$ kubectl get svc mqtts-endpoint -n azure-iot-operations
NAME                   TYPE           CLUSTER-IP      EXTERNAL-IP   PORT(S)             AGE
mqtts-endpoint         LoadBalancer   10.43.93.6      172.18.0.2    8885:30674/TCP      1m15s

Da qui seguire la stessa procedura descritta in precedenza per creare un certificato server con questo indirizzo IP esterno in --san e creare il segreto Kubernetes nello stesso modo. Dopo aver creato il segreto, viene importato automaticamente nel listener.