HOWTO: Secure Cloudflare Tunnels remote access

I have remote access to my HomeAssistant with Clouflare tunnel. Is there a way to use authenticator app on iphone to open the tunnel (like LastPassAuthenticator)?
Reason I ask is that companion app on iPhone does not work (or at least I have not managed to get it to work) with 2FA using email or Google…

I think I missed something but I can’t find what.

I configured the CF Tunnel via docker-compose:

homeassistant:
  container_name: homeassistant
  image: "ghcr.io/home-assistant/home-assistant:stable"
  volumes:
    - ./homeassistant/config:/config
    - /etc/localtime:/etc/localtime:ro
    - /run/dbus:/run/dbus:ro
  restart: unless-stopped
  env_file:
    - shared.env
  devices:
    - /dev/ttyACM0:/dev/ttyACM0
  privileged: true
  network_mode: host

tunnel:
  container_name: cloudflared-tunnel
  image: cloudflare/cloudflared
  restart: unless-stopped
  env_file:
    - shared.env
  command: tunnel run
  environment:
    - TUNNEL_TOKEN=${TUNNEL_TOKEN}
  network_mode: host

It is running and I see it connected well:

Logs:

cloudflared-tunnel | 2024-04-09T17:06:18Z INF Updated to new configuration config="{\"ingress\":[{\"hostname\":\"<masked-hostname>\",\"originRequest\":{},\"service\":\"http://localhost:8123\"},{\"service\":\"http_status:404\"}],\"warp-routing\":{\"enabled\":false}}" version=11

When I’m connecting to that hostname, I need to verify my email.

But after verifying I get Bad Gateway 502 from Cloudflare.

The log in the tunnel client is:

cloudflared-tunnel | 2024-04-09T17:24:44Z ERR  error="Unable to reach the origin service. The service may be down or it may not be responding to traffic from cloudflared: dial tcp 127.0.0.1:8123: connect: connection refused" connIndex=1 event=1 ingressRule=0 originService=http://localhost:8123
cloudflared-tunnel | 2024-04-09T17:24:44Z ERR Request failed error="Unable to reach the origin service. The service may be down or it may not be responding to traffic from cloudflared: dial tcp 127.0.0.1:8123: connect: connection refused" connIndex=1 dest=https://<masked-hostname>/ event=0 ip=198.41.200.23 type=http
cloudflared-tunnel | 2024-04-09T17:24:44Z ERR  error="Unable to reach the origin service. The service may be down or it may not be responding to traffic from cloudflared: dial tcp 127.0.0.1:8123: connect: connection refused" connIndex=1 event=1 ingressRule=0 originService=http://localhost:8123
cloudflared-tunnel | 2024-04-09T17:24:44Z ERR Request failed error="Unable to reach the origin service. The service may be down or it may not be responding to traffic from cloudflared: dial tcp 127.0.0.1:8123: connect: connection refused" connIndex=1 dest=https://<masked-hostname>/favicon.ico event=0 ip=198.41.200.23 type=http

My HomeAssistant is accessible at the same time from the internal IP, and from inside the docker-compose machine I can curl localhost:8123 and get the right HTML.

The configuration.yml includes the next part:

http:
  use_x_forwarded_for: true
  trusted_proxies:
    - 172.30.33.0/24

And of course, I restarted the docker-compose many times.

(Do you need any more info?)

Update:
Ok, first I found that even with the installed tunnel connector, I need to configure in the Tunnel settings the local IP address (192.168.1.23) instead of the localhost.
Second, I need to check which addresses are accessing to the HA and allow them in the proxy config.

1 Like

I get a “Cannot reach [test] myapp” error if I put the access rules in place when linking. If I remove the access rules, I am able to link Google Assistant. are the access rules supposed to be activated after the first link has been established?

I couldn’t connect with cast dashboard. You may need to include websocket in the rule: /api/websocket
This works for me:

(http.host eq “my.homeassistant.com” and not cf.tls_client_auth.cert_verified and http.request.uri.path eq “/api/websocket/”)

It’s probably an header issue.
God luck!

Hello

One short question how , If it is possible, set an aditiona host

additional_hosts:
  - hostname: router.example.com
    service: http://192.168.1.1

But my sevice i Want to point to a diferent homeassitant instantnce in a diferent location, so it’s not o the same network.
It is posibel to resolve it.

Hi All

Just thought I would post that I have had success with accessing the HA app without getting the Cloudfare ‘forbidden’ message while outside of the network, and also without breaking google home.

Unsure if this is the right way of going about it but adding another tunnel hostname in Cloudfare pointed at the same domain but adding a subdomain worked a treat.

To explain further:

  • Following the instructions above I managed to get google assistant working and local access to the HA instance. However attempting to externally access at https://xxxxxxxx.net through the HA app I could not get past the Cloudfare ‘Forbidden’ or the email authentication screen.
  • In Cloudfare under the existing tunnel created as documented, under Public Hostname, I added another hostname with subdomain, https://house.xxxxxxxx.net
  • Pointing the HA app external URL to this new hostname allows access without trouble, and, testing Google Home functionality everything is visible and online.

If this looks incorrect and I have rendered my instance unsafe in any way please let me know and I will go back to choosing which function to stop using, otherwise I hope this helps someone else.

The intent is to allow secure access over CF tunnels, but you’re exposing your HA to the internet directly via that new hostname. When HA has a remote compromise (and everything has one sooner or later) you’ll be wide open. I suggest adding authentication instead via github, google, etc.

Note this will not make the mobile app work; there’s a hacky workaround with certs on android but not aware of anything on iOS. I don’t care about this myself as I’m always VPN’d to my home LAN anyway.