I'm road testing the Harting MICA Complete IIoT Starter Kit.

It comes with a MQTT Broker Container. It's the heart of most examples available for the MICA.

It's installed out of the box on my MICA. But: it is an open service. Everyone that can IP the network can send and get messages (and trigger hardware).

I'm not angry. I'm disappointed . It's 2019.

 

I have two choices - securing the one that's provided by Harting or creating a certificate-protected one from scratch.

I chose option two. In this post I show how I created a more secure MQTT broker, starting from an empty Linux container.

 

I'm using the Linux Debian Stretch Container here - a reasonable lightweight yet complete MICA option to deploy Linux solutions.

 

 

Setting up the MQTT Broker

 

If you don't know how to create a new Linux container on the MICA, check this post.

It explains how to create one, and how to connect to it via SSH (PuTTy).

 

Step 1 is to deploy a fresh Debian Stretch Container on the MICA.

Name: MQTTRoadtest

At start time, the size of this container is:

At the end of this post, when we've added SSL and MQTT support, let's check what the total deploy size of the container is.

After starting the container, I used PuTTY to log on and immediately changed the password by executing the passwd command.

In a later exercise, I may create a dedicated non-root user to run the service.
I'll need to study some more to see what it takes to get the service running under a dedicated account.

 

Then I followed a mix of these three web pages to get everything set up. All the steps are documented in this post.

https://obrienlabs.net/how-to-setup-your-own-mqtt-broker/

https://dzone.com/articles/mqtt-security-securing-a-mosquitto-server

Configuring the MQTT Publish and Subscribe Nodes in Node-Red

You will find that some parts of this post are literal instructions and commands from the pages above. I hope that by referencing them here I give them the right credit.

There's no full overlap with them. To get only secure connections working and reject insecure ones (except from localhost), you need a combination of steps from all three.

 

Step 2, let's install our MQTT server.

(in my network I have to disable the proxy to make apt work)

 cd /etc/apt/apt.conf.d
mv 99proxy 99proxy.bak

 

Install Mosquitto:

apt update
apt-get install mosquitto mosquitto-clients

 

test the installation without security:

service mosquitto start

 

At this moment, we have a working MQTT service with similar security settings as the standard one.

 

Step 3, you can test if the MQTT server has basic functionality.

Here, I'm doing that with MQTT Lens:

 

 

If you change the server name to MQTTRoadtest in the CISSGateway, Node Red and GPIO examples, things will also work with the new service because our server is unsecured.

From now on, we'll add security. The examples will not work with the service anymore.

You'll be able to talk to it from your own code though, and from Node Red. But things will be closed for anyone who does not have a correct certificate.

 

Securing the MQTT Broker

 

Time to stop the service again.:

service mosquitto stop

 

Step 1, we create all the keys and certificates

 

Get openssl. We'll need it to generate the certificates and keys.

apt-get install openssl

 

Make a directory for certificates, etc ...

mkdir ~/mosquittossl
cd ~/mosquittossl

 

Create a 2048-bit key called mosq-ca.key

openssl genrsa -out mosq-ca.key 2048

 

Create an X509 certificate that uses the private key generated in the previous step

openssl req -new -x509 -days 365 -key mosq-ca.key -out mosq-ca.crt

 

 

Create the MQTT Server Certificate.

openssl genrsa -out mosq-serv.key 2048

 

 

 

Next, create a CSR (Certificate Signing Request)

openssl req -new -key mosq-serv.key -out mosq-serv.csr

 

 

Now, make the certificate to use in our MQTT Mosquitto Server.

openssl x509 -req -in mosq-serv.csr -CA mosq-ca.crt -CAkey mosq-ca.key -CAcreateserial -out mosq-serv.crt -days 365 -sha256

 

Verify:

openssl x509 -in mosq-serv.crt -out readme.txt
cat readme.txt
rm readme.txt

 

 

 

Step 2, we configure the Mosquitto Server to Secure MQTT with the certificates.

Edit the Config file.

 

nano /etc/mosquitto/mosquitto.conf

 

Add these entries:

listener 8883
cafile /root/mosquittossl/mosq-ca.crt
certfile /root/mosquittossl/mosq-serv.crt
keyfile /root/mosquittossl/mosq-serv.key

I think that the proper way to do this is to create an own config file in the /etc/mosquitto/conf.d directory. Comment below if you know it.

 

Next restart the server.

service mosquitto restart

 

The default unsecured listener in port 1883 is still running now. But we've added the secure service on 8883.

We'll refine later.

 

Step 3 is to download the certificates. In our case, you only need mosq-ca.crt.

You need to find a way to get the certificates that you need for client setup.

I installed the sFTP server for that.

apt install openssh-server
service ssh restart

 

you could also use the sdcard (check MICA's NAS Container documentation) or other file transfer options to move the certificate you need.

 

Step 4 is to test it from your pc, with the certificate.

The MQTT testbed I use to try out communication with certificates can be downloaded here: MQTT.fx .

Configure it as shown below, then connect.

Subscribe to topic /TESTSecure. Then Publish to that same topic /TESTSecure with message Secure MQTT.

You should see the message arriving at the bottom of the window. It has gone via the MICA over secure communication.

 

Step 5 is to revoke the unsecured 1883 listener.

Disable the 1883 port for anyone except the container itself.

edit the msquitto.conf file.

Add

listener 1883 localhost

before the 8883 listener.

Restart the service.

 

Step 6 is to test with the NodeRed container with a self-made flow.

Create a new NodeRed process, with a MQTT and a Debug block:

 

 

Edit the mqtt node. Replicate the settings as shown below:

 

 

Deploy, and then it's time to test.

 

As a preparation, open the debug window in the Node Red editor:

You can use the Selected Node filter to only see debug messages for this flow. Do that in case you have the CISSGateway running - we don't want to see those messages now).

 

Use the same MQTT.fx connection we used before, but publish some message to the topic /SecureTopic (the same one used in the Node Red process).

Go back to the Node Red editor. You should see the message in the debug log:

 

 

 

 

The space occupied by the container, after installation and first start of the service:

 

 

 

Things for myself to consider later on:

  • create a non-root user for mqtt
  • what about certificate expiry?
  • investigate certificate validation
  • server keys and certificates should be stored in /etc/mosquitto/certs , only readable by mosquitto user
  • enable the ws listener

 

Thanks for reading. If you see flaws and mistakes, please comment.

 

Related Blog
HARTING MICA: Develop and Debug a C GPIO Example in Eclipse - Part 1: User Experience
HARTING MICA: Develop and Debug a C GPIO Example in Eclipse - Part 2: MICA Debian Stretch Setup
HARTING MICA: Develop and Debug a C GPIO Example in Eclipse - Part 3: Eclipse Configuration on Windows
HARTING MICA: Develop and Debug a C GPIO Example in Eclipse - Part 4: Build and Debug the GPIO Example
HARTING MICA: Make a Safe(r) MQTT Container with Certificate and TLS/SSL
HARTING MICA: Manage Access to USB and other Devices
HARTING MICA: SD Card as Shared Storage
HARTING MICA: Alpine Linux and another MQTT Container with Certificate and TLS/SSL
HARTING MICA: Connect to Amazon Web Services
HARTING MICA: Install Java 8 VM in a Debian Stretch Container
HARTING MICA: Read BOSCH CISS Sensor with Java - part 1: USB Connect and Listen