Tutorial: TLS, autenticação de cliente X.509 e autorização de controle de acesso baseado em atributo (ABAC) com o agente MQTT do Azure IoT Operations
Este tutorial orienta você na configuração do agente MQTT do Azure IoT Operations com criptografia TLS e autenticação de cliente X.509. Ele inclui instruções passo a passo e scripts para criar certificados para o broker e clientes. O tutorial explica como configurar o broker MQTT com diferentes autoridades de certificação (CAs) raiz para o cliente e o broker. Ele também cobre a configuração de uma política de autorização de controle de acesso baseado em atributos (ABAC) com base na cadeia de certificados do cliente. Finalmente, o tutorial usa o cliente Mosquito para testar vários cenários para garantir que a configuração funcione corretamente.
O tutorial simula um ambiente em que o Azure IoT Operations está instalado em uma fábrica da Contoso, com dispositivos fabricados pela Fabrikam. Para fazer a autenticação TLS e X.509 funcionar:
- O agente MQTT do Azure IoT Operations, instalado em uma fábrica da Contoso, deve confiar na autoridade de certificação raiz da Fabrikam
- Os sensores da Fabrikam, como termostatos, devem confiar na autoridade de certificação raiz da Contoso
- Cada entidade deve ter seu próprio certificado de folha emitido pela autoridade de certificação raiz correta
Pré-requisitos
Para seguir este tutorial, você precisa:
- Um cluster Kubernetes com encaminhamento de porta habilitado para a porta 8883.
- Operações IoT do Azure implantadas sem um ouvinte de balanceador de carga existente.
- Acesso Kubectl ao cluster para criar segredos do Kubernetes e mapas de configuração.
- Cliente Mosquitto para publicar e assinar mensagens MQTT em execução na mesma máquina que o cluster Kubernetes para
localhost
acesso. Para não usarlocalhost
o , consulte Opcional: usar um nome de host ou endereço IP real em vez dalocalhost
seção. - Etapa CLI para criar certificados.
Gorjeta
Para atender a esses requisitos, use o espaço de código de início rápido. O espaço de código de início rápido simplifica o processo de configuração, fornecendo esses componentes prontos para uso.
Além disso, a familiaridade com criptografia de chave pública e termos como CA raiz, chave privada e certificados intermediários é útil.
Opcional: Use um nome de host ou endereço IP real em vez de localhost
Para manter este tutorial simples, usamos localhost
para acessar o broker MQTT. Essa abordagem garante que o certificado do servidor do broker tenha um SAN (Subject Alternative Name, nome alternativo da entidade) que corresponda ao nome do host usado para acessar o broker. O uso localhost
simplifica a configuração, uma vez que a SAN já está definida corretamente.
Em um cenário do mundo real, você usaria o nome do host ou IP externo do broker em vez de localhost
e se conectaria a ele a partir de outro dispositivo na rede. Nesse caso, você precisa determinar o nome de host ou endereço IP correto e usá-lo como SAN ao criar o certificado do servidor:
- Se o nome do host ou o endereço IP já for conhecido (por exemplo, por meio de um registro DNS ou IP estático), use-o como SAN ao criar o certificado do servidor. Em seguida, conecte-se ao broker usando esse nome de host ou IP em vez de
localhost
. - Se o nome do host ou endereço IP ainda não for conhecido, você poderá usar um serviço de espaço reservado para determinar o endereço IP externo:
- Crie o serviço LoadBalancer em uma porta que não está sendo usada (como 8080):
kubectl create service loadbalancer placeholder-service --tcp=8080:8080
- Recupere o IP externo:
kubectl get svc placeholder-service
- Se o IP externo:
- Mostra um valor como
192.168.X.X
- use esse IP como a SAN ao criar o certificado e o segredo do servidor. Em seguida, conecte-se ao broker usando esse IP em vez delocalhost
. - Shows
<pending>
- a distribuição Kubernetes que você usa pode não suportar a atribuição automática de um IP externo. Para localizar o IP externo, siga as etapas na documentação do Kubernetes para sua distribuição e ambiente de host. Também pode ser necessário configurar o encaminhamento de porta ou uma VPN, dependendo da configuração da rede.
- Mostra um valor como
- Depois de determinar o IP externo, exclua o serviço de espaço reservado:
kubectl delete svc placeholder-service
- Crie o serviço LoadBalancer em uma porta que não está sendo usada (como 8080):
Este método garante que o certificado do servidor corresponda ao endereço IP externo, permitindo acesso seguro ao broker MQTT.
Preparar certificados do lado do servidor e cadeia completa
Primeiro, crie uma autoridade de certificação raiz do lado do servidor. Esta autoridade de certificação é separada da autoridade de certificação raiz do lado do cliente que é criada posteriormente. Para manter a separação clara, nomeamos tudo o lado do servidor como "Contoso". Para facilitar os passos posteriores, ignoramos a palavra-passe para encriptar a chave privada. Essa prática só é aceitável em uma configuração de tutorial.
step certificate create "Contoso Root CA" \
contoso_root_ca.crt contoso_root_ca.key \
--profile root-ca \
--no-password --insecure
Em seguida, crie uma autoridade de certificação intermediária assinada por essa autoridade de certificação raiz.
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
Por fim, use essa CA intermediária para assinar um certificado de servidor para o frontend do broker MQTT. Aqui, localhost
está o nome alternativo da entidade (SAN) usado para o tutorial.
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
Com o --bundle
sinalizador, o certificado do servidor é empacotado com o certificado intermediário de assinatura. O handshake TLS requer que o pacote verifique a cadeia completa.
Preparar certificados do lado do cliente e cadeia completa
Da mesma forma, crie a autoridade de certificação raiz para a Fabrikam e a autoridade de certificação intermediária.
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
Em seguida, gere certificados de cliente para um termostato, higrômetro, aquecedor e lâmpada.
# 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
Configurar o Kubernetes
Importe o certificado do servidor recém-gerado e a chave privada para um segredo do Kubernetes. Esse segredo é usado para configurar um ouvinte TLS para o broker MQTT mais tarde.
kubectl create secret tls broker-server-cert -n azure-iot-operations \
--cert mqtts-endpoint.crt \
--key mqtts-endpoint.key
Além disso, crie um mapa de configuração para conter a CA raiz da Fabrikam (lado do cliente). Este mapa de configuração é necessário para que o broker MQTT confie nele para autenticação X.509.
kubectl create configmap fabrikam-ca -n azure-iot-operations \
--from-file=client_ca.pem=fabrikam_root_ca.crt
Configurar o broker MQTT
As próximas etapas configuram o broker MQTT com criptografia TLS e autenticação de cliente X.509. O tutorial usa o portal do Azure para configurar o broker MQTT.
Autenticação
Para permitir que os clientes se autentiquem usando certificados X.509 emitidos pela autoridade de certificação raiz da Fabrikam, crie uma política de autenticação que confie no certificado da autoridade de certificação raiz da Fabrikam e mapeie os certificados de cliente para atributos de autorização para ABAC.
No portal do Azure, navegue até sua instância de Operações IoT.
Em Componentes, selecione MQTT Broker.
Selecione a guia Autenticação .
Selecione Criar política de autenticação.
Em Nome da política, digite
x509-auth
.Adicione um novo método selecionando Adicionar método.
Escolha o tipo de método X.509 na lista suspensa e selecione Adicionar detalhes para configurar o método.
No painel de detalhes de autenticação X.509, especifique o nome
fabrikam-ca
ConfigMap do certificado de CA confiável da Fabrikam e os atributos.{ "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" } } } }
Selecione Aplicar e, em seguida, Adicionar para salvar as alterações.
Serviço de Escuta
Com a política de autenticação em vigor, crie um ouvinte que use a política de autenticação X.509. Além disso, como a autenticação X.509 requer TLS, configure o ouvinte para usar o certificado do servidor Contoso e a chave privada criados anteriormente.
No portal do Azure, navegue até sua instância de Operações IoT.
Em Componentes, selecione MQTT Broker.
Selecione o ouvinte do broker MQTT para LoadBalancer>Create. Introduza as seguintes definições:
Definição Description Name Introduzir mqtts-endpoint
.Nome do serviço Nome do serviço Kubernetes. Deixe em branco para usar o nome mqtts-endpoint
do ouvinte como nome do serviço.Tipo de serviço LoadBalancer já selecionado. Em Portas, insira as seguintes configurações para a primeira porta:
Definição Descrição Porta Digite 8883 Autenticação Escolha x509-auth Autorização Selecione Nenhum Protocolo Escolha MQTT TLS Selecione Adicionar No painel de configuração TLS, insira as seguintes configurações:
Definição Descrição Modo TLS Escolha Manual Nome do emissor Introduzir broker-server-cert
Selecione Aplicar e Criar ouvinte.
Após um ou dois minutos, o mqtts-endpoint
serviço LoadBalancer é criado.
$ 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
Em vez de usar o IP externo, usamos localhost
para o tutorial.
Gorjeta
A configuração do codespace configura automaticamente o encaminhamento de porta para 8883. Para configurar outros ambientes, consulte Usar encaminhamento de portas.
Use um único cliente Mosquito para publicar mensagens por TLS
Na mesma pasta que os arquivos de certificado: contoso_root_ca.crt
, thermostat.crt
e thermostat.key
, use o cliente Mosquito para publicar uma mensagem. O --cafile contoso_root_ca.crt
sinalizador é para o Mosquito executar a verificação do certificado do servidor.
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
A publicação é bem-sucedida porque o Mosquito usa um certificado de cliente que está enraizado no fabrikam_root_ca.crt
. O broker MQTT confia neste certificado porque a x509-auth
política de autenticação foi criada anteriormente. Além disso, o broker MQTT atualmente permite que clientes autenticados publiquem em qualquer tópico.
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
Configurar autorização para tópicos MQTT para vários clientes usando X.509
Para restringir o acesso a tópicos MQTT com base nos atributos de certificado do cliente, crie uma política de autorização que mapeie os atributos do certificado do cliente para ações permitidas em tópicos específicos.
No portal do Azure, navegue até sua instância de Operações IoT.
Em Componentes, selecione MQTT Broker.
Selecione a guia Autorização .
Selecione Criar política de autorização.
Em Nome da política, digite
abac-authz
.Em Regras, insira as seguintes regras:
[ { "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" ] } ] } ]
Selecione Adicionar para guardar as alterações.
Em seguida, atualize o ouvinte do broker MQTT para usar a nova política de autorização.
- Selecione a guia Ouvintes .
- Selecione o ouvinte mqtts-endpoint .
- Em Autorização de portas>8883>, escolha abac-authz.
- Selecione Guardar.
Publicar mensagens em um tópico restrito
Nesta seção, testamos as políticas de autorização recém-aplicadas.
Primeiro, conecte-se e thermostat
tente publicar sobre o tema 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
Uma vez thermostat
que faz parte do thermostat_group
, que não tem permissão para publicar para o tópico de umidade, a publicação falha.
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.
Altere para publicar para telemetry/temperature
, o que é permitido e a publicação é bem-sucedida. Deixe o comando em execução.
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
Subscrever mensagens sobre temas restritos
Em uma sessão de terminal separada, conecte-se para heater
assinar o 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
Uma vez que heater
não está autorizada a subscrever o tópico de pulsação, a subscrição falha. Aqui, o código 135 significa não autorizado.
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
Mude o tópico de subscrição para telemetry/temperature
, para o qual thermostat
ainda está a enviar mensagens.
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
Agora heater
começa a receber mensagens porque está autorizado com o seu nome de utilizador.
Em outra sessão de terminal separada, publique mensagens em health/heartbeat
com 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
A publicação é bem-sucedida porque lightbulb
tem um certificado intermediário com CN = Fabrikam Intermediate CA 1
, que é mapeado para o atributo manufacturer=fabrikam
. Os clientes com esse atributo podem publicar no health/heartbeat
. Quando o cliente começa a enviar mensagens, heater
iniciado mais cedo não recebe nada.
Clean up resources (Limpar recursos)
Para limpar os recursos criados neste tutorial, exclua o ouvinte e as políticas de autenticação e autorização.
- No portal do Azure, navegue até sua instância de Operações IoT.
- Em Componentes, selecione MQTT Broker.
- Selecione a guia Ouvintes .
- Marque a caixa de seleção ao lado de mqtts-endpoint listener.
- Selecione Eliminar.
- Confirme a eliminação.
- Selecione a guia Autenticação .
- Marque a caixa de seleção ao lado de x509-auth.
- Selecione Eliminar.
- Confirme a eliminação.
- Selecione a guia Autorização .
- Marque a caixa de seleção ao lado de abac-authz.
- Selecione Eliminar.
- Confirme a eliminação.
Além disso, exclua o segredo do Kubernetes e o mapa de configuração.
kubectl delete secret broker-server-cert -n azure-iot-operations
kubectl delete configmap fabrikam-ca -n azure-iot-operations
Por fim, exclua os certificados e chaves gerados anteriormente.
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