I run a home server on an old HP laptop. It's behind CGNAT (common in Malaysia), so port forwarding isn't an option. Cloudflare Tunnel solves this — it creates an encrypted outbound connection from the server to Cloudflare's edge, and Cloudflare routes traffic to it.
How it works
User → cloudflared (at Cloudflare edge) → tunnel → cloudflared (on server) → localhost:port
The server never opens a port. It connects out to Cloudflare's network, and Cloudflare handles the rest.
My setup
# Install cloudflared
wrangler tunnel create my-tunnel
wrangler tunnel route dns my-tunnel games.kamalrajnaidu.com
# Run it
cloudflared tunnel run my-tunnel
The tunnel config maps hostnames to local services:
ingress:
- hostname: games.kamalrajnaidu.com
service: http://localhost:8050
- hostname: ntfy.kamalrajnaidu.com
service: http://localhost:7200
- service: http_status:404
Why not just use a VPS?
A VPS costs $5–10/month and you still have to secure it. A tunnel is free (Cloudflare's free tier includes 50 tunnels per account), and the attack surface is tiny — there's nothing to SSH into, no open ports to scan.
DNS management
All my subdomains point to Cloudflare's edge. Some go through the tunnel (services that need a backend), others go to Cloudflare Pages (static sites like this blog). The DNS management is all in one place:
| Subdomain | Type | Destination |
|---|---|---|
| games.kamalrajnaidu.com | Tunnel | localhost:8050 |
| blog.kamalrajnaidu.com | Pages | Static site |
| music.kamalrajnaidu.com | Pages | Static site |
| status.kamalrajnaidu.com | Pages | Static site |
Trade-offs
- Latency: Traffic routes through Cloudflare's edge. Adds ~10-20ms vs direct connection.
- Bandwidth: Free tier is unlimited but subject to Cloudflare's ToS (no video streaming).
- SSL: Automatic via Cloudflare's edge certs. No Let's Encrypt setup needed.
For a hobbyist setup, the trade-offs are negligible. The convenience of zero open ports is worth it.