Motivation

When i hacked my door to open it with OpenSesame, I supposed that nobody will try to hack my hacked door to take my precious RPI and run away. Indeed, usually maker ignore the security concerns because they are complicated, painful, and time consuming issues without any WOW effect. However, we are building systems that we may use every day. We should pay a little more attention to the security aspect of our stuffs.

Examples of IoT Security Threats

Nobody has replicated yet my OpenSesame project :'( . But let suppose that your neighbor did. As you know he did (Post on Hackster.io), you can hack his WiFi using a tool like Reaver, Scan for his R-PI IP, and open his door. You can then take his precious R-PI and come back home to play with this tutorial. That can happen because i did not include any authentication mechanism while building the server part of the OpenSesame project. To avoid that, your neighbor should simply follow the tips provided in the next section.

On this second example, consider that you are connecting your R-PI to a server to store your data. It may be hacked by your other neighbor to join a Botnet. He may use your R-PI ro run a Man-In-The-Middle attack and get your Facebook password (or your credit card).

On this third and last example. Suppose that you have a connected drone with a remote camera that you have made insecurely. The same other neighbor may hack it and enjoy seeing you dancing in the morning. He may event post this video on your Facebook if he had already hacked your Facebook password :D

These are a simple examples to introduce the fact that the security threats may happens and they can be embarrassing if not harmful.

If you have $200 to spend on a book, I recommend to preorder this handbook that provide recommendations related Cyber-Physical Systems Security. Especially because i am the author of two of the chapters :D

Protect your Network

In order to prevent the many networking attacks, edit the sysctl file as described below.

pi@raspberrypi:~ $ sudo nano /etc/sysctl.conf

Modify this file to enable the protection against MITM, Spoofing, and others. The code below illustrates those modifications:

... # Do not accept ICMP redirects (prevent MITM attacks) net.ipv4.conf.all.accept_redirects = 0 net.ipv6.conf.all.accept_redirects = 0 # _or_ # Accept IC # Uncomment the next two lines to enable Spoof protection (reverse-path filter) # Turn on Source Address Verification in all interfaces to # prevent some spoofing attacks net.ipv4.conf.default.rp_filter=1 net.ipv4.conf.all.rp_filter=1 ... # Do not accept ICMP redirects (prevent MITM attacks) net.ipv4.conf.all.accept_redirects = 0 net.ipv6.conf.all.accept_redirects = 0 # _or_ # Accept ICMP redirects only for gateways listed in our default # gateway list (enabled by default) # net.ipv4.conf.all.secure_redirects = 1 # # Do not send ICMP redirects (we are not a router) net.ipv4.conf.all.send_redirects = 0 # # Do not accept IP source route packets (we are not a router) net.ipv4.conf.all.accept_source_route = 0 net.ipv6.conf.all.accept_source_route = 0

Setup a Firewall

In order to protect your R-PI against threats originating from the internet, a host based firewall is the solution to control any incoming connections. The idea is to close all the ports by default and only open up the ports you need.

The simplest solution is to install the Uncomplicated Firewall (UFW) as described below:

pi@raspberrypi:~ $ apt-get install ufw

Once installed, You have to configure a tune the firewall to your own needs. However, deny any incoming connection by default as described below:

pi@raspberrypi:~ $ ufw default deny incoming

You may for example allow ssh access only from your local network. The command below illustrate that. note that you have to change the xxx.yyy.zzz by your local network information.

pi@raspberrypi:~ $ ufw allow from xxx.yyy.zzz.0/24 to any port 22 proto tcp

To allow access to your web server using HTTP and HTTPS, you have to open the corresponding ports. Below two configuration, the first open the port to your local network, the second open them for internet:

# open the ports locally pi@raspberrypi:~ $ ufw allow from xxx.yyy.zzz.0/24 to any port 80 proto tcp pi@raspberrypi:~ $ ufw allow from xxx.yyy.zzz.0/24 to any port 443 proto tcp





# open the ports to internet pi@raspberrypi:~ $ ufw allow from any to any port 80 proto tcp pi@raspberrypi:~ $ ufw allow from any to any port 443 proto tcp

Setup an Intrusion Detection System (IDS)

Firewall blocks the traffic from/to unauthorized ports. However, it may be some malicious traffic coming over the ports authorized by the firewall (22, 80, and 443 in occurrence). IDS is a program that looks deeper into packets payloads allowing it to detect malicious traffic. Snort is one of the best open source IDS. There is not yet a supported version for Raspbian Jessie. You have to build it from the sources. Note that the build in your R-PI may take more than a hour. Below the commands to build it :

pi@raspberrypi:~ $ wget https://www.snort.org/downloads/snort/daq-2.0.6.tar.gz pi@raspberrypi:~ $ tar xvfz daq-2.0.6.tar.gz pi@raspberrypi:~/daq-2.0.6 $ cd daq-2.0.6 pi@raspberrypi:~/daq-2.0.6 $ ./configure && make && sudo make install pi@raspberrypi:~ $ cd .. pi@raspberrypi:~ $ wget https://www.snort.org/downloads/snort/snort-2.9.8.0.tar.gz pi@raspberrypi:~ $ tar xvfz snort-2.9.8.0.tar.gz pi@raspberrypi:~ $ cd snort-2.9.8.0 pi@raspberrypi:~/snort-2.9.8.0 $ ./configure --enable-sourcefire && make && sudo make install

In order to configure Snort, edit the configuration file as described below :

pi@raspberrypi:~ $ sudo nano /etc/snort/snort.conf

Configure your internal/external networks and the rules file path as described below. Again, adapt xxx.yyy.zzz to your network :

################################################### # Step #1: Set the network variables. For more information, see README.variables ################################################### # Setup the network addresses you are protecting ipvar HOME_NET xxx.yyy.zzz.0/24 # Set up the external network addresses. Leave as "any" in most situations ipvar EXTERNAL_NET !$HOME_NET ... # Path to your rules files (this can be a relative path) # Note for Windows users: You are advised to make this an absolute path, # such as: c:\snort\rules var RULE_PATH /etc/snort/rules ...

In addition, you may want to install Tripwire to keep track of your file system data points in order to detect whether unauthorized changes have occurred. Tripwire will send you an Email each time that a suspect change happen on your file system.

First you have to install Tripwire (choose yes to create a policy file during installation) and Email utilities as illustrated below :

pi@raspberrypi:~ $ sudo apt-get install tripwire pi@raspberrypi:~ $ sudo apt-get install mailutils

Now you have to initialize the tip wire database using the command below:

pi@raspberrypi:~ $ sudo tripwire --init

In order to configure tripwire, you need to execute a first check, get the results, and do some tuning on the policy file based on those results.

Run the first check and save the result to a file using the following command:

pi@raspberrypi:~ $ sudo sh -c 'tripwire --check | grep Filename > checkResults.txt

One the file generated, edit the policy file and comment all the lines that appear on your result file. For example /etc/rc.boot

To edit the policy file, use the following command:

pi@raspberrypi:~ $ sudo nano /etc/tripwire/twpol.txt

Your policy file should be ready. you have to implement it, reinitialize the database and check the new configuration using the following command:

pi@raspberrypi:~ $ sudo twadmin -m P /etc/tripwire/twpol.txt pi@raspberrypi:~ $ sudo tripwire --init pi@raspberrypi:~ $ sudo tripwire --check

Now tripwire is ready to use, you should configure a cron task on your system to receive a report every day on your mailbox. Edit your crontab using the command below :

pi@raspberrypi:~ $ sudo crontab -e

Add the following command in order to have tripwire run at 12:00am every day:

00 12 * * * /usr/sbin/tripwire --check | mail -s "Tripwire report for `uname -n`" your_email@you-pi.com

More details about Tripwire tailoring are available here.

Secure your Communications

Transport Layer Security (TLS) formally Secure Sockets Layer (SSL) session is used to enable privacy and security for the communications over internet. In occurrence, TLS enables a kind of tunneling over internet between your IoT device and an IoT platform.

Consider that a hacker is sniffing your packets on the network. As illustrated in the Figure below, he can read all your data if you are not using TLS. By Using TLS, you cannot stop him capturing you packets. However, he will be unable to understand them.

Roughly, TLS session is composed by three main steps :

The device and the platform agree upon a cipher suite and algorithm using a Hello exchange of the TLS handshake.

The device and the platform exchange keys as per the agreed key exchange algorithm.

The device and the platform use the negotiated cipher and exchanged keys to establish an encrypted connection.

IoT platforms like Amazon IoT and Structure provides security features that you can use to communicate with them. I have personally a preference for Structure as they provide an powerful authentication mechanism without any extra complication.

As example, Structure platform provides a NodeJs SDK that uses TLS by default to communicate with their MQTT broker.

Moreover, they provide support for secure MQTT websocket that you may use directly as illustrated in the code below :

var mqtt; var reconnectTimeout = 2000; var host = "broker.getstructure.io"; var port = 443; var clientID = "YOUR-DEVICE-ID"; var username = "YOUR-ACCESS-KEY"; var password = "YOUR-ACCESS-SECRET"; var commandtopic = "structure/"+clientID+"/command"; var statetopic = "structure/"+clientID+"/state"; var useTLS = true; var cleansessionmqtt = true; function MQTTconnect() { mqtt = new Paho.MQTT.Client( host, port, clientID); var options = { timeout: 5, useSSL: useTLS, cleanSession: cleansessionmqtt, onSuccess: onConnect, onFailure: function (message) { $('#status').val("Connection failed: " + JSON.stringify(message) + "Retrying"); console.log("Connection failed: " + JSON.stringify(message) + "Retrying"); setTimeout(MQTTconnect, reconnectTimeout); } }; mqtt.onConnectionLost = onConnectionLost; mqtt.onMessageArrived = onMessageArrived; if (username != null) { options.userName = username; options.password = password; } console.log("Host="+ host + ", port=" + port + " TLS = " + useTLS + " username=" + username + " password=" + password); mqtt.connect(options); } function onConnect() { $('#status').val('Connected to ' + host + ':' + port); console.log('Connected to ' + host + ':' + port); // Connection succeeded; subscribe to our topic mqtt.subscribe(commandtopic, {qos: 0}); }

Conclusion

Security in complicated an painful. However, it protects you and your devices against threats. The main solutions presented in this article are installed once per device (ex; IDS and firewall). So do this effort and install them !!

Regarding the secure communication, please note that all the IoT platforms provides more or less similar features, do nor hesitate to ask them on their forum if you need help to secure you communication with their products.