AWS IoT is an easy way to transmit IoT sensor data to the Cloud (AWS) using the lightweight MQTT protocol. However AWS IoT supports only the secure MQTTS version of MQTT. It requires a set of security certificates to be stored on each sensor/device and support for SSL/TLS on the sensor. Also all the devices need to be connected to the Internet. Instead of managing certificates on all the different sensors and providing them with secure Internet access, sometimes it is preferable and practical to have an intermediate gateway that the sensors communicate with on MQTT, and have the gateway in turn communicate with AWS IoT on MQTTS.

The gateway acts as an MQTT proxy, and if using cellular connections, a proxy could potentially save hundreds to thousands of dollars per month (depending on the number of connections and volume of data) by avoiding the overhead of SSL/TLS on individual sensor links.

The script to achieve proxying is rather straightforward and there are only a couple of configuration issues to take care of to enable the MQTT proxy.

The requirements/steps in implementing an MQTT proxy are:

  • AWS IoT configured with a device "thing" to receive sensor data
  • Security Certificates and keys from AWS
  • A Linux machine with MQTT broker (usually Mosquitto)
  • Node.js installed on the Linux machine
  • Run proxy script

Configure AWS IoT

There are many tutorials online, not to mention Amazon's own documentation that explain in detail how to configure AWS IoT. In short,

  • On AWS IoT Core, create the Thing that will be used to represent gateway
  • Create security credentials for the Thing from the Security menu and download the following:

    • device certificate (<device name>-certificate.pem.crt)
    • private key ('-private.pem.key')
    • public key ('-public.pem.key')
    • Amazon root certificate ('AmazonRootCA1.pem')

    Important:

    • you can only download the public and private keys when you create the credentials. They will not be available for download once you leave the page!
    • download the Amazon Trust Services Endpoints certificate, not the older Verisign issued certificate
  • Assign the certificate to the Thing
  • Create a Policy and assign it to the Thing. Ensure that the Policy allows at least iot:Connnect, iot:Publish, and iot:Subscribe actions.
  • Note down the Custom AWS endpoint from the view endpoint menu. It will have the format like: <account number>-ats.iot.<AWS region>.amazonaws.com

Configure Linux machine as MQTT proxy

We use a Linux machine as a the MQTT proxy/gateway. This could be a standalone machine, SBC like Raspberry Pi, or an instance on AWS.

Install MQTT broker

  • Follow a tutorial like the one from DigitalOcean to install and configure an MQTT broker on Linux
  • Test and make sure that the sensor(s) is (are) able to connect and publish data to the broker
  • Ensure that clients are able to subscribe to topics and receive messages published by the sensor

Install proxy script

  • Install nodejs and npm on the Linux machine
  • Create directory ~/mqttproxy and cd into it
  • Create directory certs and copy (scp) the certificates and keys downloaded above into this directory
  • Use npm install to install dependencies mqtt, url, aws-iot-device-sdk
  • Create a file mqttproxy.js as below
var mqtt = require('mqtt'), url = require('url');
var client = mqtt.connect('mqtt://localhost:1883');

console.log("ConnectedQTT Broker:- localhost" + client.toString());

var awsIot = require('aws-iot-device-sdk');
var device = awsIot.device({
keyPath:  './certs/<device name>-private.pem.key',
certPath: './certs/<device name>.pem.crt',
caPath:   './certs/AmazonRootCA1.pem',
clientId: 'my-id-1234567890', // Create a unique Client ID
host:   '<account number>-ats.iot.<AWS Region>.amazonaws.com', // AWS endpoint
});

device.on('connect', function () {
  console.log("ConnectedWS IoT Broker:- " + device.toString());
});

client.on('connect', function()
{
//subscribe to a topic (#)
client.subscribe('#', function () {
  client.on('message', function (topic, message, packet) {
    console.log("Received " + message + " on " + topic);
    device.publish(topic, message);
    console.log("Sent " + message + " on " + topic);
    });
  });
});
  • Start the script using node mqttproxy.js
  • All the sensor data sent to the proxy machine should appear on the AWS IoT console (if they are published and subscribed to the same topic)
  • Once tested, the script can be started as a daemon using forever
forever -a -l frvr.log -o outfrvr.log -e errfrvr.log start mqttproxy.js

Conclusion

This is a quick and easy way to start proxying MQTT data from multiple sensors to AWS IoT through a single MQTT gateway.

Blog Comments powered by Disqus.

Next Post Previous Post