HOWTO: Secure Cloudflare Tunnels remote access

Thank you for the step-by-step guide, it was really good.
I followed your steps.
I tested the lambda function as explained, and it worked (my Alexa devices were exposed during the test).

The issue seems to occur when I try to open the skill using the Alexa app. I receive a “forbidden” error from Zero Trust.

So, I temporarily removed Zero Trust and was able to activate the skill. Then, I reactivated Zero Trust, and everything kept working… until I needed to restart Home Assistant. After restarting, everything stops working.

Do you have any idea what the problem might be?

Hi @danirivas i just followed your very clear instructions but when i test it the curl returns my home assistant instance but when i try to link my alexa skill i get “Unable to link the skill at this time” after login into home assistant.

Also tried the payload in aws test and it worked, it looks like the policies is not working properly to accept Service auth

what am I doing wrong?

Do you have bot protection enabled?

Hi @rossiluis22,

As @LiQuid_cOOled mentions, do you have bot protection enabled? I remember having to disable every single protection measure other than the CF service token or requests wouldn’t go through. Not saying it’s not possible, but I never figured it out. AFAIK, as long as that token is kept secure (I only use it for the Alexa Skill passed as an env var), this is already secure enough for the purpose (happy to be proven wrong here).

@cru5h3r sorry for the late response but the same applies, maybe you could try disabling every security measure except for the token. For what you mention, you may have had a DNS record and the tunnel both pointing to the same hostname, and IIRC when this happens Cloudflare prioritizes the tunnel so disabling it just got your requests routed through the DNS entry, which isn’t blocking them.

Nonetheless, I was just reviewing my configuration because out of pure chance I tried to access the hostname I use in the tunnel from my browser (i.e., w/o sending the CF token) and it took me to my HA’s login page. I don’t know if I made a mistake in my previous guide or CF has changed something and I wasn’t aware.

Now, if I follow step 4 and go to Access -> Applications, select my HA app, click Configure -> Policies I see that the policy I created back when I wrote the guide has a big gray LEGACY next to the policy name. Maybe they deprecated it since then.

To secure the tunnel again with the CF service token, just go edit your tunnel, then go to Public hostnames, edit the one you use for HA, click on Additional application settings -> Access, enable Protect with Access and select the service token you created and the Alexa Skill is using.

AI Bot Protection can still be enabled.

I am curious, what SSL/TLS encryption mode do you run?

I use Full (strict)

morning all - just received notice from AWS that they’re retiring the version of Python I’m using in Lamda and I only use if for this I believe (been a long while since I set it up or changed anything!)
Any concerns with updating the Python version and making no other changes?

Great guide. I’ve been running this setup for a while and wanted to flag one gotcha that bites a lot of people following these exact steps, plus a drop-in fix.

After a few days/weeks (depending on your Access session policy), the CF_Authorization cookie expires. In the HA Companion app that’s visible, you get prompted to re-auth. In the browser it’s invisible: the UI shows “Unable to connect to Home Assistant” and no amount of refreshing fixes it, because HA’s Service Worker keeps serving the cached shell and never hits the network to trigger a Cloudflare redirect. You have to open HA in an incognito window, copy the signed Cloudflare Access login URL, paste it into the stuck regular window, and then it comes back.

I wrote a ~80-line JS module that detects this state and self-heals the tab: GitHub - mayerwin/HA-Cloudflare-Access-Recovery: Self-healing Cloudflare Access auth for Home Assistant - recovers the HA web frontend in any browser (desktop or mobile) when the CF_Authorization cookie expires. · GitHub

Install is one file in /config/www/ + three YAML lines. Might be worth a “known limitation + workaround” note in the guide itself.

I went to my Cloudflare page to show a friend how the tunnelling is configured and found the admin page has changed. I can’t manage the URLs like I could when I first set the tunnel up and Cloudflare is now saying I need to migrate the connection:

Migrate tunnelname

tunnelname cannot be managed from the Zero Trust dashboard as it is a locally configured tunnel.

However, you can choose to migrate its ingress rules to be managed from the dashboard without causing any downtime. Any other configurations on the configuration file will not be migrated, and any changes you make locally will not be reflected on the dashboard.

Keep in mind that tunnel migration is irreversible.

Am I safe to do this migration without breaking things?

1 Like