Well, yeah, who might have believed it! A BeagleBone black is able to handle reverse-proxy workload for my HA instance and not only. In these times of utterly complex software stacks and multi-megabytes “hello world” programs, we can still use common-sense when building web sites.

Why A Reverse Proxy

Home Assistant needs to be accessible via the Internet. But HA is not really meant to be directly accessible from the internet. And this is even more true for the computer your HA is running on. The internet is full of bots continuously looking for computers to break into. In this wild world, one need to be extra-cautious when exposing servers directly to the internet.

The security experts like to say: “you need to reduce the surface of attack” so the bots won’t be able to break into your system because of some unknown flaws. For instance, HA is a complex software, using docker and Python. Main focus of these technologies is not exactly the security. Sure, they offer some security features, but they are far from being safe to directly expose to the internet.

The common practice is to have a special computer sitting in between the internet and your home network. That special computer needs only to run the bare minimum software for it to boot up and open the HTTPS ports to the internet. It takes care of the SSL encryption and SSL certificates handling, and systematically hands over all of the HTTP requests it receives to the HA server. This is the reverse-proxy computer.

Even though the reverse proxy computer only runs the bare minimum software, specially dedicated for handling HTTP trafic, it may also have unknown flaws. These are way less common than those the HA instance could hanve, but still, they might be there. So, enter another layer of security: the firewall. Every publicly exposed internet service should always be placed behind a firewall.

The access path from the public internet to your HA instance should look like this:

Public internet ---> Firewall ---> Reverse Proxy ---> Home Assistant

How To Implement These Steps

If you’re in a hurry, then just activate the Home Assistant Cloud service and they’ll automatically configure this for you. Another situation where Home Assistant Cloud comes-in handy is when you’re behind a mobile operator access point. This is because mobile operators have a layer of IP address translations that would defeat any attempt to set-up your own DNS entry (more on this DNS thing below).

If you’re like me and like to own your system, and don’t risk to depend on some external “cloud” - remember “cloud” is just “someone else’s computers” - then stick with me. All of this uses Linux, so it needs only to be configured once then it would run forever without any changes.

DNS

For your mobile phone to be able to find your HA instance when outside of your home, the first step you need to resolve is the DNS entry. This depends on the kind your Internet Service Provider -provided IP address.

Your public IP address is Then
Dynamic Use dynamic DNS
Fixed Create your own domain name

Dynamic DNS

This involves going to some provider such as dynDNS or others like them.

Already this post, initially intended to describe reverse-proxy with a BeagleBone Black, started to get quite long, so I’ll let you on your own for this step :-)

Create Your Own Domain Name

This will look just like this website, where you entered “rusu.info”. There are several services available on the internet offering domain name reservation. This also is out of the scope of this article, as it tends to become quite long. If you still need help on this step, use the contact link by the bottom of this page and drop me an e-mail.

Separate Networks

To further secure things - and also to further complicate things - the different networks involved in the above set-up should also be physically separated. So, the diagram will look something like this:

                                      VLAN1              VLAN2
Public internet ---> Firewall ---> Reverse Proxy ---> Home Assistant

Please write me using the link at the bottom of this page if you’d like me to write more on the VLAN topic.

SSL Encryption

The trafic from the internet should always be encrypted with SSL, and exposed via HTTPS. So, the diagram now looks like this:

                                          VLAN1              VLAN2
               (https)         (https)               (http)
Public internet -----> Firewall -----> Reverse Proxy -----> Home Assistant

Notice, there’s no need to expose HA using HTTPS on the local network.

The SSL topic can become quite arduous and expensive, but nowadays we are lucky to have Let’sEncrypt. We’ll use it below.

IMPORTANT: If you have activate SSL connection to your local Home Assistant, in the configuration.yaml file, then go ahead and dactivate it now. You should use the regular HTTP port 80 and no SSL encryption for it.

The BeagleBone Black As Reverse Proxy

First, install a minimal software image on your BeagleBone Black. No need for a graphical session on a headless server! You’ll only connect to it by SSH.

Install nginx:

sudo apt install nginx

Then configure the reverse proxy connection. Suppose your DNS name is example.org then create this file, and replace in it exmple.org with your own DNS name, and with it's local IP address.

/etc/nginx/sites-available/example.org
---
server {

	root /var/www/html;

	server_name example.org;
	server_tokens off;

	listen 443 ssl http2;

	client_max_body_size 0;
	add_header X-Robots-Tag "noindex, nofollow, nosnippet, noarchive";
	add_header Strict-Transport-Security "max-age=31536000; includeSubdomains" always;
	proxy_buffering off;

	location /.well-known/ {
		alias /var/www/.well-known/;
	}
	location / {
		proxy_pass http://<HA Local IP Address>;
		proxy_set_header Host $host;
		proxy_redirect http:// https://;
		proxy_http_version 1.1;
		proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
		proxy_set_header X-Forwarded-Host $remote_addr;
		proxy_set_header X-Real-IP $remote_addr;
		proxy_set_header Upgrade $http_upgrade;
		proxy_set_header Connection $connection_upgrade;
	}
}

Activate the site at the root prompt:

ln -s /etc/nginx/sites-available/example.org /etc/nginx/sites-enabled/
nginx -t # fix any errors that may be generated here
systemctl restart nginx

Configure LetsEncrypt by following these instructions and use it to create the SSL certificates for your own DNS name. The certbot script will also modify the above file to configure the SSL certificates.

Mobile Application Configuration

The “Home Assistant Companion Application” has takes two URLs for your HA instance. One is the local address (you deactivated SSL in HA configuration, right?) and id should look like: http://homeassistant or http://192.168.x.x or yet http://10.x.x.x.

The other URL is the remote one, and there you should enter https://example.org (replace example.org with your own DNS name).

While on the local WiFi, the application should be able to connect to the local URL. And when disconnecting the WiFi, and switching to the mobile network, connection should resume from the remote URL.

Enjoy your personal, cloud-free, Home Assistant!

You have questions?