Compartir a través de


Protección de la comunicación de agente MQTT mediante BrokerListener

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.

Para personalizar el acceso a la red y la seguridad, use el recurso BrokerListener. Un agente de escucha corresponde a un punto de conexión de red que expone el agente a la red. Puede tener uno o varios recursos de BrokerListener para cada recurso de Broker y, por tanto, varios puertos con control de acceso diferente cada uno.

Cada puerto del agente de escucha puede tener sus propias reglas de autenticación y autorización que definen quién puede conectarse al agente de escucha y qué acciones pueden realizar en el agente. Puede usar recursos BrokerAuthentication y BrokerAuthorization para especificar las directivas de control de acceso para cada agente de escucha. Esta flexibilidad le permite ajustar los permisos y roles de los clientes MQTT, en función de sus necesidades y casos de uso.

Sugerencia

Solo puede acceder a la implementación de corredor MQTT predeterminada mediante la dirección IP del clúster, TLS y un token de cuenta de servicio. Los clientes que se conectan fuera del clúster necesitan una configuración adicional para poder conectarse.

Los agentes de escucha tienen las siguientes características:

  • Puede tener hasta tres agentes de escucha. Un agente de escucha por tipo de servicio de loadBalancer, clusterIp, o nodePort. El BrokerListener predeterminado denominado predeterminado es el tipo de servicio clusterIp.
  • Cada agente de escucha admite varios puertos
  • Las referencias BrokerAuthentication y BrokerAuthorization son por puerto
  • La configuración de TLS es por puerto
  • Los nombres de servicio deben ser únicos
  • Los puertos no pueden entrar en conflicto con diferentes clientes de escucha

Para obtener una lista de las configuraciones disponibles, consulte la referencia de API de Broker Listener.

BrokerListener predeterminado

Al implementar versión preliminar de Operaciones de IoT de Azure, la implementación también crea un recurso de BrokerListener denominado default en el espacio de nombres azure-iot-operations. Este agente de escucha está vinculado al recurso Agente predeterminado denominado default que también se crea durante la implementación. El agente de escucha predeterminado expone el agente en el puerto 18883 con la autenticación TLS y SAT habilitada. El certificado TLS se administra automáticamente por medio de cert-manager. La autorización está deshabilitada de forma predeterminada.

Para ver o editar el cliente de escucha:

  1. En Azure Portal, vaya a su instancia de IoT Hub.

  2. En recursos de Operaciones de IoT de Azure, seleccione corredor MQTT.

    Captura de pantalla con Azure Portal para ver la configuración de MQTT de Operaciones de IoT de Azure.

  3. En la lista cliente de escucha del corredor, seleccione el cliente de escucha predeterminado.

    Captura de pantalla con Azure Portal para ver o editar el cliente de escucha del corredor predeterminado.

  4. Revise la configuración del cliente de escucha y realice los cambios según sea necesario.

Crear nuevos clientes de escucha del corredor

En este ejemplo se muestra cómo crear un nuevo recurso de BrokerListener denominado loadbalancer-listener para un recurso my-broker. El recurso BrokerListener define dos puertos que aceptan conexiones MQTT de clientes.

  • El primer puerto escucha en el puerto 1883 sin TLS ni autenticación desactivada. Los clientes pueden conectarse al agente sin cifrado ni autenticación.
  • El segundo puerto escucha en el puerto 18883 con TLS y la autenticación habilitada. Solo los clientes autenticados pueden conectarse al agente con cifrado TLS. TLS se establece en automatic, lo que significa que el agente de escucha usa cert-manager para obtener y renovar su certificado de servidor.
  1. En Azure Portal, vaya a su instancia de IoT Hub.

  2. En recursos de Operaciones de IoT de Azure, seleccione corredor MQTT.

  3. Seleccione cliente de escucha de corredor MQTT para LoadBalancer>Crear. Solo puede crear un cliente de escucha por tipo de servicio. Si ya tiene un cliente de escucha del mismo tipo de servicio, puede agregar más puertos al cliente de escucha existente.

    Captura de pantalla con Azure Portal para crear el corredor MQTT para el cliente de escucha del equilibrador de carga.

    Escriba la siguiente configuración:

    Configuración Descripción
    Nombre Nombre del recurso BrokerListener.
    Nombre del servicio Nombre del servicio Kubernetes asociado con BrokerListener.
    Tipo de servicio. Tipo de servicio de corredor, como LoadBalancer, NodePort o ClusterIP.
    Port Número de puerto en el que BrokerListener escucha las conexiones MQTT.
    Autenticación La referencia de recursos de autenticación.
    Authorization La referencia del recurso de autorización.
    TLS Indica si TLS está habilitado para la comunicación segura. Puede establecerse en automática o manual.
  4. Seleccione Crear cliente de escucha.

Configuración de TLS con administración automática de certificados

Para habilitar TLS con administración automática de certificados, especifique la configuración de TLS en un puerto de escucha.

Compruebe la instalación de cert-manager

Con la administración automática de certificados, se usa cert-manager para administrar el certificado de servidor TLS. De forma predeterminada, el administrador de certificados se instala junto con la versión preliminar de operaciones de Azure IoT en el espacio de nombres azure-iot-operations. Compruebe la instalación antes de continuar.

  1. Use kubectl para comprobar si los pods coinciden con las etiquetas de la aplicación cert-manager.

    kubectl get pods --namespace azure-iot-operations -l 'app in (cert-manager,cainjector,webhook)'
    
    NAME                                           READY   STATUS    RESTARTS       AGE
    aio-cert-manager-64f9548744-5fwdd              1/1     Running   4 (145m ago)   4d20h
    aio-cert-manager-cainjector-6c7c546578-p6vgv   1/1     Running   4 (145m ago)   4d20h
    aio-cert-manager-webhook-7f676965dd-8xs28      1/1     Running   4 (145m ago)   4d20h
    
  2. Si ve que los pods se muestran como listos y en ejecución, cert-manager está instalado y listo para usarse.

Sugerencia

Para comprobar aún más la instalación, consulte la documentación de cert-manager para comprobar la instalación. Recuerde usar el espacio de nombres azure-iot-operations.

Creación de un emisor para el certificado de servidor TLS

El recurso emisor cert-manager define cómo se emiten automáticamente los certificados. Cert-manager admite varios tipos de emisores de forma nativa. También admite un tipo de emisor externo para ampliar la funcionalidad más allá de los emisores admitidos de forma nativa. El broker MQTT puede utilizarse con cualquier tipo de emisor de cert-manager.

Importante

Durante la implementación inicial, las Operaciones de IoT de Azure se instala con un emisor predeterminado para los certificados de servidor TLS. Puede usar este emisor para desarrollo y pruebas. Para más información, consulte Entidad de certificación raíz predeterminada y emisor con Operaciones de loT de Azure. Los pasos siguientes solo son necesarios si desea usar otro emisor.

El enfoque para crear el emisor es diferente en función del escenario. En las secciones siguientes se enumeran ejemplos para ayudarle a empezar.

El emisor de CA es útil para el desarrollo y las pruebas. Debe configurarse con un certificado y una clave privada almacenadas en un secreto de Kubernetes.

Configuración del certificado raíz como un secreto de Kubernetes

Si ya tiene un certificado de CA, cree un secreto de Kubernetes con los archivos PEM del certificado de CA y la clave privada. Ejecute el siguiente comando y haya configurado el certificado raíz como un secreto de Kubernetes y puede omitir la sección siguiente.

kubectl create secret tls test-ca --cert tls.crt --key tls.key -n azure-iot-operations

Si no tiene un certificado CA, cert-manager puede generar un certificado CA raíz para usted. El uso de cert-manager para generar un certificado de CA raíz se conoce como arranque de un emisor CA con un certificado autofirmado.

  1. Empiece por crear ca.yaml:

    apiVersion: cert-manager.io/v1
    kind: Issuer
    metadata:
      name: selfsigned-ca-issuer
      namespace: azure-iot-operations
    spec:
      selfSigned: {}
    ---
    apiVersion: cert-manager.io/v1
    kind: Certificate
    metadata:
      name: selfsigned-ca-cert
      namespace: azure-iot-operations
    spec:
      isCA: true
      commonName: test-ca
      secretName: test-ca
      issuerRef:
        # Must match Issuer name above
        name: selfsigned-ca-issuer
        # Must match Issuer kind above
        kind: Issuer
        group: cert-manager.io
      # Override default private key config to use an EC key
      privateKey:
        rotationPolicy: Always
        algorithm: ECDSA
        size: 256
    
  2. Cree el certificado CA con firma propia con el siguiente comando:

    kubectl apply -f ca.yaml
    

Cert-manager crea un certificado CA utilizando sus valores predeterminados. Las propiedades de este certificado pueden cambiarse modificando la especificación del certificado. Consulte Documentación de cert-manager para obtener una lista de opciones válidas.

Distribuir el certificado raíz

El ejemplo anterior almacena el certificado CA en un secreto de Kubernetes llamado test-ca. El certificado en formato PEM se puede recuperar del secreto y almacenar en un archivo ca.crt con el siguiente comando:

kubectl get secret test-ca -n azure-iot-operations -o json | jq -r '.data["tls.crt"]' | base64 -d > ca.crt

Todos los clientes deben distribuir y confiar en este certificado. Por ejemplo, use la marca --cafile para un cliente de mosquitto.

Crear emisor basado en certificado CA

Cert-manager necesita un emisor basado en el certificado CA generado o importado en el paso anterior. Cree el siguiente archivo como issuer-ca.yaml:

apiVersion: cert-manager.io/v1
kind: Issuer
metadata:
  name: my-issuer
  namespace: azure-iot-operations
spec:
  ca:
    # Must match secretName of generated or imported CA cert
    secretName: test-ca

Cree el emisor con el siguiente comando:

kubectl apply -f issuer-ca.yaml

El comando anterior crea un emisor para emitir los certificados de servidor TLS. Anote el nombre y el tipo del emisor. En el ejemplo, nombre my-issuer y tipo Issuer. Estos valores se establecen en el recurso BrokerListener más adelante.

Habilitar la administración automática de certificados TLS para un puerto

A continuación se muestra un ejemplo de un recurso BrokerListener que habilita TLS en el puerto 8884 con administración automática de certificados.

  1. En Azure Portal, vaya a la instancia de operaciones de IoT.

  2. En recursos de Operaciones de IoT de Azure, seleccione corredor MQTT.

  3. Seleccione o cree un cliente de escucha. Solo puede crear un cliente de escucha por tipo de servicio. Si ya tiene un cliente de escucha del mismo tipo de servicio, puede agregar más puertos al cliente de escucha existente.

  4. Puede agregar la configuración de TLS al cliente de escucha seleccionando TLS en un puerto existente o agregando un puerto nuevo.

    Recorte de pantalla con Azure Portal para crear el corredor MQTT para el cliente de escucha del equilibrador de carga con certificados TLS automáticos.

    Escriba la siguiente configuración:

    Configuración Descripción
    Port Número de puerto en el que BrokerListener escucha las conexiones MQTT. Necesario.
    Autenticación La referencia de recursos de autenticación.
    Authorization La referencia del recurso de autorización.
    TLS Selecciona el botón Agregar.
    Nombre del emisor Nombre del emisor del administrador de certificados. Necesario.
    Tipo de emisor Tipo de emisor de cert-manager. Necesario.
    Grupo de emisores Grupo del emisor de cert-manager. Necesario.
    Algoritmo de clave privada Algoritmo para la clave privada.
    Directiva de rotación de claves privadas Directiva para rotar la clave privada.
    Nombres DNS Nombres alternativos del firmante DNS para el certificado.
    Direcciones IP Direcciones IP de los nombres alternativos del firmante para el certificado.
    Nombre secreto Secreto de Kubernetes que contiene un certificado de cliente X.509.
    Duration Duración total del certificado de servidor TLS Por defecto, 90 días.
    Renovar antes Cuándo empezar a renovar el certificado.
  5. Seleccione Guardar para guardar la configuración de TLS.

Conexión al agente con TLS

Una vez configurado el certificado de servidor, TLS está habilitado. Para probar con mosquitto:

mosquitto_pub -h $HOST -p 8884 -V mqttv5 -i "test" -t "test" -m "test" --cafile ca.crt

El argumento--cafile habilita TLS en el cliente mosquitto y especifica que el cliente debe confiar en todos los certificados de servidor emitidos por el archivo especificado. Debe especificar un archivo que contenga el emisor del certificado de servidor TLS configurado.

Reemplace por $HOST el host adecuado:

  • Si se conecta desde dentro del mismo clúster, reemplace por el nombre de servicio especificado (my-new-tls-listener por ejemplo) o el servicio CLUSTER-IP.
  • Si se conecta desde fuera del clúster, el servicio EXTERNAL-IP.

Recuerde especificar métodos de autenticación si es necesario.

Entidad de certificación raíz predeterminada y emisor

Para ayudarle a empezar, las operaciones de Azure IoT se implementan con una CA raíz predeterminada de "inicio rápido" y un emisor para los certificados de servidor TLS. Puede usar este emisor para desarrollo y pruebas. Para obtener más información, consulte Entidad de certificación raíz predeterminada y emisor para certificados TLS de servidor.

Para la producción, debe configurar un emisor de CA con un certificado de una CA de confianza, como se describe en las secciones anteriores.

Configuración de TLS con administración manual de certificados

Para configurar manualmente el corredor MQTT a fin de usar un certificado TLS específico, especifíquelo en un recurso BrokerListener con una referencia a un secreto de Kubernetes. A continuación, impleméntelo mediante kubectl. En este artículo se muestra un ejemplo de cómo configurar TLS con certificados autofirmados para la realización de pruebas.

Creación de una entidad de certificación con la CLI de Step

Step es un administrador de certificados que puede ayudarle a ponerse en marcha rápidamente cuando vaya a crear y administrar su propia entidad de certificación (CA) privada.

  1. Instale la CLI de Step y cree un certificado y una clave de entidad de certificación raíz.

    step certificate create --profile root-ca "Example Root CA" root_ca.crt root_ca.key
    
  2. Cree un certificado y una clave de entidad de certificación intermedia firmados por la entidad de certificación raíz.

    step certificate create --profile intermediate-ca "Example Intermediate CA" intermediate_ca.crt intermediate_ca.key \
    --ca root_ca.crt --ca-key root_ca.key
    

Creación de un certificado de servidor

Use la CLI de Step para crear un certificado de servidor a partir del firmado por la entidad de certificación intermedia.

step certificate create mqtts-endpoint mqtts-endpoint.crt mqtts-endpoint.key \
--profile leaf \
--not-after 8760h \
--san mqtts-endpoint \
--san localhost \
--ca intermediate_ca.crt --ca-key intermediate_ca.key \
--no-password --insecure

Aquí, mqtts-endpoint y localhost son los nombres alternativos del firmante (SAN) para el front-end del corredor MQTT en Kubernetes y los clientes locales, respectivamente. Para conectarse a través de Internet, agregue un elemento --san con una dirección IP externa. Las marcas --no-password --insecure se usan para la realización de pruebas a fin de omitir las solicitudes de contraseña y deshabilitar la protección de contraseñas para la clave privada debido a que se almacena en un secreto de Kubernetes. En producción, use una contraseña y almacene la clave privada en una ubicación segura, como Azure Key Vault.

Requisitos del algoritmo de clave de certificado

Se admiten claves EC y RSA, pero todos los certificados de la cadena deben usar el mismo algoritmo de clave. Si importa sus propios certificados de CA, asegúrese de que el certificado de servidor use el mismo algoritmo de clave que las entidades de certificación.

Importación de cadena del certificado raíz como secreto de Kubernetes

  1. Cree una cadena de certificados de servidor completa, donde el orden de los certificados es importante: el certificado de servidor es el primero del archivo, el intermedio es el segundo.

    cat  mqtts-endpoint.crt intermediate_ca.crt  > server_chain.crt
    
  2. Cree un secreto de Kubernetes con la cadena de certificados de servidor y la clave de servidor mediante kubectl.

    kubectl create secret tls server-cert-secret -n azure-iot-operations \
    --cert server_chain.crt \
    --key mqtts-endpoint.key
    

Habilitar la administración manual de certificados TLS para un puerto

A continuación se muestra un ejemplo de un recurso BrokerListener que habilita TLS en el puerto 8884 con la administración manual de certificados.

  1. En Azure Portal, vaya a su instancia de IoT Hub.

  2. En recursos de Operaciones de IoT de Azure, seleccione corredor MQTT.

  3. Seleccione o cree un cliente de escucha. Solo puede crear un cliente de escucha por tipo de servicio. Si ya tiene un cliente de escucha del mismo tipo de servicio, puede agregar más puertos al cliente de escucha existente.

  4. Puede agregar la configuración de TLS al cliente de escucha seleccionando TLS en un puerto existente o agregando un puerto nuevo.

    Recorte de pantalla con Azure Portal para crear el corredor MQTT para el cliente de escucha del equilibrador de carga con certificados TLS manuales.

    Escriba la siguiente configuración:

    Configuración Descripción
    Port Número de puerto en el que BrokerListener escucha las conexiones MQTT. Necesario.
    Autenticación La referencia de recursos de autenticación.
    Authorization La referencia del recurso de autorización.
    TLS Selecciona el botón Agregar.
    Nombre secreto Secreto de Kubernetes que contiene un certificado de cliente X.509.
  5. Seleccione Guardar para guardar la configuración de TLS.

Conexión al agente con TLS

Para probar la conexión TLS con el cliente mosquitto, publique un mensaje y pase el certificado de CA raíz en el parámetro --cafile.

mosquitto_pub -d -h localhost -p 8885 -i "my-client" -t "test-topic" -m "Hello" --cafile root_ca.crt
Client my-client sending CONNECT
Client my-client received CONNACK (0)
Client my-client sending PUBLISH (d0, q0, r0, m1, 'test-topic', ... (5 bytes))
Client my-client sending DISCONNECT

Sugerencia

Para usar localhost, el puerto debe estar disponible en la máquina host. Por ejemplo, kubectl port-forward svc/mqtts-endpoint 8885:8885 -n azure-iot-operations. Con algunas distribuciones de Kubernetes como K3d, puede agregar un puerto reenviado con k3d cluster edit $CLUSTER_NAME --port-add 8885:8885@loadbalancer.

Nota:

Para conectarse al agente, debe distribuir la raíz de confianza a los clientes, también conocido como agrupación de confianza. En este caso, la raíz de confianza es la CA raíz autofirmado creada por la CLI del paso. La distribución de la raíz de confianza es necesaria para que el cliente compruebe la cadena de certificados del servidor. Si los clientes MQTT son cargas de trabajo en el clúster de Kubernetes, también debe crear un ConfigMap con la entidad de certificación raíz y montarlo en el pod.

Recuerde especificar el nombre de usuario, la contraseña etc. Si la autenticación del corredor MQTT está habilitada.

Uso de una dirección IP externa para el certificado de servidor

Para conectarse con TLS a través de Internet, el certificado de servidor del corredor MQTT debe tener su nombre de host externo como SAN. En producción, este suele ser un nombre DNS o una dirección IP conocida. Sin embargo, durante la fase de desarrollo/pruebas, es posible que no sepa qué nombre de host o dirección IP externa se ha asignado antes de la implementación. Para resolverlo, implemente primero el cliente de escucha sin el certificado de servidor; a continuación, cree el certificado de servidor y el secreto con la dirección IP externa y, por último, importe el secreto en el cliente de escucha.

Si intenta implementar el cliente de escucha TLS de ejemplo manual-tls-listener pero el secreto de Kubernetes al que se hace referencia server-cert-secret no existe, se crea el servicio asociado, pero los pods no se inician. El servicio se crea porque el operador necesita reservar la dirección IP externa para el cliente de escucha.

kubectl get svc mqtts-endpoint -n azure-iot-operations
NAME                   TYPE           CLUSTER-IP      EXTERNAL-IP   PORT(S)             AGE
mqtts-endpoint         LoadBalancer   10.X.X.X        172.X.X.X     8885:30674/TCP      1m15s

Sin embargo, se espera este comportamiento y no importa dejarlo así mientras importamos el certificado de servidor. Los registros del administrador de mantenimiento mencionan que el corredor MQTT está esperando el certificado de servidor.

kubectl logs -l app=health-manager -n azure-iot-operations
...
<6>2023-11-06T21:36:13.634Z [INFO] [1] - Server certificate server-cert-secret not found. Awaiting creation of secret.

Nota:

Por lo general, en un sistema distribuido, los registros de los pods no son deterministas y se deben usar con precaución. La forma correcta para mostrar información como esta es a través de eventos de Kubernetes y del estado de los recursos personalizados, que se encuentra en el trabajo pendiente. Considere el paso anterior como solución temporal.

Aunque los pods del front-end no estén en uso, la dirección IP externa ya está disponible.

kubectl get svc mqtts-endpoint -n azure-iot-operations
NAME                   TYPE           CLUSTER-IP      EXTERNAL-IP   PORT(S)             AGE
mqtts-endpoint         LoadBalancer   10.X.X.X        172.X.X.X     8885:30674/TCP      1m15s

A partir de aquí, siga los mismos pasos que antes para crear un certificado de servidor con esta dirección IP externa en --san y cree el secreto de Kubernetes de la misma forma. Una vez creado el secreto, este se importa automáticamente en el cliente de escucha.