TL;DR: Cloudflare offers two free VPN solutions: WARP (consumer privacy VPN using WireGuard) and Cloudflare Tunnel + Zero Trust (self-hosted VPN replacement for accessing your home network). This guide covers both approaches step-by-step, with Docker Compose configs, split-tunnel setup, and security hardening. Zero Trust is free for up to 50 users — enough for any homelab or small team.
Why Build Your Own VPN in 2026?
Commercial VPN providers make bold promises about privacy, but their centralized architecture creates a fundamental trust problem. You’re routing all your traffic through servers you don’t control, operated by companies whose revenue model depends on subscriber volume — not security audits. ExpressVPN, NordVPN, and Surfshark have all faced scrutiny over logging practices, jurisdiction shopping, and opaque ownership structures.
Cloudflare offers a different model. Instead of renting someone else’s VPN, you build your own using Cloudflare’s global Anycast network (330+ data centers in 120+ countries) as the transport layer. The result is a VPN that’s faster than most commercial alternatives, costs nothing, and gives you full control over access policies.
There are two distinct approaches, and you might want both:
- Cloudflare WARP — A consumer VPN app that encrypts your device traffic using WireGuard. Install, toggle on, done. Best for: browsing privacy on public Wi-Fi.
- Cloudflare Tunnel + Zero Trust — A self-hosted VPN replacement that lets you access your home network (NAS, Proxmox, Pi-hole, Docker services) from anywhere without opening a single firewall port. Best for: homelabbers, remote workers, small teams.
Part 1: Cloudflare WARP — The 5-Minute Privacy VPN
What WARP Actually Does
WARP is built on the WireGuard protocol — the same modern, lightweight VPN protocol that replaced IPSec and OpenVPN in most serious deployments. When you enable WARP, your device establishes an encrypted tunnel to the nearest Cloudflare data center. From there, your traffic exits onto the internet through Cloudflare’s network.
Key technical details:
- Protocol: WireGuard (via Cloudflare’s BoringTun implementation in Rust)
- DNS: Queries routed through 1.1.1.1 (Cloudflare’s privacy-first DNS resolver, audited by KPMG)
- Encryption: ChaCha20-Poly1305 for data, Curve25519 for key exchange
- Latency impact: Typically 1-5ms added (vs. 20-50ms for most commercial VPNs) because traffic routes to the nearest Anycast PoP
- No IP selection: WARP doesn’t let you choose exit countries — it’s a privacy tool, not a geo-unblocking tool
Installation
WARP runs on every major platform through the 1.1.1.1 app:
| Platform | Install Method |
|---|---|
| Windows | one.one.one.one → Download |
| macOS | one.one.one.one → Download |
| iOS | App Store → search “1.1.1.1” |
| Android | Play Store → search “1.1.1.1” |
| Linux | curl -fsSL https://pkg.cloudflare.com/cloudflare-main.gpg | sudo tee /usr/share/keyrings/cloudflare-archive-keyring.gpg && echo "deb [signed-by=/usr/share/keyrings/cloudflare-archive-keyring.gpg] https://pkg.cloudflare.com/cloudflared $(lsb_release -cs) main" | sudo tee /etc/apt/sources.list.d/cloudflared.list && sudo apt update && sudo apt install cloudflare-warp |
After installing, launch the app and toggle WARP on. That’s it. Your DNS queries now go through 1.1.1.1 and your traffic is encrypted to Cloudflare’s edge.
WARP vs. WARP+ vs. Zero Trust
| Feature | WARP (Free) | WARP+ ($) | Zero Trust WARP |
|---|---|---|---|
| Price | $0 | ~$5/month | Free (50 users) |
| Encryption | WireGuard | WireGuard | WireGuard |
| Speed optimization | Standard routing | Argo Smart Routing | Standard routing |
| Private network access | No | No | Yes |
| Access policies | No | No | Full ZTNA |
| DNS filtering | No | No | Gateway policies |
For most people, free WARP is sufficient for everyday privacy. If you need remote access to your homelab, keep reading — Part 2 is where it gets interesting.
Part 2: Cloudflare Tunnel + Zero Trust — The Self-Hosted VPN Replacement
This is the setup that replaces WireGuard, OpenVPN, or Tailscale for accessing your home network. The architecture is elegant: a lightweight daemon called cloudflared runs inside your network and maintains an outbound-only encrypted tunnel to Cloudflare. Remote clients connect through Cloudflare’s network using the WARP client. No inbound ports. No dynamic DNS. No exposed IP address.
Architecture Overview
┌─────────────────┐ ┌──────────────────────┐ ┌─────────────────┐ │ Remote Device │ │ Cloudflare Edge │ │ Home Network │ │ (WARP Client) │◄───────►│ 330+ PoPs globally │◄───────►│ (cloudflared) │ │ │ WireGuard│ │ Outbound │ │ │ Phone/Laptop │ Tunnel │ Zero Trust Policies │ Tunnel │ NAS/Docker/LAN │ └─────────────────┘ └──────────────────────┘ └─────────────────┘Prerequisites
- A Cloudflare account (free tier works)
- A domain name with DNS managed by Cloudflare (required for tunnel management)
- A server on your home network — any Linux box, Raspberry Pi, Synology NAS, or even a Docker container on TrueNAS
- Docker + Docker Compose (recommended) or bare-metal
cloudflaredinstallation
Step 1: Create a Tunnel in the Zero Trust Dashboard
- Go to one.dash.cloudflare.com → Networks → Tunnels
- Click Create a tunnel
- Select Cloudflared as the connector type
- Name your tunnel (e.g.,
homelab-tunnel) - Copy the tunnel token — you’ll need this for the Docker config
Step 2: Deploy cloudflared with Docker Compose
Create a docker-compose.yml on your home server:
version: "3.8" services: cloudflared: image: cloudflare/cloudflared:latest container_name: cloudflared-tunnel restart: unless-stopped command: tunnel --no-autoupdate run --token ${TUNNEL_TOKEN} environment: - TUNNEL_TOKEN=${TUNNEL_TOKEN} network_mode: host # Required for private network routing # Example: expose a local service whoami: image: traefik/whoami container_name: whoami ports: - "8080:80"Create a
.envfile alongside it:TUNNEL_TOKEN=eyJhIjoiYWJj...your-token-hereStart the tunnel:
docker compose up -d docker logs cloudflared-tunnel # Should show "Connection registered"Critical note: Use
network_mode: hostif you want to route traffic to your entire LAN subnet (192.168.x.0/24). Without it, cloudflared can only reach services within the Docker network.Step 3: Expose Services via Public Hostnames
Back in the Zero Trust dashboard, under your tunnel’s Public Hostnames tab:
- Click Add a public hostname
- Set subdomain:
nas, domain:yourdomain.com- Service type:
HTTP, URL:localhost:5000(or wherever your service runs)- Save
Cloudflare automatically creates a DNS record. Your NAS is now accessible at
https://nas.yourdomain.com— with automatic SSL, DDoS protection, and Cloudflare WAF.Step 4: Enable Private Network Routing (Full VPN Mode)
This is what turns a simple tunnel into a full VPN replacement. Instead of exposing individual services, you route an entire IP subnet through the tunnel.
- In Zero Trust dashboard → Networks → Tunnels → your tunnel → Private Networks
- Add your LAN CIDR:
192.168.1.0/24(adjust to your subnet)- Go to Settings → WARP Client → Split Tunnels
- Switch to Include mode and add
192.168.1.0/24Now, any device running the WARP client (enrolled in your Zero Trust org) can access
192.168.1.xaddresses as if they were on your home network. SSH into your server, access your NAS web UI, reach your Pi-hole dashboard — all without port forwarding.Step 5: Enroll Client Devices
- Install the 1.1.1.1 / WARP app on your phone or laptop
- Go to Settings → Account → Login to Cloudflare Zero Trust
- Enter your team name (set during Zero Trust setup)
- Authenticate with the method you configured (email OTP, Google SSO, GitHub, etc.)
- Enable Gateway with WARP mode
Test it: connect to mobile data (not your home Wi-Fi) and try accessing a LAN IP like
http://192.168.1.1. If the router admin page loads, your VPN is working.Step 6: Lock It Down — Zero Trust Access Policies
The “Zero Trust” part of this setup is what separates it from a traditional VPN. Instead of “anyone with the VPN key gets full network access,” you define granular policies:
Zero Trust Dashboard → Access → Applications → Add an Application Application type: Self-hosted Application domain: nas.yourdomain.com Policy: Allow Include: Emails ending in @yourdomain.com Require: Country equals United States (optional geo-fence) Session duration: 24 hoursYou can create different policies per service. Your Proxmox admin panel might require hardware key (FIDO2) authentication, while your Jellyfin media server only needs email OTP. This is Zero Trust Network Access (ZTNA) — the same architecture that Google BeyondCorp and Microsoft Entra use internally.
Cloudflare Tunnel vs. Alternatives: Honest Comparison
Feature Cloudflare Tunnel WireGuard Tailscale OpenVPN Price Free (50 users) Free Free (100 devices) Free Open ports required None 1 UDP port None 1 UDP/TCP port Setup complexity Medium Medium-High Low High Works behind CG-NAT Yes Needs port forward Yes Needs port forward Access control Full ZTNA policies Key-based only ACLs + SSO Cert-based DDoS protection Yes (Cloudflare) No No No SSL/TLS termination Automatic N/A N/A Manual Trust model Trust Cloudflare Self-hosted Trust Tailscale Self-hosted Best for Web services + LAN Pure privacy Mesh networking Enterprise legacy The honest tradeoff: Cloudflare Tunnel routes your traffic through Cloudflare’s infrastructure. If you fundamentally distrust any third party touching your packets, self-hosted WireGuard is the purist choice. But for most homelabbers, the convenience of zero open ports + free DDoS protection + granular access policies makes Cloudflare Tunnel the pragmatic winner.
Advanced: Multi-Service Docker Stack
Here’s a production-grade Docker Compose that exposes multiple services through a single tunnel:
version: "3.8" services: cloudflared: image: cloudflare/cloudflared:latest container_name: cloudflared restart: unless-stopped command: tunnel --no-autoupdate run --token ${TUNNEL_TOKEN} environment: - TUNNEL_TOKEN=${TUNNEL_TOKEN} networks: - tunnel depends_on: - nginx nginx: image: nginx:alpine container_name: nginx-proxy volumes: - ./nginx.conf:/etc/nginx/nginx.conf:ro networks: - tunnel # Add your services here — they just need to be on the 'tunnel' network # Configure public hostnames in the CF dashboard to point to nginx networks: tunnel: name: cf-tunnelMap each service to a subdomain in the Zero Trust dashboard:
grafana.yourdomain.com → http://nginx:3000,code.yourdomain.com → http://nginx:8443, etc.Troubleshooting Common Issues
Tunnel shows “Disconnected” in the dashboard
- Check Docker logs:
docker logs cloudflared-tunnel - Verify your token hasn’t been rotated
- Ensure outbound HTTPS (port 443) isn’t blocked by your router/ISP
- If behind a corporate firewall,
cloudflaredalso supports HTTP/2 over port 7844
Private network routing doesn’t work
- Confirm
network_mode: hostin Docker Compose (or use macvlan) - Check that the CIDR in “Private Networks” matches your actual subnet
- Verify Split Tunnels are set to Include mode (not Exclude)
- On the client, run
warp-cli settingsto verify the private routes are active
WARP client won’t enroll
- Double-check your team name in Zero Trust → Settings → Custom Pages
- Ensure you’ve created a Device enrollment policy under Settings → WARP Client → Device enrollment permissions
- Allow email domains or specific emails that can enroll
Security Hardening Checklist
- ☐ Enable Require Gateway in device enrollment — forces all enrolled devices through Cloudflare Gateway for DNS filtering
- ☐ Set session duration to 24h or less for sensitive services
- ☐ Require FIDO2/hardware keys for admin panels (Proxmox, router, etc.)
- ☐ Enable device posture checks: require screen lock, OS version, disk encryption
- ☐ Use Service Tokens (not user auth) for machine-to-machine tunnel access
- ☐ Monitor Access audit logs: Zero Trust → Logs → Access
- ☐ Never put your tunnel token in a public Git repository — use
.envfiles and.gitignore - ☐ Rotate tunnel tokens periodically via the dashboard
FAQ
Is Cloudflare Tunnel really free?
Yes. Cloudflare Zero Trust offers a free plan that includes tunnels, access policies, and WARP client enrollment for up to 50 users. There are no bandwidth limits on the free tier. Paid plans (starting at $7/user/month) add features like logpush, extended session management, and dedicated egress IPs.
Can Cloudflare see my traffic?
Cloudflare terminates TLS at their edge, so they technically could inspect unencrypted HTTP traffic passing through the tunnel. For HTTPS services, end-to-end encryption between your browser and origin server means Cloudflare sees metadata (domain, timing) but not content. If this is a concern, use WireGuard for a fully self-hosted solution where no third party touches your packets.
Does this work with Starlink / CG-NAT / mobile hotspots?
Yes — this is one of Cloudflare Tunnel’s biggest advantages. Since the tunnel is outbound-only, it works behind any NAT, including carrier-grade NAT (CG-NAT) used by Starlink, T-Mobile Home Internet, and most 4G/5G connections. No port forwarding needed.
Can I use this for site-to-site VPN?
Yes, using WARP Connector (currently in beta). Install cloudflared with WARP Connector mode on a device at each site, and Cloudflare routes traffic between subnets. This replaces traditional IPSec site-to-site tunnels.
Cloudflare Tunnel vs. Tailscale — which should I use?
Use Tailscale if your primary need is device-to-device mesh networking (see also our guide on home network segmentation with OPNsense) (accessing any device from any other device). Use Cloudflare Tunnel if you want to expose web services with automatic HTTPS and DDoS protection, or if you need granular ZTNA policies. Many homelabbers use both: Tailscale for device mesh, Cloudflare Tunnel for public-facing services.
References
- Cloudflare. “Connect private networks.” Cloudflare One Documentation, 2026.
- Cloudflare. “Cloudflare Tunnel setup guide.” Cloudflare Developers, 2026.
- Donenfeld, Jason A. “WireGuard: Next Generation Kernel Network Tunnel.” NDSS Symposium, 2017.
- Cloudflare. “Introducing WARP: Fixing Mobile Internet Performance and Security.” Cloudflare Blog, 2019.
- Ward, Brendan and Harris, Rustam. “BoringTun: a userspace WireGuard implementation in Rust.” Cloudflare Blog, 2019.
- Google. “BeyondCorp: A New Approach to Enterprise Security.” Google Cloud, 2014.
📧 Get weekly insights on security, trading, and tech. No spam, unsubscribe anytime.

Leave a Reply