Python MQTT Client to OpenRemote - mqtt/1: SSL handshake failure

Deal!

So the issue should be somewhere with the cert / haproxy :thinking:
Looking into it.

Could the .dev tld be an issue? …
Can the domain simply be swapped out via the ENV Vars?

No, i guess not…

So i found out, if you want to validate the certificate with mqtt explorer, you have to click on “advanced” then “certificates” and mqtt explorer will compare the certificates with the server.

same behaviour like i mentioned before in paho, you have to add the certs to your py script to validate the server certs.

btw client.tls_set(cert_reqs=ssl.CERT_NONE) works for me

Hope you are not running into my setup now :grimacing:
Since I shutdown the .dev one and deployed a .de version.
But I will test it right now.

nah, i tried it at my server.

btw, your error log has nothing to do with the ssl cert. there is an issue with your credentials.

Yea but which certs to add?¿
I am running a standalone mosquitto broker with cert auth so I am familiar with that.

But with OpenRemote which certs do I add there?

openssl s_client -showcerts -connect openremote.ready2plugin.dev:443

there are your certs shown :slight_smile:

its casing… I am going insane.

VS

Something in my code is doing something funky…

Its python3 requests or OpenRemote is returning something wrong for the Asset ID.
In my Code I create assets and users via API.

    getApiToken()
    rURL = f'{apiurl}/api/master/asset'
    rData = {'name':f'{assetName}','type':'ThingAsset','realm':'master','attributes':{'notes':{'name':'notes','type':'text'},'location':{'name':'location','type':'GEO_JSONPoint'},'subscribeAttribute':{'name':'subscribeAttribute','type':'boolean'},'writeAttribute':{'name':'writeAttribute','type':'number'}}}
    rHeaders = {'Authorization': f'Bearer {thismodule.apitoken}'}
    r = requests.post(url=rURL, json=rData, headers=rHeaders)

r.text =>

{
   "id":"32q3XeXJYgRUGRAjWDmtFX",
   "version":0,
   "createdOn":1687281410731,
   "name":"MQTT-TESTING",
   "accessPublicRead":false,
   "realm":"master",
   "type":"ThingAsset",
   "path":[
      "32q3XeXJYgRUGRAjWDmtFX"
   ],
   "attributes":{
      "notes":{
         "type":"text",
         "value":null,
         "name":"notes",
         "timestamp":1687281410729
      },
      "location":{
         "type":"GEO_JSONPoint",
         "value":null,
         "name":"location",
         "timestamp":1687281410729
      },
      "subscribeAttribute":{
         "type":"boolean",
         "value":null,
         "name":"subscribeAttribute",
         "timestamp":1687281410729
      },
      "writeAttribute":{
         "type":"number",
         "value":null,
         "name":"writeAttribute",
         "timestamp":1687281410729
      }
   }
}

Looking at the id 32q3XeXJYgRUGRAjWDmtFX


It looks like the returned ID has random casing.
In the UI the ID is 32q3xexjygrugrajwdmtfx

+ 32q3xexjygrugrajwdmtfx
- 32q3XeXJYgRUGRAjWDmtFX

This screams encoding / charset issue.
logging: r.encoding is => utf-8 which should be right.

But this is my issue! Which I am solving FOR NOW with a simple .lower -_- json.loads(r.content)["id"].lower()

This whole thing is rather odd since all other responses return the expected values only this one is mangled with the casing.
Will test with the swagger view :thinking:

omg…
Since I am using asset ids for the service usernames…

The Asset ID is correctly: 4SkSVEYFoHwGkvRdfZJLOT
But when I create a service User with the name 4SkSVEYFoHwGkvRdfZJLOT

{"enabled":true, "realm":"master","serviceAccount":true,"username":"4SkSVEYFoHwGkvRdfZJLOT"}
{
  "realm": "master",
  "id": "33118ee6-ebfe-4de6-8e7d-5cf2fdc9add4",
  "enabled": true,
  "serviceAccount": true,
  "username": "4sksveyfohwgkvrdfzjlot"
}

It gets lowered…

@Denis @Rich

I figured it out.


| WARNING  | 2023-06-20 19:49:48,123 | MQTT TLS Config not complete - try setting only ca_certs
| INFO     | 2023-06-20 19:49:53,345 | Connected to broker with msg id 0 - Connection accepted

Thanks for attending my private shit show :neutral_face:

2 Likes

Haha, glad you got it now! :slight_smile:

1 Like

Excellent detective work!

Indeed keycloak doesn’t support case sensitive usernames so that’s where the lower case is introduced.

The auth checks should also ignore case but there’s clearly some mismatch somewhere.

1 Like

Am I blind or something?
I had it working already publishing to the Asset via the MQTT Client with static testing.
Now dynamically something is off.

It seems to be a topic / publish issue.

Here is my program log so you can understand a bit what is happening.

| DEBUG    | 2023-06-23 11:21:21,966 | mqtt.main                      | __init__                       | line 37  in /home/eha/develop/ready2plugin/r2p-mqtt-openremotebridge/Docker/app/code/mqtt/main.py | Set MQTT tls options
| DEBUG    | 2023-06-23 11:21:21,967 | mqtt.main                      | __init__                       | line 46  in /home/eha/develop/ready2plugin/r2p-mqtt-openremotebridge/Docker/app/code/mqtt/main.py | Set MQTT username: r2p-or-connector and password:
| DEBUG    | 2023-06-23 11:21:21,967 | mqtt.main                      | sub_topics                     | line 92  in /home/eha/develop/ready2plugin/r2p-mqtt-openremotebridge/Docker/app/code/mqtt/main.py | Client not connected yet, waiting for CONNACK. . .
| INFO     | 2023-06-23 11:21:22,125 | mqtt.main                      | on_connect                     | line 66  in /home/eha/develop/ready2plugin/r2p-mqtt-openremotebridge/Docker/app/code/mqtt/main.py | Connected to broker with msg id 0 - Connection accepted
| DEBUG    | 2023-06-23 11:21:22,125 | mqtt.main                      | on_connect                     | line 67  in /home/eha/develop/ready2plugin/r2p-mqtt-openremotebridge/Docker/app/code/mqtt/main.py | Client: <paho.mqtt.client.Client object at 0x7f8177f56590> | Userdata: None | Flags: {'session present': 0}
| DEBUG    | 2023-06-23 11:21:22,468 | mqtt.main                      | sub_topics                     | line 95  in /home/eha/develop/ready2plugin/r2p-mqtt-openremotebridge/Docker/app/code/mqtt/main.py | Subscribed to topic: #
| DEBUG    | 2023-06-23 11:21:22,468 | __main__                       | r2pToOrAsset                   | line 26  in /home/eha/develop/ready2plugin/r2p-mqtt-openremotebridge/Docker/app/code/main.py | Started r2pToOrAsset Thread
| DEBUG    | 2023-06-23 11:21:22,468 | __main__                       | r2pToOrAsset                   | line 48  in /home/eha/develop/ready2plugin/r2p-mqtt-openremotebridge/Docker/app/code/main.py | Messages Queue: 0
| DEBUG    | 2023-06-23 11:21:25,678 | mqtt.main                      | on_message                     | line 80  in /home/eha/develop/ready2plugin/r2p-mqtt-openremotebridge/Docker/app/code/mqtt/main.py | message payload: {"client_id":"DEVELOP-WAECHTER-CONSOLE","mac":"DEADBEEF2342","pcb_id":"0478303","dev_id":"0101010478303DEADBEEF2342","uptime":4991,"localtime":1687512085,"ts_since_unix_epoch":1687512085,"reset_cause":23924,"wake_cause":9667,"mem_free":22024,"mem_alloc":8003,"mpy_sysname":"TESTING","mpy_nodename":"TESTING","mpy_release":"TESTING","mpy_ver_str":"TESTING","mpy_git_tag":"TESTING","mpy_git_hash":"TESTING","mpy_machine":"TESTING","part_boot":21730,"tainted":false,"pcb_temp":6451,"cable_temp_esp32":22808,"cable_temp_stm32":399,"ampere_rms_esp32":18065,"ampere_rms_stm32":1185,"volt_gridmeter":32731,"ip_addr":"192.168.1.254","ip_subnet":"255.255.255.0","ip_gateway":"192.168.1.1","ip_dns":"192.168.1.1","wifi_rssi":9943,"wifi_essid":"WLAN","wifi_peer_mac":"DE:AD:BE:EF:23:42"}
| DEBUG    | 2023-06-23 11:21:25,678 | mqtt.main                      | on_message                     | line 81  in /home/eha/develop/ready2plugin/r2p-mqtt-openremotebridge/Docker/app/code/mqtt/main.py | message topic: r2p/waechter/DEVELOP-WAECHTER-CONSOLE/tele/
| DEBUG    | 2023-06-23 11:21:27,469 | __main__                       | r2pToOrAsset                   | line 42  in /home/eha/develop/ready2plugin/r2p-mqtt-openremotebridge/Docker/app/code/main.py | Asset not found in DB. Creating new Asset and sending Data.
| DEBUG    | 2023-06-23 11:21:27,470 | urllib3.connectionpool         | _new_conn                      | line 1003 in /home/eha/develop/ready2plugin/r2p-mqtt-openremotebridge/.venv/lib/python3.11/site-packages/urllib3/connectionpool.py | Starting new HTTPS connection (1): openremote.ready2plugin.dev:443
| DEBUG    | 2023-06-23 11:21:27,571 | urllib3.connectionpool         | _make_request                  | line 456 in /home/eha/develop/ready2plugin/r2p-mqtt-openremotebridge/.venv/lib/python3.11/site-packages/urllib3/connectionpool.py | https://openremote.ready2plugin.dev:443 "POST /auth/realms/master/protocol/openid-connect/token HTTP/1.1" 200 2055
| DEBUG    | 2023-06-23 11:21:27,572 | urllib3.connectionpool         | _new_conn                      | line 1003 in /home/eha/develop/ready2plugin/r2p-mqtt-openremotebridge/.venv/lib/python3.11/site-packages/urllib3/connectionpool.py | Starting new HTTPS connection (1): openremote.ready2plugin.dev:443
| DEBUG    | 2023-06-23 11:21:27,668 | urllib3.connectionpool         | _make_request                  | line 456 in /home/eha/develop/ready2plugin/r2p-mqtt-openremotebridge/.venv/lib/python3.11/site-packages/urllib3/connectionpool.py | https://openremote.ready2plugin.dev:443 "POST /api/master/asset HTTP/1.1" 200 574
| DEBUG    | 2023-06-23 11:21:27,670 | urllib3.connectionpool         | _new_conn                      | line 1003 in /home/eha/develop/ready2plugin/r2p-mqtt-openremotebridge/.venv/lib/python3.11/site-packages/urllib3/connectionpool.py | Starting new HTTPS connection (1): openremote.ready2plugin.dev:443
| DEBUG    | 2023-06-23 11:21:27,891 | urllib3.connectionpool         | _make_request                  | line 456 in /home/eha/develop/ready2plugin/r2p-mqtt-openremotebridge/.venv/lib/python3.11/site-packages/urllib3/connectionpool.py | https://openremote.ready2plugin.dev:443 "POST /api/master/user/master/users HTTP/1.1" 200 135
| DEBUG    | 2023-06-23 11:21:27,893 | urllib3.connectionpool         | _new_conn                      | line 1003 in /home/eha/develop/ready2plugin/r2p-mqtt-openremotebridge/.venv/lib/python3.11/site-packages/urllib3/connectionpool.py | Starting new HTTPS connection (1): openremote.ready2plugin.dev:443
| DEBUG    | 2023-06-23 11:21:27,983 | urllib3.connectionpool         | _make_request                  | line 456 in /home/eha/develop/ready2plugin/r2p-mqtt-openremotebridge/.venv/lib/python3.11/site-packages/urllib3/connectionpool.py | https://openremote.ready2plugin.dev:443 "POST /api/master/asset/user/link HTTP/1.1" 204 0
utf-8
| DEBUG    | 2023-06-23 11:21:27,985 | urllib3.connectionpool         | _new_conn                      | line 1003 in /home/eha/develop/ready2plugin/r2p-mqtt-openremotebridge/.venv/lib/python3.11/site-packages/urllib3/connectionpool.py | Starting new HTTPS connection (1): openremote.ready2plugin.dev:443
| DEBUG    | 2023-06-23 11:21:28,089 | urllib3.connectionpool         | _make_request                  | line 456 in /home/eha/develop/ready2plugin/r2p-mqtt-openremotebridge/.venv/lib/python3.11/site-packages/urllib3/connectionpool.py | https://openremote.ready2plugin.dev:443 "GET /api/master/user/master/reset-secret/b8c2b293-d771-4ece-9ae7-b22c3cc30997 HTTP/1.1" 200 32
| WARNING  | 2023-06-23 11:21:28,091 | mqtt.main                      | __init__                       | line 27  in /home/eha/develop/ready2plugin/r2p-mqtt-openremotebridge/Docker/app/code/mqtt/main.py | MQTT TLS Config not complete - try setting only ca_certs
| DEBUG    | 2023-06-23 11:21:28,091 | mqtt.main                      | __init__                       | line 37  in /home/eha/develop/ready2plugin/r2p-mqtt-openremotebridge/Docker/app/code/mqtt/main.py | Set MQTT tls options
| DEBUG    | 2023-06-23 11:21:28,091 | mqtt.main                      | __init__                       | line 40  in /home/eha/develop/ready2plugin/r2p-mqtt-openremotebridge/Docker/app/code/mqtt/main.py | No Full TLS config - just ca_certs or certfile or keyfile defined!
| DEBUG    | 2023-06-23 11:21:28,091 | mqtt.main                      | __init__                       | line 42  in /home/eha/develop/ready2plugin/r2p-mqtt-openremotebridge/Docker/app/code/mqtt/main.py | Try setting ca_certs only
| DEBUG    | 2023-06-23 11:21:28,091 | mqtt.main                      | __init__                       | line 46  in /home/eha/develop/ready2plugin/r2p-mqtt-openremotebridge/Docker/app/code/mqtt/main.py | Set MQTT username: master:4zszrqpl2atmpepkqymqy9 and password: qNmnenpZN8JkdcsH7UVsYaBENCfe1rz6
| INFO     | 2023-06-23 11:21:33,295 | mqtt.main                      | on_connect                     | line 66  in /home/eha/develop/ready2plugin/r2p-mqtt-openremotebridge/Docker/app/code/mqtt/main.py | Connected to broker with msg id 0 - Connection accepted
| DEBUG    | 2023-06-23 11:21:33,301 | mqtt.main                      | on_connect                     | line 67  in /home/eha/develop/ready2plugin/r2p-mqtt-openremotebridge/Docker/app/code/mqtt/main.py | Client: <paho.mqtt.client.Client object at 0x7f8177f67ed0> | Userdata: None | Flags: {'session present': 0}
| DEBUG    | 2023-06-23 11:21:33,306 | mqtt.main                      | pub_topic                      | line 102 in /home/eha/develop/ready2plugin/r2p-mqtt-openremotebridge/Docker/app/code/mqtt/main.py | Publish topic: master/4zsZrQpl2ATMpEPKqyMQy9/writeattributevalue/tele/4zsZrQpl2ATMpEPKqyMQy9 with data {'client_id': 'DEVELOP-WAECHTER-CONSOLE', 'mac': 'DEADBEEF2342', 'pcb_id': '0478303', 'dev_id': '0101010478303DEADBEEF2342', 'uptime': 4991, 'localtime': 1687512085, 'ts_since_unix_epoch': 1687512085, 'reset_cause': 23924, 'wake_cause': 9667, 'mem_free': 22024, 'mem_alloc': 8003, 'mpy_sysname': 'TESTING', 'mpy_nodename': 'TESTING', 'mpy_release': 'TESTING', 'mpy_ver_str': 'TESTING', 'mpy_git_tag': 'TESTING', 'mpy_git_hash': 'TESTING', 'mpy_machine': 'TESTING', 'part_boot': 21730, 'tainted': False, 'pcb_temp': 6451, 'cable_temp_esp32': 22808, 'cable_temp_stm32': 399, 'ampere_rms_esp32': 18065, 'ampere_rms_stm32': 1185, 'volt_gridmeter': 32731, 'ip_addr': '192.168.1.254', 'ip_subnet': '255.255.255.0', 'ip_gateway': '192.168.1.1', 'ip_dns': '192.168.1.1', 'wifi_rssi': 9943, 'wifi_essid': 'WLAN', 'wifi_peer_mac': 'DE:AD:BE:EF:23:42'}
| DEBUG    | 2023-06-23 11:21:33,306 | __main__                       | r2pToOrAsset                   | line 48  in /home/eha/develop/ready2plugin/r2p-mqtt-openremotebridge/Docker/app/code/main.py | Messages Queue: 0
| DEBUG    | 2023-06-23 11:21:33,330 | mqtt.main                      | on_disconnect                  | line 76  in /home/eha/develop/ready2plugin/r2p-mqtt-openremotebridge/Docker/app/code/mqtt/main.py | MQTT Client disconnected.

It seems I am publishing to the wrong topic.

openremote-manager-1     | 2023-06-23 11:21:33.317  ERROR   [Thread-1 (ActiveMQ-serve..ebc)] ache.activemq.artemis.core.protocol.mqtt : AMQ834002: Er
ror processing control packet: MqttPublishMessage[fixedHeader=MqttFixedHeader[messageType=PUBLISH, isDup=false, qosLevel=AT_MOST_ONCE, isRetain=false, remainingLength=920], variableHeader=MqttPublishVariableHeader[topicName=master/4zsZrQpl2ATMpEPKqyMQy9/writeattributevalue/tele/4zsZrQpl2ATMpEPKqyM
Qy9, packetId=-1], payload=PooledSlicedByteBuf(ridx: 0, widx: 841, cap: 841/841, unwrapped: PooledUnsafeDirectByteBuf(ridx: 923, widx: 923, cap: 2048))]
openremote-manager-1     | ActiveMQSecurityException[errorType=SECURITY_EXCEPTION message=AMQ229032: User: master:4zszrqpl2atmpepkqymqy9 does not have permission='SEND' on address master.4zsZrQpl2ATMpEPKqyMQy9.writeattributevalue.tele.4zsZrQpl2ATMpEPKqyMQy9]
openremote-manager-1     |      at org.apache.activemq.artemis.core.security.impl.SecurityStoreImpl.check(SecurityStoreImpl.java:289)                openremote-manager-1     |      at org.apache.activemq.artemis.core.server.impl.ServerSessionImpl.securityCheck(ServerSessionImpl.java:502)
openremote-manager-1     |      at org.apache.activemq.artemis.core.server.impl.ServerSessionImpl.doSend(ServerSessionImpl.java:2212)
openremote-manager-1     |      at org.apache.activemq.artemis.core.server.impl.ServerSessionImpl.send(ServerSessionImpl.java:1840)
openremote-manager-1     |      at org.apache.activemq.artemis.core.server.impl.ServerSessionImpl.send(ServerSessionImpl.java:1781)
openremote-manager-1     |      at org.apache.activemq.artemis.core.protocol.mqtt.MQTTPublishManager.sendToQueue(MQTTPublishManager.java:217)
openremote-manager-1     |      at org.apache.activemq.artemis.core.protocol.mqtt.MQTTProtocolHandler.handlePublish(MQTTProtocolHandler.java:317)
openremote-manager-1     |      at org.apache.activemq.artemis.core.protocol.mqtt.MQTTProtocolHandler.act(MQTTProtocolHandler.java:160)
openremote-manager-1     |      at org.apache.activemq.artemis.utils.actors.Actor.doTask(Actor.java:33)
openremote-manager-1     |      at org.apache.activemq.artemis.utils.actors.ProcessorBase.executePendingTasks(ProcessorBase.java:67)
openremote-manager-1     |      at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136)
openremote-manager-1     |      at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635)
openremote-manager-1     |      at org.apache.activemq.artemis.utils.ActiveMQThreadFactory$1.run(ActiveMQThreadFactory.java:118)

Tele is 'tele':{'name':'tele','type':'JSONObject'

Credentials are OK. MQTT Client is OK.
But something about publishing to the topic is still off.

From: Tutorial: Connect your MQTT Client · openremote/openremote Wiki · GitHub
master/client123/writeattributevalue/writeAttribute/6xIa9MkpZuR7slaUGB6OTZ

Translates to me: master/{mqttid}/writeattributevalue/{Attribute}/{assetid}
In my case:

  • mqttid == assetid as seen in MqttPublishVariableHeader[topicName=master/4zsZrQpl2ATMpEPKqyMQy9/writeattributevalue/tele/4zsZrQpl2ATMpEPKqyM
  • Attribute is tele
  • assetid == mqttid

Any thoughts?

can you show your py code?

Which part would you like to see?

some explanation:

r2pclient is 1x MQTT Client which listens for # on our MQTT Broker.
orClients are N MQTT Clients which connect to OpenRemote.

The goal is:

  • :white_check_mark: find the Devices in our Broker on topic r2p/waechter/DEVICE_UUID/tele.
  • :white_check_mark: Create a new Asset, Service User, link it, and store in a local DB for future access. (future access like a restart, where known clients can just be loaded from the local DB)
  • :white_check_mark: Conncet the newly created Asset/User to the MQTT Client
  • :x: Publish the send messages from our Broker to OpenRemote to the created Asset

Sorry if I’m wrong but I’m jumping in because my eye saw

ActiveMQSecurityException[errorType=SECURITY_EXCEPTION message=AMQ229032: User: master:4zszrqpl2atmpepkqymqy9 does not have permission='SEND' on address master.4zsZrQpl2ATMpEPKqyMQy9.writeattributevalue.tele.4zsZrQpl2ATMpEPKqyMQy9]

In your screenshot I don’t see write permissions on that user, maybe that’s the issue?

3 Likes

Yes that is the issue :sweat_smile:

1 Like

Big thanks for your support guys - @pcr @Denis @Rich

I now have a fully working version. :blush:

3 Likes

So now I can share some more :slight_smile:

Warning
This video has no sound at all

FYI: All credentials shown in the video have already been changed and or deleted.

2 Likes

Good work! Thanks for the video!

1 Like