haroonbarlas.com

cd ../writing

Self-hosting with no open ports: Cloudflare Tunnel plus Zero Trust

2026-11-01 · 5 min read · by Haroon Barlas

The classic way to reach a home server from outside is port forwarding: open a port on the router and point it at the server. It works, but it also means anyone on the internet can knock on that port, and scanners do, constantly. I publish my home-lab services a different way.

Outbound-only with Cloudflare Tunnel

A small connector, cloudflared, runs next to the service and makes an outbound encrypted connection to Cloudflare. Visitors reach the service through Cloudflare, and the connection back to my network rides that existing tunnel. The router has no inbound ports open, so there’s nothing for a port scan to find.

Identity in front of everything

A tunnel alone just moves the front door. The second layer is Cloudflare Access, which makes visitors prove who they are before a single request reaches my server. Behind it I use Authentik for single sign-on with passkeys, so there are no shared passwords to phish.

Don’t trust the proxy blindly

Zero Trust means not assuming that anything which reached the origin must be legitimate. Cloudflare Access adds a signed token (a JWT) to each request it allows. My origin checks that token itself: the signature, the issuer, the audience, the user’s email and the hostname. If someone found a way around Access, the origin would still refuse them.

What I watch

  • Sign-in events go to my Wazuh SIEM, where custom rules flag failed-login bursts, new passkeys and policy changes.
  • Each published service runs with the least privilege it needs.
  • Releases are hash-verified with a rollback path.

Takeaway: no inbound ports, identity before access, and an origin that verifies every request itself. Each layer assumes the one in front of it might fail.

cd ../writing · ls ~/work