Sunday, November 7, 2021

Using Cloudflare Access to Protect Home Assistant

In my last post, I mentioned how I've been using Cloudflare Access to secure my Home Assistant server.

If you're not familiar with Cloudflare, it's basically a global content distribution network. They host reverse proxies all around the world to provide customers with low-latency caching and DDoS protection. Basically, you stick Cloudflare in front of your website and it makes it faster.

Cloudflare Access adds two specific features that we can use to secure Home Assistant:

  • "Argo tunnels" change the way requests flow from Cloudflare to Home Assistant. Normally, with reverse proxies, the proxy makes a connection to the "origin" server (i.e. Cloudflare would make a connection to our Home Assistant server). With "Argo tunnels", we instead make a connection from the Home Assistant server to Cloudflare to establish a tunnel, and connections are proxied over this tunel. This ensures that all connections come from Cloudflare directly and avoids us needing to accept connections from the internet (e.g. with port forwarding).
  • "Cloudflare Access" is an additional mechanism to limit access to our server to authorized users only. It uses third-party oauth providers (e.g. GitHub) to handle identity, and rules we create to decide who is authorized. This is the feature that prevents unauthorized users from even seeing the Home Assistant login screen.
This setup has been working fairly well for me for the last month or so, but it might not be for everyone.

Benefits

Secure: As I mentioned in the previous post, Cloudflare Access an important layer of security on top of exposing Home Assistant directly on the internet. Because Cloudflare is doing all the work, the only thing we need to do to keep this working and safe is to update cloudflared from time to time.

Free*: This is all available as part of Cloudflare's free tier. The only expense involved is that you need to own your own domain name. Depending on the TLD and the registrar this can be less than $10/year.

One stop shop: Cloudflare also takes care of DNS and SSL for you, so you don't need to worry about setting up Let's Encrypt. You can even buy domain names from them at cost.


Drawbacks

Configuration is complex: Unfortunately, I haven't found a good configuration guide on how to set up Cloudflare Access with Home Assistant. A lot of what I did was by trial and error. Making matters worse, the Cloudflare Access configuration was recently merged with Cloudflare for Teams, which seems to be an entirely separate unrelated product that we don't want.

Furthermore, Cloudflare Access also feels "bolted on" to Cloudflare's core functionality. While I hope this isn't the case, the way the configuration is laid out gives me the impression that if the Cloudflare Access config were to disappear, the system would "fail open" and expose Home Assistant directly to the internet.

Cookie-based authentication not well supported: Cloudflare Access's authentication scheme relies on cookies, and without cookies enabled, you won't be able to access the protected site. The Android app recently gained cookie support, but the iOS app (as far as I know) does not support cookies.

Trust & Privacy: Unlike Home Assistant Cloud, where your traffic is encrypted end-to-end, with Cloudflare Access, Cloudflare does SSL termination. As a result, Cloudflare has the technical means to intercept the traffic to your Home Assistant instance. I can't imagine this being an actual problem, but it's worth noting for completeness.

Handling of long-lived sessions: Cloudflare Access is configured with a maximum session length, and the longest setting is one month. When a session expires, it's not very graceful. Once a month we'll have to log in again with our Github credentials, to gain access to Home Assistant, and then (possibly) again with our Home Assistant credentials.


In Conclusion

Cloudflare Access is a relatively new product and it's really exciting that it's available for free. It's great for securing remote access to home servers. I expect the configuration complexity will get ironed out soon.

Sunday, October 17, 2021

Protect Home Assistant from No-Auth Vulnerabilities

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 login screen

No-auth vulnerabilities

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.

Saturday, September 25, 2021

It's been a while...

So it's been over eight years since my last post. It's amazing how time flies. I've changed the name of the blog, but the content going forward should be about the same as it has always been... which isn't saying much.

Using Cloudflare Access to Protect Home Assistant

In my last post, I mentioned how I've been using Cloudflare Access to secure my Home Assistant server. If you're not familiar wit...