Cloudflare VPN replacement
Separate the client, Tunnel, and Workers
Give the Cloudflare One Client, Cloudflare Tunnel, and Workers their correct roles instead of calling each one a VPN server.
8 minute lesson
Three Cloudflare products show up around this lab, and people casually call each of them “the VPN”. They do different jobs, and mixing them up leads to designs that cannot work.
The Cloudflare One Client, formerly WARP, runs on user devices. It creates the device-side path into Cloudflare: it registers the device with your organization, applies your enrollment rules, and forwards the device’s matching traffic to Cloudflare’s edge. It is the piece your users install.
Cloudflare Tunnel runs near private resources. The cloudflared daemon creates the outbound path from Cloudflare into that network. It is the resource-side half of the connection — the counterpart to the client.
Cloudflare Workers runs request-handling code at the edge. Workers respond to requests: useful for APIs, sites, and glue logic. A Worker cannot accept arbitrary inbound TCP connections and is not a general-purpose VPN endpoint. Its TCP socket API opens outbound connections from your code; nothing in the platform lets a Worker sit there listening for VPN clients.
Cloudflare One Client device side "my laptop's traffic enters Cloudflare"
Cloudflare Tunnel resource side "Cloudflare can reach into my private network"
Workers edge compute "my code runs on requests" — not a VPN component
Why insist on this? Because “can I run a WireGuard server on Workers?” comes up constantly, and the answer is no by design. WireGuard needs a listening UDP port and raw packet handling. A Worker has neither. Knowing each product’s shape saves you from architectures that fail at the whiteboard stage.
For this course lab we need the client and Tunnel. We do not need a Worker.
The role split also tells you where to look when things break. Device-side problems show up in the client:
warp-cli status
# Status update: Connected
Resource-side problems show up in the connector — systemctl status cloudflared on the machine running it, and the Tunnel health indicator in the dashboard. When a private connection fails, checking each half separately beats staring at the whole system at once.
Lesson completed