TL;DR: Cloudflare Tunnels let you expose internal services to the internet without port forwarding or exposing your home IP address. Setup takes 10 minutes, works through NAT, and gives you free DDoS protection. Perfect for home lab dashboards, development servers, and self-hosted apps.
Home labs are great until you need to access them remotely. The traditional approach is port forwarding: punch holes in your firewall, expose your public IP, and hope your router’s security holds up. This works, but it’s ugly. Your IP address gets scanned constantly. You’re responsible for TLS certificate management. And if you mess up the firewall rules, you’ve exposed more than you meant to.
Cloudflare Tunnels solve this by reversing the connection model. Instead of opening inbound ports, you run a lightweight daemon (cloudflared) on your network that establishes an outbound connection to Cloudflare’s edge. When someone hits your domain, Cloudflare routes the traffic through that tunnel to your internal service. No open ports. No exposed IP. No port forwarding.
Here’s how I set it up for my home lab dashboard (running on a Raspberry Pi with a bunch of Docker containers).
Step 1: Install cloudflared
On your server (Linux example):
curl -L https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-linux-amd64 -o cloudflared
sudo mv cloudflared /usr/local/bin/
sudo chmod +x /usr/local/bin/cloudflared
Step 2: Authenticate with Cloudflare
cloudflared tunnel login
This opens a browser for OAuth. Once authenticated, it saves a cert to ~/.cloudflared/cert.pem.
Step 3: Create a tunnel
cloudflared tunnel create homelab
This generates a tunnel ID and credentials file. Save both.
Step 4: Configure the tunnel
Create ~/.cloudflared/config.yml:
tunnel: <your-tunnel-id>
credentials-file: /home/user/.cloudflared/<tunnel-id>.json
ingress:
- hostname: lab.yourdomain.com
service: http://localhost:3000
- service: http_status:404
This routes traffic from lab.yourdomain.com to a local service on port 3000 (e.g., a dashboard).
Step 5: Create a DNS record
cloudflared tunnel route dns homelab lab.yourdomain.com
This creates a CNAME in Cloudflare DNS pointing to your tunnel.
Step 6: Run the tunnel
cloudflared tunnel run homelab
Or install as a system service so it runs on boot:
sudo cloudflared service install
sudo systemctl start cloudflared
Now https://lab.yourdomain.com routes to your internal service. TLS is handled by Cloudflare. DDoS protection is automatic. Your home IP stays hidden.
Security considerations:
-
Authentication: The tunnel itself doesn’t authenticate users. Anyone who knows the URL can access your service. Add Cloudflare Access (free for up to 50 users) to require login before reaching your app. This gives you SSO with Google, GitHub, or email OTP.
-
Internal exposure: If your internal service has vulnerabilities, you’ve now made them internet-accessible. Run your services in isolated Docker containers and apply least privilege. Don’t expose admin interfaces this way.
-
Credential management: The tunnel credentials file (
<tunnel-id>.json) is sensitive. If someone gets it, they can route traffic to your tunnel. Store it securely and rotate it periodically. -
Logging: Cloudflare logs all requests through the tunnel. Enable Cloudflare Gateway logs if you want to audit access.
Cloudflare Tunnels are a better default than port forwarding for home lab access. Setup is trivial, security posture is stronger, and you get Cloudflare’s edge network for free. If you’re still port-forwarding SSH or HTTPS to your home network, stop. Use tunnels.
Sources
- Cloudflare Tunnel Documentation - Official setup guide and architecture details
- Cloudflare Access - Zero Trust authentication for tunneled services
- Cloudflare Gateway Logs - Request logging and audit trail configuration