Tag Archives: iot

Securing ESP8266 Communication

Having a tiny device based on the ESP8266 and connecting it directly to the internet, is not a trivial task. The ‘thing’ needs to communicate somehow to at least one remote entity, and it needs to do this in a reliable way.
Regular plain communication, like TCP, HTTP or WebSockets might work in a sandboxed environment, localised on a single monitored and protected network. However, if only one single byte needs to escape this comfort zone, then all precautions need to be taken.

NodeMCU 1.0
NodeMCU 1.0

There are several problems that need to be accounted for in order to secure the communication. Out of these, three will be handled in this article:

  1. End-to-end encrypted transmission
  2. Remote server identity
  3. Local device identity

One way to handle device identity is to flash a generated client key and certificate alongside with the sketch, and use them to authenticate against the server. However, this aproach is rather bulky, and hard to implement when provisining multiple devices.
A simpler option is to generate a unique set of device address/keys and implement safe storing and mapping mechanism:

  • the device stores its unique adress either in memory (if always on), hardcoded in the sketch, flashed as data, or stored in the EEPROM (a bit insecure, because it can easily be read). For additional security, the final device address can be interleaved with pieces of the ESP8266 hardware adress.
  • the remote server contains a mapper which maps a single device address to a unique device id, in this case maybe even human readable. This is required if the device owner needs to do some registration or administration, so he/she should not know the ‘physical id’ of the device. Also with this, the human factor of exposing the device adress is eliminated.

For the other two problems, the end-to-end encryption and remote server identity, the Arduino port for ESP8266 has a nice secure client library called WiFiClientSecure. It’s not really a state of the art, but if used properly, it will do the job just right.

The WiFiClientSecure uses a TLS implementation which is based on the axTLS library. It supports TLS 1.2, so generally a default up to date server configuration will work.
However, the ESP8266 is still a limited embedded device, and the library itself is also constrained. In order to properly use it, please be aware of the following:

  • the device can’t store and process trusted CAs in order to verify the server certificate. In order to do so, the SHA1 fingerprint is only saved and compared.
  • the axTLS library supports only the following cypher suites: TLS_RSA_WITH_AES_128_CBC_SHA, TLS_RSA_WITH_AES_256_CBC_SHA, TLS_RSA_WITH_AES_128_CBC_SHA256 and TLS_RSA_WITH_AES_256_CBC_SHA256
  • the library can also be a bit buggy of the certificate is too big, or if you’re dealing with big payloads
  • the server configuration needs to be as precise, complete and simple as possible, meaning full correct configuration with no redirects and no rewrites

Getting the pieces together

1. Server configuration (apache httpd)

In your apache.conf, you need to map port 443, enable SSL, and bind the certificate(s):

2. Check the configuration

Go to https://www.ssllabs.com/ssltest/analyze.html and scan your server.
In the results, first check the following sections:

  • Server Key And Certificate. They should all be valid, up to date, and the name of the certificate pointing to your domain/server name. Check the RSA KeySize as well, 2048bits works just fine, and according to the docs, axTLS can handle 4096 as well
  • In the configuration section, see if TLS 1.2 is there (TLS 1.0 and 1.1 will work too) and from the list of Cipher Suites search for the supported ones listed above. At least one of them should be present.
  • Find the Incorrect SNI alerts entry in the Protocol Details sections. It must not show any problem at all.

3. Extract the fingerprint

With Chrome:

  1. Open your website (use https if you use both HTTP/HTTPS)
  2. Open DeveloperTools
  3. Go to the security tab and click on View certificate
  4. Expand the details and go to the bottom to see the SHA-1 fingerprint

4. Client implementation

The Arduino code is rather straight forward, and a sample is included in the library examples. If you can’t find it in the examples menu, you can check it out from github: https://github.com/esp8266/Arduino/blob/master/libraries/ESP8266WiFi/examples/HTTPSRequest/HTTPSRequest.ino
For your implementation, adapt the server hostname, the location(s) to your resources and of-course the logic.
Since in most of the cases, the devices will periodically communicate to the server, you can instantiate the WiFiClientSecure object globally and reuse it at every loop.

5*. Debug (if needed)

If something goes wrong, simple tracing and logging throughout the code will not help you a lot. When the SSL comm breaks or fails, a little is shown directly. One layer of additional debugging output can be achieved by executing “Serial.setDebugOutput(true);” after initializing the Serial object in setup(). But most often, that will not be enough.
In order to get all the details, you need to enable full debugging. If you use a NodeMCU as a development board, and you have it selected in the Arduino, then the debugging option will not be visible.
To enable full debugging for the NodeMCU, follow these steps:

  1. from the boards menu, select Generic ESP8266 Module
  2. from the freshly appeared options, find Flash Size, and choose 4M (3M SPIFFS)
  3. select nodemcu as Reset Method
  4. from Debug Port choose Serial
  5. from Debug Level choose core + ssl (or even + TLS mem)

Re-flash your sketch and open Serial Monitor. You should now see a lot more info.

At the end, again, if something goes wrong, rarely a direct error message will appear. My suggestion here is, if you’re up to date with your Arduino SDK installation and board libraries, inspect in details your server settings, because there is not much you can do wrong on the client side.

TheThingsNetwork LoRa node with ESP8266 and RN2483

TheThingsNetwork is a global community with a mission of bringing the Internet Of Things world closer to the people and making the connectivity easy and completely free. It’s doing that by providing open to use communication base stations and distributed back end system that handles all the communication, security and data availability throughout your devices and target system.

The communication protocol used is LoRaWAN. It allows low powered devices to connect from far distances, having in mind that they can only send or receive short bursts of data every now and then. The communication works on open frequencies, meaning that they don’t rely on regulators or major telecommunication providers.

Recently I applied for a local TTN community in Skopje, which got approved and the infrastructure is still in development. For the first test subject, I used Arduino Uno combined with the Microchip RN2483 for LoRaWAN connectivity. It’s the most basic example and it worked just fine. However the real requirement is to have an ESP8266 main controller that will talk to the RN2483. The reason for this is, that the case I’m working on needs an end-user configuration mechanism, and the ESP’s integrated WiFi and WebServer are just the thing.

For convenience and easier prototyping, I used the NodeMCU devkit board which is based on ESP-12E chip. It resembles Arduino quite much, has direct micro USB connection removing the need for FTDI and has all the pins necessary to connect the RN2483 chip and additional sensors / actuators you’ll need. For development, you can use the Arduino IDE and SDK with the ESP8266 boards and port. I’ve written on this topic before here (it may be a bit outdated though…).

Part 1: Connecting the parts

For a very basic setup, you’ll be needing a proto PCB (or a protoboard if you don’t wan’t to solder everything just yet), NodeMCU 1.0 devkit, RN2483 chip, some patch wires, solid core wire to act as an antenna, and soldering wire.

The NodeMCU has a bigger form factor than the RN2483 chip, so it’s possible even to solder them tightly together or one under the other by using some header pins aside.

The connection between the two goes like this:

RN2483 TX (6) <-> NodeMCU D6
RN2483 RX (7) <-> NodeMCU D5
RN2483 VDD (12 or 34) <-> NodeMCU 3.3V
RN2483 GND (20 or 33 …) <-> NodeMCU GND
RN2483 RESET (32) <-> NodeMCU D7
RN2483 RFH (23) <-> Antenna or 8.6cm solid core wire

My gruesome implementation looks like this:

NodeMCU + RN2483 side    NodeMCU + RN2483 top

Part 2: Prepare a TTN app

Go to TheThingsNetwork and create an account if you don’t have one. Check afterwards in your local community whether you have LoRa TTN coverage in your area.

After that, go to the staging app and create a new application. Choose Activate Devices with default app key in order to be able to use OTAA (this is not mandatory, I’m just using OTAA in the example code). When the app is created, take the App EUI and in Settings get the Default App Key. You’ll be needing them in the code afterwards. Leave the main app page opened, so that you can see the connections and the data sent afterwards.

Part 3: Code

Before you go off coding, first do some preparations:
– get the latest Arduino IDE
– install the nodemcu devkit driver
– install the esp8266 board in the Boards manager (or update to the latest)
– install the RN2483 library
– install the ESPSoftwareSerial library

The code I’m using is a modification of this nice tutorial done by jpmeiers.

*) this is the bare minimum you need in order to start things working. I got it by modifying the original code and removing the other parts afterwards, so let me know if something is not right.

When you got all packed, choose NodeMCU to be your current board, fire the serial monitor, set it to 57600 baud rate, and flash the code to the device. If everything is fine, you should see nice messages in the serial log, and by refreshing the app page on ttn, you should see your device registered and messages arriving every minute.

Part extra: extend and pack

The final product I made with all this is a Dust, Temperature and humidity TTN sensor node. You can do that by combining DHT22 (tutorial here) and sharp dust sensor (arduino tutorial here). However, the code still looks a bit shaky, and the dust sensor might need some extra work and/or calibration, so I don’t dare yet to publish it.

Dust, Temperature and Humidity LoRa TTN Sensor
The final sensor node prototype

And as a final touch, I designed a custom enclosure in OpenSCAD (a mix of this design by b2vn) and I 3D printed it. I just made it longer and wider, and put holes for the DHT and the dust sensor opening, to have air circulating.

The final result:

Dust, Humidity and temperature TTN sensor node with 3d printed housing
Dust, Humidity and temperature TTN sensor node with 3d printed housing