Remote Access for HA without firewall changes and static ip

Hi there,

I cannot get to my HA server from outside my local network when connecting through a VPN over https.

Background
I am working on changing the way I can access my home assistant installation. Originally, I had set up a reverse proxy (traefik) on my internal network for which I set up port forwarding (80 and 443) on my router’s firewall and linked to it through a DDNS provider. This setup was working without any issues and let me access HA internally as well as externally through the same https://ha.mydomain.com URL.

New approach
I decided that I wanted a more universal approach which was more secure and easier to set up no matter what network configuration I have in use. The idea I came up with was to use an inside-out connection by opening a secure tunnel from my home network to an external host through VPN. I would then terminate my domain at the external server and use a reverse proxy on that server to route my requests through to my local home server.

My new setup
In more detail, this is my new setup:

At home: one server (Intel NUC) with Docker running on an Ubuntu host. All services I want to access externally are containers running on that setup, HA being one of them. The server sits behind a router which also acts as firewall. All firewall ports are closed, no DynDNS setup is running. HA is running with network_mode: host so that the docker container is part of my home network (which is required anyways to access all my devices on my home network).

Externally, I got myself a virtual server (from Scaleway) with Ubuntu and Docker running on it.

To access my Home Assistant service on my home server, I connected the home server to the external server through VPN (tinc) and have a reverse proxy (Caddy) running on the external server which does two things: for one, it maintains the SSL certificates and it routes my public requests back to my home server. Both services, tinc and caddy are running in docker containers.

When I now want to access my home assistant UI remotely, the following routing happens:

https://ha.mydomain.com -> resolves to IP address of my external server -> reverse proxy forwards the request to 10.0.0.2:8123 (the VPN address of my local machine) -> 192.168.1.x:8123 (the actual IP of my HA docker instance)

Where I am stuck
This all is working fine for getting to the login screen of HA. However, after entering my credentials, I get redirected to https://ha.mydomain.com/lovelace and see an “Unable to connect to Home Assistant” screen rendered together with a HA logo. This means that I can actually get through to my HA server, but for some reason when loading the lovelace UI, something is not quite right.

If I call my HA instance up using the local IP http://192.168.1.x:8123 directly from inside my home network, everything is working as expected and I do not see the above error.

For testing, I was using a brand new docker container with the latest HA release 0.91.1, so there should not be anything special about my HA environment:

docker run --init -d --name="home-assistant" -v /etc/localtime:/etc/localtime:ro --net=host homeassistant/home-assistant

When checking the logs for HA, I only see entries like the following for my attempt to connect:

2019-04-07 11:49:37 INFO (MainThread) [homeassistant.components.http.view] Serving / to 10.0.0.1 (auth: False)
2019-04-07 11:49:37 INFO (MainThread) [homeassistant.components.http.view] Serving /auth/authorize to 10.0.0.1 (auth: False)
2019-04-07 11:49:38 INFO (MainThread) [homeassistant.components.http.view] Serving /auth/providers to 10.0.0.1 (auth: False)
2019-04-07 11:49:38 INFO (MainThread) [homeassistant.components.http.view] Serving /auth/login_flow to 10.0.0.1 (auth: False)
2019-04-07 11:50:12 INFO (MainThread) [homeassistant.components.http.view] Serving /auth/login_flow/6c646aa86f124836bbe19d5217a551b8 to 10.0.0.1 (auth: False)
2019-04-07 11:50:12 INFO (MainThread) [homeassistant.components.http.view] Serving / to 10.0.0.1 (auth: False)
2019-04-07 11:50:13 INFO (MainThread) [homeassistant.components.http.view] Serving /auth/token to 10.0.0.1 (auth: False)
2019-04-07 11:50:13 INFO (MainThread) [homeassistant.components.http.view] Serving /api/websocket to 10.0.0.1 (auth: False)

I am wondering whether auth: false is pointing to a problem.

Note that 10.0.0.1 is the address of the remote server connected through VPN to my home server (IP 10.0.0.2).

I went on to experiment setting different values for base_url in the HA configuration, but the result was always the same.

I can access other services running on my containers this way just fine (like https://plex.mydomain.com for Plex for example) from outside my home network so the issue is only related to the way I access HA.

For DNS services, I am using Cloudflare. Since their setup is quite sophisticated with caching etc., I am wondering whether this is causing an issue.

Alternatives
I know that I could simply use NABU CASA (which works in a similar way to my current approach), but since I want my setup to be more generic so that I can run other non-HA services as well, I am not considering this option.

Recently, Hass.io got a ZeroTier add-on which basically does the same as Tinc. However, I do not like the idea of having a central third party involved for my services to work since this creates dependencies and relies on trusting another company (even though the implementation of ZeroTier suggests that all communication is private and encrypted).

I need your help
Any idea what is going wrong with my setup or where to dig for answers?

Does your base_url begin with https?

I tried both ways without luck:

https://ha.mydomain.com and ha.mydomain.com:443.

The comment in the original configuration.yaml file is using this example: base_url: example.duckdns.org:8123 suggesting http implicitly.

I went on using my docker host ip (192.168.1.x:8123) and also the VPN IP (10.0.0.2:8123), but the result is always the same Cannot to connect to Home Assistant error.

Plex and NodeRed are working fine on my setup (accessing from inside my local network as well as from externally like this: https://nodered.mydomain.com).

I also enabled Development mode on Cloudflare (to disable caching) and switched my CNAME & A-Record entries to use only DNS and not HTTP Proxy. The results are still the same…

Btw, on the HA login screen, I can see the following message:

You’re about to give https://ha.mydomain.com/ access to your Home Assistant instance.

Logging in with Home Assistant Local.

Does this look correct to you?

This is the screen I keep getting after authenticating through https://ha.mydomain.com:

This is true for the iOS app (screenshot above) as well as for regular browsers on mobile and desktop computers.

Do you have:

auth_providers:
  - type: trusted_networks
    trusted_networks:
      - 10.0.0.0/24

(or whatever your subnet is)…?

If you can reach Plex and NodeRed externally I’m pretty sure your problem with HA is going to be isolated to either the http: or auth_providers: section of your configuration.yaml.

Could you post those two sections (redacted, of course)?

1 Like

Home Assistant uses the Websocket protocol for some things, for example checking that the server is available (which is why you get the “Connection lost. Reconnecting…” toast pop up when the server restarts). It may be that the reverse proxy is not forwarding the Websocket requests properly.
Have you enabled the forwarding of the Websocket headers in the reverse proxy?

Searching Google indicates that in Caddy this would involve either using the websocket preset or the following settings (which the prefix is shorthand for):

header_upstream Connection {>Connection}
header_upstream Upgrade {>Upgrade}
2 Likes

You guys are awesome! I got it working by setting the base_url to https://ha.mydomain.com and configuring Caddy to accept websockets (I was missing the websocket and transparent keywords):

ha.mydomain.com {
    proxy / 10.0.0.2:8123 {
        websocket
        transparent
    }
    tls {
        dns cloudflare
    }
}

While researching the issue, I learned that there is actually documentation for Caddy on the Home Assistant site at https://www.home-assistant.io/docs/ecosystem/caddy/.

1 Like

Great find.

I’m not familiar with Caddy but I noticed in the documentation you cited that trusted_proxies: needs to be configured to restrict access. You’ve probably already done that but I thought I’d point it out just in case.

Glad you got it working! :slight_smile:

Good catch @jparthum , thanks for pointing this out. The configuration I am using is as follows:

http:
  base_url: https://ha.mydomain.com
  use_x_forwarded_for: true
  trusted_proxies: 10.0.0.1
1 Like