Reading Matthew Garret’s exposés of home automation IoT devices makes most engineers think “hell no!” or “over my dead body!”. However, there’s also the siren lure that the ability to program your home, or update its settings from anywhere in the world is phenomenally useful: for instance, the outside lights in my house used to depend on two timers (located about 50m from each other). They were old, loud (to the point the neighbours used to wonder what the buzzing was when they visited) and almost always wrongly set for turning the lights on at sunset. The final precipitating factor for me was the need to replace our thermostat, whose thermistor got so eccentric it started cooling in winter; so away went all the timers and their loud noises and in came a z-wave based home automation system, and the guilty pleasure of having an IoT based home automation system. Now the lights precisely and quietly turn on at sunset and off at 23:00 (adjusting themselves for daylight savings); the thermostat is accessible from my phone, meaning I can adjust it from wherever I happen to be (including Hong Kong airport when I realised I’d forgotten to set it to energy saving mode before we went on holiday). Finally, there’s waking up at 3am to realise your wife has fallen asleep over her book again and being able to turn off her reading light from your alarm clock without having to get out of bed … Automation bliss!
We all want the convenience; the trick is to work around the rampant insecurity that comes with today’s IoT to avoid your home automation system being part of the DDoS bot net that brings down the internet.
Selecting your network
For me, nothing IP/Wifi based was partly due to Matthew’s blog and partly because my home Wifi network looks different from everyone else’s: I actually run an internal, secure, home network that is wired and have my Wifi sit unsecured and outside the firewall. This goes back to the good old days of expecting to find wifi wherever you travelled and returning the courtesy by ensuring your wifi was accessible, but it does mean that any wifi connected device would be outside my firewall and open to all, which, given the general insecurity of the devices, makes this a non-starter.
The next level down is to use a private network, like zigbee or z-wave. I chose z-wave because it covers longer distances (which I need) and it doesn’t interfere with wifi (I have a hard time covering the entire house, even with two wifi access points). Z-wave also looks secure, but, if you dig deeply, you find that there are flaws in the protocol that lay you open to a local attacker. This, by the way, shows the futility of demanding security from IoT vendors who really don’t understand how to do it: a flawed security implementation is pretty much as bad as no security at all.
Once this decision is made, the next is to choose a gateway to the internet that does what you want, namely give you remote control without giving up your security.
Gateway Phone Home?
A surprising number of z-wave controllers are of the phone home type (this means phone their manufacturer’s home, not you), and almost all of these simply won’t work if they’re not allowed to phone home. Google comprehensively demonstrated the issues this raises with nest: lots of early adopters now have so much non-functional junk.
For me, there was also the burned hand experience with Google services: whenever I travel, I invariably get locked out because of some pseudo-security issue and it takes a fight to get back in again. This ultimately precipitated my move away from the Google cloud and on to Owncloud for calendar and contacts, but also means I really don’t want to have to trust another external service for my home automation.
Given the significantly limited choice of non-phone home z-wave controllers, I chose the HomeSeer Zee S2. It’s basically a raspberry pi with a z-wave dongle and Linux. If you’re into Linux on evereything, you should be aware that the home automation system is actually written in .net and it uses mono to bridge the gap; an odd choice given that there’s no known windows platform that could actually possibly run this system.
Secure Internet based Automation
The ZS2 does actually come with wifi, but given my already listed wifi problems, it’s actually plugged into my secure wired network with all phone home capabilities disabled. Great, but that means it’s only accessible over a VPN and I want to be able to control it from things like my phone, where running a VPN is cumbersome, so lets do some magic tricks to make it securely accessible by any member of the family from any device.
Obviously, since I already run Owncloud, I have a server of my own in a co-located site. It’s this server I propose to use as my secure gateway. The obvious way of doing this is simply proxying the ZS2 controller web page, but there are a couple of problems: firstly if I do it globally the ZS2 will be visible to port scans and secondly it only actually has an unencrypted web page with http authentication, meaning the login credentials would go over the internet in clear text … oops!
The solution to the first of these is to make the web page only accessible to authenticated devices. My current method is to use firewall whitelisting and a hook to an existing service authentication to open up the port. So in the firewall mangle table, all the ports which require whitelisting are marked. Then, in the input firewall, any packet so marked is checked against the whitelist for a matching source IP. If a match is found, then the packet is permitted, otherwise it is denied.
Whitelisting itself is done by a simple pam script
#!/usr/bin/perl use Socket; $xt_file = '/proc/net/xt_recent/whitelist'; $name = $ENV{'PAM_RHOST'}; if ($name =~ m/^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$/) { $addr = $name; } else { $ip = gethostbyname($name); $addr = inet_ntoa($ip); } open(FD, ">$xt_file"); print FD "+$addr\n"; close(FD); exit 0
And this script is executed from the dovecot pam file as
# add session to cause ip address of successful login to be whitelisted session optional pam_exec.so /etc/pam.d/whitelist.pl
Meaning that any IP address that gets an authenticated imap connection (which is basically everybody’s internet device, since they all connect to email) is now allowed to access the authenticated ports. Since imap requires re-authentication after a configurable timeout, the whitelist entry only lasts for just over that timeout and hey presto, we have our secured port system.
Obviously, this isn’t foolproof: in particular whitelisting by external IP means that anyone sharing the same ip address via nat (like at a hotel) also has access to the secured ports, but it does cut down enormously on generic internet visibility.
The final thing is to add security to the insecure web page, so anyone in the path to my internet host can’t sniff the password. This is easily achieved by an stunnel redirect from the secure incoming port to the ZS2 over the VPN that connects to the internal network. The beauty of this is that stunnel can now use the existing web certificate for my internet host to afford protection from man in the middle attacks as well.
Last thoughts about Security
Obviously, the security above isn’t perfect. Anyone sharing my external IP would be able to run a port scan and (if they’re clever) detect the https port the ZS2 is on. However, it does require a lot of luck to do this and, obviously, even if they’re in the fortunate position of sharing an IP address, I’ve changed the default password, so the recent Mirai attack wouldn’t have been able to compromise the device.
Do I think this is good enough security: absolutely. In security, the bear principle applies: in that when escaping from a ravenous bear, you don’t have to be able to run faster than the bear itself, you merely need to be able to run faster than the slowest other potential food source … In internet terms, this means that while there are so many completely insecure devices out there, no-one can be bothered to hack a moderately secure system like mine because the customisation makes it quite a bit harder. It’s also instructive to think that the bear principle is why Linux has such a security reputation: it’s not that we have perfect security against virus and trojan systems, it’s just that Windows was always so much worse …
Eventually, something like Mirai will look to attack the ZS2 web server itself (it is .net based, after all) rather than simply try a list of default passwords and then I’ll need to be a bit more clever, but while everyone else is so much more insecure, that day will be long delayed.
Well… bear principle only applies for attackers that want to compromise as many IoT devices as possible. If you make Russia’s government angry (for example) or if they decide that compromising your home system is easy way to get back door into kernel, you can no longer hope that bear principle protects you.
If the bear is hunting you specifically, then you have to run faster than the bear, yes.
My current next level that I’m exploring is a squid proxy for the website, still doing https<->http so I can plug it into the server fail2ban security for automated scanning and also filter the html that goes to the .net system to make sure only reasonable requests get through.
“We all want the convenience” — absolutely not. We don’t *all* want this kind of convenience.