Archives for April 2017

ESP8266 SSL/TLS MQTT Connection

Securing your IoT things is critical. MQTT connections are definitely at risk. But simply using username/password combinations for your MQTT connection is NOT secure.

Why not?

Well, even with passwords, everything sent over the Internet is unencrypted…open for any and all prying eyes to see…and possible maliciously manipulate.

Fortunately, we can solve that problem by creating TLS connections for secure MQTT data transfers. And yes, this encryption layer can even be brought to the ESP8266 platform.

But it does come at a cost…a huge bite out  of the limited ESP RAM heap. With grave consequences. I certainly experienced catastrophic results during in my initial attempts. Finally, and after several iterations, the implementation presented here now manages the heap successfully. Using this approach, we achieve the desired results…a  stable, reset-free ESP8266 platform with a secure interface to an MQTT broker.

Cutting to the Chase

At this point, if you would like to jump in without the benefit of additional explanation, please find the code for this Arduino 1.8.2 IDE compiled project here.

Compiler Issue

The first step towards adding TLS to the ESP8266 framework was to access a secure MQTT Broker. Installation of a TLS MQTT Broker was presented in my last post. After setting up the TLS MQTT broker on a VPS host, the next step was to update the ESP8266 IoT platform developed previously to support the secure connection. This required the addition of a new class to the project; WiFiClientSecure. This class supports secure TCP connections.

But I soon discovered the first problem…

You see, the project simply would not compile with the introduction of this class.

Through much research and frustration, I finally discovered the root cause of the problem and better yet, a solution.

As it turned out, one of the compiler flags used by the Arduino IDE was incompatible with the new WiFiClientSecure class library, and had to be   revised. While your computer may have a different path to the compiler options file, mine was located on a Windows 10 PC at:

C:\Users\owner\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.2.0\platform.txt

Here is the line that needs to be changed in order to compile the project:

 
 
  1. #OLD: compiler.c.elf.libs=-lm -lgcc -lhal -lphy -lpp -lnet80211 -llwip -lwpa -lcrypto -lmain -lwps -lsmartconfig -lmesh <span style="color: #ff0000;">-lssl</span>
  2. #NEW: compiler.c.elf.libs=-lm -lgcc -lhal -lphy -lpp -lnet80211 -llwip -lwpa -lcrypto -lmain -lwps -lsmartconfig -lmesh <span style="color: #ff0000;">-laxtls</span>

A Heap of Trouble

After a successful compilation and upload to my development ESP8266 hardware, I soon discovered that the TLS connection consumed a huge chunk of the ESP heap (RAM). Somewhere between 12 and 15 kB. This was such a big resource hog that the ESP8266 would reset anytime a TLS MQTT connection was attempted.

And I also discovered that the configuration screen also used a large amount of ESP heap. That was because, even though the page’s HTML was stored in program memory as a constant, it had to be brought into the heap for run-time modifications before the page was rendered.

These two processes, ESP configuration and TLS MQTT connection negotiation were fighting for the same limited heap space. While each process would work on its own, they simply could not both exists at the same time.

So the project was modified to start up in one of two modes:

  1. Configuration Mode – Sets unique ESP8266 operational parameters
  2. MQTT Connection Mode – Connects to TLS Sensor and continuously reads sensors

Start-up Mode

Upon power-up, the ESP8266 had to know which mode to start up in. That would limit the heap usage to the requirements of the selected mode. This was implemented as a EEPROM location that is read in the programs setup() function.

 
 
  1. SetSysCfgFromEeprom(); // Set Session Cfg from EEPROM Values

Two EEPROM locations are now used for MQTT initialization.

 
 
  1. GetEepromVal(&amp;Param, EEPROM_MQTTSSLEN, EEPROM_CHR);
  2. mqtt_ssl_enable = os_strcmp(Param.c_str(), "true")==0;
  3. GetEepromVal(&amp;Param, EEPROM_MQTTCLEN, EEPROM_CHR);
  4. mqtt_cl_enable = os_strcmp(Param.c_str(), "true")==0;

If MQTT is configured to be enabled (mqtt_cl_enable), then the second parameter (mqtt_ssl_enable) is used to determine whether a TLS connection (sslClient) or a standard connection (espClient) is to be used at ESP8266 startup:

 
 
  1. if(mqtt_cl_enable) {
  2. client = mqtt_ssl_enable ? new PubSubClient(sslClient) : new PubSubClient(espClient);
  3. MqttServer_Init(); // Start MQTT Server
  4. }

These two parameters are set within the operational mode that the ESP8266 is currently operating.

Identifying the Start-up Mode

There are two methods to determine which mode the ESP8266 start up running. You can either look at the start-up output from the serial port or query the ESP8266.

Configuration Mode with Web Server:
The start-up output will include the following if the ESP has started up in configuration mode, with the web server running:

ESP8266 IP: 192.168.0.133
ESP8266 WebServer Port: 9705
ESP8266 Mode: Web Server Running – Type = SDK API

Of course, the port and IP values may vary if they are configured differently.

MQTT Mode:
The start-up output will include the following if the ESP has started up in MQTT Mode:

MQTT Rx Topic: mqtt_rx_18fe34a26629
MQTT Tx Topic: mqtt_tx_18fe34a26629
ESP8266 Mode: MQTT Client Running

Note the MQTT topics are provided. These values need to be known in order to communicate with the ESP, which acts like a server for this project.

Start-up Mode Query
The start-up mode can also be determined from the response to a query. This method may be preferred for applications that do not have access to the ESP serial port or are using the serial link for other purposes.

The ESP will not respond if it is not running in the queried mode. For configuration mode, simply enter the configuration URL (or any other valid web server URL). If the ESP responds, it is running in this mode.

Likewise, attempt to send a message to the ESP MQTT  “server”. If is running in MQTT mode if a response is received

Configuration Mode

The configuration screen from the last iteration of this project was modified to add the new MQTT parameters. Just as before, this screen is accessed by entering the ESP8266 IP (or domain name) with it’s assigned web server port with the following suffix :

http://192.168.0.133:9705/config

If you want to switch to the TSL MQTT operating mode at power-up, just check the 2 new boxes, click SAVE, and then RESET ESP8266.

A URL has also been provided to switch modes within your application code:

http://192.168.0.133:9705/?request=MqttSslOn

This will change the EEPROM content to switch modes and reset the ESP8266 so it starts-up in the selected mode.

MQTT Mode

When the ESP8266 starts up in MQTT mode with TLS connection enabled, it will respond to server requests just like it did in the last iteration of this project. And switching back to ESP web server/configuration mode is simply a matter of sending the request in an MQTT message:

/?request=HttpOn

Conclusion

We now have a secure MQTT connection to the ESP8266. Here is the project code link again. And with careful management of the RAM (heap), it will perform reliably. More functionality in this case requires the distribution of tasks between two operating modes which are only loaded in memory when needed. This technique can be used in other cases as well to stretch the capabilities of this amazing little system on a chip (SoC) we call ESP8266.

 

Loading

Share This:
FacebooktwitterredditpinterestlinkedintumblrFacebooktwitterredditpinterestlinkedintumblr

VPS Application 1: MQTT Broker

Using an MQTT Broker to publish and subscribe to IoT events is a critical aspect of many IoT infrastructures. And hosting your own broker retains complete control in your hands. This writing provides step-by-step instructions for installing the Mosquitto MQTT broker on a VPS running Linux Ubuntu 16.04.

Don’t have a personal Virtual Private Server (VPS)? Check here  to find out how to get one.

MQTT Broker Installation Overview

Installing the Mosquitto MQTT broker on your Linux Ubuntu VPS can be broken down into 3 basic steps. And if you wish to also provide secure connections, four additional steps are needed.

  1. Install Mosquitto
  2. Configuring MQTT Passwords
  3. Configuring MQTT Over Websockets
  4. Securing your MQTT Broker
    1. Install Certbot
    2. Run Cerbot
    3. Setting up Certbot Automatic Renewals
    4. Configuring MQTT SSL

Installing Mosquitto

A  telnet client is needed to install and configure the MQTT broker on your VPS. PuTTY is a widely used telnet client. It can be downloaded here. Make sure you have a telnet client installed and your non-root linux user credentials are handy before continuing.

Then, log in with your non-root user with PuTTY and install Mosquitto with apt-get by entering:

sudo apt-get install mosquitto mosquitto-clients

The MQTT broker service will start automatically after the installation has completed. To test, open a second command-line interface (CLI) using PuTTY. With one of the terminal windows, subscribe to a test topic named “mymqtttesttopic” by entering:

mosquitto_sub -h localhost -t mymqtttesttopic

Then, publish a message from the other terminal:

mosquitto_pub -h localhost -t mymqtttesttopic -m “Sent from my own MQTT Broker”

If the installation is properly working, the subscribe terminal will receive the message:

Configuring MQTT Passwords

First level of security is to configure Mosquitto to use passwords. Mosquitto includes a utility to generate a special password file called mosquitto_passwd. Using this utility, you will be prompted to enter a password for the specified username, and place the results in /etc/mosquitto/passwd. From the terminal, enter:

sudo mosquitto_passwd -c /etc/mosquitto/passwd testuser

Note: Use “password” for the password for this test case when prompted

Now we’ll open up a new configuration file for Mosquitto and tell it to use this password file to require logins for all connections:

sudo nano /etc/mosquitto/conf.d/default.conf

This should open an empty file. Paste in the following:

/etc/mosquitto/conf.d/default.conf
allow_anonymous false
password_file /etc/mosquitto/passwd

allow_anonymous false will disable all non-authenticated connections, and the password_file line tells Mosquitto where to look for user and password information. Save and exit the file.

Now we need to restart Mosquitto and test our changes:

sudo systemctl restart mosquitto

Try to publish a message without a password:

mosquitto_pub -h localhost -t “test” -m “hello world”

The message should be rejected:

Output
Connection Refused: not authorized.
Error: The connection was refused.

Before we try again with the password, switch to your second terminal window again, and subscribe to the ‘test’ topic, using the username and password this time:

mosquitto_sub -h localhost -t test -u “testuser” -P “password

It should connect and sit, waiting for messages. You can leave this terminal open and connected for the rest of the tutorial, as we’ll periodically send it test messages.

Now publish a message with your other terminal, again using the username and password:

mosquitto_pub -h localhost -t “test” -m “hello world” -u “testuser” -P “password

The message should be passed from one terminal to the other in the same way as the initial test without passwords. If the message was received, we have successfully added password protection to our Mosquitto MQTT Broker.

Passwords for multiple users

Most likely, your MQTT broker will need to support more than one user. Here is how to create a password file for multiple users:

First create a plain text file, adding a line for each user: <username>:<password>

sudo nano /etc/mosquitto/passwd

For 3 users, the file contents:

username1:password1
username2:password2
username3:password3

Then encrypt the plain text file by entering:

sudo mosquitto_passwd -U /etc/mosquitto/passwd

Configuring MQTT Over Websockets

You will probably want to have your MQTT Broker support Websockets. This makes it possible to communicate with your MQTT broker using JavaScript. Very useful for web applications. Here is how to add it to your Mosquitto configuration.

Open the configuration file to add port listeners:

sudo nano /etc/mosquitto/conf.d/default.conf

Add to the bottom of the file:

listener 1883 localhost

listener 8883

listener 8083
protocol websockets

listener 18083
protocol websockets

Then update the firewall to support these listener ports.

sudo ufw allow 8883
sudo ufw allow 8083
sudo ufw allow 18083

Restart Mosquitto to activate the listener configuration:

sudo systemctl restart mosquitto

Here is the MQTT port allocation:

Usage
1883 Standard TCP/IP Port
8883 Secure SSL TCP/IP Port
8083 Secure Websockets Port
18083 Insecure Websockets Port

Note that the last listener on port 18083 is not a standard MQTT port. This port is used for insecure (non-encrypted connections). While it is not required, it can sometimes be useful when communicating with tiny IoT devices that cannot support the additional overhead required to connect using the SSL protocol.

Testing MQTT Websockets

The easiest method of verifying the Websockets ports is to use a web browser MQTT client. While there are many such tools available, HiveMQ will be used for this demonstration.

First, open an incognito web browser window to this link.

Note: You must use an incognito window. A normal browser window sends extra information to track your browsing history. This extra http traffic will interfere with the MQTT websocket protocol and cause the connection to fail.

And create a new connection:

Once the connection is made, publish a test message:

Securing your MQTT Broker

There are four steps required to securing the MQTT Broker with SSL/TLS.

Step 1: Install Certbot

We must first install the official client from an Ubuntu PPA, or Personal Package Archive. These are alternative repositories that package more recent or more obscure software. First, add the repository from the VPS terminal.

sudo add-apt-repository ppa:certbot/certbot

Note: If this command is not found, the following package needs to be installed first:

sudo apt-get install software-properties-common

You’ll need to press ENTER to accept. Afterwards, update the package list to pick up the new repository’s package information.

sudo apt-get update

And finally, install the official Let’s Encrypt client, called certbot.

sudo apt-get install certbot

Now that we have certbot installed, let’s run it to get our certificate.

Step 2: Run Certbot

The Certbot that was just installed needs to answer a cryptographic challenge issued by the Let’s Encrypt API in order to prove we control our domain. It uses ports 80 (HTTP) and/or 443 (HTTPS) to accomplish this. We’ll only use port 80, so let’s allow incoming traffic on that port now:

sudo ufw allow http

Output
Rule added

We can now run Certbot to get our certificate. We’ll use the --standalone option to tell Certbot to handle the HTTP challenge request on its own, and --standalone-supported-challenges http-01 limits the communication to port 80. -d is used to specify the domain you’d like a certificate for, and certonly tells Certbot to just retrieve the certificate without doing any other configuration steps.

sudo certbot certonly –standalone –standalone-supported-challenges http-01 -d mqtt.example.com

When running the command, you will be prompted to enter an email address and agree to the terms of service. After doing so, you should see a message telling you the process was successful and where your certificates are stored.

We’ve got our certificates. Now we need to make sure Certbot renews them automatically when they’re about to expire.

Step 3: Setting up Cerbot Automatic Renewals

Let’s Encrypt’s certificates are only valid for ninety days. This is to encourage users to automate their certificate renewal process. We’ll need to set up a regularly run command to check for expiring certificates and renew them automatically.

To run the renewal check daily, we will use cron, a standard system service for running periodic jobs. We tell cron what to do by opening and editing a file called a crontab.

sudo crontab -e

You’ll be prompted to select a text editor. Choose your favorite, and you’ll be presented with the default crontab which has some help text in it. Paste in the following line at the end of the file, then save and close it.

crontab
. . .
15 3 * * * certbot renew --noninteractive --post-hook "systemctl restart mosquitto"

The 15 3 * * * part of this line means “run the following command at 3:15 am, every day”. The renewcommand for Certbot will check all certificates installed on the system and update any that are set to expire in less than thirty days. --noninteractive tells Certbot not to wait for user input.

--post-hook "systemctl restart mosquitto" will restart Mosquitto to pick up the new certificate, but only if the certificate was renewed. This post-hook feature is what older versions of the Let’s Encrypt client lacked, and why we installed from a PPA instead of the default Ubuntu repository. Without it, we’d have to restart Mosquitto every day, even if no certificates were actually updated. Though your MQTT clients should be configured to reconnect automatically, it’s wise to avoid interrupting them daily for no good reason.

Now that automatic certificate renewal is all set, we’ll get back to configuring Mosquitto to be more secure.

Step 4. Configuring MQTT SSL

To enable SSL encryption, we need to tell Mosquitto where our Let’s Encrypt certificates are stored. Open up the configuration file we previously started:

sudo nano /etc/mosquitto/conf.d/default.conf

Replace the file content with the following:

 
 
  1. allow_anonymous false
  2. password_file /etc/mosquitto/passwd
  3. listener 1883 localhost
  4. listener 8883
  5. certfile /etc/letsencrypt/live/&lt;yourVPSdomainname&gt;/cert.pem
  6. cafile /etc/letsencrypt/live/&lt;yourVPSdomainname&gt;/chain.pem
  7. keyfile /etc/letsencrypt/live/&lt;yourVPSdomainname&gt;/privkey.pem
  8. listener 8083
  9. protocol websockets
  10. certfile /etc/letsencrypt/live/&lt;yourVPSdomainname&gt;/cert.pem
  11. cafile /etc/letsencrypt/live/&lt;yourVPSdomainname&gt;/chain.pem
  12. keyfile /etc/letsencrypt/live/&lt;yourVPSdomainname&gt;/privkey.pem
  13. listener 18083
  14. protocol websockets
This file is the same as the last version, except the SSL certificates have been added to the SSL and websocket ports:
 
 
  1. certfile /etc/letsencrypt/live/&lt;yourVPSdomainname&gt;/cert.pem
  2. cafile /etc/letsencrypt/live/&lt;yourVPSdomainname&gt;/chain.pem
  3. keyfile /etc/letsencrypt/live/&lt;yourVPSdomainname&gt;/privkey.pem

listener 8883 sets up an encrypted listener on port 8883. This is the standard port for MQTT + SSL, often referred to as MQTTS. The next three lines, certfile, cafile, and keyfile, all point Mosquitto to the appropriate Let’s Encrypt files to set up the encrypted connections.

Save and exit the file, then restart Mosquitto to update the settings:

sudo systemctl restart mosquitto

Now we test again using mosquitto_pub, with a few different options for SSL:

mosquitto_pub -h <your VPS domainname> -t test -m “hello again” -p 8883 –capath /etc/ssl/certs/ -u “user1” -P “password

Note that we’re using the full hostname instead of localhost. Because our SSL certificate is issued for <yourVPSdomainname>, if we attempt a secure connection to localhost we’ll get an error saying the hostname does not match the certificate hostname (even though they both point to the same Mosquitto server).

--capath /etc/ssl/certs/ enables SSL for mosquitto_pub, and tells it where to look for root certificates. These are typically installed by your operating system, so the path is different for Mac OS, Windows, etc. mosquitto_pub uses the root certificate to verify that the Mosquitto server’s certificate was properly signed by the Let’s Encrypt certificate authority. It’s important to note that mosquitto_pub and mosquitto_sub will not attempt an SSL connection without this option (or the similar --cafile option), even if you’re connecting to the standard secure port of 8883.

If all goes well with the test, we’ll see hello again show up in the other mosquitto_sub terminal.

You can also run additional tests using the HiveMQ MQTT client again to verify the websocket port 8083, which is now configured securely. This time, make sure the “SSL” checkbox is selected when making a connection.

Once this final test has been performed successfully, your MQTT broker is fully set up!

In Closing

With your own secure MQTT broker running on a VPS, you have a powerful platform at your disposal. Using a reliable provider, you no longer need to keep any hardware running 24-7, no longer vulnerable to power interruptions or computer crashes. And there are no constraints on your custom configuration options. That is all taken care of by the VPS provider.

I hope you find this information useful

Loading

Share This:
FacebooktwitterredditpinterestlinkedintumblrFacebooktwitterredditpinterestlinkedintumblr

Your Own VPS for IoT and More

Having a Virtual Private Server (VPS) at your disposal opens up boundless IoT possibilities – all under your direct control – with no reliance on third-party cloud services. Like hosting your own MQTT broker, CoAP server, and scheduling periodic tasks to monitor and control your IoT devices or store/retrieve information using a database. Website hosting, including popular CMS sites such as WordPress, Joomla!, Drupal and more as well as file/picture sharing are also possible with your VPS.

Does this seem like a daunting task? Difficult to set-up? And expensive?

It doesn’t have to be.

Building on a past project, all  I did initially was port my USB Thumb Drive LAMP server to a VPS. And the basic framework, including the Linux distribution  you choose to use, are installed automatically for you. This greatly simplifies the setup…

Shared Host vs VPS

Before moving on with VPS, it should be noted that “Shared Host” are also available. They are tempting as the lowest cost available, they do not provide the capabilities or flexibility of VPS, and thus are not addressed in this post. Here is one decent article I have found that provides clear support for the superiority of VPS over a shared host. You are in control with a VPS, free from the restrictions placed on a shared host account.

Selecting a VPS Provider 

First thing you have to do is select a VPS provider. There are many to choose from. All options I have seen start with a basic package and scale up to fit your needs. For basic DIY IoT enthusiasts, the entry-level offering provides more capability that you should ever need. Here are a few of the VPS providers and their basic features:

Website Cost/month CPU Cores RAM Storage Transfer
LiNode linode.com $5.00 1 1G 20G SSD 1 TB
LiNode linode.com $10.00 1 2G 30G SSD 2 TB
iPage iPage.com $19,99 1 1G 40G 1 TB
HostGator HostGator.com $19,95 2 2G 120G 1.5 TB
FatCow fatcow.com $19,99 1 1G 40G 1 TB
JustHost justhost.com $19,99 2 2G 30G 1 TB
Bluehost bluehost.com $19,99 2 2G 30G SAN 1 TB

I found that the Linode option offered the best value. At 10 USD per month, this provider was the lowest cost of the ones I had looked at. And recently, they have added even a lower, 5 USD per month package. In fact, there were many others that offered teaser rates initially, only to cost much more than the rates listed above. Those providers were eliminated from my consideration.

LiNode uses Solid-State Disks (SSD) which yield lightning fast performance, even with the entry level package that uses a single CPU core. I have been had an active VPS account with LiNode for about a year now, with 100% uptime.

If you do choose to setup a VPS using LiNode, please consider using this link, which, full disclosure, would provide me with a referral credit to help fund my own VPS account and continue sharing information.

Operating System Options 

LiNode VPS provides step-by-step instructions for setting up your system. While I do not have any personal experience, I suspect other VPS providers offer similar directions to simplify the setup procedure. or those familiar with Linux, here are the distributions that LiNode offers for immediate deployment:

I chose to deploy Ubuntu 16.04 LTS, which is a widely used distribution. With that basic configuration, I have customized the setup for my own personal needs.

Exploiting Your VPS Platform 

Once your VPS is setup, it is ripe and ready for practical applications. The first thing many DIY enthusiasts will want to add is a private MQTT broker. As an avid ESP8266, the first 3 applications listed below can interface directly with the VPS. This and other uses for the VPS will be covered in follow-up posts…

  • VPS Application 1: MQTT Broker
  • VPS Application 2: CoAP Server
  • VPS Application 3: Scheduled IoT Monitor/Control Scripts
  • VPS Application 4: Hosting a Website
  • VPS Application 5: Private Email Server

And this is just the beginning.

Hope you find this information useful.

Loading

Share This:
FacebooktwitterredditpinterestlinkedintumblrFacebooktwitterredditpinterestlinkedintumblr

Press Ctrl+C to copy the following code.
"