I've been using Home Assistant for several years. It's really great to be able to control all of our devices from a single place, and being able to adjust the lights or the thermostat from miles away never seems to get old.
The most common way to set up Home Assistant for remote access is to set up port forwarding or to use Home Assistant Cloud. Either of these puts Home Assistant on the internet, and lets you log in from anywhere.
But it also means that anyone else on the internet can get to your Home Assistant login screen, served by your Home Assistant server.
Home Assistant is designed to refuse access to anyone that doesn't provide valid credentials, but all software has bugs, and modern web applications are surprisingly complex. It's easy to imagine a bug that would allow someone on the internet to access Home Assistant, or worse, the underlying operating system, without successfully logging in.
This sort of no-auth vulnerability is common across the software world. This type of vulnerability has even affected Home Assistant users in the past. In January 2021, Home Assistant disclosed that several vulnerabilities were discovered in third-party custom integrations. Malicious users on the internet, without valid credentials, could read any file accessible to Home Assistant. This would include the Home Assistant database which might contain sensitive data such as location history. (In this particular case, only users with certain third-party integrations were affected, but this type of vulnerability could happen against Home Assistant core, too.)
So, how do we protect ourselves from this kind of vulnerability?
Defense in depth
We want to prevent random people on the internet from being able to talk to any part of Home Assistant at all while still allowing valid users to connect. The easiest way to do this is to put a reverse proxy (such as Nginx) between the internet and your Home Assistant server and configure it to do some sort of access control. You can be creative here: use another username/password, use client SSL certificates, set up IP allow-listing, or create some sort of complicated port knocking scheme.
It doesn't have to be perfect. We want to make it hard for anyone scanning around the internet looking to exploit a vulnerability. It might mean you have to log in twice to get to Home Assistant, once to satisfy the reverse proxy, and then once again for Home Assistant, but that's a pretty minor nuisance.
With this approach, Home Assistant is protected, but our reverse proxy could still be vulnerable to remote attacks. We're exchanging one problem for another but it's probably a net win. The most popular remote proxies attract a lot of scrutiny from security researchers, so it's likely that vulnerabilities will be discovered and fixed quickly. Still, we should be sure to set up our operating system's automatic updates to make sure we apply security patches quickly.
To the cloud!
We could reduce our risk somewhat further by putting our reverse proxy on a VM in the cloud and connect to Home Assistant over a tunnel. This way any vulnerabilities would (hopefully) only impact the VM and not our Home Assistant server. Of course, this is easier said than done. I've been thinking about implementing something like this for years, but I've never gotten around to it because it's a pretty big endeavor.
Recently, I was very excited to learn about Cloudflare Access, which is a hosted product that pretty much does exactly this out of the box, without needing me to maintain the VM. And, it's now available on Cloudflare's free tier. I've been using it for about a month and it seems to work well.
In my next post I'll dive into the pros and cons of using Cloudflare Access to secure Home Assistant.