Compartir a través de


Prueba de la conectividad a la versión preliminar de MQ de Azure IoT con clientes MQTT

Importante

Operaciones de IoT de Azure, habilitado 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.

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.

En este artículo se muestran diferentes maneras de probar la conectividad a la versión preliminar de Azure IoT MQ con clientes MQTT en un entorno de no producción.

De forma predeterminada, la versión preliminar de Azure IoT MQ:

  • Implementa un agente de escucha habilitado para TLS en el puerto 8883 con ClusterIp como tipo de servicio. ClusterIp significa que solo se puede acceder al agente desde el clúster de Kubernetes. Para acceder al agente desde fuera del clúster, debe configurar un servicio de tipo LoadBalancer o NodePort.

  • Acepta cuentas de servicio de Kubernetes para la autenticación de conexiones desde el clúster. Para conectarse desde fuera del clúster, debe configurar un método de autenticación diferente.

Precaución

En escenarios de producción, debe usar la autenticación de cuentas de servicio y TLS para proteger la solución de IoT. Para más información, vea:

Antes de empezar, instale o implemente Operaciones de IoT. Use las siguientes opciones para probar la conectividad a IoT MQ con clientes MQTT en un entorno de no producción.

Conexión desde un pod dentro del clúster con la configuración predeterminada

La primera opción es conectarse desde el clúster. Esta opción usa la configuración predeterminada y no requiere actualizaciones adicionales. En los ejemplos siguientes se muestra cómo conectarse desde dentro del clúster mediante Alpine Linux sin formato y un cliente MQTT usado habitualmente, mediante la cuenta de servicio y el certificado de CA raíz predeterminado.

  1. Cree un archivo denominado client.yaml con el código de configuración siguiente:

    apiVersion: v1
    kind: Pod
    metadata:
      name: mqtt-client
      # Namespace must match IoT MQ BrokerListener's namespace
      # Otherwise use the long hostname: aio-mq-dmqtt-frontend.azure-iot-operations.svc.cluster.local
      namespace: azure-iot-operations
    spec:
      # Use the "mqtt-client" service account which comes with default deployment
      # Otherwise create it with `kubectl create serviceaccount mqtt-client -n azure-iot-operations`
      serviceAccountName: mqtt-client
      containers:
        # Mosquitto and mqttui on Alpine
      - image: alpine
        name: mqtt-client
        command: ["sh", "-c"]
        args: ["apk add mosquitto-clients mqttui && sleep infinity"]
        volumeMounts:
        - name: mq-sat
          mountPath: /var/run/secrets/tokens
        - name: trust-bundle
          mountPath: /var/run/certs
      volumes:
      - name: mq-sat
        projected:
          sources:
          - serviceAccountToken:
              path: mq-sat
              audience: aio-mq # Must match audience in BrokerAuthentication
              expirationSeconds: 86400
      - name: trust-bundle
        configMap:
          name: aio-ca-trust-bundle-test-only # Default root CA cert
    
  2. Use kubectl apply -f client.yaml para implementar la configuración. Solo debe tardar unos segundos en iniciarse.

  3. Una vez que se ejecuta el pod, use kubectl exec para ejecutar comandos dentro del pod.

    Por ejemplo, para publicar un mensaje en el agente, abra un shell dentro del pod:

    kubectl exec --stdin --tty mqtt-client --namespace azure-iot-operations -- sh
    
  4. Dentro del shell del pod, ejecute el siguiente comando para publicar un mensaje en el agente:

    mosquitto_pub --host aio-mq-dmqtt-frontend --port 8883 --message "hello" --topic "world" --username '$sat' --pw $(cat /var/run/secrets/tokens/mq-sat) --debug --cafile /var/run/certs/ca.crt
    

    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.

  5. Para suscribirse al tema, ejecute el siguiente comando:

    mosquitto_sub --host aio-mq-dmqtt-frontend --port 8883 --topic "world" --username '$sat' --pw $(cat /var/run/secrets/tokens/mq-sat) --debug --cafile /var/run/certs/ca.crt
    

    La salida debe tener una apariencia similar a la siguiente:

    Client (null) sending CONNECT
    Client (null) received CONNACK (0)
    Client (null) sending SUBSCRIBE (Mid: 1, Topic: world, QoS: 0, Options: 0x00)
    Client (null) received SUBACK
    Subscribed (mid: 1): 0
    

    El cliente de mosquitto usa el mismo token de cuenta de servicio y certificado de CA raíz para autenticarse con el agente y suscribirse al tema.

  6. También puede usar mqttui para conectarse al agente mediante el token de cuenta de servicio. La marca --insecure es necesaria porque mqttui no admite la comprobación de la cadena de certificados TLS con un certificado de CA raíz personalizado.

    Precaución

    No se recomienda usar --insecure para escenarios de producción. Úselo solo con fines de prueba o desarrollo.

    mqttui --broker mqtts://aio-mq-dmqtt-frontend:8883 --username '$sat' --password $(cat /var/run/secrets/tokens/mq-sat) --insecure
    
  7. Para quitar el pod, ejecute kubectl delete pod mqtt-client -n azure-iot-operations.

Conexión de clientes desde fuera del clúster al puerto TLS predeterminado

Cadena de confianza TLS

Dado que el agente usa TLS, el cliente debe confiar en la cadena de certificados TLS del agente. Debe configurar el cliente para que confíe en el certificado de entidad de certificación raíz usado por el agente.

Para usar el certificado de CA raíz predeterminado, descárguelo de ConfigMap aio-ca-trust-bundle-test-only:

kubectl get configmap aio-ca-trust-bundle-test-only -n azure-iot-operations -o jsonpath='{.data.ca\.crt}' > ca.crt

Use el archivo ca.crt descargado para configurar el cliente para que confíe en la cadena de certificados TLS del agente.

Autenticación con el agente

De manera predeterminada, IoT MQ solo acepta cuentas de servicio de Kubernetes para la autenticación para las conexiones desde dentro del clúster. Para conectarse desde fuera del clúster, debe configurar un método de autenticación diferente, como X.509 o un nombre de usuario y contraseña. Para obtener más información, consulte Configuración de la autenticación.

Desactivar la autenticación sirve solo con fines de prueba

Para desactivar la autenticación con fines de prueba, edite el recurso BrokerListener y establezca el campo authenticationEnabled en false:

Precaución

La desactivación de la autenticación solo debe usarse con fines de prueba con un clúster de prueba que no sea accesible desde Internet.

kubectl patch brokerlistener listener -n azure-iot-operations --type='json' -p='[{"op": "replace", "path": "/spec/authenticationEnabled", "value": false}]'

Conectividad del puerto

Algunas distribuciones de Kubernetes pueden exponer IoT MQ a un puerto en el sistema host (localhost). Debe usar este enfoque porque facilita que los clientes del mismo host accedan a IoT MQ.

Por ejemplo, para crear un clúster K3d con la asignación del puerto 8883 MQTT predeterminado de IoT MQ a localhost:8883:

k3d cluster create --port '8883:8883@loadbalancer'

Pero para que este método funcione con IoT MQ, debe configurarlo para que use un equilibrador de carga en lugar de una dirección IP del clúster. Hay dos maneras de hacerlo: crear un equilibrador de carga o aplicar revisiones al tipo de servicio de recursos BrokerListener predeterminado existente para el equilibrador de carga.

Opción 1: Crear un equilibrador de carga

  1. Cree un archivo denominado loadbalancer.yaml con el código de configuración siguiente:

    apiVersion: v1
    kind: Service
    metadata:
        name: iotmq-public-svc
    spec:
        type: LoadBalancer
        ports:
        - name: mqtt1
          port: 8883
          targetPort: 8883
        selector:
          app: broker
          app.kubernetes.io/instance: broker
          app.kubernetes.io/managed-by: dmqtt-operator
          app.kubernetes.io/name: dmqtt
          tier: frontend
    
  2. Aplique la configuración para crear un servicio de equilibrador de carga:

    kubectl apply -f loadbalancer.yaml
    

Opción 2: Revisión del equilibrador de carga predeterminado

  1. Edite el recurso BrokerListener y cambie el campo serviceType a loadBalancer.

    kubectl patch brokerlistener listener --namespace azure-iot-operations --type='json' --patch='[{"op": "replace", "path": "/spec/serviceType", "value": "loadBalancer"}]'
    
  2. Espere a que se actualice el servicio.

    kubectl get service aio-mq-dmqtt-frontend --namespace azure-iot-operations
    

    La salida debe tener una apariencia similar a la siguiente:

    NAME                    TYPE           CLUSTER-IP     EXTERNAL-IP   PORT(S)          AGE
    aio-mq-dmqtt-frontend   LoadBalancer   10.43.107.11   XXX.XX.X.X    8883:30366/TCP   14h
    
  3. Puede usar la dirección IP externa para conectarse a IoT MQ a través de Internet. Asegúrese de usar la dirección IP externa en lugar de localhost.

    mosquitto_pub --qos 1 --debug -h XXX.XX.X.X --message hello --topic world --username client1 --pw password --cafile ca.crt
    

Sugerencia

Puede usar la dirección IP externa para conectarse a IoT MQ desde fuera del clúster. Si se ha usado el comando K3d con la opción de reenvío de puertos, se puede usar localhost para conectarse a IoT MQ. Por ejemplo, para conectarse con el cliente de mosquitto:

mosquitto_pub --qos 1 --debug -h localhost --message hello --topic world --username client1 --pw password --cafile ca.crt --insecure

En este ejemplo, el cliente de mosquitto usa el nombre de usuario y la contraseña para autenticarse con el agente junto con el certificado de CA raíz para comprobar la cadena de certificados TLS del agente. Aquí, la marca --insecure es necesaria porque el certificado TLS predeterminado emitido al equilibrador de carga solo es válido para el nombre de servicio predeterminado del equilibrador de carga (aio-mq-dmqtt-frontend) y direcciones IP asignadas, no localhost.

Nunca exponga el puerto IoT MQ a Internet sin autenticación ni TLS. Esto es peligroso y puede provocar un acceso no autorizado a los dispositivos IoT y traer tráfico no solicitado al clúster.

Para obtener información sobre cómo agregar localhost al nombre alternativo del firmante (SAN) del certificado para evitar el uso de la marca no segura, consulte Configuración de parámetros de certificado de servidor.

Uso del reenvío de puertos

Con minikube, kind y otros sistemas de emulación de clúster, es posible que no se asigne automáticamente una dirección IP externa. Por ejemplo, podría mostrarse como estado Pendiente.

  1. Para acceder al agente, reenvíe el puerto 8883 de escucha del agente al host.

    kubectl port-forward --namespace azure-iot-operations service/aio-mq-dmqtt-frontend 8883:mqtts-8883
    
  2. Use 127.0.0.1 para conectarse al agente en el puerto 8883 con la misma autenticación y configuración de TLS que el ejemplo sin reenvío de puertos.

El reenvío de puertos también es útil para probar IoT MQ localmente en la máquina de desarrollo sin tener que modificar la configuración del agente.

Para obtener más información, consulte Uso del reenvío de puertos para acceder a aplicaciones en un clúster para minikube y Exposición de servicios de Kubernetes a dispositivos externos para Azure Kubernetes Services Edge Essentials.

Sin TLS y sin autenticación

La razón por la que IoT MQ usa la autenticación de cuentas de servicio y TLS de manera predeterminada es proporcionar una experiencia segura de manera predeterminada que minimiza la exposición involuntaria de la solución de IoT a los atacantes. No debe desactivar TLS ni la autenticación en producción.

Precaución

No use en producción. Exponer IoT MQ a Internet sin autenticación ni TLS podría resultar en accesos no autorizados e, incluso, ataques DDOS.

Si comprende los riesgos y necesita usar un puerto no seguro en un entorno bien controlado, puede desactivar TLS y la autenticación con fines de prueba siguiendo estos pasos:

  1. Cree un nuevo recurso BrokerListener sin la configuración de TLS:

    apiVersion: mq.iotoperations.azure.com/v1beta1
    kind: BrokerListener
    metadata:
      name: non-tls-listener
      namespace: azure-iot-operations
    spec:
      brokerRef: broker
      serviceType: loadBalancer
      serviceName: my-unique-service-name
      authenticationEnabled: false
      authorizationEnabled: false
      port: 1883
    

    Los campos authenticationEnabled y authorizationEnabled se establecen en false para desactivar la autenticación y la autorización. El campo port se establece en 1883 para usar el puerto MQTT común.

  2. Espere a que se actualice el servicio.

    kubectl get service my-unique-service-name --namespace azure-iot-operations
    

    La salida debe tener una apariencia similar a la siguiente:

    NAME                     TYPE           CLUSTER-IP      EXTERNAL-IP   PORT(S)          AGE
    my-unique-service-name   LoadBalancer   10.43.144.182   XXX.XX.X.X    1883:31001/TCP   5m11s
    

    El nuevo puerto 1883 está disponible.

  3. Use el cliente mosquitto para conectarse al agente:

    mosquitto_pub --qos 1 --debug -h localhost --message hello --topic world
    

    La salida debe tener una apariencia similar a la siguiente:

    Client mosq-7JGM4INbc5N1RaRxbW sending CONNECT
    Client mosq-7JGM4INbc5N1RaRxbW received CONNACK (0)
    Client mosq-7JGM4INbc5N1RaRxbW sending PUBLISH (d0, q1, r0, m1, 'world', ... (5 bytes))
    Client mosq-7JGM4INbc5N1RaRxbW received PUBACK (Mid: 1, RC:0)
    Client mosq-7JGM4INbc5N1RaRxbW sending DISCONNECT