-
Notifications
You must be signed in to change notification settings - Fork 16.2k
Hostname routing GA + public IP range for initial resolved IPs #32544
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: production
Are you sure you want to change the base?
Changes from all commits
6cc9c34
2fd20b8
95df08f
669917d
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,302 @@ | ||
| --- | ||
| /* `role="list"` on the `<ol>` below is intentional, not redundant: Safari | ||
| + VoiceOver drop the implicit list role when `list-style: none` is | ||
| applied, so the explicit role is required to preserve list semantics | ||
| for screen reader users. */ | ||
| /* eslint-disable astro/jsx-a11y/no-redundant-roles */ | ||
| import { Icon as AstroIcon } from "astro-icon/components"; | ||
| --- | ||
|
|
||
| <figure | ||
| class="tunnel-hostname-diagram not-content" | ||
| aria-label="How hostname routing works with Cloudflare Tunnel: a client requests a hostname, Cloudflare Gateway assigns a token IP and rewrites the destination, and the tunnel delivers the traffic to a private host on your network or egresses it to the public Internet" | ||
| > | ||
| <ol class="flow" role="list"> | ||
| <li class="flow-step"> | ||
| <div class="node-card client-card"> | ||
| <div class="node-header"> | ||
| <span class="node-icon client-icon" aria-hidden="true" | ||
| ><AstroIcon name="warp-client" /></span | ||
| > | ||
| <a | ||
| class="node-title" | ||
| href="/cloudflare-one/team-and-resources/devices/cloudflare-one-client/" | ||
| >Client device</a | ||
| > | ||
| </div> | ||
| <p class="node-caption"> | ||
| Requests <code>wiki.internal.local</code> | ||
| </p> | ||
| </div> | ||
| </li> | ||
|
|
||
| <li class="flow-connector"> | ||
| <span class="connector-label">DNS query</span> | ||
| <span class="connector-arrow" aria-hidden="true">↓</span> | ||
| </li> | ||
|
|
||
| <li class="flow-step"> | ||
| <div class="node-card gateway-card"> | ||
| <div class="node-header"> | ||
| <span class="node-icon gateway-icon" aria-hidden="true" | ||
| ><AstroIcon name="gateway" /></span | ||
| > | ||
| <a class="node-title" href="/cloudflare-one/traffic-policies/" | ||
| >Cloudflare Gateway</a | ||
| > | ||
| </div> | ||
| <p class="node-caption"> | ||
| Returns a token IP, then rewrites the destination to the real IP. | ||
| </p> | ||
| <div class="pill-row"> | ||
| <span class="token-pill"><code>172.64.128.0/20</code></span> | ||
| </div> | ||
| </div> | ||
| </li> | ||
|
|
||
| <li class="flow-connector"> | ||
| <span class="connector-label">Hostname route</span> | ||
| <span class="connector-arrow" aria-hidden="true">↓</span> | ||
| </li> | ||
|
|
||
| <li class="flow-step"> | ||
| <div class="node-card tunnel-card"> | ||
| <div class="node-header"> | ||
| <span class="node-icon tunnel-icon" aria-hidden="true" | ||
| ><AstroIcon name="tunnel" /></span | ||
| > | ||
| <a | ||
| class="node-title" | ||
| href="/cloudflare-one/networks/connectors/cloudflare-tunnel/" | ||
| >Cloudflare Tunnel</a | ||
| > | ||
| </div> | ||
| <p class="node-caption"> | ||
| Forwards traffic to your private network, or egresses it to the public | ||
| Internet | ||
| </p> | ||
| </div> | ||
| </li> | ||
|
|
||
| <li class="flow-connector" aria-hidden="true"> | ||
| <span class="connector-arrow">↓</span> | ||
| </li> | ||
|
|
||
| <li class="flow-step"> | ||
| <div class="node-card host-card"> | ||
| <div class="node-header"> | ||
| <span class="node-icon host-icon" aria-hidden="true" | ||
| ><AstroIcon name="dns" /></span | ||
| > | ||
| <span class="node-title">Private host</span> | ||
| </div> | ||
| <p class="node-caption"> | ||
| <code>wiki.internal.local</code> · <code>10.0.0.50</code> | ||
| </p> | ||
| </div> | ||
| </li> | ||
| </ol> | ||
| </figure> | ||
|
|
||
| <style> | ||
| .tunnel-hostname-diagram { | ||
| --map-bg: light-dark(#fafafa, #0f0f10); | ||
| --map-card: light-dark(#ffffff, #171719); | ||
| --map-elevated: light-dark(#fafafa, #111113); | ||
| --map-line: light-dark(rgb(0 0 0 / 12%), rgb(255 255 255 / 14%)); | ||
| --map-text: light-dark(#171717, #f5f5f5); | ||
| --map-strong: light-dark(#525252, #a3a3a3); | ||
| --map-caption: light-dark(#737373, #a3a3a3); | ||
| --map-brand: #f6821f; | ||
| --map-tunnel: light-dark(#4f46e5, #818cf8); | ||
| --map-gateway: light-dark(#0ea5e9, #38bdf8); | ||
| --map-host: light-dark(#10b981, #34d399); | ||
|
|
||
| display: flex; | ||
| flex-direction: column; | ||
| gap: 12px; | ||
| margin: 1.25rem 0; | ||
| padding: 18px; | ||
| border: 1px solid var(--map-line); | ||
| border-radius: 12px; | ||
| background: | ||
| radial-gradient(circle, var(--map-line) 1px, transparent 1px), | ||
| var(--map-bg); | ||
| background-size: 14px 14px; | ||
| font-family: "Inter Variable", ui-sans-serif, system-ui, sans-serif; | ||
| font-feature-settings: "cv02", "cv03", "cv04", "calt"; | ||
| -webkit-font-smoothing: antialiased; | ||
| letter-spacing: -0.01em; | ||
| } | ||
|
|
||
| .tunnel-hostname-diagram a { | ||
| color: inherit; | ||
| text-decoration: none; | ||
| } | ||
|
|
||
| .flow { | ||
| display: flex; | ||
| flex-direction: column; | ||
| align-items: center; | ||
| gap: 6px; | ||
| margin: 0; | ||
| padding: 0; | ||
| list-style: none; | ||
| } | ||
|
|
||
| .flow-step { | ||
| display: block; | ||
| width: 100%; | ||
| max-width: 360px; | ||
| } | ||
|
|
||
| .node-card { | ||
| display: flex; | ||
| flex-direction: column; | ||
| gap: 8px; | ||
| padding: 12px 14px; | ||
| border: 1px solid var(--map-line); | ||
| border-radius: 10px; | ||
| background: var(--map-card); | ||
| box-shadow: 0 5px 14px rgb(0 0 0 / 7%); | ||
| color: var(--map-text); | ||
| } | ||
|
|
||
| .node-header { | ||
| display: flex; | ||
| align-items: center; | ||
| justify-content: center; | ||
| gap: 10px; | ||
| } | ||
|
|
||
| .node-title { | ||
| min-width: 0; | ||
| color: var(--map-text); | ||
| font-size: 14px; | ||
| font-weight: 600; | ||
| letter-spacing: -0.01em; | ||
| } | ||
|
|
||
| a.node-title { | ||
| transition: color 150ms ease; | ||
| } | ||
|
|
||
| a.node-title:hover { | ||
| color: var(--map-brand); | ||
| } | ||
|
|
||
| .node-icon { | ||
| display: inline-flex; | ||
| flex: 0 0 auto; | ||
| align-items: center; | ||
| justify-content: center; | ||
| width: 28px; | ||
| height: 28px; | ||
| border-radius: 7px; | ||
| font-size: 14px; | ||
| font-weight: 600; | ||
| } | ||
|
|
||
| .node-icon :global(svg) { | ||
| width: 18px; | ||
| height: 18px; | ||
| fill: currentColor; | ||
| } | ||
|
|
||
| .client-icon { | ||
| background: color-mix(in srgb, var(--map-brand) 14%, transparent); | ||
| color: var(--map-brand); | ||
| } | ||
|
|
||
| .gateway-icon { | ||
| background: color-mix(in srgb, var(--map-gateway) 14%, transparent); | ||
| color: var(--map-gateway); | ||
| } | ||
|
|
||
| .tunnel-icon { | ||
| background: color-mix(in srgb, var(--map-tunnel) 14%, transparent); | ||
| color: var(--map-tunnel); | ||
| } | ||
|
|
||
| .host-icon { | ||
| background: color-mix(in srgb, var(--map-host) 14%, transparent); | ||
| color: var(--map-host); | ||
| } | ||
|
|
||
| .node-caption { | ||
| margin: 0; | ||
| color: var(--map-caption); | ||
| font-size: 12px; | ||
| line-height: 1.5; | ||
| text-align: center; | ||
| } | ||
|
|
||
| .node-caption code { | ||
| display: inline; | ||
| padding: 1px 6px; | ||
| border: 1px solid var(--map-line); | ||
| border-radius: 5px; | ||
| background: var(--map-elevated); | ||
| color: var(--map-text); | ||
| font-family: | ||
| "Paper Mono", ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, | ||
| monospace; | ||
| font-size: 11px; | ||
| white-space: nowrap; | ||
| } | ||
|
|
||
| .flow-connector { | ||
| display: flex; | ||
| flex-direction: column; | ||
| align-items: center; | ||
| justify-content: center; | ||
| gap: 2px; | ||
| padding: 2px 0; | ||
| color: var(--map-strong); | ||
| } | ||
|
|
||
| .connector-label { | ||
| color: var(--map-caption); | ||
| font-family: | ||
| "Paper Mono", ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, | ||
| monospace; | ||
| font-size: 11px; | ||
| font-weight: 500; | ||
| line-height: 1; | ||
| } | ||
|
|
||
| .connector-arrow { | ||
| font-size: 18px; | ||
| line-height: 1; | ||
| color: var(--map-strong); | ||
| } | ||
|
|
||
| .pill-row { | ||
| display: flex; | ||
| flex-wrap: wrap; | ||
| justify-content: center; | ||
| gap: 6px; | ||
| } | ||
|
|
||
| .token-pill { | ||
| display: inline-flex; | ||
| align-items: center; | ||
| padding: 4px 10px; | ||
| border: 1px solid | ||
| color-mix(in srgb, var(--map-gateway) 35%, var(--map-line)); | ||
| border-radius: 6px; | ||
| background: color-mix(in srgb, var(--map-gateway) 6%, var(--map-card)); | ||
| } | ||
|
|
||
| .token-pill code { | ||
| padding: 0; | ||
| border: 0; | ||
| background: transparent; | ||
| color: var(--map-gateway); | ||
| font-family: | ||
| "Paper Mono", ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, | ||
| monospace; | ||
| font-size: 11px; | ||
| white-space: nowrap; | ||
| } | ||
| </style> | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,39 @@ | ||
| --- | ||
| title: Hostname routing is now generally available, with a new public IP range for initial resolved IPs | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Do you want it to be Tunnel Hostname? or something that calls out what kind of routing it is. Just thinking about when your changelog gets posted on twitter and stuff like that, might need one extra identifier.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It works for both Tunnel and Mesh, so trying to go generic here :) |
||
| description: Hostname routing is now GA. Initial resolved IPs are moving to a public Cloudflare IP range instead of CGNAT, resolving a conflict with Chromium's Local Network Access restrictions. | ||
| products: | ||
| - tunnel | ||
| - cloudflare-tunnel-sase | ||
| - mesh | ||
| - gateway | ||
| - cloudflare-one | ||
| date: 2026-08-12 | ||
| --- | ||
|
|
||
| import { DashButton, Render, GlossaryTooltip } from "~/components"; | ||
|
|
||
| [Hostname routing](https://blog.cloudflare.com/tunnel-hostname-routing/) is now generally available. Instead of managing static IP lists and routes, you can route traffic by hostname across multiple Cloudflare One connectors: | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm not clear what "route traffic by hostname across multiple connectors means" I would be more explicit here maybe. like: Tunnel hostname routing now supports routing traffic across multiple Cloudflare One Connectors with a dynamic set of IPs (? or something). Previously, you had to manage static IP address lists. |
||
|
|
||
| - **Cloudflare Tunnel**: route a [private hostname](/cloudflare-one/networks/connectors/cloudflare-tunnel/private-net/cloudflared/connect-private-hostname/) (for example, `wiki.internal.local`) to a private application behind your tunnel, or a [public hostname](/cloudflare-one/traffic-policies/egress-policies/egress-cloudflared/) (for example, `bank.example.com`) to egress through a specific tunnel and anchor traffic to a dedicated exit node. | ||
| - **Cloudflare Mesh**: attract a [private or public hostname's traffic](/cloudflare-one/networks/connectors/cloudflare-mesh/routes/#hostname-routes) to a Mesh node. | ||
|
|
||
| Alongside GA, the default IPv4 range used for <GlossaryTooltip term="initial resolved IP">initial resolved IPs</GlossaryTooltip> (also called token IPs) is changing from a Carrier-Grade NAT (CGNAT) range to a public Cloudflare-owned range: | ||
|
|
||
| <Render file="gateway/egress-selector-cgnat-ips" product="cloudflare-one" /> | ||
|
|
||
| **Why this is changing:** Starting with [Chrome 142](https://developer.chrome.com/release-notes/142), Local Network Access (LNA) restrictions block background requests to CGNAT addresses (`100.64.0.0/10`), which included the previous initial resolved IP default (`100.80.0.0/16`). LNA is implemented at the Chromium engine level, so it affects all Chromium-based browsers (for example, Microsoft Edge, Brave, and Opera), not only Google Chrome. This could silently break hostname-based Gateway features for users of these browsers, and required Chrome Enterprise policy workarounds. The new default range is public Cloudflare address space, so it is not affected by this restriction. | ||
|
|
||
| **What is affected:** Initial resolved IPs are used by several features that associate a DNS query with the network connection that follows it: | ||
|
|
||
| - [Private](/cloudflare-one/networks/connectors/cloudflare-tunnel/private-net/cloudflared/connect-private-hostname/) and [public](/cloudflare-one/traffic-policies/egress-policies/egress-cloudflared/) hostname routing for Cloudflare Tunnel | ||
| - [Hostname routes](/cloudflare-one/networks/connectors/cloudflare-mesh/routes/#hostname-routes) for Cloudflare Mesh | ||
| - [Access private applications](/cloudflare-one/access-controls/applications/non-http/self-hosted-private-app/) on non-HTTPS ports | ||
| - [Egress policy host selectors](/cloudflare-one/traffic-policies/egress-policies/host-selectors/) (Domain, Host, Application, and Content Categories) | ||
|
|
||
| **Rollout:** Cloudflare is migrating all accounts to the new default range over the next few days. Once migration is complete, you can check your account's current range, or configure a custom range, at any time from **Networking** > **IP addresses** > **Address space** > **Custom IPs**, or using the [Initial Resolved IP Subnet API](/api/resources/zero_trust/subresources/networks/subresources/subnets/#(resource)%20zero_trust.networks.subnets.initial_resolved_ip). | ||
|
|
||
| <DashButton url="/?to=/:account/ip-addresses/address-space/custom-ips" /> | ||
|
|
||
| For full instructions, refer to [Configure initial resolved IPs](/cloudflare-one/networks/routes/configure-initial-resolved-ips/). The IPv6 range (`2606:4700:0cf1:4000::/64`) is unchanged and is not affected by this restriction. | ||
|
|
||
| If you were relying on a Chrome Enterprise policy workaround (such as `LocalNetworkAccessRestrictionsTemporaryOptOut`) while your account was still on the legacy CGNAT-based range, refer to [Google Chrome restricts access to private hostnames](/cloudflare-one/networks/connectors/cloudflare-tunnel/private-net/cloudflared/connect-private-hostname/#google-chrome-restricts-access-to-private-hostnames) for next steps. | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🚫 [eslint] <eslint.rules.astro/jsx-a11y/no-redundant-roles> reported by reviewdog 🐶
The element ol has an implicit role of list. Defining this explicitly is redundant and should be avoided. (astro/jsx-a11y/no-redundant-roles)