If you’ve followed along with our series so far, you know we’ve set up a network of Raspberry Pis that PXE boot off a central server, and then used Zoneminder to run a network of IP cameras. Now that some useful services are running in our smart house, how do we access those services when away from home, and how do we keep the rest of the world from spying on our cameras?
Before we get to VPNs and port forwarding, there is a more fundamental issue: Do you trust your devices? What exactly is the firmware on those cheap cameras really doing? You could use Wireshark and a smart switch with port mirroring to audit the camera’s traffic. How much traffic would you need to inspect to feel confident the camera never sends your data off somewhere else?
Thankfully, there’s a better way. One of the major features of surveillance software like Zoneminder is that it aggregates the feeds from the cameras. This process also has the effect of proxying the video feeds: We don’t connect directly to the cameras in order to view them, we connect to the surveillance software. If you don’t completely trust those cameras, then don’t give them internet access. You can make the cameras a physically separate network, only connected to the surveillance machine, or just set their IP addresses manually, and don’t fill in the default route or DNS. Whichever way you set it up, the goal is the same: let your surveillance software talk to the cameras, but don’t let the cameras talk to the outside world.
Edit: As has been pointed out in the comments, leaving off a default route is significantly less effective than separate networks. A truly malicious peice of hardware could easily probe for the gateway.
This idea applies to more than cameras. Any device that doesn’t need internet access to function, can be isolated in this way. While this could be considered paranoia, I consider it simple good practice. Join me after the break to discuss port forwarding vs. VPNs.
For the Lazy: Port Forwarding
There are two broad categories of solutions to the problem of remote access, the first being port forwarding. Simply forwarding the assigned port from your router to the server is certainly easiest, but it’s also the least secure. The logs of a port 80 (HTTP) or 22 (SSH) exposed to the internet are frightening to sift through. And before you assume you’ll never be found in the vast sea of open ports, I present Robert Graham and masscan. Able to scan every IP address for a given port in just a few minutes, you’re not hiding that web server for long.
Stories like the libssh vulnerability are constant reminders of the dangers of leaving services open to the internet. If you opt to go this route, you must stay on top of security updates, use very strong passwords, and hope for the best. Fail2ban, virtualization, and good backups are all invaluable tools for standing up to the onslaught that is the public internet. Suffice it to say, I don’t recommend this approach for a home user.
One of the alternatives is to simply use a different external port number. Port 8080 for an HTTP server is a popular choice, which makes it a bad choice when trying to hide the service. Using a random port between 10,000 and 65,000 is a strategy known as security by obscurity. Someone with a grudge who knew your IP address will find it. But random scans through every possible port at every possible IP address make finding this more of a needle in a haystack problem.
Another technique that falls under the port forwarding category is port knocking. A series of TCP SYN packets (initial connection attempts) sent to a predetermined list of ports signals to a listening daemon which then allows your connection through the firewall. While clever, port knocking is subject to replay attacks and a few other problems. If the cleverness of port knocking appeals to you, there is a more modern take on the idea in the form of Fwknop (Full disclosure, I do some of the development on this project).
For Peace of Mind: VPN
Another approach to secure remote access is a VPN. A Virtual Private Network has been described as stretching a ridiculously long Ethernet cable through the internet. Traffic is encrypted between the endpoints, and because a VPN creates a virtual network adapter, a remote user can access the network as if they were physically connected to it.
OpenVPN is the time-tested contender in the open source VPN space, and has a good track record. It’s based on TLS, can run over TCP or UDP, and is widely used. There is good support for Android, iPhone, Windows, MacOS, and Linux. The configuration can be a challenge to work through, but once it’s up and running, OpenVPN is a great solution.
Wireguard is a much newer project, and aims to be simpler than OpenVPN. I’ve opted to use Wireguard, which has good Android and Linux support. In fact, Wireguard has been making steady progress towards being officially included in the Linux kernel. There is already macOS support through MacPorts and Homebrew, and their iOS app just entered beta. Wireguard uses more modern cryptography, aiming to be faster and more secure than the alternatives.
Both VPNs are supported by OpenWrt, and there are advantages to hosting the VPN on the router. When hosting a VPN on another machine on the local network, I have two pieces of advice, as these two problems trip me up repeatedly. The first is to enable IPv4 forwarding on the VPN machine. The second is that other devices on the network must have routes configured to get to the VPN network, in order for traffic to flow in either direction. Without that static route, packets addressed to the VPN are sent to the default router instead of the VPN server.
One final consideration is whether you want your IP address to be completely silent. Called a “black hole”, or “stealth mode”, this is when your IP address doesn’t respond to pings, and instead of responding to connection attempts with ICMP error packets, those incoming packets are dropped silently. The goal here is that to a network scan, your IP address appears to be unassigned with nothing listening for traffic.
OpenVPN and Wireguard both support this style of quiet operation when in UDP mode. In the case of OpenVPN, a Hash-based Message Authentication Code (HMAC) allows incoming UDP packets to be quickly dropped when they aren’t signed with a valid HMAC. Wireguard was written with this sort of radio silence as a design goal, and doesn’t require any extra configuration to enable it.
Why It’s Worth Thinking About
This has obviously been an overview, and there are many clever ideas we haven’t touched on. I often turn to Fwknop combined with SSH tunneling when I don’t want to set up a full VPN. IPSec via the Strongswan project is still a valid solution, and there are many others.
Most important, don’t thoughtlessly let the entire world try logging in to your house. Part of the appeal of hacking a house is to be able to monitor things while on vacation, but you don’t want to always feel like somebody’s watching you!
Up next, we’ll look at a networked garage door opener, and talk about the ways to work around a vendor’s proprietary protocol, and maybe a primer on how to reverse engineer it.