Configurar a autenticação do Agente MQTT

Importante

A Versão Prévia das Operações da Internet das Coisas do Azure – habilitadas pelo Azure Arc – está atualmente em versão prévia. Você não deve usar esse software em versão prévia em ambientes de produção.

Você precisará implantar uma nova instalação das Operações da Internet das Coisas do Azure quando uma versão em disponibilidade geral for disponibilizada. Você não poderá atualizar uma instalação de versão prévia.

Veja os Termos de Uso Complementares para Versões Prévias do Microsoft Azure para obter termos legais que se aplicam aos recursos do Azure que estão em versão beta, versão prévia ou que, de outra forma, ainda não foram lançados em disponibilidade geral.

O Agente MQTT dá suporte a vários métodos de autenticação para clientes e você pode configurar cada ouvinte para ter seu próprio sistema de autenticação com os recursos BrokerAuthentication. Para uma lista das configurações disponíveis, confira a Referência da API de Autenticação do Broker.

As seguintes regras se aplicam ao relacionamento entre BrokerListener e BrokerAuthentication:

  • Cada BrokerListener pode ter várias portas. Cada porta pode ser vinculada a um recurso BrokerAuthentication.
  • Cada BrokerAuthentication pode dar suporte a vários métodos de autenticação ao mesmo tempo.

Para vincular um BrokerListener a um recurso BrokerAuthentication, especifique o campo authenticationRef na configuração ports do recurso BrokerListener. Para saber mais, confira Recurso BrokerListener.

Recurso do BrokerAuthentication padrão

A Visualização de Operações do Azure IoT implanta um recurso BrokerAuthentication padrão chamado authn vinculado ao ouvinte padrão chamado listener no azure-iot-operationsnamespace. O recurso é configurado para usar apenas Tokens de Conta de Serviço do Kubernetes (SATs) para a autenticação. Para inspecioná-lo, execute:

kubectl get brokerauthentication authn -n azure-iot-operations -o yaml

A saída mostra o recurso BrokerAuthentication padrão, com metadados removidos para brevidade:

apiVersion: mqttbroker.iotoperations.azure.com/v1beta1
kind: BrokerAuthentication
metadata:
  name: authn
  namespace: azure-iot-operations
spec:
  authenticationMethods:
    - method: ServiceAccountToken
      serviceAccountTokenSettings:
        audiences:
          - aio-internal

Importante

O método de autenticação de token de conta de serviço (SAT) no recurso BrokerAuthentication padrão é obrigatório para que os componentes das Operações do Azure IoT funcionem corretamente. Evite atualizar ou excluir o recurso BrokerAuthentication padrão. Se precisar fazer alterações, modifique o campo authenticationMethods nesse recurso mantendo o método de autenticação SAT com o público-alvo aio-internal. Preferencialmente, você pode criar um recurso BrokerAuthentication com um nome diferente e implantá-lo usando kubectl apply.

Para alterar a configuração, modifique a configuração authenticationMethods nesse recurso BrokerAuthentication ou crie um recurso BrokerAuthentication com um nome diferente. Em seguida, implante-o usando kubectl apply.

Fluxo de autenticação

A ordem dos métodos de autenticação na matriz determina como o Agente MQTT autentica os clientes. O Agente MQTT tenta autenticar as credenciais do cliente usando o primeiro método especificado e itera pela matriz até encontrar uma correspondência ou chegar ao final.

Para cada método, o Agente MQTT verifica primeiro se as credenciais do cliente são relevantes para esse método. Por exemplo, a autenticação SAT requer um nome de usuário que comece com K8S-SAT e a autenticação X.509 requer um certificado de cliente. Se as credenciais do cliente forem relevantes, o Agente MQTT verificará se elas são válidas. Para obter mais informações, confira a seção Configurar método de autenticação.

Para autenticação personalizada, o Agente MQTT trata a falha de comunicação com o servidor de autenticação personalizada como credenciais não relevantes. Esse comportamento permite que o Agente MQTT recorra a outros métodos se o servidor personalizado estiver inacessível.

O fluxo de autenticação termina quando:

  • Uma dessas condições é verdadeira:
    • As credenciais do cliente são relevantes e válidas para um dos métodos.
    • As credenciais do cliente não são relevantes para nenhum dos métodos.
    • As credenciais do cliente são relevantes, mas inválidas para qualquer um dos métodos.
  • O Agente MQTT concede ou nega acesso ao cliente com base no resultado do fluxo de autenticação.

Com vários métodos de autenticação, o Agente MQTT tem um mecanismo de fallback. Por exemplo:

apiVersion: mqttbroker.iotoperations.azure.com/v1beta1
kind: BrokerAuthentication
metadata: 
  name: authn
  namespace: azure-iot-operations
spec:
  authenticationMethods:
    - method: Custom
      customSettings:
        # ...
    - method: ServiceAccountToken
      serviceAccountTokenSettings:
        # ...
    - method: X509
      x509Settings:
        # ...

O exemplo anterior especifica autenticação personalizada e SAT. Quando um cliente se conecta, o Agente MQTT tenta autenticar o cliente usando os métodos especificados na ordem personalizado e depois SAT.

  1. O Agente MQTT verifica se as credenciais do cliente são válidas para a autenticação personalizada. Como a autenticação personalizada depende de um servidor externo para determinar a validade das credenciais, o agente considera todas as credenciais relevantes para a autenticação personalizada e as encaminha para o servidor de autenticação personalizado.

  2. Se o servidor de autenticação personalizado responder com um resultado Pass ou Fail, o fluxo de autenticação irá terminar. No entanto, se o servidor de autenticação personalizada não estiver disponível, o Agente MQTT voltará para os métodos especificados restantes, com o SAT sendo o próximo.

  3. O Agente MQTT tenta autenticar as credenciais como credenciais SAT. Se o nome de usuário MQTT começar com K8S-SAT, o Agente MQTT avaliará a senha MQTT como um SAT.

Se o servidor de autenticação personalizado não estiver disponível e todos os métodos subsequentes determinarem que as credenciais fornecidas não são relevantes, o agente negará a conexão ao cliente.

Desabilitar a autenticação

Para testar, você pode desabilitar a autenticação omitindo authenticationRef na configuração ports de um recurso BrokerListener.

Configurar o método de autenticação

Para saber mais sobre cada uma das opções de autenticação, confira as próximas seções para cada método.

Para mais informações sobre como habilitar configurações seguras configurando um Azure Key Vault e habilitando identidades de carga de trabalho, confira Habilitar configurações seguras na implantação de visualização das Operações do Azure IoT.

X.509

Um certificado confiável de AC raiz do cliente é necessário para validar o certificado do cliente. Os certificados do cliente devem estar enraizados nessa AC para que o Agente MQTT os autentique. Tanto as chaves EC quanto RSA tem suporte, mas todos os certificados na precisam devem usar o mesmo algoritmo de chave. Se estiver importando seus próprios certificados de AC, certifique-se de que o certificado do cliente usa o mesmo algoritmo de chave que as CAs. Para importar um certificado raiz que pode ser usado para validar certificados de cliente, importe o PEM do certificado como ConfigMap sob a chave client_ca.pem. Por exemplo:

kubectl create configmap client-ca --from-file=client_ca.pem -n azure-iot-operations

Para verificar se o certificado de AC raiz foi importado corretamente, execute kubectl describe configmap. O resultado mostra a mesma codificação base64 do arquivo do certificado PEM.

kubectl describe configmap client-ca -n azure-iot-operations
Name:         client-ca
Namespace:    azure-iot-operations

Data
====
client_ca.pem:
----
-----BEGIN CERTIFICATE-----
<Certificate>
-----END CERTIFICATE-----


BinaryData
====

Uma vez que o certificado da autoridade de certificação raiz do cliente confiável e o mapeamento de certificado para atributo forem importados, habilite a autenticação do cliente X.509 adicionando-a como um dos métodos de autenticação como parte de um recurso BrokerAuthentication vinculado a um ouvinte habilitado para TLS. Por exemplo:

spec:
  authenticationMethods:
    - method: X509
      x509Settings:
        trustedClientCaCert: client-ca
        authorizationAttributes:
        # ...

Atributos de certificado para autorização

Atributos X.509 podem ser especificados no recurso BrokerAuthentication e são usados para autorizar clientes com base nas propriedades de seus certificados. Os atributos são definidos no campo authorizationAttributes. Por exemplo:

spec:
  authenticationMethods:
    - method: X509
      x509Settings:
        authorizationAttributes:
          root:
            subject = "CN = Contoso Root CA Cert, OU = Engineering, C = US"
            attributes:
              organization = contoso
          intermediate:
            subject = "CN = Contoso Intermediate CA"
            attributes:
              city = seattle
              foo = bar
          smart-fan:
            subject = "CN = smart-fan"
            attributes:
              building = 17

Neste exemplo, cada cliente que tem um certificado emitido pela AC raiz CN = Contoso Root CA Cert, OU = Engineering, C = US ou uma AC intermediária CN = Contoso Intermediate CA recebe os atributos listados. Além disso, o ventilador inteligente recebe atributos específicos a ele.

A correspondência de atributos sempre começa no certificado do cliente folha e, em seguida, vai ao longo da cadeia. A atribuição de atributo é interrompida após a primeira correspondência. No exemplo anterior, mesmo que smart-fan tenha o certificado intermediário CN = Contoso Intermediate CA, ele não obtém os atributos associados.

As regras de autorização podem ser aplicadas a clientes que usam certificados X.509 com esses atributos. Para saber mais, confira Autorizar clientes que usam a autenticação X.509.

Conectar o cliente mosquitto ao Agente MQTT com certificado de cliente X.509

Um cliente como o mosquitto precisa de três arquivos para poder se conectar ao Agente MQTT com TLS e autenticação de cliente X.509. Por exemplo:

mosquitto_pub -q 1 -t hello -d -V mqttv5 -m world -i thermostat \
-h "<IOT_MQ_EXTERNAL_IP>" \
--cert thermostat_cert.pem \
--key thermostat_key.pem \
--cafile chain.pem

No exemplo:

  • O parâmetro --cert especifica o arquivo PEM do certificado do cliente.
  • O parâmetro --key especifica o arquivo PEM da chave privada do cliente.
  • O terceiro parâmetro --cafile é o mais complexo, um banco de dados de certificado confiável, usado para duas finalidades:
    • Quando o cliente mosquitto se conecta ao Agente MQTT por TLS, ele valida o certificado do servidor. Também pesquisa certificados raiz no banco de dados para criar uma cadeia confiável para o certificado do servidor. Por essa razão, o certificado raiz do servidor precisa ser copiado para esse arquivo.
    • Quando o Agente MQTT solicita um certificado de cliente do cliente mosquitto, ele também exige uma cadeia de certificados válida para enviar ao servidor. O parâmetro --cert informa ao Mosquitto qual certificado enviar, mas não é suficiente. O Agente MQTT não pode verificar esse certificado sozinho porque também precisa do certificado intermediário. O Mosquitto usa o arquivo de banco de dados para criar a cadeia de certificados necessária. Para dar suporte a isso, o cafile precisa conter tanto os certificados intermediários quanto raiz.

Entenda o fluxo de autenticação de cliente X.509 do Agente MQTT

Diagrama do fluxo de autenticação do cliente X.509.

Essas são as etapas para o fluxo de autenticação do cliente:

  1. Quando a autenticação de cliente X.509 está habilitada, os clientes conectados devem apresentar seu certificado de cliente e quaisquer certificados intermediários para permitir que o Agente MQTT crie uma cadeia de certificados com raiz em um de seus certificados confiáveis configurados.
  2. O balanceador de carga direciona a comunicação para um dos agentes de front-end.
  3. Após ter recebido o certificado do cliente, o agente de front-end tenta criar uma cadeia de certificado com raiz em um dos certificados configurados. O certificado é necessário para um handshake TLS. Se tiver criado uma cadeia com sucesso e a cadeia apresentada for verificada, o agente de front-end irá concluir o handshake TLS. O cliente que está se conectando é capaz de enviar pacotes de MQTT para o front-end por meio do canal TLS criado.
  4. O canal TLS está aberto, mas a autenticação ou autorização do cliente ainda não foi concluída.
  5. Em seguida, o cliente envia um pacote CONNECT para o Agente MQTT.
  6. O pacote CONNECT é roteado novamente para um front-end.
  7. O front-end coleta todas as credenciais apresentadas pelo cliente até o momento, como campos de nome de usuário e senha, dados de autenticação do pacote CONNECT e a cadeia de certificados do cliente apresentada durante o handshake TLS.
  8. O front-end envia essas credenciais para o serviço de autenticação. O serviço de autenticação verifica mais uma vez a cadeia de certificados e coleta os nomes de entidade de todos os certificados na cadeia.
  9. O serviço de autenticação usa suas regras de autorização configuradas para determinar os atributos que os clientes de conexão têm. Esses atributos determinam quais operações o cliente pode executar, incluindo o próprio pacote CONNECT.
  10. O serviço de autenticação retorna a decisão para o agente de front-end.
  11. O agente de front-end sabe quais são os atributos do cliente e se ele tem permissão para se conectar. Nesse caso, a conexão do MQTT será concluída e o cliente poderá continuar enviando e recebendo os pacotes de MQTT determinados por suas regras de autorização.

Tokens da Conta de Serviço do Kubernetes

Os Tokens da Conta de Serviço do Kubernetes (SATs) são Tokens Web JSON associados a Contas de Serviço do Kubernetes. Os clientes apresentam SATs ao Agente MQTT para se autenticarem.

O Agente MQTT usa tokens de conta de serviço associados que são detalhados na postagem O que os usuários do GKE precisam saber sobre os novos tokens de conta de serviço do Kubernetes. Aqui estão os recursos que mais se destacam na postagem:

Lançados no Kubernetes 1.13 e tendo se tornado o formato padrão no 1.21, os tokens vinculados abordam toda a funcionalidade limitada de tokens herdados e muito mais:

  • Os tokens em si são mais difíceis de roubar e usar indevidamente; são limitados por tempo, limitados por público e limitados por objeto.
  • Além disso, adotam um formato padronizado: OpenID Connect (OIDC), com Descoberta de OIDC completa, facilitando a aceitação dos provedores de serviços.
  • São distribuídos para os pods com mais segurança, usando um novo tipo de volume projetado do Kubelet.

O agente verifica os tokens usando a API de Revisão de Tokens do Kubernetes. Habilite o recurso TokenRequestProjection do Kubernetes para especificar audiences (padrão desde o 1.21). Se esse recurso não estiver habilitado, os SATs não poderão ser usados.

Criar uma conta de serviço

Para criar SATs, crie primeiro uma conta de serviço. O comando a seguir cria uma conta de serviço chamada mqtt-client.

kubectl create serviceaccount mqtt-client -n azure-iot-operations

Adicionar atributos para autorização

A autenticação de clientes por meio de SAT pode, opcionalmente, ter seus SATs anotados com os atributos a serem usados com políticas de autorização personalizadas. Para saber mais, confira Autorizar clientes que usam Tokens da Conta de Serviço do Kubernetes.

Habilitar a autenticação do Token da Conta de Serviço (SAT)

Modifique a configuração authenticationMethods em um recurso BrokerAuthentication para especificar ServiceAccountToken como um método de autenticação válido. O audiences especifica a lista de públicos válidos para os tokens. Escolha valores exclusivos que identifiquem o serviço do Agente MQTT. Você precisa especificar pelo menos um público e todos os SATs precisam corresponder a um dos públicos especificados.

spec:
  authenticationMethods:
    - method: ServiceAccountToken
      serviceAccountTokenSettings:
        audiences:
        - "aio-internal"
        - "my-audience"

Aplique suas alterações com o kubectl apply. Pode levar alguns minutos para que as alterações entrem em vigor.

Testar a autenticação do SAT

A autenticação SAT deve ser usada de um cliente no mesmo cluster que o Agente MQTT. Apenas campos de autenticação avançada são permitidos. Defina o método de autenticação como K8S-SAT e os dados de autenticação como o token.

O comando a seguir especifica um pod que tem o cliente do Mosquitto e monta no pod o SAT criado nas etapas anteriores.

apiVersion: v1
kind: Pod
metadata:
  name: mqtt-client
  namespace: azure-iot-operations
spec:
  serviceAccountName: mqtt-client
  containers:
  - image: efrecon/mqtt-client
    name: mqtt-client
    command: ["sleep", "infinity"]
    volumeMounts:
    - name: mqtt-client-token
      mountPath: /var/run/secrets/tokens
  volumes:
  - name: mqtt-client-token
    projected:
      sources:
      - serviceAccountToken:
          path: mqtt-client-token
          audience: my-audience
          expirationSeconds: 86400

Aqui, o campo serviceAccountName na configuração do pod precisa corresponder à conta de serviço associada ao token que está sendo usado. Além disso, o campo serviceAccountToken.audience na configuração do pod deve ser um dos audiences configurados no recurso BrokerAuthentication.

Depois que o pod for criado, inicie um shell no pod:

kubectl exec --stdin --tty mqtt-client -n azure-iot-operations -- sh

Dentro do shell do pod, execute o seguinte comando para publicar uma mensagem para o agente:

mosquitto_pub --host aio-broker --port 18883 --message "hello" --topic "world" --debug --cafile /var/run/certs/ca.crt -D CONNECT authentication-method 'K8S-SAT' -D CONNECT authentication-data $(cat /var/run/secrets/tokens/broker-sat)

O resultado deve ser semelhante ao seguinte:

Client (null) sending CONNECT
Client (null) received CONNACK (0)
Client (null) sending PUBLISH (d0, q0, r0, m1, 'world', ... (5 bytes))
Client (null) sending DISCONNECT

O cliente do Mosquitto usa o token de conta de serviço montado em /var/run/secrets/tokens/broker-sat para se autenticar junto ao agente. O token é válido por 24 horas. O cliente também usa o certificado de AC raiz padrão montado em /var/run/certs/ca.crt para verificar a cadeia de certificados TLS do agente.

Atualizar tokens de conta de serviço

Os tokens da conta de serviço são válidos por tempo limitado e configurados com expirationSeconds. No entanto, o Kubernetes atualiza automaticamente o token antes que ele expire. O token é atualizado em segundo plano e o cliente não precisa fazer nada além de buscá-lo novamente.

Por exemplo, se o cliente for um pod que usa o token montado como um volume, como no exemplo teste de autenticação SAT, então o token mais recente estará disponível no mesmo caminho /var/run/secrets/tokens/mqtt-client-token. Ao fazer uma nova conexão, o cliente pode buscar o token mais recente e usá-lo para autenticação. O cliente também deve ter um mecanismo para lidar com erros não autorizados do MQTT, buscando o token mais recente e tentando novamente a conexão.

Autenticação personalizada

Estenda a autenticação do cliente para além dos métodos de autenticação fornecidos com a autenticação personalizada. É plugável, já que o serviço pode ser qualquer coisa que possa aderir à API.

Quando um cliente se conecta ao Agente MQTT e a autenticação personalizada está habilitada, o Agente MQTT delega a verificação das credenciais do cliente a um servidor de autenticação personalizada com uma solicitação HTTP junto com todas as credenciais que o cliente apresenta. O servidor de autenticação personalizado responde com a aprovação ou negação para o cliente com os atributos para autorização do cliente.

Criar um serviço de autenticação personalizado

O servidor de autenticação personalizada é implementado e implantado separadamente do Agente MQTT.

Uma amostra de servidor de autenticação personalizado e instruções estão disponíveis no GitHub. Use essa amostra como um modelo a usaria e como ponto de partida para implementar sua própria lógica de autenticação personalizada.

API

A API entre o Agente MQTT e o servidor de autenticação personalizada segue a especificação de API para autenticação personalizada. A especificação OpenAPI está disponível em GitHub.

O HTTPS com criptografia TLS é obrigatório

O Agente MQTT envia solicitações contendo credenciais confidenciais do cliente para o servidor de autenticação personalizada. Para proteger essas credenciais, a comunicação entre o Agente MQTT e o servidor de autenticação personalizada deve ser criptografada com TLS.

O servidor de autenticação personalizada deve apresentar um certificado de servidor, e o Agente MQTT deve ter um certificado AC raiz confiável para validar o certificado do servidor. Opcionalmente, o servidor de autenticação personalizada pode exigir que o Agente MQTT apresente um certificado de cliente para se autenticar.

Habilitar a autenticação personalizada para um ouvinte

Modifique a configuração authenticationMethods em um recurso BrokerAuthentication para especificar Custom como um método de autenticação válido. Em seguida, especifique os parâmetros necessários para se comunicar com um servidor de autenticação personalizado.

Esse exemplo mostra todos os parâmetros possíveis. Os parâmetros exatos necessários dependem dos requisitos de cada servidor personalizado.

spec:
  authenticationMethods:
    - method: Custom
      customSettings:
        # Endpoint for custom authentication requests. Required.
        endpoint: https://auth-server-template
        # Optional CA certificate for validating the custom authentication server's certificate.
        caCertConfigMap: custom-auth-ca
        # Authentication between MQTT broker with the custom authentication server.
        # The broker may present X.509 credentials or no credentials to the server.
        auth:
          x509:
            secretName: custom-auth-client-cert
            namespace: azure-iot-operations
        # Optional additional HTTP headers that the broker will send to the
        # custom authentication server.
        headers:
          header_key: header_value

Desconexão do cliente após a expiração das credenciais

O Agente MQTT desconecta os clientes quando suas credenciais expiram. A desconexão após a expiração da credencial se aplica a todos os clientes que se conectam aos front-ends do Agente MQTT, inclusive:

  • Os clientes autenticados com SATs se desconectam quando o SAT expira
  • Clientes autenticados com X.509 se desconectam quando o certificado do cliente expira
  • Os clientes autenticados com autenticação personalizada se desconectam com base no tempo de expiração retornado pelo servidor de autenticação personalizada.

Na desconexão, a conexão de rede do cliente é fechada. O cliente não receberá um pacote MQTT DISCONNECT, mas o agente registrará uma mensagem indicando que desconectou o cliente.

Os clientes MQTT v5 autenticados com SATs e autenticação personalizada podem se autenticar novamente com uma nova credencial antes que a credencial inicial expire. Os clientes X.509 não podem se autenticar novamente e devem restabelecer a conexão, pois a autenticação é feita na camada TLS.

Os clientes podem se autenticar novamente enviando um pacote AUTH MQTT v5.

Os clientes SAT enviam um cliente AUTH com os campos method: K8S-SAT, data: <token>. Os clientes de autenticação personalizada definem o método e o campo de dados conforme exigido pelo servidor de autenticação personalizada.

A reautenticação bem-sucedida atualiza a expiração da credencial do cliente com o tempo de expiração da sua nova credencial, e o agente responde com um pacote de AUTH de sucesso. A falha na autenticação devido a problemas transitórios faz com que o agente responda com um pacote ContinueAuthentication AUTH. Por exemplo, o servidor de autenticação personalizada não está disponível. O cliente pode tentar novamente mais tarde. Outras falhas de autenticação fazem com que o agente envie um pacote DISCONNECT e feche a conexão de rede do cliente.