emqx/emqx-bridge-mqtt

Bridge to Azure IoT Hub fails

frodecat opened this issue · 7 comments

Hi,

I am trying to setup an Emqx mqtt bridge to Azure IoT hub, but when trying to start the bridge it fails all the time. I have tried several different configurations.

Do you have any pinpointers on how to setup a working bridge to Azure IoT ?

I use the same username, same password and same CAcert in a python client script which works fine, but the bridge is not working.

See attached configuration, log and the working python script. I have removed the signature part of the shared access key for privacy purposes.

Thanks,
Frode

testiotmedcert - Copy.py.txt

emqx.log - Copy (16).1.txt
emqx conf 23.juni 2020.txt

Hi @frodecat It seems failed to establish an SSL connection. Could you give me a tcpdump to me? Thanks

Thank you for your response.

Please see the below image of wireshark when I run the "emqx_ctl bridges start aws" command and receives "Start bridge failed".

Btw. I am currently running this on windows. Will consider moving it to Linux when going to production.

image

I have same problem. And i can provide test parameters.

Azure TLS https://docs.azure.cn/zh-cn/iot-hub/iot-hub-mqtt-support#tlsssl-configuration

Errors

2020-08-06 18:49:51.567 [notice] [Bridge] Bridge emqx_bridge_worker_aws discarded info type event at state idle:{disconnected,
                                                                                <0.1757.0>,
                                                                                {shutdown,
                                                                                 unacceptable_protocol_version}}

Config:

# Azure TLS https://docs.azure.cn/zh-cn/iot-hub/iot-hub-mqtt-support#tlsssl-configuration

bridge.mqtt.aws.address = yst-iot.azure-devices.net:8883

## - mqttv5
## - mqttv4
## - mqttv3
bridge.mqtt.aws.proto_ver = mqttv4

bridge.mqtt.aws.start_type = auto

bridge.mqtt.aws.bridge_mode = true

bridge.mqtt.aws.clientid = ttt

bridge.mqtt.aws.clean_start = true

bridge.mqtt.aws.username = yst-iot.azure-devices.net/ttt/?api-version=2018-06-30

bridge.mqtt.aws.password = SharedAccessSignature sr=yst-iot.azure-devices.net%2Fttt%2F%3Fapi-version%3D2018-06-30&sig=aNMY1KQRPFHx%2BhXBCOV0TTmX5QlA5GZWg9p%2BYj8dibM%3D&se=1600283731&skn=

# bridge.mqtt.aws.forwards = devices/ttt/messages/events/

# bridge.mqtt.aws.forward_mountpoint = bridge/aws/${node}/

bridge.mqtt.aws.ssl = on

## PEM-encoded CA certificates of the bridge.
bridge.mqtt.aws.cacertfile = /Users/emqx/Downloads/w.crt

# bridge.mqtt.aws.certfile = etc/certs/client-cert.pem

# bridge.mqtt.aws.keyfile = etc/certs/client-key.pem

bridge.mqtt.aws.ciphers = ECDHE-ECDSA-AES256-GCM-SHA384,ECDHE-RSA-AES256-GCM-SHA384,ECDHE-ECDSA-AES256-SHA384,ECDHE-RSA-AES256-SHA384,ECDHE-ECDSA-DES-CBC3-SHA,ECDH-ECDSA-AES256-GCM-SHA384,ECDH-RSA-AES256-GCM-SHA384,ECDH-ECDSA-AES256-SHA384,ECDH-RSA-AES256-SHA384,DHE-DSS-AES256-GCM-SHA384,DHE-DSS-AES256-SHA256,AES256-GCM-SHA384,AES256-SHA256,ECDHE-ECDSA-AES128-GCM-SHA256,ECDHE-RSA-AES128-GCM-SHA256,ECDHE-ECDSA-AES128-SHA256,ECDHE-RSA-AES128-SHA256,ECDH-ECDSA-AES128-GCM-SHA256,ECDH-RSA-AES128-GCM-SHA256,ECDH-ECDSA-AES128-SHA256,ECDH-RSA-AES128-SHA256,DHE-DSS-AES128-GCM-SHA256,DHE-DSS-AES128-SHA256,AES128-GCM-SHA256,AES128-SHA256,ECDHE-ECDSA-AES256-SHA,ECDHE-RSA-AES256-SHA,DHE-DSS-AES256-SHA,ECDH-ECDSA-AES256-SHA,ECDH-RSA-AES256-SHA,AES256-SHA,ECDHE-ECDSA-AES128-SHA,ECDHE-RSA-AES128-SHA,DHE-DSS-AES128-SHA,ECDH-ECDSA-AES128-SHA,ECDH-RSA-AES128-SHA,AES128-SHA

bridge.mqtt.aws.psk_ciphers = PSK-AES128-CBC-SHA,PSK-AES256-CBC-SHA,PSK-3DES-EDE-CBC-SHA,PSK-RC4-SHA

bridge.mqtt.aws.keepalive = 60s

bridge.mqtt.aws.tls_versions = tlsv1.2

bridge.mqtt.aws.reconnect_interval = 30s

bridge.mqtt.aws.retry_interval = 20s

bridge.mqtt.aws.batch_size = 32

bridge.mqtt.aws.max_inflight_size = 32

bridge.mqtt.aws.queue.replayq_dir = data/emqx_aws_bridge/

bridge.mqtt.aws.queue.replayq_seg_bytes = 10MB

bridge.mqtt.aws.queue.max_total_size = 5GB

/Users/emqx/Downloads/w.crt

-----BEGIN CERTIFICATE-----
MIIDdzCCAl+gAwIBAgIEAgAAuTANBgkqhkiG9w0BAQUFADBaMQswCQYDVQQGEwJJ
RTESMBAGA1UEChMJQmFsdGltb3JlMRMwEQYDVQQLEwpDeWJlclRydXN0MSIwIAYD
VQQDExlCYWx0aW1vcmUgQ3liZXJUcnVzdCBSb290MB4XDTAwMDUxMjE4NDYwMFoX
DTI1MDUxMjIzNTkwMFowWjELMAkGA1UEBhMCSUUxEjAQBgNVBAoTCUJhbHRpbW9y
ZTETMBEGA1UECxMKQ3liZXJUcnVzdDEiMCAGA1UEAxMZQmFsdGltb3JlIEN5YmVy
VHJ1c3QgUm9vdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKMEuyKr
mD1X6CZymrV51Cni4eiVgLGw41uOKymaZN+hXe2wCQVt2yguzmKiYv60iNoS6zjr
IZ3AQSsBUnuId9Mcj8e6uYi1agnnc+gRQKfRzMpijS3ljwumUNKoUMMo6vWrJYeK
mpYcqWe4PwzV9/lSEy/CG9VwcPCPwBLKBsua4dnKM3p31vjsufFoREJIE9LAwqSu
XmD+tqYF/LTdB1kC1FkYmGP1pWPgkAx9XbIGevOF6uvUA65ehD5f/xXtabz5OTZy
dc93Uk3zyZAsuT3lySNTPx8kmCFcB5kpvcY67Oduhjprl3RjM71oGDHweI12v/ye
jl0qhqdNkNwnGjkCAwEAAaNFMEMwHQYDVR0OBBYEFOWdWTCCR1jMrPoIVDaGezq1
BE3wMBIGA1UdEwEB/wQIMAYBAf8CAQMwDgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3
DQEBBQUAA4IBAQCFDF2O5G9RaEIFoN27TyclhAO992T9Ldcw46QQF+vaKSm2eT92
9hkTI7gQCvlYpNRhcL0EYWoSihfVCr3FvDB81ukMJY2GQE/szKN+OMY3EU/t3Wgx
jkzSswF07r51XgdIGn9w/xZchMB5hbgF/X++ZRGjD8ACtPhSNzkE1akxehi/oCr0
Epn3o0WC4zxe9Z2etciefC7IpJ5OCBRLbf1wbWsaY71k5h+3zvDyny67G7fyUIhz
ksLi4xaNmjICq44Y3ekQEe5+NauQrz4wlHrQMz2nZQ/1/I6eYs9HRCwBXbsdtTLS
R9I4LtD+gdwyah617jzV/OeBHRnDJELqYzmp
-----END CERTIFICATE-----

test python

azure.py

from paho.mqtt import client as mqtt
import ssl

URL = 'yst-iot.azure-devices.net'
PORT = 8883
CLIENT_ID = 'ttt'
USERNAME = 'yst-iot.azure-devices.net/ttt/?api-version=2018-06-30'
PWD = 'SharedAccessSignature sr=yst-iot.azure-devices.net%2Fttt%2F%3Fapi-version%3D2018-06-30&sig=aNMY1KQRPFHx%2BhXBCOV0TTmX5QlA5GZWg9p%2BYj8dibM%3D&se=1600283731&skn='
SSL = True


path_to_root_cert = "/Users/emqx/Downloads/w.crt"
device_id = CLIENT_ID
sas_token = PWD
iot_hub_name = "yst-iot"

def on_connect(client, userdata, flags, rc):
  print ("Device connected with result code: " + str(rc))
def on_disconnect(client, userdata, rc):
  print ("Device disconnected with result code: " + str(rc))
def on_publish(client, userdata, mid):
  print ("Device sent message")
def on_message(d):
  print(d)

client = mqtt.Client(client_id=device_id, protocol=mqtt.MQTTv311)

client.on_connect = on_connect
client.on_disconnect = on_disconnect
client.on_publish = on_publish
client.on_message = on_message


u = username=iot_hub_name+".azure-devices.cn/" + device_id + "/?api-version=2018-06-30"
print('username: ' + u)
client.username_pw_set(u, password=sas_token)

client.tls_set(ca_certs=path_to_root_cert, certfile=None, keyfile=None,
               cert_reqs=ssl.CERT_REQUIRED, tls_version=ssl.PROTOCOL_TLSv1_2, ciphers=None)
client.tls_insecure_set(False)

client.connect(iot_hub_name+".azure-devices.net", port=8883)

client.publish("devices/" + device_id + "/messages/events/", "{id=123}", qos=1)
client.loop_forever()

Hi @wivwiv Plz turn off bridge.mqtt.aws.bridge_mode = true

This option is only available for brokers that support bridge mode. for example: mosquitto, rabbtimq mqtt-plugin

In other brokers, this option needs to be set to false.

Hi guys, We have fixed it on 4.2-beta.1. Plz check it again

Hi @wivwiv Plz turn off bridge.mqtt.aws.bridge_mode = true

This option is only available for brokers that support bridge mode. for example: mosquitto, rabbtimq mqtt-plugin

In other brokers, this option needs to be set to false.

Thank you! That was it! It is now working! :)

For others out there who want to bridge to Azure IoT hub, this is the final working configuration I have now:

bridge.mqtt.aws.address = myiothubname.azure-devices.net:8883
bridge.mqtt.aws.proto_ver = mqttv4
bridge.mqtt.aws.bridge_mode = false
bridge.mqtt.aws.clientid = starkDevice
bridge.mqtt.aws.clean_start = true
bridge.mqtt.aws.username = myiothubname.azure-devices.net/starkDevice/?api-version=2018-06-30
bridge.mqtt.aws.forwards = devices/starkDevice/messages/events/
bridge.mqtt.aws.ssl = on
bridge.mqtt.aws.cacertfile = etc/certs/Baltimore.pem
bridge.mqtt.aws.certfile = etc/certs/starkDevice.pem
bridge.mqtt.aws.keyfile = etc/certs/starkDevice.key
bridge.mqtt.aws.tls_versions = tlsv1.2

Rest of the options are more or less default.

So bridge mode false and use mqttv4.

4ff4n commented

Hi @frodecat, how did you generate these
bridge.mqtt.aws.cacertfile = etc/certs/Baltimore.pem
bridge.mqtt.aws.certfile = etc/certs/starkDevice.pem
bridge.mqtt.aws.keyfile = etc/certs/starkDevice.key

Do we need to generate these on our local machine or is there anything else we need to do on azure side as well?

It would be awesome if you could help

Thanks