August 22, 2026
Cloudflare Tunnel for Ingress
Exposing homelab services behind CG-NAT without port forwarding using the Cloudflare Dashboard connector.
When running a homelab at home, one of the biggest challenges is being behind CG-NAT (Carrier-Grade NAT). This makes port forwarding impossible because you don’t own a public IPv4 address directly. For personal remote access between internal devices, Tailscale is already a great solution. However, when you want to share a website or service with the public or friends, a different tool is needed. That is where Cloudflare Tunnel comes in.
Why Cloudflare Tunnel
Cloudflare Tunnel establishes outbound connections from your host to Cloudflare’s edge network. Public requests hit Cloudflare’s edge and get proxied over that outbound connection to your internal service.
Benefits of this outbound approach:
- No router port forwarding needed.
- No public IP address exposed.
- Services stay safely accessible to the public.
Architecture
[ Internet Client ] ---> [ Cloudflare Edge (DNS & Access) ]
|
( Outbound Tunnel Connection )
v
[ Homelab Host (cloudflared) ] ---> [ Internal Service ]
Private mesh paths (Tailscale) and public ingress paths (Cloudflare Tunnel) operate independently based on their intended roles.
Configuration: CLI vs Cloudflare Dashboard
Initially, tunnels were set up manually via terminal with a local config.yml file. However, this process becomes cumbersome because every new domain or service route requires SSH access and manual configuration edits on the server.
A much simpler approach is managing the tunnel directly via the Cloudflare Dashboard:
- Log in to the Cloudflare Dashboard and select your domain.
- Navigate to Networks -> Connectors -> Cloudflare Tunnels.
- Create a new tunnel and run the
cloudflaredbinary on your host using the provided token. - Add Public Hostname mappings to internal origin services (e.g.,
http://localhost:8080) right inside the web UI.
Important: CLI configuration (
config.yml) and Cloudflare Dashboard management are mutually exclusive. Settings created in the Dashboard will not show up in a localconfig.yml, and vice versa. It is strongly recommended to pick one as your single source of truth to avoid confusion over where a route is configured.
Installing the cloudflared Binary
To run the connector, the cloudflared binary still needs to be installed on your host machine:
Verify the binary installation:
cloudflared --version
Install and run the service using the token from the Cloudflare Dashboard:
cloudflared service install <DASHBOARD_TOKEN>
Security
- Runtime tokens and credentials are sensitive secrets. Never commit them to public repositories.
- Cloudflare Tunnel acts as the entry path, not application authentication. Ensure origin applications keep their own authentication active or guard them with Cloudflare Access.
Disaster Recovery
Disaster recovery is straightforward when using Dashboard-managed tunnels:
- Store your connector token and hostname mapping notes in an encrypted vault.
- If the host or VM dies, install
cloudflaredon a fresh host and run the service using the same token. All routes configured in the Dashboard will automatically connect back without rebuilding rules from scratch.
Troubleshooting
| Symptom | Common Cause | Solution |
|---|---|---|
| 502 Bad Gateway on public domain | Internal service is down or target port is wrong | Check internal service health and verify origin URL in Dashboard |
| Tunnel status Disconnected | Host lost internet connection or cloudflared daemon stopped |
Check internet connectivity and systemctl status cloudflared |
| Frequent reconnects | Outbound network instability or packet throttling | Inspect connector logs using journalctl -u cloudflared -f |
Conclusion
Cloudflare Tunnel provides a clean way to expose homelab services to the public behind CG-NAT without messing with router port forwarding. Using the Cloudflare Dashboard as a centralized configuration hub makes managing hostnames far simpler and easier to maintain long term.
