INTEGRITY Cloudflare Docs

Routes

By default, a Mesh node is reachable only by its own Mesh IP. To make other devices on the subnet behind the node reachable — servers, databases, printers, IoT devices that cannot run the Cloudflare One Client — add a route to the node. A Mesh node supports two types of routes:

When you add a route, the Mesh node acts as a gateway: traffic destined for the advertised CIDR or hostname is forwarded to the node, which delivers it to the appropriate host on the local network (or egresses it to the public Internet).

Both IPv4 and IPv6 CIDR routes are supported. IPv6 routes require that the Mesh node's device profile is configured to use MASQUE; they will not work if the device profile uses WireGuard instead.

When to use routes

flowchart LR
  subgraph subnet["Subnet 10.0.0.0/24"]
    node["Mesh node <br> 10.0.0.1"]
    db["Database <br> 10.0.0.50"]
    printer["Printer <br> 10.0.0.100"]
  end
  client["Client device <br> 100.96.0.10"] --> CF((Cloudflare)) --> node
  node --> db
  node --> printer

Manage CIDR routes

Use CIDR routes to forward traffic from your mesh node to devices on your local network.

Add a route

  1. In the Cloudflare dashboard, go to Networking > Mesh.

    Go to Mesh ↗
  2. Select your Mesh node.

  3. Go to the Routes tab.

  4. Select Add route.

  5. Enter the private CIDR you want to route through this node (for example, 10.0.0.0/24).

  6. (Optionally) add a description for the route.

  7. Select Add route.

Required API token permissions

At least one of the following token permissions is required:
  • Cloudflare One Networks Write
  • Cloudflare Tunnel Write
Create a tunnel route
curl "https://api.cloudflare.com/client/v4/accounts/$ACCOUNT_ID/teamnet/routes" \
	--request POST \
	--header "Authorization: Bearer $CLOUDFLARE_API_TOKEN" \
	--json '{
		"network": "10.0.0.0/24",
		"tunnel_id": "{mesh_node_id}",
		"comment": "Staging subnet"
	}'

Edit a route

  1. Go to Networking > Mesh > select your node > Routes tab.
  2. Select the edit icon next to the route you want to modify.
  3. Update the CIDR or description.
  4. Select Save.

Required API token permissions

At least one of the following token permissions is required:
  • Cloudflare One Networks Write
  • Cloudflare Tunnel Write
Update a tunnel route
curl "https://api.cloudflare.com/client/v4/accounts/$ACCOUNT_ID/teamnet/routes/$ROUTE_ID" \
	--request PATCH \
	--header "Authorization: Bearer $CLOUDFLARE_API_TOKEN" \
	--json '{
		"network": "10.0.0.0/24",
		"comment": "Updated description"
	}'

Delete a route

  1. Go to Networking > Mesh > select your node > Routes tab.
  2. Select the delete icon next to the route.
  3. Confirm deletion.

Required API token permissions

At least one of the following token permissions is required:
  • Cloudflare One Networks Write
  • Cloudflare Tunnel Write
Delete a tunnel route
curl "https://api.cloudflare.com/client/v4/accounts/$ACCOUNT_ID/teamnet/routes/$ROUTE_ID" \
	--request DELETE \
	--header "Authorization: Bearer $CLOUDFLARE_API_TOKEN"

Configure Split Tunnels

For traffic to reach your advertised CIDR, the range must route through Cloudflare on both the Mesh node and client devices.

On the Mesh node

In your Mesh node's device profile, ensure the advertised CIDR routes through Cloudflare:

For example, if you are advertising 10.0.0.0/24 and your Split Tunnels exclude list contains 10.0.0.0/8, you need to remove 10.0.0.0/8 and re-add the portions of the 10.0.0.0/8 range that you do not want to route through Cloudflare.

On client devices

Repeat the same Split Tunnel configuration on the device profiles used by your client devices, ensuring the advertised CIDR routes through Cloudflare.

Return traffic routing

The Mesh node forwards inbound traffic from Cloudflare to devices on the subnet. However, for return traffic (responses from subnet devices back to Mesh clients), the subnet devices need a route back to the Mesh node.

flowchart LR
  client["Client device <br> 100.96.0.10"] -- request --> CF((Cloudflare)) -- request --> node["Mesh node <br> 10.0.0.1"]
  node --> db["Database <br> 10.0.0.50"]
  db -. "response: <br> needs route to node" .-> node -. response .-> CF -. response .-> client

How you configure this depends on where the Mesh node is installed:

Option 1: Mesh node is the default gateway

If the Mesh node is the subnet's default gateway (or is installed on the router), no additional configuration is needed. All traffic from subnet devices naturally routes through the node.

Option 2: Mesh node is not the default gateway

If the Mesh node is a regular host on the subnet, configure the subnet's router to send Mesh traffic through the node. Add a static route:

This ensures that responses to Mesh clients are forwarded to the Mesh node for delivery through Cloudflare.

Site-to-site routing

When you have Mesh nodes at multiple sites, devices on one subnet can reach devices on another subnet through Cloudflare.

flowchart TD
  subgraph siteA["Site A — 10.0.0.0/24"]
    serverA["Server <br> 10.0.0.50"] --- nodeA["Mesh node <br> 10.0.0.1"]
  end
  subgraph siteB["Site B — 192.168.1.0/24"]
    serverB["Server <br> 192.168.1.50"] --- nodeB["Mesh node <br> 192.168.1.1"]
  end
  nodeA <--> CF((Cloudflare))
  nodeB <--> CF

For this to work:

  1. Each Mesh node must advertise the local subnet as a CIDR route so Cloudflare knows which node to forward traffic to.
  2. The remote subnet CIDRs must route through Cloudflare on each node. In your Mesh node's Split Tunnel configuration, add the remote site's CIDR to the include list (or remove it from the exclude list).
  3. Each site's router needs static routes pointing remote subnets to the local Mesh node:

Site A router:

Site B router:

For production site-to-site deployments, consider enabling high availability on each node. HA provides failover for the CIDR routes advertised by a node — if the active replica goes down, Cloudflare promotes a standby so traffic to the subnet continues to flow.

DNS filtering

To filter DNS queries from the subnet using Cloudflare Gateway:

  1. Configure DNS on your router: Point your router's DNS to the Gateway resolver IPs:

    • 172.64.36.1
    • 172.64.36.2
  2. Add IP routes to your router: On your router, add static routes pointing the Gateway resolver IPs to your Mesh node's local IP. This allows DNS traffic to reach Cloudflare through the node.

    • Destination: 172.64.36.1Next hop: 10.0.0.1 (local Mesh node)
    • Destination: 172.64.36.2Next hop: 10.0.0.1
  3. Configure Split Tunnels: Ensure the following IPs route through the Mesh node in your Split Tunnels configuration:

    • The subnet's internal DNS resolver IP
    • Gateway initial resolved IP range: 172.64.128.0/20 (IPv4) and 2606:4700:0cf1:4000::/64 (IPv6)

Gateway logs DNS queries with the private source IP of the originating device. You can use this to create resolver policies for internal DNS records.

Hostname routes

Instead of advertising an IP range, you can attract traffic for a specific hostname to a Mesh node. When a user requests the hostname, Cloudflare Gateway assigns an initial resolved IP and routes the traffic through the node.

Hostname routes replace virtual networks as the way to reach resources: because a hostname is globally unique, overlapping hostnames are not supported and a hostname can only be routed to one node or tunnel at a time.

  1. Requests wiki.internal.local

  2. DNS query
  3. Returns a token IP, then rewrites the destination to the real private IP.

    172.64.128.0/20
  4. Hostname route
  5. Forwards traffic to the host on the local network

  6. Private host

    wiki.internal.local · 10.0.0.50

For a deeper look at the packet flow behind hostname routing, refer to the announcement blog post.

Prerequisites

Add a hostname route

  1. In the Cloudflare dashboard, go to Networking > Mesh.

    Go to Mesh ↗
  2. Select your Mesh node.

  3. Go to the Routes tab.

  4. Select Add route, then select Private hostname.

  5. Enter the fully qualified domain name (FQDN) you want to route through this node (for example, wiki.internal.local).

    Hostname format restrictions

    • Character limit: Must be less than 255 characters.
    • Supported wildcards: A single wildcard (*) is allowed, and it must represent a full DNS label. Example: *.internal.local
    • Unsupported wildcards: The following wildcard formats are not supported:
      • Partial wildcards such as *-dev.internal.local or dev-*.internal.local.
      • Wildcards in the middle, such as foo*bar.internal.local or foo.*.internal.local.
      • Multiple wildcards in the hostname, such as *.*.internal.local.
    • Wildcard trimming: Leading wildcards (*) are trimmed off and an implicit dot (.) is assumed. For example, *.internal.local is saved as internal.local but will match all subdomains at the wildcard level (covers foo.internal.local but not foo.bar.internal.local).
    • Dot trimming: Leading and ending dots (.) are allowed but trimmed off.
  6. (Optionally) add a description for the route.

  7. Select Add hostname.

Required API token permissions

At least one of the following token permissions is required:
  • Cloudflare One Networks Write
  • Cloudflare Tunnel Write
Create hostname route
curl "https://api.cloudflare.com/client/v4/accounts/$ACCOUNT_ID/zerotrust/routes/hostname" \
	--request POST \
	--header "Authorization: Bearer $CLOUDFLARE_API_TOKEN" \
	--json '{
		"hostname": "wiki.internal.local",
		"tunnel_id": "{mesh_node_id}",
		"comment": "Internal wiki"
	}'

Configure DNS resolution

For a private hostname, Gateway must be able to resolve the hostname to its private IP. How you configure this depends on whether DNS resolution and application traffic use the same connector or different connectors.

The node resolves the hostname (default)

By default, the Mesh node resolves the hostname using the DNS resolver configured on its host machine (for example, in /etc/resolv.conf on Linux) — the same way cloudflared does. If the node can already resolve the hostname to its private IP through that resolver, no further configuration is required.

If the node cannot resolve the hostname on its own, the simplest option is to add an entry to the node's hosts file (for example, /etc/hosts on Linux) mapping the hostname to its private IP. Unlike a Cloudflare Tunnel, a Mesh node does not require you to run a dedicated DNS server:

/etc/hosts
10.0.0.50 wiki.internal.local

Split DNS: DNS and application traffic use different connectors

You only need a Gateway resolver policy when the DNS query must be sent to a different connector than the application traffic — for example, the internal DNS server sits behind one Mesh node or Cloudflare Tunnel, while the application is reached through another. In that case:

  1. Add a CIDR route for the DNS server's IP so Gateway can reach it through the connector where the DNS server lives (a Mesh node or a Cloudflare Tunnel).
  2. Create a resolver policy that sends DNS queries for the hostname (or its domain) to that internal DNS server.

For a public hostname, the Mesh node handles resolution: Gateway sends the DNS query to the node, the node resolves it through its upstream DNS provider, and then routes the packet to the destination and egresses using its own public IP. No internal DNS server or resolver policy is required.

Secure hostname traffic

After adding a hostname route, secure it with either an Access self-hosted application or Gateway network policies. For details and examples, refer to Connect a private hostname.

Limitations

Starting with Chrome 142, Local Network Access (LNA) restricts requests from websites to local IP addresses. LNA is implemented at the Chromium engine level, so this affects all Chromium-based browsers (for example, Microsoft Edge, Brave, and Opera), not only Google Chrome. This can affect accounts whose Gateway initial resolved IP range is still drawn from Carrier-Grade NAT (CGNAT) address space (100.64.0.0/10) — for example, the legacy default range 100.80.0.0/16, or a custom range configured within CGNAT space. These browsers categorize such addresses as belonging to a local network. When a website loaded from a public IP makes subrequests to a domain resolved through an initial resolved IP in this space, the browser treats this as a public-to-local network request and displays a prompt asking the user to allow access to devices on the local network. The browser blocks requests to these domains until the user accepts this prompt.

This commonly occurs when an Egress policy matches broadly used domains (such as cloudfront.net or github.com), causing subrequests from public pages to resolve into CGNAT space.

Accounts using the current default initial resolved IP range (172.64.128.0/20) are not affected, because this range is public Cloudflare address space rather than CGNAT. If your account was created before this default changed, or if you configured a custom CGNAT-space range, refer to Configure initial resolved IPs to move to a non-CGNAT range instead of relying on the following browser workarounds.

The workarounds below use Google Chrome Enterprise policies. If your organization manages a different Chromium-based browser, consult that browser's enterprise policy documentation for an equivalent control.

Iframes

If the affected request originates from within an iframe (for example, an application embedded in a third-party portal), the iframe must declare the local-network-access permission for the browser prompt to appear in the parent frame:

If iframes are nested, every iframe in the chain must include the appropriate attribute. Since third-party applications control their own iframe attributes, this may not be configurable by the end user.

Workarounds

To avoid this issue, choose one of the following options: