koalazak / dorita980

Unofficial iRobot Roomba and Braava (i7/i7+, 980, 960, 900, e5, 690, 675, m6, etc) node.js library (SDK) to control your robot
MIT License
945 stars 150 forks source link

Have the robot mqtt client connect to local mqtt server #108

Closed kumy closed 4 years ago

kumy commented 4 years ago

I would have loved to have my robot publishing himself it's payloads to my own local mqtt server, without relying on cloud infrastructures. I've managed to get the robot configured to connect to my server but let's encrypt certificates doesn't seems to be recognized the the robot internal trust store.

For interested people, here how I proceeded:

app = Flask(name)

my_host = 'your.fqdn' my_port = 8880

@app.route('/') def hello(): name = request.args.get("name", "World") return f'Hello, {escape(name)}!'

@app.route('/generate_204') def generate_204(): return '', 204

@app.route('/discovery') def robot_discovery(): resp = { "discoveryTTL": 172800, "httpBase": "http://%s:%d" % (my_host, my_port), "iotTopics": "$aws", "irbtTopics": "v005-irbthbu", "mqtt": my_host, "svcDeplId": "v005" } return jsonify(resp)

@app.route('/v1//register', methods=['GET', 'POST']) def robot_register(blid): print(request.headers) print(request.data) return 'ok', 200

if name == 'main': app.run(use_reloader=True)

Launch it using : `env FLASK_APP=server.py flask run -h 0.0.0.0 -p 8880`

* Then publish your discovery url to the robot:
`$ mosquitto_pub -L mqtts://YOUR_BLID@ROBOT_IP:8883/  --insecure  -P "$ROOMBA_PASSWORD"  -V mqttv311 --cafile ~/roomba.crt -i YOUR_BLID -d -t wifictl -m '{ "state" : { "sdiscUrl" : "http://<your.fqdn>:8880/discovery" } }'`

The robot will then issue a `GET` request to the `discovery` url and a `POST` to the `register` endpoint (payload is a json including your robot public certificate, timestamp, robot password, signature. Then after that, it will try to connect to the host defined in the json filed `mqtt`.

From there looking in wireshark, the robot seems to reject my cert/ca, and try again and again.

If someone find which CA are accepted by the internal trust store other than the one from Amaz0n ACM it would help a bit :)

## Logs from the fake webserver

$ env FLASK_APP=server.py flask run -h 0.0.0.0 -p 8880

10.42.0.122 - - [21/Jan/2020 20:38:26] "GET /discovery HTTP/1.0" 200 - Host: your.fqdn User-Agent: WMSDK Content-Type: application/json Content-Length: 1946

b'{"certificate":"-----BEGIN CERTIFICATE-----\r\nMIIDnjCCAoagAwIBAgIIalFxcSRLUigwDQYJKoZIhvcNAQELBQAwXzELMAkGA1UE\r\nBhMCVVMxCzAJBgNVBAgTAk1BMRAwDgYDVQQHEwdCZWRmb3JkMQ8wDQYDVQQKEwZp\r\nUm9ib3QxDDAKBgNVBAsTxxxxxxxxMBAGA1UEAxMJUm9vbWJhIENBMB4XDTE5MDky\r\nNzEzNDYzOVoXDTI5MDkyNzEzNDYzOVowXzELMAkGA1UEBhMCVVMxDzANBgNVBAoM\r\nBmlSb2JvdDEQMA4GA1UEBwwHQmVkZm9yZDELMAkGA1UECAwCTUExIDAeBgNVBAMM\r\nF1Jvb21iYS04MEE3MDgyMDkxMzM0NzcwMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A\r\nMIIBCgKCAQEAniqRdSOxLYWOKdK6+nNi2giQlmkWoWnjYk/Y99K8UI79z9UJ1BOg\r\nOZUA7Og6I+FVCvWfpFu7Lpr+ERqSqU+Smz355ojcmL/etkewEGXtCii203OKl2rQ\r\nI9har6KdLG4PyrI+p0F6ltgUkuyiWNM6y9hvjaxxxxxxxxgOXUxFfDDircYW/fyV\r\nhluBwlVIjmVbct6kXq73c/L1kukHAoNe6SeFvjulbdmZqxcmQ1NXhTnDLZ12IDnz\r\nfPU5VN+8gb0ZLRe9XDvKfT2QQq4FmJPlQDVBkWag9s4r8l1MJTbm4sbYIMcOmpBO\r\n5Y4nqSFqqVIANfIbzmBeDkvb6rFG49YEcQIDAQABo14wXDAdBgNVHQ4EFgQUe5Yx\r\nVcXNiJhF1nYyYWqNk9bGzTUwDAYDVR0TAQH/BAIwADAdBgNVHSUEFjAUBggrBgEF\r\nBQcDAQYIKwYBBQUxxxxxxxxYDVR0PAQH/BAQDAgWgMA0GCSqGSIb3DQEBCwUAA4IB\r\nAQBwWzKuVV+HT2MHermoMuAEMGvfJNaRwY+Q19bSbmUbHfyOzUTC/P0pqefSBolO\r\nmADdP94OHQSXpop/lI+Rgbmln/f5YaVXmOZBk7op1V1A3rET20FBXrTLbeULRsmW\r\nfQ3motkzSS7rm92EgkS8hJ/bPuLpG/HQWpwRt0CTIEjIdsazxIxZX/oQlju6adYK\r\n/dwiyiy8B7lluulgEcsgx+EBELOawpshhA8VM6R8o/i3E8Tdkx4jZw2kJ3rnIEhC\r\nUBVzqH/kXepS/zU/POHb86AQ+fWl8bs8SwAyyr4TvjXsgM7ILn7uxxxxxxxxNm1iQV\r\nMRgyg1k5/L054BfpUaIyUu9G\r\n-----END CERTIFICATE-----","timestamp":1579635506,"password":":1:1579195386:8fx7nYqVtKgWJxxx","signature":"xxxcb5b287fee8616a824f28edd94273d2df7532b95137f4f7d7e0284f3410b0c9b7d08d705c3c5bda44ac2c39bdb6c02eb32633abb18138f59774df092c2c3a1afce9d85d62f3f66af293e194a9fa04220b681bf60d37165c25e6fac6ffe3c7bfe2187a746efcf11d832e3bddd663f9c67b6f21f7ad9b66acd79f7099f70240bf395cfa926af5f2480edb7cd74c9a155eaee1100ebe9f9b9cf6741edaf72d762f699b60ed89a49e698f8b87a8cd495c3b3148945ad8d1ad53c4b86e2288b3c47910f7bbb76fcc5c4e8cb8834768a77e173f17f96c093f8dd8983e29805b69fa90da79babc288980349a2d352136241a7a67f0d38cf190375adf556348axxx"}' 10.42.0.122 - - [21/Jan/2020 20:38:27] "POST /v1/MY_BLID/register HTTP/1.0" 200 -

## Valid trust chain

$ openssl s_client -connect a2uowfjvhio0fa-ats.iot.us-east-1.amazonaws.com:8883 CONNECTED(00000003) […]

Certificate chain 0 s:CN = *.iot.us-east-1.amazonaws.com i:C = US, O = Amazon, OU = Server CA 1B, CN = Amazon 1 s:C = US, O = Amazon, OU = Server CA 1B, CN = Amazon i:C = US, O = Amazon, CN = Amazon Root CA 1 2 s:C = US, O = Amazon, CN = Amazon Root CA 1 i:C = US, ST = Arizona, L = Scottsdale, O = "Starfield Technologies, Inc.", CN = Starfield Services Root Certificate Authority - G2 3 s:C = US, ST = Arizona, L = Scottsdale, O = "Starfield Technologies, Inc.", CN = Starfield Services Root Certificate Authority - G2 i:C = US, O = "Starfield Technologies, Inc.", OU = Starfield Class 2 Certification Authority […]


But even if such certificate could be generated for free on ACM, they cannot be downloaded to be used locally :(

@koalazak If you prefer to close this issue, feel free to do so :)
koalazak commented 4 years ago

this is nice! I will close the issue but adding a tag for future references. thank you!