Configure Azure IoT Edge for downstream devices
A lot of documentation and posts are available to setup an Azure IoT Edge to act as an IoT Hub for downstream devices. In order to get it up and running in a dev environment, I had to do some more research.
My setup is a RaspberryPi 3 with Raspbian stretch and an Azure IoT DevKit which looks like this. And please remember the setup I used is for development only. I’ve used symmetric key authentication for the IoT Device. In a production scenario you would probably use certificate based authentication and no self signed certificates for the TLS encryption.
Some starting points for reading are:
- https://docs.microsoft.com/en-us/azure/iot-edge/iot-edge-as-gateway
- https://docs.microsoft.com/en-us/azure/iot-edge/how-to-authenticate-downstream-device
- https://docs.microsoft.com/en-us/azure/iot-edge/troubleshoot
And here are my findings with the solutions that worked for my setup
- The downstream IoT devices should be able to connect to port 443 on the Edge module. But that port was not open/listening.
- How to verify the gateway certificate after the connection has been established?
The connectionstring for connecting to the gateway instead of an IoT Hub you can add ;GatewayHostName=hostname and the device should then go to the gateway. Take a note of the hostname and make sure it matches the name you specified when you were creating the certificates.
Looking at the serial output of the DevKit, I noticed it could not connect to the gateway. A quick analysis revealed that it does not accept connections on port 443. Hmm. Maybe a firewall on the Pi? As it turned out you have to tell the edge container to listen to 443 if you want to use it as a gateway.
{ "HostConfig": { "PortBindings": { "8883/tcp": [{ "HostPort": "8883" }], "443/tcp": [{ "HostPort": "443" }], "5671/tcp": [{ "HostPort": "5671" }] } } }
This will allow incoming connections not only for HTTPS. After the change was pushed to the Edge device, I could connect to it on port 443. Hurray.
The next challenge was to get the downstream device accept the certificate, that the gateway offered. In order to be able to verify the certificate, it has to trust the root certificate. This was, in my case, the file azure-iot-test-only.root.ca.cert.pem from the ~/certividates/certs directory. Open it with an editor, paste the content into the ino file and use the certificate.
// declare a constant with the content of // azure-iot-test-only.root.ca.cert.pem from ~/certificates/certs static const char edgeCert [] = "-----BEGIN CERTIFICATE-----\r\n" ... "-----END CERTIFICATE-----"; // set trusted certs for the client DevKitMQTTClient_SetOption(OPTION_MINI_SOLUTION_NAME, "something"); DevKitMQTTClient_SetOption("TrustedCerts", edgeCert);
Now the IoT device should be able to connect to the gateway. Have fun with IoT 😉