Compartilhar via


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

Diagrama mostrando a relação de confiança das raízes da autoridade de certificação do lado do cliente e do servidor.

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 usar localhost, confira a seção Opcional: Usar um nome de host real ou endereço IP em vez de localhost.
  • 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:
    1. 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
      
    2. Recuperar o IP externo:
      kubectl get svc placeholder-service
      
    3. 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 de localhost.
      • 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.
    4. Depois de determinar o IP externo, exclua o serviço de espaço reservado:
      kubectl delete svc placeholder-service
      

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.

  1. No portal do Azure, navegue até a instância de Operações de IoT.

  2. Em Componentes, selecione Agente MQTT.

  3. Selecione a guia Autenticação.

  4. Selecione Criar política de autenticação.

  5. Em Nome da política, insira x509-auth.

  6. Adicione um novo método selecionando Adicionar método.

  7. Escolha o tipo de método X.509 na lista suspensa e selecione Adicionar detalhes para configurar o método.

  8. No painel Detalhes da autenticação X.509, especifique o nome do ConfigMap do certificado de AC confiável da Fabrikamfabrikam-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"
          }
        }
      }
    }
    
  9. Selecione Aplicar e, em seguida, Adicionar para salvar as alterações.

Captura de tela mostrando como usar o portal do Azure para criar o método de autenticação X.509 do agente MQTT.

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.

  1. No portal do Azure, navegue até a instância de Operações de IoT.

  2. Em Componentes, selecione Agente MQTT.

  3. 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.
  4. 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
  5. 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
  6. Selecione Aplicar e Criar ouvinte.

Captura de tela mostrando o método do portal do Azure para definir um ouvinte com a porta TLS.

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.

  1. No portal do Azure, navegue até a instância de Operações de IoT.

  2. Em Componentes, selecione Agente MQTT.

  3. Selecione a guia Autorização.

  4. Selecione Criar política de autorização.

  5. Em Nome da política, insira abac-authz.

  6. 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"
            ]
          }
        ]
      }
    ]
    
  7. Selecione Adicionar para salvar as alterações.

Captura de tela mostrando o portal do Azure para configurar uma política de autorização.

Em seguida, atualize o ouvinte do agente MQTT para usar a nova política de autorização.

  1. Selecione a guia Ouvintes.
  2. Selecione o ouvinte do mqtts-endpoint.
  3. Em Portas>8883>Autorização, escolha abac-authz.
  4. Selecione Salvar.

Captura de tela mostrando o portal do Azure para vincular uma porta a uma política de autorização.

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.

  1. No portal do Azure, navegue até a instância de Operações de IoT.
  2. Em Componentes, selecione Agente MQTT.
  3. Selecione a guia Ouvintes.
  4. Marque a caixa de seleção ao lado do ouvinte mqtts-endpoint.
  5. Selecione Excluir.
  6. Confirme a exclusão.
  7. Selecione a guia Autenticação.
  8. Marque a caixa de seleção ao lado de x509-auth.
  9. Selecione Excluir.
  10. Confirme a exclusão.
  11. Selecione a guia Autorização.
  12. Marque a caixa de seleção ao lado de abac-authz.
  13. Selecione Excluir.
  14. 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