A Routing IoT Gateway to the Cloud

DZone 's Guide to

A Routing IoT Gateway to the Cloud

Follow along to see how a properly configured router can solve the problem of securely connecting the IoT to the cloud.

· IoT Zone ·
Free Resource

Imagine that you have an embedded solution (or if you like it, an IoT solution) with a bunch of tiny devices that are connected to an on-premise server, which receives telemetry data from them and is able to execute some elaboration in order to show information in real time on a dashboard and control the devices.

Imagine that your solution is based on the AMQP protocol, and perhaps your on-premise server is running a messaging broker for gathering data from devices as messages through the local network.

Imagine that, due to your very constrained devices, the security in the network is guaranteed only at data level by encrypting the body of every single AMQP message. It's possible that due to their complexity and the need of more resources (CPU and memory), you can't use sophisticated algorithms (i.e. DES, 3DES, AES, etc.) on your devices — only simple ones (i.e. TEA).

Your solution is just working great in your environment.

But Now We Want to Move it to the Cloud

Imagine that for some reason, you need to change the on-premise nature of your solution and you want to connect the devices directly to the cloud with a very strict rule: nothing to change on the devices. At least you can change some configuration parameter (i.e. server IP) but not the way they communicate, nor the protocol they use for it.

The first simple solution could be moving your messaging broker from the on-premise server on an IaaS in the Cloud; just changing the connection parameters on your devices and all continue to work as before.

The big problem now is that your data are sent through the public network, and your security is based on a simple encryption algorithm applied only on the payload of the messages. For this reason, you start to think about using SSL/TLS in order to have security at the connection level on top of TCP/IP, data encryption, and server authentication.

You start to think about it but then, wait, I can't use SSL/TLS on my tiny devices. They don't have the needed resources in terms of CPU and memory. Now what?

Fog Computing and IoT Gateway: The Solution?

You know about "fog computing" (the new buzz word after IoT ?) and that you can solve your problem using an IoT gateway. Having this gateway could mean having an intelligent piece of software that is able to gather data from the local network, process it in some way, and then send it to the cloud. The gateway could give you more features like filtering data (sending only part of it), offline handling (if the cloud isn't reachable), and complex local processing. But wait, you don't want it. You just want that data arriving to the Cloud in the same way as before (to the on-premise server) and for now, you don't need other additional great features.

Could we have a very simple IoT gateway with only the two following features we need:

  • SSL/TLS protocol support on behalf of the tiny devices.
  • Traffic routing from devices to the cloud in a transparent way.

The answer is yes ! You have such solution, and it's provided by the Qpid Dispatch Router project from the ASF (Apache Software Foundation).

I already wrote about it in some previous articles, so let me just show how you can use the router in a way that solves your "porting" problem.

The Router Just Needs the Right Configuration

In order to show in a very simple way how to configure the router for our objective, we can use the Azure IoT Hub as a cloud platform for the IoT. As all the Azure messaging services, like Service Bus and Event Hub, the IoT Hub needs an encrypted connection based on the SSL/TLS protocol, so it's the problem we want to solve for our non-SSL capable devices.

For the sake of simplicity, we can run the router on a Raspberry Pi using the Raspbian distribution as the OS; you can read about installing the Qpid Dispatch Router on Linux and on the Raspberry Pi in these articles.

The main point is the configuration needed for the router in order to connect to an IoT Hub and routing the traffic from devices to it.

First of all we have to consider all the addresses that at AMQP level are used in order to send telemetry data to the hub, receive commands and reply with feedback. All this information is deeply explained here.

The routing mechanism used in this configuration is "link routing," which means that the router creates a sort of "tunneling" between devices and the IoT Hub; it opens the TCP/IP connection with the hub, establishing it with SSL/TLS on top, and then opens the AMQP connection. All the SSL/TLS stuff happens between router and IoT Hub, and the devices aren’t aware of it. You can see what happens through the router trace:

pi@raspberrypi:~ $ PN_TRACE_FRM=1 qdrouterd --conf ex06_iothub.conf
Sat Jul 23 11:56:17 2016 SERVER (info) Container Name: Router.A
Sat Jul 23 11:56:17 2016 ROUTER (info) Router started in Standalone mode
Sat Jul 23 11:56:17 2016 ROUTER_CORE (info) Router Core thread running. 0/Router.A
Sat Jul 23 11:56:17 2016 ROUTER_CORE (info) In-process subscription M/$management
Sat Jul 23 11:56:18 2016 ROUTER_CORE (info) In-process subscription L/$management
Sat Jul 23 11:56:18 2016 AGENT (info) Activating management agent on $_management_internal
Sat Jul 23 11:56:18 2016 ROUTER_CORE (info) In-process subscription L/$_management_internal
Sat Jul 23 11:56:18 2016 DISPLAYNAME (info) Activating DisplayNameService on $displayname
Sat Jul 23 11:56:18 2016 ROUTER_CORE (info) In-process subscription L/$displayname
Sat Jul 23 11:56:18 2016 CONN_MGR (info) Configured Listener: proto=any role=normal
Listening on
Sat Jul 23 11:56:18 2016 CONN_MGR (info) Configured Connector: ppatiernoiothub.azure-devices.net:5671 proto=any role=on-demand
Sat Jul 23 11:56:20 2016 POLICY (info) Policy configured maximumConnections: 0, policyFolder: '', access rules enabled: 'false'
Sat Jul 23 11:56:20 2016 SERVER (info) Operational, 4 Threads Running
Connected to ppatiernoiothub.azure-devices.net:5671
[0x19dc6c8]: -> SASL
[0x19dc6c8]:0 -> @sasl-init(65) [mechanism=:ANONYMOUS, initial-response=b"anonymous@raspberrypi"]
[0x19dc6c8]: -> AMQP
[0x19dc6c8]:0 -> @open(16) [container-id="Router.A", hostname="ppatiernoiothub.azure-devices.net", max-frame-size=65536, channel-max=32767, idle-time-out=60000, offered-capabilities=:"ANONYMOUS-RELAY", properties={:product="qpid-dispatch-router", :version="0.6.0"}]
[0x19dc6c8]: <- SASL
[0x19dc6c8]:0 <- @sasl-mechanisms(64) [sasl-server-mechanisms=@PN_SYMBOL[:EXTERNAL, :MSSBCBS, :ANONYMOUS, :PLAIN]]
[0x19dc6c8]:0 <- @sasl-outcome(68) 
[0x19dc6c8]: <- AMQP
[0x19dc6c8]:0 <- @open(16) [container-id="DeviceGateway_1766cd14067b4c4b8008b15ba75f1fd6", hostname="", max-frame-size=65536, channel-max=8191, idle-time-out=240000]

At this point, the devices can connect locally to the router, and when they asked for all the AMQP links related to the IoT Hub addresses, they will be tunneled by the router: the AMQP "attach" performatives are routed to the IoT Hub through the connection with the router. The communication then continues on this link in terms of message transfers directly between the IoT Hub and devices, but it's all encrypted until the router runs through the SSL/TLS protocol.router_iothub

The router configuration is something like this:

listener {
    port: 5672
    authenticatePeer: no

ssl-profile {
    name: azure-ssl-profile
    cert-db: /opt/qdrouterd/Equifax_Secure_Certificate_Authority.pem

connector {
    name: IOTHUB
    addr: <iotHub>.azure-devices.net
    port: 5671
    role: on-demand
    sasl-mechanisms: ANONYMOUS
    ssl-profile: azure-ssl-profile
    idleTimeoutSeconds: 120

# sending CBS token
linkRoute {
    prefix: $cbs/
    connection: IOTHUB
    dir: in

# receiving the status of CBS token request
linkRoute {
    prefix: $cbs/
    connection: IOTHUB
    dir: out

# sending telemetry path and command replies from device to hub on : devices/<DEVICE_ID>/messages/events
# ATTENTION ! Here we need CBS Token
linkRoute {
    prefix: devices/
    connection: IOTHUB
    dir: in

# receiving command on device from hub on : devices/<DEVICE_ID>/messages/deviceBound
# ATTENTION ! Here we need CBS Token
linkRoute {
    prefix: devices/
    connection: IOTHUB
    dir: out

With this setup, there is:

  • A listener entity, which defines that the router accepts incoming AMQP connections on port 5672 (not encrypted).
  • The ssl-profile entity in order to configure the parameters for SSL/TLS connection to the IoT Hub and, specifically, the CA certificate to use for server authentication.
  • The connector entity, which defines the way the router connects to the IoT Hub (address and port) using the above SSL profile.

After above parameters, there is a bunch of linkRoute entities, which define the addresses that should be link-routed by the router from devices to the hub (using the specified connector).

You can find the complete configuration file here.

The Netduino Plus 2 Use Case

In order to develop an application very quickly on te device side, I decided to use my knowledge of .NET Micro Framework using a board that doesn't have SSL/TLS support: the Netduino Plus 2 board.

The simple application is able to send a message to the IoT Hub and receive a new one replying with feedback. All the code is available here.

In the following pictures, you can see the message sent by the board and the command received (with the related feedback) through the Device Explorer tool.




Of course, the Qpid Dispatch Router project has a greater objective than I showed here. It could be providing connections to messaging services at scale thanks a more complex router network — with a path redundancy feature to reach a broker or a simple receiver.

In this article, I just showed a different way to use it in order to give more power to tiny devices that aren't able to connect to AMQP-based services due to their limitation (in this case the lack of SSL/TLS support).

If you consider the starting point, the configuration change could be avoided because the router could have same IP address and AMQP listening port as the previous on-premise server.

It means that only adding a router configured for the cloud connection solves the problem!

amqp, azure, c sharp, dot net, iot app development

Published at DZone with permission of Paolo Patierno , DZone MVB. See the original article here.

Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}