Cloudflare Tunnel Setup for Self-Hosted Apps
Exposing a home server to the internet is risky. Open ports get scanned constantly. Cloudflare Tunnel solves this by creating an outbound-only connection from your server to Cloudflare's edge network.
Why Tunnels Beat Port Forwarding
| Aspect | Port Forwarding | Cloudflare Tunnel |
|---|---|---|
| Attack surface | Open port on router | None — no inbound connections |
| SSL | DIY (Let's Encrypt) | Auto-managed |
| DDoS protection | None | Built-in |
| IP hiding | No | Yes (CF IPs only) |
| Auth layer | None | Can add Cloudflare Access |
Setup in 3 Steps
1. Install and authenticate
cloudflared tunnel login
This opens a browser to Cloudflare, authenticates your domain, and writes a cert.
2. Create a tunnel
cloudflared tunnel create my-tunnel
This registers a tunnel and creates a credentials JSON file.
3. Configure ingress
My current setup (single tunnel serving multiple services):
tunnel: c89caec5-08e6-4f6a-91b6-d8306b6748ad
credentials-file: /home/user/.cloudflared/tunnel.json
ingress:
- hostname: ntfy.kamalrajnaidu.com
service: http://localhost:7200
- hostname: hermes.kamalrajnaidu.com
service: http://localhost:8787
- hostname: gaming.kamalrajnaidu.com
service: http://localhost:8050
- service: http_status:404
The last entry is a catch-all — anything that doesn't match a hostname gets a 404.
4. Run as a service
sudo cloudflared service install
Or run as user service:
cloudflared tunnel run my-tunnel
Security Notes
- Services bind to
localhostonly — never0.0.0.0 - Use Cloudflare Access for admin interfaces
- The tunnel binary auto-updates
- Enable WAF rules in the Cloudflare dashboard