Tutorial: TLS, autenticação de cliente X.509 e autorização de controle de ABAC (acesso baseado em atributo) com o agente MQTT das Operações do Azure IoT
Este tutorial orientará você na configuração do agente MQTT das Operações do Azure IoT com criptografia TLS e autenticação de cliente X.509. Ele inclui instruções passo a passo e scripts para a criação de certificados para o agente e os clientes. O tutorial explica como configurar o agente MQTT com diferentes autoridades de AC (certificação raiz) para o cliente e o agente. Ele também aborda a configuração de uma política de autorização de controle de acesso baseado em atributo (ABAC) com base na cadeia de certificados do cliente. Por fim, o tutorial usa o cliente Mosquito para testar vários cenários e garantir que a configuração funcione corretamente.
O tutorial simula um ambiente em que as Operações de IoT do Azure são instaladas em uma fábrica da Contoso, com dispositivos fabricados pela Fabrikam. Para fazer o TLS e a autenticação de X.509 funcionarem:
- O agente MQTT das Operações IoT do Azure, instalado em uma fábrica da Contoso, deve confiar na AC raiz da Fabrikam
- Os sensores da Fabrikam, como os termostatos, devem confiar na CA raiz da Contoso
- Cada entidade deve ter seu próprio certificado folha emitido pela AC raiz correta
Pré-requisitos
Para seguir este tutorial, você precisa do seguinte:
- Um cluster do Kubernetes com encaminhamento de porta habilitado para a porta 8883.
- Operações de IoT do Azure implantadas sem um ouvinte de balanceador de carga existente.
- Acesso do Kubectl ao cluster para criar mapas de configuração e segredos do Kubernetes.
- Cliente Mosquitto para publicar e assinar mensagens MQTT em execução no mesmo computador que o cluster do Kubernetes para acesso
localhost
. Para não usarlocalhost
, confira a seção Opcional: Usar um nome de host real ou endereço IP em vez delocalhost
. - Etapa CLI para criar certificados.
Dica
Para atender a esses requisitos, use o codespace de início rápido. O codespace de início rápido simplifica o processo de instalação fornecendo esses componentes prontos para uso.
Além disso, é útil ter familiaridade com criptografia de chave pública e termos como AC raiz, chave privada e certificados intermediários.
Opcional: Usar um nome de host real ou endereço IP em vez de localhost
Para manter este tutorial simples, usamos localhost
para acessar o agente MQTT. Essa abordagem garante que o certificado do servidor do agente tenha um SAN (nome alternativo da entidade) que corresponda ao nome do host usado para acessar o agente. Usar localhost
simplificará a configuração, pois o SAN já está configurado corretamente.
Em um cenário real, você usaria o nome do host ou o IP externo do agente em vez de localhost
e se conectaria a ele de outro dispositivo na rede. Nesse caso, você precisará determinar o nome do host ou o endereço IP correto e usá-lo como SAN ao criar o certificado do servidor:
- Se o nome do host ou 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 agente 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
- Recuperar o IP externo:
kubectl get svc placeholder-service
- Se o IP externo:
- Mostra um valor como
192.168.X.X
— use esse IP como SAN ao criar o certificado e o segredo do servidor. Em seguida, conecte-se ao agente usando esse IP em vez delocalhost
. - Mostra
<pending>
— a distribuição do Kubernetes que você usa pode não dar suporte à 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. Talvez você também precise 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):
Esse método garante que o certificado do servidor corresponda ao endereço IP externo, permitindo acesso seguro ao agente MQTT.
Preparar certificados do lado do servidor e cadeia completa
Primeiro, crie uma AC raiz no lado do servidor. Essa AC é separada da AC raiz do lado do cliente que será criada posteriormente. Para manter a separação clara, nomeamos tudo no lado do servidor como "Contoso". Para facilitar as etapas posteriores, ignoramos a senha para criptografar a chave privada. Essa prática só é aceitável em um ambiente 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 AC intermediária assinada por essa AC 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 AC intermediária para assinar um certificado de servidor para o front-end do agente MQTT. Aqui, localhost
é o SAN (nome alternativo da entidade) 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 sinalizador --bundle
, o certificado do servidor é agrupado com o certificado intermediário de assinatura. O handshake do TLS requer o pacote para verificar a cadeia completa.
Preparar certificados do lado do cliente e cadeia completa
Da mesma forma, crie a AC raiz para Fabrikam e a AC 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 de servidor e a chave privada recém-gerados em um segredo do Kubernetes. Esse segredo é usado para configurar um ouvinte TLS para o agente MQTT posteriormente.
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 AC raiz da Fabrikam (lado do cliente). Esse mapa de configuração é necessário para que o agente MQTT confie nele para a autenticação X.509.
kubectl create configmap fabrikam-ca -n azure-iot-operations \
--from-file=client_ca.pem=fabrikam_root_ca.crt
Configurar o agente MQTT
As próximas etapas configuram o agente MQTT com criptografia TLS e autenticação de cliente X.509. O tutorial usa o portal do Azure para configurar o agente MQTT.
Autenticação
Para permitir que os clientes se autentiquem usando certificados X.509 emitidos pela AC raiz da Fabrikam, crie uma política de autenticação que confie no certificado de AC raiz da Fabrikam e mapeie os certificados do cliente para atributos de autorização para ABAC.
No portal do Azure, navegue até a instância de Operações de IoT.
Em Componentes, selecione Agente MQTT.
Selecione a guia Autenticação.
Selecione Criar política de autenticação.
Em Nome da política, insira
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 Detalhes da autenticação X.509, especifique o nome do ConfigMap do certificado de AC confiável da Fabrikam
fabrikam-ca
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.
Ouvinte
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 a chave privada e o certificado do servidor da Contoso criados anteriormente.
No portal do Azure, navegue até a instância de Operações de IoT.
Em Componentes, selecione Agente MQTT.
Selecione Ouvinte do agente MQTT para LoadBalancer>Criar. Digite as seguintes configurações:
Configuração Descrição Nome Digite mqtts-endpoint
.Nome do serviço Nome do serviço kubernetes. Deixe vazio para usar o nome do ouvinte mqtts-endpoint
como nome de serviço.Tipo de serviço LoadBalancer já selecionado. Em Portas, insira as seguintes configurações para a primeira porta:
Configuração Descrição Porta Insira 8883 Autenticação Escolher x509-auth Autorização Escolha Nenhuma Protocolo Escolha MQTT TLS Selecione Adicionar No painel de configuração do TLS, insira as seguintes configurações:
Configuração Descrição Modo TLS Escolher Manual Nome do emissor Inserir broker-server-cert
Selecione Aplicar e Criar ouvinte.
Após um ou dois minutos, o serviço LoadBalancer mqtts-endpoint
será 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, usaremos localhost
para o tutorial.
Dica
A configuração do codespace configurará automaticamente o encaminhamento de porta para 8883. Para configurar outros ambientes, confira Usar o encaminhamento de porta.
Usar um único cliente Mosquito para publicar mensagens no 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 sinalizador --cafile contoso_root_ca.crt
é para que o Mosquito execute 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 em fabrikam_root_ca.crt
. O agente MQTT confia nesse certificado devido à política de autenticação x509-auth
criada anteriormente. Além disso, o agente 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 a autorização para tópicos MQTT para vários clientes usando o X.509
Para restringir o acesso aos tópicos MQTT com base nos atributos do 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é a instância de Operações de IoT.
Em Componentes, selecione Agente MQTT.
Selecione a guia Autorização.
Selecione Criar política de autorização.
Em Nome da política, insira
abac-authz
.Em Regras, insira os seguintes valores:
[ { "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 salvar as alterações.
Em seguida, atualize o ouvinte do agente MQTT para usar a nova política de autorização.
- Selecione a guia Ouvintes.
- Selecione o ouvinte do mqtts-endpoint.
- Em Portas>8883>Autorização, escolha abac-authz.
- Selecione Salvar.
Publicar mensagens em um tópico restrito
Nesta seção, testaremos as políticas de autorização recém-aplicadas.
Primeiro, conecte-se a thermostat
e tente publicar no tópico 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
Como thermostat
faz parte do thermostat_group
, que não tem permissão para publicar no tópico de umidade, a publicação falhará.
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 em telemetry/temperature
, o que é permitido e a publicação será 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
Assinar mensagens em tópicos restritos
Em uma sessão de terminal separada, conecte-se a heater
para 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
Como heater
não está autorizado a assinar o tópico de pulsação, a assinatura falhará. 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
Alterne o tópico da assinatura para telemetry/temperature
, para o qual thermostat
ainda está enviando 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çará a receber mensagens porque ela está autorizada com seu nome de usuário.
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 será 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 em health/heartbeat
. Quando o cliente começar a enviar mensagens, heater
iniciado anteriormente não receberá nada.
Limpar os 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é a instância de Operações de IoT.
- Em Componentes, selecione Agente MQTT.
- Selecione a guia Ouvintes.
- Marque a caixa de seleção ao lado do ouvinte mqtts-endpoint.
- Selecione Excluir.
- Confirme a exclusão.
- Selecione a guia Autenticação.
- Marque a caixa de seleção ao lado de x509-auth.
- Selecione Excluir.
- Confirme a exclusão.
- Selecione a guia Autorização.
- Marque a caixa de seleção ao lado de abac-authz.
- Selecione Excluir.
- Confirme a exclusã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 as 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