I’ve started playing with the IoT Hub in Azure and it took some time to assemble the pieces for testing secure MQTT messaging, so here’s a writeup of some notes I made along the way.
Table of Contents
Getting started
First sign up for a free Azure account. You’ll get some free credits to play around with the services before committing to paying anything.
Then install the Azure CLI. Once that’s installed, add the IoT extension:
And now you’re ready to go!
Create an IoT Hub
An instance of IoT Hub can be created using the Azure GUI (Create a resource -> search for IoT Hub) or using the CLI.
First create a Resource Group named “internet-of-gaz” to keep all the resources organised.
Next create a new IoT Hub instance with the same name. “norwayeast” is not available for IoT Hubs so we’ll use “northeurope” instead.
The output from the previous command should indicate that a new instance has been created under the “free tier”. The IoT Hub Pricing page has more details about the differences between the tiers.
Add a device
Now that we’ve got our hub we need to start registering our IoT devices. This registration process can be automated which is useful if you’re dealing with a large number of devices, but let’s start by registering a single device named “gaz-device-1”.
And now we’re ready for our device to start communicating with the hub!
Monitoring Hub Messages
First we need a way to monitor messages received by the Hub. The documentation has examples for how to use the SDKs to read from the default endpoints, but there’s also a built-in monitor using the CLI:
Device to Cloud Messaging
I have the Mosquitto broker software installed, so I’ll use mosquitto_pub for sending messages to the Hub. To find out what to specify for the hostname, username, etc, we once again need to Read The Fabulous Manual to see what IoT Hub expects. The hostname, user, and topic are defined as follows:
Since we’re using Mosquitto we’re also going to need to obtain the PEM-encoded Azure CA certificates to enable SSL communication. This can be done by opening https://portal.azure.com in your browser, viewing the certificate details, and then (if using Firefox) click on the “Download PEM (cert)” link on the “Baltimore CyberTrust Root” tab. Save the file as “portal-azure-com.pem”.
But what about the password for authentication? We’ll look at two options: short-lived tokens and X.509 certificates.
Shared Access Signature (SAS) Token Authentication
By default the device is registered using the “symmetric key” authentication type. This means that the messages from our device will need to include a “Shared Access Signature” (SAS) token for authentication. The IoT Hub Security documentation has examples of how to generate these tokens programatically using the SDKs. Alternatively we can use the CLI to generate a token that will be valid for 10 minutes (600 seconds). I haven’t touched on “Shared access policies” here, but by default the token will use the “iothubowner” policy name, which isn’t recommended for use in a production setting.
Putting it all together we get:
If we look in the monitoring window we should see the message appear:
Hooray!
X.509 Certificate Authentication
SAS tokens are fine if our device is able to generate its own tokens in some way, but that may not be possible. The device may not have the capacity or capability to perform the generation, so an alternative means of securing communications is by using X.509 certificates. The basic idea here is that the device carries a certificate which is signed by a known and trusted Certificate Authority. These certificates may be generated installed on the devices at the time the device is manufactured, or distributed in a secure way. There’s an interesting Azure blog post that covers some of the options here.
Create a Certificate Authority
For our testing we’re going to create our own Certificate Authority (CA) (referred to as “self-managed PKI” in that blog post) using good old openssl. This is as easy as the following steps:
- Create a CA private key.
- Create a CA certificate using the private key.
- Convert the CRT to PEM format.
- Upload the PEM to our IoT Hub.
Proof of Posession
If you list our ceritificates or view them in the Portal in our browser, you might notice that the certificate is listed as “not verified”
This is because we need to perform what is known as “proof of posession”, to prove that we actually control the CA. Once again there’s an Azure blog post detailing the steps involved. What it basically boils down to is using our CA to generate a certificate with a specific Common Name (CN) and then uploading the verification certificate into the Hub.
Repeat the command from earlier to ensure that the CA “isVerified” property is now true.
Generate a Device Certificate
Now that we have a verified CA any certificates given to our devices will be accepted. Here we’ll set up a new device and configure it to use “X509 CA signed” authentication.
First register a second device in IoT Hub and configure it to use X509 CA authentication:
Now generate a certificate for the device to use, and sign it using our CA.
Now we’re ready to send the message. Note that we now pass our certificate and key instead of the SAS token as a password.
Then, as when sending the message using SAS authentication, the message should appear in the monitor window!
Cleanup
When you’re done playing with your IoT Hub then remember to remove the resources. If you’re using the ‘free tier’ then you probably don’t have to worry about an unexpected bill, but if you chose a Basic or Standard then delete the resource group and all the associated resources using the following command:
Check the list of resource groups to ensure that internet-of-gaz has been removed
Conclusion / What’s Next
Phew. That felt like quite a lot of work. So, to recap what we’ve achieved here:
- Created a new IoT Hub in Azure
- Registered a couple of devices, one for SAS and one for X.509 CA authentication
- Generated a SAS token and used it to send an MQTT message
- Created a CA, verified it with Azure, then generated a client certificate and using it to send an MQTT message
Now that we’ve got our events (messages) successfully flowing in to the Hub we need to decide what to do with them. Topics for future investigation include storage, monitoring, and analytical worktools. Azure has a shedload of native services to offer (DataBlocks, EventHub, databases, etc.), and of course it’s pretty trivial to just spin up the infrastructure to run any other open-source data engineering projects that might be useful. Stay tuned!