This guide walks you through proxying public hostnames to origins on a private network. The private network is reachable through a Cloudflare WAN (formerly Magic WAN) IPsec tunnel. The CDN, WAF, Cache, and other proxied features apply to this traffic the same way they apply to traffic destined for public origins.
This guide uses IPsec. The same flow works over GRE and CNI. Configure the on-ramp using those docs, then continue from step 2.
Confirm the following before you start:
- Active Cloudflare WAN subscription: this guide requires a Cloudflare WAN subscription on your account.
- Private Origins available on your account: contact your account team to enable it.
- IPsec tunnels configured: Set up two anycast IPsec tunnels for redundancy, each with a different Cloudflare anycast endpoint. Refer to Configure tunnel endpoints. Two settings are important for this use case:
- Leave Automatic return routing disabled. It does not apply to the public-to-private origin traffic pattern, where requests originate on the Internet and reach your origin through Cloudflare's reverse proxy.
- Keep the default Health check settings (type
reply, directionbidirectional, ratemid). These defaults are required for tunnel health to track correctly in this use case.
- Static routes configured: Add two static routes for the private prefix you want to reach, one per tunnel, with different priorities so traffic fails over to the backup tunnel if the primary goes down. For example, set priority
100on the route through your primary tunnel and101on the route through your backup tunnel (lower numbers are higher priority). Refer to Configure routes. - Unified Routing enabled: your account must be on Unified Routing to use a private Cloudflare source range. Contact your account team to enable it. This applies to new and existing accounts.
- MSS clamp set: set the TCP MSS clamp on your IPsec tunnels to
1360or lower. - Cloudflare Source IP set to a private range: The Cloudflare Source IP is the IP that Cloudflare uses when sending proxied requests into your private network. If it is left as a public range, your network cannot route the return traffic back through the tunnel and requests time out. Refer to Configure Cloudflare source IPs. You also need a return route for the IPv6 source range
2606:4700:cf1:5000::/64if any origin uses IPv6.
A misconfigured Cloudflare Source IP is the most common cause of failure. If the Source IP is left as a public range, the network where your origin lives has no return route and requests time out before reaching the application.
Go to Configure Cloudflare source IPs and verify that the Source IP is set to a private range, such as 100.64.0.0/12 (the default) or another private /12 you have selected.
Create an A or AAAA record that points to the private IP address of your origin, with proxy status enabled and Use private network routing turned on. This tells Cloudflare to send traffic for the hostname through your Cloudflare WAN tunnel instead of over the public Internet.
For the dashboard and API steps, refer to Private network routing.
After the DNS record is in place, validate the path from the Cloudflare network through your tunnel to the origin.
In the Cloudflare dashboard, confirm that your IPsec tunnel is healthy. Refer to Check tunnel health on the dashboard.
From a machine outside your private network, send an HTTPS request to the proxied hostname:
curl -v https://<YOUR_DOMAIN>/A successful response confirms that Cloudflare accepted the request, applied your proxied features, and reached the origin through the tunnel.
On the origin VM, verify that requests are arriving from the Cloudflare Source IP range. For example, to watch for incoming traffic from 100.64.0.0/12 on port 443:
sudo tcpdump -n -i any 'src net 100.64.0.0/12 and dst port 443'For IPv6 origins, watch for incoming traffic from the Cloudflare IPv6 source range:
sudo tcpdump -n -i any 'src net 2606:4700:cf1:5000::/64 and dst port 443'Replace 100.64.0.0/12 with the Source IP range configured for your account, and adjust the port to match the listener on your origin.
| Symptom | Cause and fix |
|---|---|
| Connection timeouts from clients | Cloudflare Source IP is set to a public range. Set it to a private /12. |
| Request times out, no response on the origin | The network where your origin lives has no return route for the Cloudflare Source IP range. Add a route that sends that range back through the tunnel. |
| Tunnel shows IKE established but health checks fail | ICMP is blocked on the path or the health check is misconfigured. Allow ICMP between the tunnel endpoints and confirm the health check direction is bidirectional and type is reply. |
| Traffic tries to route over the public Internet | The Use private network routing toggle is not turned on for the DNS record. Edit the record and turn the toggle on. |
| Large responses hang or stall | The MSS clamp is missing or above 1360 on the IPsec tunnel. Set it to 1360 or lower. |
| IPv6 requests time out | No return route for 2606:4700:cf1:5000::/64. Add one through the tunnel. |
Cacheable assets return 403 |
Known Tiered Cache issue. Refer to Limitations. |
- Configure tunnel health alerts to get notified when a tunnel goes down.
- Review the Private network routing reference for dashboard and API details.
- If you run into tunnel issues, refer to Tunnel health troubleshooting and IPsec troubleshooting.