Compartir a través de


Prueba de la conectividad con el corredor MQTT con clientes 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.

En este artículo se muestran diferentes formas de probar la conectividad con el corredor MQTT con clientes MQTT en un entorno de no producción.

De manera predeterminada, el corredor MQTT:

  • Implementa un cliente de escucha habilitado para TLS en el puerto 18883 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 comenzar, instale o configure operaciones de loT. Use las siguientes opciones para probar la conectividad con el corredor MQTT 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 MQTT broker BrokerListener's namespace
      # Otherwise use the long hostname: aio-broker.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-internal # 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-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.

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

    mosquitto_sub --host aio-broker --port 18883 --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 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. 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.

Si se conecta al agente desde otro espacio de nombres, debe usar el nombre de host de servicio completo aio-broker.azure-iot-operations.svc.cluster.local. También debe agregar el nombre DNS al certificado de servidor mediante la inclusión de un campo DNS de nombre alternativo de firmante (SAN) al recurso BrokerListener. Para obtener más información, consulte Configuración de parámetros de certificado de servidor.

Autenticación con el agente

De manera predeterminada, el corredor MQTT 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. 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 el corredor MQTT a un puerto en el sistema host (localhost). Debe usar este enfoque porque facilita que los clientes del mismo host accedan al corredor MQTT.

Por ejemplo, para crear un clúster K3d con la asignación del puerto MQTT predeterminado del corredor MQTT 18883 a localhost:18883:

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

Pero para que este método funcione con el corredor MQTT, debe configurarlo para que use un equilibrador de carga en lugar de la 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: 18883
          targetPort: 18883
        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-broker --namespace azure-iot-operations
    

    La salida debe tener una apariencia similar a la siguiente:

    NAME                    TYPE           CLUSTER-IP     EXTERNAL-IP   PORT(S)          AGE
    aio-broker   LoadBalancer   10.43.107.11   XXX.XX.X.X    18883:30366/TCP   14h
    
  3. Puede usar la dirección IP externa para conectarse al corredor MQTT 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 al corredor MQTT desde fuera del clúster. Si ha usado el comando K3d con la opción de reenvío de puertos, puede usar localhost para conectarse al agente MQTT. 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-broker) y las direcciones IP asignadas, no localhost.

Nunca exponga el puerto del corredor MQTT 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 corredor, reenvíe el puerto de escucha 18883 del corredor al host.

    kubectl port-forward --namespace azure-iot-operations service/aio-broker 18883:mqtts-18883
    
  2. Use 127.0.0.1 para conectarse al corredor en el puerto 18883 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 el corredor MQTT localmente en la máquina de desarrollo sin tener que modificar la configuración del agente. Para más información sobre minikube, vea Uso del enrutamiento de puerto para acceder a aplicaciones en un clúster

Enrutamiento de puerto en AKS Edge Essentials

Para Edge Essentials de Azure Kubernetes Services, debe realizar algunos pasos adicionales. Para más información sobre el enrutamiento de puerto, vea Exposición de servicios de Kubernetes a dispositivos externos.

  1. Imagine que el servicio del agente se expone a una dirección IP externa mediante un equilibrador de carga. Por ejemplo, si ha revisado el equilibrador de carga predeterminado aio-broker, obtenga la dirección IP externa del servicio.

    kubectl get service aio-broker --namespace azure-iot-operations
    

    La salida debe tener una apariencia similar a la siguiente:

    NAME                    TYPE           CLUSTER-IP     EXTERNAL-IP   PORT(S)          AGE
    aio-broker   LoadBalancer   10.43.107.11   192.168.0.4   18883:30366/TCP   14h
    
  2. Configure el enrutamiento de puerto al servicio aio-broker en la dirección IP externa 192.168.0.4 y el puerto 18883:

    netsh interface portproxy add v4tov4 listenport=18883 connectport=18883 connectaddress=192.168.0.4
    
  3. Abra el puerto en el firewall para permitir el tráfico al servicio del agente:

    New-NetFirewallRule -DisplayName "AIO MQTT Broker" -Direction Inbound -Protocol TCP -LocalPort 18883 -Action Allow
    
  4. Use la dirección IP pública del host para conectarse al agente MQTT.

Sin TLS y sin autenticación

La razón por la que el corredor MQTT usa la autenticación TLS y las cuentas de servicio de forma 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 el corredor MQTT a Internet sin autenticación y TLS puede provocar 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: mqttbroker.iotoperations.azure.com/v1beta1
    kind: BrokerListener
    metadata:
      name: non-tls-listener
      namespace: azure-iot-operations
    spec:
      brokerRef: default
      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