Remote access for Home Assistant

Sometimes you want remote access to Home Assistant. Maybe it’s just so you can have a mobile app update your location, or so you can use some integration that requires it, or you want full access to the user interface.

Whatever the reason you’ve got two main choices:

  1. Use the (paid) Nabu Casa cloud service. This doesn’t require any port forwarding, and will work even if your ISP is using CGNAT or allocating out of the private IPv4 space. The use of these is normal if you’re using mobile internet services.
  2. Configure your chosen DNS service, SSL provider, and port forwarding. This can be free (depending on your choices of DNS and SSL providers), and if done correctly is largely a “set and forget”. This is what we’ll cover here.

Before you begin

Log on to your router’s admin pages and check the WAN IP. You don’t want to see a value that begins with:

  • 100.64.x.y through to 100.127.x.y (CGNAT)
  • 10.x.y.z (private IP space)
  • 172.16.x.y through to 172.31.x.y (private IP space)
  • 192.168.x.y (private IP space)

If you see any of these then you need to check to see if you have another router or modem and if so check the WAN IP there. If that has a “good” IP address then you’re ok, but you’ll need to forward any required ports from that to your router.

If you have mobile internet (LTE/5G/etc) then it’s almost certain that you’ll have one of the IP ranges above allocated by your ISP.

If you don’t have another router or modem, and you don’t have mobile Internet, then you’ll need to contact your ISP and see what the options are, if any.


SSL

You have a range of choices here from the free LetsEncrypt to paid certificates. Unless you already have paid certificates I’d suggest there’s little reason to use those.

Commercial provider

Download the certificates and manually copy them to your HA system.

LetsEncrypt

Using LetsEncrypt will either require that you forward port 80 to the host running the LetsEncrypt software (HTTP-01) or that you’re using a DNS provider that supports the DNS-01 method.

Home Assistant OS or Supervised

The DuckDNS add-on (see below about DNS) can handle this for you, as can the LetsEncrypt add-on if you’re using another DNS provider.

Configure these according to their own instructions.

Home Assistant Container

You have many choices here, but one option is the linuxserver/letsencrypt Docker image. As well as allowing you to get and update SSL certificates, it also includes a reverse proxy (see below) that you can use.

Home Assistant Core

You can use certbot or dehydrated, and other tools. Dehydrated has the advantage that it supports the DNS-01 verification method, which certbot doesn’t.

All SSL types

If you’re not using a reverse proxy (see below) you now need to configure http to have these certificates loaded. The following examples assumes that you’re using LetsEncrypt in some way. Update them to match the folders and file names you’re using.

Home Assistant OS or Supervised:

http:
 ssl_certificate: /ssl/fullchain.pem
 ssl_key: /ssl/privkey.pem

Home Assistant Container:

You’ll need to mount the location with your SSL keys and certificates to /ssl/ in the container.

http:
 ssl_certificate: /ssl/fullchain.pem
 ssl_key: /ssl/privkey.pem

Home Assistant Core:

http:
 ssl_certificate: /etc/letsencrypt/live/hass.example.com/fullchain.pem
 ssl_key: /etc/letsencrypt/live/hass.example.com/privkey.pem

After you check your configuration from the command line and then restart Home Assistant you’ll need to use https:// to access your system, even from your local network.

Now is a good time to check that you can access it using https:// - knowing it works will help you later if you run into issues.


DNS

If you don’t have a static (fixed) IP from your ISP you’ll need some form of Dynamic DNS provider. DuckDNS is a popular choice, but there are many out there. If you have your own domain many providers support dynamic DNS updates.

If you do have a static IP then any DNS provider will do.

One thing to consider is whether your DNS provider can be used with the LetsEncrypt DNS-01 verification method. If it does then you don’t need to set up port forwarding for LetsEncrypt.

Home Assistant OS and Supervised

There’s a DuckDNS add-on that can update your DNS records, and handle LetsEncrypt certificates.

Home Assistant Container

The linuxserver/duckdns Docker image will update your DuckDNS records for you. There’s also the DuckDNS integration.

If you’re using another DNS provider look at inadyn or whatever your DNS provider recommends.

Home Assistant Core

You can either use the DuckDNS integration or whatever software your DNS provider recommends. There are many choices here, including inadyn and DNS-O-Matic


Reverse Proxy (optional)

There are many reasons you may want to use a reverse proxy. Common reasons are that you don’t want to use SSL inside your network, or that you want to limit remote access to only webhooks. If you want more than remote access to the API and webhooks you’ll need to ensure the proxy is configured with websocket support.

Home Assistant OS and Supervised

There’s an NGINX add-on.

Home Assistant Container

The linuxserver/letsencrypt Docker image includes NGINX so nothing more is required if you’re using it. Otherwise you can use the official NGINX image.

Home Assistant Core

Install NGINX, or your other choice of reverse proxy, on your operating system and configure appropriately.


Port forwarding

Congratulations on getting this far without throwing your computer out of the window!

The next step is to forward a port. Port 443 is the default for HTTPS and if you use this then you’ll be able to use a URL without a port number. Of course, every scanner on the Internet will find your system, so you should consider enabling MFA on all the (user and administrator) accounts in HA.

If you’ve never done port forwarding before there’s a site that covers most popular routers. Follow the guide for your router there, and forward your chosen port to either your proxy (if you’re using one) or Home Assistant.

No proxy

  • Forward your chosen port (default 443) to port 8123 on your Home Assistant IP
  • If you’re using LetsEncrypt and the default (HTTP-01) verification method, forward port 80 too

Proxy

  • Forward your chosen port (default 443) to port 443 on your proxy server
  • If you’re using LetsEncrypt and the default (HTTP-01) verification method, forward port 80 too

Testing

You can check the port is forwarded with an open port checker and an SSL tester to confirm that everything is working.

Common problems include:

  • Your ISP blocking inbound port 443
  • Routers not wanting to forward the port used for their admin interface
  • Routers not supporting NAT loopback - so the hostname only works from outside your network
  • Using multiple routers and not forwarding through them all correctly

Final configuration

Now we need to set external_url and internal_url to match what will work. If you’re not using a proxy these will be the same thing. If you’ve forwarded port 443 then they’ll look like:

https://yourhost.example.org

If you forwarded another port - here for example we’re using the port 12345, they’ll look like:

https://yourhost.example.org:12345

If you’re using a proxy server then your internal URL for Home Assistant on 192.168.0.42 will look like:

http://192.168.0.42:8123
11 Likes

I’ve never forwarded port 80 and my DuckDNS/lets encrypt certs have always renewed. Is this really required for the DuckDNS addon?

Duckdns supports DNS-01, so no port forwarding required.

1 Like

Ah. I missed this:

If you use CloudFlare, even the free version, they provide a free SSL. You can both have SSL provided end to end without having to do anything but turn it on, or you can download the 15 year wildcard cert to do with what you please.

How reliable is CloudFlare?

Euh, Akamai and Cloudflare are the biggest CDN providers on the internet. So pretty reliable.

Is there a guide to set-up the remote access which does not involve Port Forwarding? Either the via OpenVPN or SSH tunneling?

Not as such. Using a VPN you’re effectively “at home”, so there’s nothing special beyond install and configure your VPN.

Of course, you have to port forward to the VPN server :wink:

But I can set-up a “private” VPN server on a RPi right?

Sure, VPN servers are, unless you decide otherwise, private by nature. You generally have to work quite hard to make one that’s “public”.

Wireguard is a good choice, and the PiVPN project has an installer that will allow you to configure, and run, either Wireguard or OpenVPN.

My advise… start looking into zerotier and create a free account. Link you HA instance to your own virtual zerotier network, give it a similar fixed virtual IP address (local IP eg 192.168.1.88, zerotier IP 192.168.192.88) and link all your devices also to zerotier via a client.

At home I connect via 192.168.1.88:8123
On the road, I turn on zerotier on my device and use 192.168.192.88:8123

This works more than perfect… No router/firewall issues (unless the zerotier port is blocked by a router in your building).

3 Likes

I currently have a personal domain name that I use with DYNU dns. I have a Nextcloud server that is running with a LetsEncrypt ssl certifcate. Is it possible to use the same certificate for my Home Assistant server? and if so, how would I go about it.

Thank you,
Robert

A post was split to a new topic: Remote access for HA

6 posts were split to a new topic: Problems with remote access

How do I limit access to webhooks only? I can’t figure it out …

Depends on your proxy server, but limit access to /api/webhook.

If you use NGINX then I cover it here:

	location /api/websocket {
		allow all;
		include conf.d/proxy.conf;
		proxy_pass http://127.0.0.1:8123;
		proxy_set_header Host $host;
		proxy_http_version 1.1;
		proxy_set_header X-Forwarded-For $remote_addr;
		proxy_set_header Upgrade $http_upgrade;
		proxy_set_header Connection "upgrade";
		proxy_ignore_client_abort on;
	}

Traefik is easier:

http:  
  routers:  
    homeassistant:  
      entryPoints:  
        - "websecure"  
      rule: "Host(`homeassistant.example.org`) && PathPrefix(`/api/webhook`)"