Tutorial: Home Assistant Secure Remote Access

July 9th, 2022

I was watching Paul Hibbert’s beginner’s guide to setting up Home Assistant (https://youtu.be/LI3lhgOiZ-8) a few weeks ago and one of the things he said got me thinking: he said that the easiest way to get both remote access and Alexa integration working with Home Assistant is to sign up and pay for the monthly Home Assistant Cloud subscription. He’s totally right of course, and I’ve said that before too. In the case of Alexa integration it’s an absolute ball-ache to set up and get working manually – totally rock solid once it is working, but a massive hassle to get there and there are many great videos/guides out there talking you through that already. But, remote access, specifically secured remote access is actually very easy to set up, if a little bit of a long winded process.

Yes, you can just open a port on your router and forward it straight through to your Home Assistant server, but that would be totally unencrypted and transmit your passwords and other data in plaintext for everyone to see. You could also just use the Let’s Encrypt add-on and use the default Home Assistant port 8123 for encrypted access but again this can cause a lot of issues with certain integrations. If you add encryption to the default port then that means that unencrypted access is no longer possible. If any devices on your local network want to talk to Home Assistant then they must be capable of ignoring invalid certificates because your certificate will not be valid when accessing directly by IP address instead of the external hostname.

This is how the solution is going to work: First of all we’re going to use Dynamic DNS to provide us with a hostname on the internet. 

Then we’re going to install a special proxy server add-on in Home Assistant which listens for external encrypted connection requests, which will be secured with a free Let’s Encrypt certificate.

We’ll configure your router to port forward that encrypted traffic through to your new proxy server.

That proxy server passes traffic through to the unencrypted Home Assistant server internally… so your end solution has unencrypted internal access on the original port 8123, and encrypted external access on port 8126. This whole process is probably a lot easier to follow on my YouTube video (see the top of this article), and then you can pop back here for the exact configuration… but in any case, here we go…

DuckDNS

  • Visit www.duckdns.org and create yourself an account.
  • Once signed in, you’ll need to create yourself a domain – this will be in the form of ‘something_you_made_up.duckdns.org’
  • On your account page, copy the ‘token’ to your clipboard for later. This is a form of password so treat it as such – do not share it!
  • Back over in Home Assistant, install the DuckDNS add-on from the Home Assistant Add-on Store.
  • In the DuckDNS add-on’s configuration page, type in the domain name you previously registered (i.e. something_you_made_up.duckdns.org) in the DNS name field.
  • Paste your token into the token field
  • In the “Let’s Encrypt” section, change “accept_terms: false” to “accept_terms: true”
  • Save!
  • Back over on the DuckDNS info tab, click Start to run the add-on.
  • This will link your Home Assistant server with your DuckDNS hostname and also provide you with a Let’s Encrypt SSL certificate automatically.

Router Configuration

This is the trickiest part to talk you through because it involves logging into your router’s web interface and configuring a port forwarding rule to allow traffic on the Internet to access your Home Assistant server. Hopefully you can figure out how to log in to your specific router (every type of router is different 🙁 ) and locate the ‘port forwarding’ section. This may be under the WAN or Firewall sections in most routers.

Once you’ve found that, you need to forward TCP port 8126 to the internal IP address of your Home Assistant server (this usually looks like 192.168.something.something) – hopefully you already know this because you’re already on your Home Assistant server’s web interface!

NGINX Proxy

  • In Home Assistant, install the add-on “NGINX Home Assistant SSL proxy”
  • Open the add-on’s Configuration page
  • Under the ‘options’ section
    • Enter your domain in the ‘domain’ field (i.e. something.duckdns.org)
    • Under Customise, set the ‘active’ option to ‘true’ instead of ‘false’
    • Click on the ‘save’ button for this section before moving on or you’ll lose what you’ve just done!
  • Under the ‘network’ section change the port to 8126 and click on this section’s ‘save’ button.
  • Select the add-on’s Info tab and click on ‘Start’ to run the add-on.

Home Assistant Configuration

  • Open your profile page (bottom-left… click on your username)
  • Scroll down the options and enable ‘Advanced Mode’
  • Navigate the menus Settings > System > Network.
  • Under the ‘Home Assistant URL’ section, edit the ‘Internet’ field and paste in your new external URL, for example ‘https://something_you_made_up.duckdns.org:8126’.
  • Click on Save

Configuration.yaml

Edit your configuration.yaml file (you can use the File Editor add-on to do this if you’re not sure how) and paste in the following lines:

http:
  use_x_forwarded_for: true
  trusted_proxies:
    - 172.30.33.0/24

Save the file, open the ‘Developer’ page, check the YAML configuration (just in case you’ve made a typo!) and restart Home Assistant to apply the changes.

ESPHome: extra steps required

If you’re running ESPHome (and some other add-ons with embedded web servers) then you’ll need to upload another configuration file of NGINX in order to get it working properly. The ESPHome symptoms are that the live logging / installing consoles refuse to connect when accessing Home Assistant via the external URL. If you have issues with add-ons working when connected locally but not working when using the external URL, then apply this fix!

Create a new text file named ‘nginx_proxy_default_fix_ingress.conf’ and paste into it the following configuration:

location /api {
    proxy_connect_timeout 60;
    proxy_read_timeout 60;
    proxy_send_timeout 60;
    proxy_intercept_errors off;
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection $connection_upgrade;
    proxy_set_header Host $host:8126;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto $scheme;
    proxy_pass http://homeassistant.local.hass.io:8123/api;
}

Upload this file to the /share folder in Home Assistant, which is in the root. You can use the File Editor add-on to easily do this just so long as you disable the add-on’s enforce_basepath option. Disabling that option allows you to browse outside of the /config folder and view the entire server’s filesystem.

Once the file has been uploaded to the correct location, restart NGINX and you’re ready to test it out!

Just open your web browser and attempt to access your new registered domain (i.e. https://something_you_made_up.duckdns.org:8126). Don’t forget the ‘s’ in https and the port on the end of the URL.

  • As an Amazon Associate I earn from qualifying purchases.