Compartir a través de


Configuración de la autenticación del corredor MQTT

Importante

Versión preliminar de operaciones de Azure IoT: habilitada por Azure Arc está actualmente en versión preliminar. No se debería usar este software en versión preliminar en entornos de producción.

Deberá implementar una nueva instalación de Azure IoT Operations cuando esté disponible una versión general. No podrá actualizar una instalación de versión preliminar.

Consulte Términos de uso complementarios para las versiones preliminares de Microsoft Azure para conocer los términos legales que se aplican a las características de Azure que se encuentran en la versión beta, en versión preliminar o que todavía no se han publicado para que estén disponibles con carácter general.

El corredor MQTT admite varios métodos de autenticación de clientes, y puede configurar cada cliente de escucha para que tenga su propio sistema de autenticación con recursos BrokerAuthentication. Para obtener una lista de la configuración disponible, consulte la referencia de API Autenticación de Broker.

Las siguientes reglas se aplican a la relación entre BrokerListener y BrokerAuthentication:

  • Cada instancia de BrokerListener puede tener varios puertos. Cada puerto se puede vincular a un recurso BrokerAuthentication.
  • Cada recurso BrokerAuthentication puede admitir varios métodos de autenticación a la vez.

Para vincular un BrokerListener a un recurso de BrokerAuthentication, especifique el campo authenticationRef en la configuración de ports del recurso BrokerListener. Para más información, consulte Recurso BrokerListener.

Recurso BrokerAuthentication predeterminado

Operaciones de IoT de Azure implementa un recurso BrokerAuthentication predeterminado denominado authn vinculado con el cliente de escucha predeterminado denominado listener en el espacio de nombres azure-iot-operations. Se configura para usar solamente tokens de cuenta de servicio (SAT) de Kubernetes para la autenticación. Para inspeccionarlo, ejecute:

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

La salida muestra el recurso BrokerAuthentication predeterminado (para mayor brevedad, los metadatos se han quitado):

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

Importante

El método de autenticación de token de cuenta de servicio (SAT) en el recurso BrokerAuthentication predeterminado es necesario para que los componentes de Operaciones de IoT de Azure funcionen correctamente. Evite actualizar o eliminar el recurso predeterminado BrokerAuthentication. Si necesita realizar cambios, modifique el campo authenticationMethods de este recurso mientras conserva el método de autenticación SAT con la audiencia de aio-internal. Preferiblemente, puede crear un nuevo recurso de BrokerAuthentication con un nombre diferente e implementarlo mediante kubectl apply.

Para cambiar la configuración, modifique el valor authenticationMethods de este recurso BrokerAuthentication o cree un nuevo recurso BrokerAuthentication con otro nombre. A continuación, impleméntelo mediante kubectl apply.

Flujo de autenticación

El orden de los métodos de autenticación de la matriz determina cómo autentica corredor MQTT a los clientes. Corredor MQTT intenta autenticar las credenciales del cliente mediante el primer método especificado e itera por la matriz hasta que encuentra una coincidencia o llega al final.

Para cada método, corredor MQTT comprueba primero si las credenciales del cliente son pertinentes para ese método. Por ejemplo, la autenticación SAT requiere un nombre de usuario que empiece por K8S-SAT y la autenticación X.509 requiere un certificado de cliente. Si las credenciales del cliente son pertinentes, corredor MQTT comprueba si son válidas. Para más información, consulte Configuración del método de autenticación.

Para la autenticación personalizada, el error para comunicarse con el servidor de autenticación personalizado se trata en corredor MQTT como que las credenciales no son pertinentes. Este comportamiento permite que el corredor MQTT recurra a otros métodos si el servidor personalizado no es accesible.

El flujo de autenticación finaliza cuando:

  • Se cumple una de estas condiciones:
    • Las credenciales del cliente son pertinentes y válidas para uno de los métodos.
    • Las credenciales del cliente no son pertinentes para ninguno de los métodos.
    • Las credenciales del cliente son pertinentes, pero no son válidas para ninguno de los métodos.
  • El corredor MQTT concede o deniega el acceso al cliente en función del resultado del flujo de autenticación.

Con varios métodos de autenticación, el corredor MQTT tiene un mecanismo de reserva. Por ejemplo:

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:
        # ...

En el ejemplo anterior se especifican personalizada y SAT. Cuando un cliente se conecta, el corredor MQTT intenta autenticarlo mediante los métodos especificados en el orden especificado personalizada y después SAT.

  1. El corredor MQTT comprueba si las credenciales del cliente son válidas para la autenticación personalizada. Dado que la autenticación personalizada se basa en un servidor externo para determinar la validez de las credenciales, el agente considera todas las credenciales pertinentes para la autenticación personalizada y las reenvía al servidor de autenticación personalizada.

  2. Si el servidor de autenticación personalizada responde con Pass o Fail, finaliza el flujo de autenticación. Pero si el servidor de autenticación personalizada no está disponible, el corredor MQTT recurre al resto de métodos especificados, donde SAT es el siguiente.

  3. El corredor MQTT intenta autenticar las credenciales como credenciales SAT. Si el nombre de usuario de MQTT comienza con K8S-SAT, el corredor MQTT evalúa la contraseña MQTT como SAT.

Si el servidor de autenticación personalizada no está disponible y todos los métodos posteriores determinaron que las credenciales proporcionadas no son pertinentes, el agente deniega la conexión del cliente.

Deshabilitación de la autenticación

Para realizar pruebas, puede deshabilitar la autenticación si omite authenticationRef en el valor ports de un recurso BrokerListener.

Configuración del método de autenticación

Para obtener más información sobre cada una de las opciones de autenticación, consulte las siguientes secciones para cada método.

Para más información sobre cómo habilitar la configuración segura mediante la configuración de Azure Key Vault y la habilitación de identidades de carga de trabajo, consulte Habilitar la configuración segura en la implementación de la versión preliminar de operaciones de IoT de Azure.

X.509

Se requiere un certificado de CA raíz de confianza para validar el certificado de cliente. Los certificados de cliente deben tener como raíz esta CA para que el corredor MQTT los autentique. Se admiten claves EC y RSA, pero todos los certificados de la cadena deben usar el mismo algoritmo de clave. Si va a importar sus propios certificados de CA, asegúrese de que el certificado de cliente use el mismo algoritmo de clave que las entidades de certificación. Para importar un certificado raíz que se pueda usar para validar los certificados de cliente, importe el certificado PEM como ConfigMap en la clave client_ca.pem. Por ejemplo:

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

Para comprobar que el certificado de CA raíz se ha importado correctamente, ejecute kubectl describe configmap. El resultado muestra la misma codificación en base64 del archivo de 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
====

Una vez importados el certificado de CA raíz del cliente de confianza y la asignación de certificado a atributo, habilite la autenticación de cliente X.509 agregándola como uno de los métodos de autenticación como parte de un recurso BrokerAuthentication vinculado a un cliente de escucha habilitado para TLS. Por ejemplo:

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

Atributos de certificado para la autorización

Los atributos X.509 se pueden especificar en el recurso BrokerAuthentication y se usan para autorizar a los clientes en función de sus propiedades de certificado. Los atributos se definen en el campo authorizationAttributes. Por ejemplo:

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

En este ejemplo, cada cliente que tiene un certificado emitido por la CA raíz CN = Contoso Root CA Cert, OU = Engineering, C = US o una CA intermedia CN = Contoso Intermediate CA recibe los atributos enumerados. Además, el ventilador inteligente recibe atributos específicos de él.

La coincidencia de atributos siempre comienza desde el certificado de cliente hoja y, a continuación, pasa por la cadena. La asignación de atributos se detiene después de la primera coincidencia. En el ejemplo anterior, incluso si smart-fan tiene el certificado intermedio CN = Contoso Intermediate CA, no obtiene los atributos asociados.

Se pueden aplicar reglas de autorización a los clientes que usan certificados X.509 con estos atributos. Para obtener más información, consulte Autorización de clientes que usan la autenticación X.509.

Conexión del cliente mosquitto a corredor MQTT con un certificado de cliente X.509

Un cliente como mosquitto necesita tres archivos para poder conectarse al corredor MQTT con la autenticación de cliente TLS y X.509. Por ejemplo:

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

En el ejemplo:

  • El parámetro --cert especifica el archivo PEM del certificado de cliente.
  • El parámetro --key especifica el archivo PEM de la clave privada de cliente.
  • El tercer parámetro --cafile es el más complejo: la base de datos de certificados de confianza, que se usa con dos propósitos:
    • Cuando el cliente mosquitto se conecta al corredor MQTT mediante TLS, valida el certificado de servidor. Busca certificados raíz en la base de datos para crear una cadena de confianza con el certificado del servidor. Debido a esto, el certificado raíz del servidor debe copiarse en este archivo.
    • Cuando el corredor MQTT solicita un certificado de cliente desde el cliente mosquitto, también necesita una cadena de certificados válida para enviar al servidor. El parámetro --cert indica a mosquitto qué certificado enviar, pero no es suficiente. El corredor MQTT no puede comprobar este certificado por sí solo porque también necesita el certificado intermedio. Mosquitto usa el archivo de base de datos para compilar la cadena de certificados necesaria. Para admitir esto, cafile debe contener los certificados intermedio y raíz.

Descripción del flujo de autenticación de cliente X.509 del corredor MQTT

Diagrama del flujo de autenticación de cliente X.509.

Estos son los pasos del flujo de autenticación de cliente:

  1. Cuando se activa la autenticación de cliente X.509, los clientes que se conectan deben presentar su certificado de cliente y los certificados intermedios para permitir que el corredor MQTT cree una cadena de certificados con la raíz en uno de sus certificados de confianza configurados.
  2. El equilibrador de carga dirige la comunicación a uno de los agentes de front-end.
  3. Una vez que el agente de front-end recibe el certificado de cliente, intenta crear una cadena de certificados que tiene como raíz uno de los certificados configurados. El certificado es necesario para el protocolo de enlace TLS. Si el agente de front-end ha creado correctamente una cadena y se comprueba la cadena presentada, finaliza el protocolo de enlace TLS. El cliente de conexión puede enviar paquetes MQTT al front-end mediante el canal TLS compilado.
  4. El canal TLS está abierto, pero la autenticación o autorización de cliente aún no ha finalizado.
  5. Después, el cliente envía un paquete CONNECT al corredor MQTT.
  6. El paquete CONNECT se enruta de nuevo a un front-end.
  7. El front-end recopila todas las credenciales que el cliente presentó hasta ahora, como los campos de nombre de usuario y contraseña, los datos de autenticación del paquete CONNECT y la cadena de certificados de cliente presentada durante el protocolo de enlace TLS.
  8. El front-end envía estas credenciales al servicio de autenticación. El servicio de autenticación comprueba de nuevo la cadena de certificados y recopila los nombres de firmante de todos los certificados de la cadena.
  9. El servicio de autenticación usa sus reglas de autorización configuradas para determinar qué atributos tienen los clientes que se conectan. Estos atributos determinan qué operaciones puede ejecutar el cliente, incluido el propio paquete CONNECT.
  10. El servicio de autenticación devuelve la decisión al agente de front-end.
  11. El agente de front-end conoce los atributos de cliente y si se le permite conectarse. Si es así, la conexión MQTT finaliza y el cliente puede seguir enviando y recibiendo paquetes MQTT determinados por sus reglas de autorización.

Tokens de cuenta de servicio de Kubernetes

Los tokens de cuenta de servicio de Kubernetes (SAT) son tokens JSON Web Token asociados a cuentas de servicio de Kubernetes. Los clientes presentan SAT al corredor MQTT para autenticarse a sí mismos.

El corredor MQTT usa tokens de cuenta de servicio enlazados que se detallan en la publicación ¿Qué necesitan los usuarios de GKE para conocer los nuevos tokens de cuenta de servicio de Kubernetes?. Estas son las características destacadas de la publicación:

Lanzados en Kubernetes 1.13 y convertidos en el formato predeterminado en la versión 1.21, los tokens enlazados abordan toda la funcionalidad limitada de los tokens heredados, y mucho más:

  • Los tokens en sí son más difíciles de robar y utilizar indebidamente; están vinculados al tiempo, al público y al objeto.
  • Adoptan un formato estandarizado: OpenID Connect (OIDC), con detección completa de OIDC, lo que facilita que los proveedores de servicios los acepten.
  • Se distribuyen a pods de forma más segura mediante un nuevo tipo de volumen proyectado de Kubelet.

El agente comprueba los tokens mediante la API de revisión de tokens de Kubernetes. Habilite la característica TokenRequestProjection de Kubernetes para especificar audiences (valor predeterminado desde la versión 1.21). Si esta característica no está habilitada, no se pueden usar SAT.

Crear una cuenta de servicio

Para crear SAT, cree primero una cuenta de servicio. Con el siguiente comando se crea una cuenta de servicio llamada mqtt-client.

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

Adición de atributos de autorización

La autenticación de cliente mediante SAT puede hacer que sus SAT se anoten con atributos que se usarán con directivas de autorización personalizadas. Para más información, consulte Autorización de clientes que usan tokens de cuenta de servicio de Kubernetes.

Habilitación de la autenticación de tokens de cuenta de servicio (SAT)

Modifique el valor authenticationMethods de un recurso BrokerAuthentication para especificar ServiceAccountToken como método de autenticación válido. El valor audiences especifica la lista de públicos válidos para tokens. Elija valores únicos que identifiquen el servicio de corredor MQTT. Debe especificar al menos un público y todos los SAT deben coincidir con uno de los públicos especificados.

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

Aplique los cambios con kubectl apply. Puede que los cambios tarden unos minutos en surtir efecto.

Prueba de la autenticación SAT

La autenticación SAT se debe usar desde un cliente del mismo clúster que el corredor MQTT. Solo se permiten campos de autenticación mejorados. Establezca el método de autenticación en K8S-SAT y los datos de autenticación en el token.

El siguiente comando especifica un pod que tiene el cliente mosquitto y monta el SAT creado en los pasos anteriores en el pod.

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

Aquí, el campo serviceAccountName de la configuración del pod debe coincidir con la cuenta de servicio asociada al token que se está usando. Además, el campo serviceAccountToken.audience de la configuración del pod debe ser uno de los valores audiences configurados en el recurso BrokerAuthentication.

Una vez que se cree el pod, inicie un shell en él:

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

Dentro del shell del pod, ejecute el siguiente comando para publicar un mensaje en el 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/mq-sat)

La salida debe tener una apariencia similar a la siguiente:

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

El cliente de mosquitto usa el token de cuenta de servicio montado en /var/run/secrets/tokens/mq-sat para autenticarse con el agente. El token es válido durante 24 horas. El cliente también usa el certificado de CA raíz predeterminado montado en /var/run/certs/ca.crt para comprobar la cadena de certificados TLS del agente.

Actualizar tokens de cuenta de servicio

Los tokens de cuenta de servicio son válidos durante un tiempo limitado y configurados con expirationSeconds. Sin embargo, Kubernetes actualiza automáticamente el token antes de que expire. El token se actualiza en segundo plano y el cliente no necesita hacer nada más que capturarlo de nuevo.

Por ejemplo, si el cliente es un pod que usa el token montado como un volumen, como en el ejemplo de autenticación SAT de prueba, el token más reciente está disponible en la misma ruta de acceso /var/run/secrets/tokens/mqtt-client-token. Al realizar una nueva conexión, el cliente puede capturar el token más reciente y usarlo para autenticarse. El cliente también debe tener un mecanismo para controlar errores no autorizados de MQTT mediante la captura del token más reciente y el reintento de la conexión.

Autenticación personalizada

Amplíe la autenticación de cliente más allá de los métodos de autenticación proporcionados con la autenticación personalizada. Es conectable, ya que el servicio puede ser cualquier cosa siempre que se ajuste a la API.

Cuando un cliente se conecta al corredor MQTT y está habilitada la autenticación personalizada, el corredor MQTT delega la comprobación de las credenciales de cliente en un servidor de autenticación personalizada con una solicitud HTTP junto con todas las credenciales que presenta el cliente. El servidor de autenticación personalizada responde con la aprobación o la denegación del cliente con los atributos de autorización de este.

Creación de un servicio de autenticación personalizada

El servidor de autenticación personalizada se implementa por separado del corredor MQTT.

En GitHub, se puede encontrar un ejemplo de servidor de autenticación personalizada e instrucciones. Use este ejemplo como plantilla y punto de partida para implementar su propia lógica de autenticación personalizada.

API

La API entre el corredor MQTT y el servidor de autenticación personalizada sigue la especificación de API de la autenticación personalizada. La especificación openAPI está disponible en GitHub.

Se requiere HTTPS con cifrado TLS

El corredor MQTT envía solicitudes que contienen credenciales de cliente confidenciales al servidor de autenticación personalizado. Para proteger estas credenciales, la comunicación entre el corredor MQTT y el servidor de autenticación personalizada se debe cifrar con TLS.

El servidor de autenticación personalizada debe presentar un certificado de servidor y el corredor MQTT debe tener un certificado de CA raíz de confianza para validarlo. Opcionalmente, el servidor de autenticación personalizada podría exigir que el corredor MQTT presente un certificado de cliente para autenticarse.

Habilitación de la autenticación personalizada para un cliente de escucha

Modifique el valor authenticationMethods de un recurso BrokerAuthentication para especificar Custom como método de autenticación válido. A continuación, especifique los parámetros necesarios para comunicarse con un servidor de autenticación personalizada.

En este ejemplo se muestran todos los parámetros posibles. Los parámetros exactos necesarios dependen de los requisitos personalizados de cada servidor.

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

Desconexión del cliente después de que expiren las credenciales

El corredor MQTT desconecta los clientes cuando expiran sus credenciales. La desconexión después de la expiración de credenciales se aplica a todos los clientes que se conectan a los front-end del corredor MQTT, incluidos los siguientes:

  • Los clientes autenticados con SAT se desconectan cuando expira su SAT
  • Los clientes autenticados con X.509 se desconectan cuando expira su certificado de cliente
  • Los clientes autenticados con la autenticación personalizada se desconectan en función de la hora de expiración devuelta del servidor de autenticación personalizada.

Al desconectarse, se cierra la conexión de red del cliente. El cliente no recibirá un paquete MQTT DISCONNECT, pero el agente registra un mensaje de que el cliente se ha desconectado.

Los clientes MQTT v5 autenticados con SAT y la autenticación personalizada se pueden volver a autenticar con una nueva credencial antes de que expire su credencial inicial. Los clientes X.509 no se pueden volver a autenticar y deben volver a establecer la conexión, ya que la autenticación se realiza en la capa TLS.

Los clientes se pueden volver a autenticar mediante el envío de un paquete AUTH de MQTT v5.

Los clientes SAT envían un cliente AUTH con los campos method: K8S-SAT, data: <token>. Los clientes de autenticación personalizada establecen el método y el campo de datos según sea necesario para el servidor de autenticación personalizada.

La nueva autenticación correcta actualiza la expiración de las credenciales del cliente con la hora de expiración de su nueva credencial y el agente responde con un paqueteSuccess AUTH. La autenticación con errores debido a problemas transitorios hace que el agente responda con un paquete ContinueAuthentication AUTH. Por ejemplo, el servidor de autenticación personalizada no está disponible. El cliente puede volver a intentarlo más tarde. Otros errores de autenticación provocan que el agente envíe un paquete DISCONNECT y cierre la conexión de red del cliente.