Feature availability
| Client 模式 | Zero Trust 方案 ↗ |
|---|---|
|
所有方案 |
| 系统 | 可用性 | 最低客户端版本 |
|---|---|---|
| Windows | ✅ | 2025.10.186.0 |
| macOS | ✅ | 2025.10.186.0 |
| Linux | ✅ | 2025.10.186.0 |
| iOS | ❌ | |
| Android | ❌ | |
| ChromeOS | ❌ |
设备 IP 用于识别并路由流量到您的 Zero Trust 组织中的特定设备。当用户注册 Cloudflare One Client(前身为 WARP)时,Cloudflare 将为该设备注册分配虚拟 IPv4 和 IPv6 地址。Cloudflare One Client 使用这些 IP 地址在设备上创建虚拟网络接口,从而允许您的私有网络通过 Cloudflare Mesh 或 Cloudflare WAN 入口访问该设备。
您可以验证设备 IP,并在需要时重新配置地址池以避免与现有内部资源重叠 IP。
默认情况下,Cloudflare 从以下地址空间分配设备 IP:
- 默认 IPv4:
100.96.0.0/12 - 默认 IPv6:
2606:4700:0cf1:1000::/64
如果您的组织已经将默认 IPv4 范围用于内部网络,或者如果您在防火墙策略管理中需要更精细的 IP 分配,则可以配置自定义设备 IPv4 子网。您可以根据用户身份为设备分配不同的 IPv4 子网。
默认 IPv6 范围由 Cloudflare 所有,因此不应与您的私有网络上的服务发生冲突。设备 IPv6 范围不可配置。
当默认 IPv4 范围与您的私有网络上的服务发生冲突时,请创建自定义 IP 子网。
要为设备 IP 定义自定义 IPv4 子网:
-
在 Cloudflare 仪表板 ↗中,转到 Zero Trust > Team & Resources(团队和资源) > Devices(设备) > Device profiles(设备配置文件)。
-
在 Device IP subnet(设备 IP 子网) 下,选择 Add new IP subnet(添加新 IP 子网)。
-
输入该子网的任意名称。
-
在 CIDR 中,输入支持的私有范围中的有效 IPv4 CIDR 块:
10.0.0.0/8172.16.0.0/12192.168.0.0/16100.64.0.0/10
配置的 CIDR 块大小必须至少为
/24。 -
选择 Add subnet(添加子网) 并保存。
接下来,将此子网分配给一组设备。
分配自定义 IP 子网,以确保根据特定的用户身份标准在可预测的地址空间内配置设备。
- 在您的常规设备配置文件中已启用 为每个设备分配唯一 IP 地址。
要将 IP 子网分配给您的设备:
- 在 Cloudflare 仪表板 ↗中,转到 Zero Trust > Team & Resources(团队和资源) > Devices(设备) > Device profiles(设备配置文件)。
- 在 Device IP profile(设备 IP 配置文件) 下,选择 Add new IP profile(添加新 IP 配置文件)。
- 输入此设备组的名称(例如
IT department)。 - 创建规则以定义将接收这些 IP 的用户或设备。详细了解可用的选择器、运算符和值。
- 从下拉菜单中选择一个现有的 IPv4 子网,或者创建新子网。
- 选择 Assign IP address(分配 IP 地址)。
- (可选)在 Device IP profile(设备 IP 配置文件) 表中,更改 IP 配置文件从优先级顺序。
设备将根据符合您规则的条件,在注册时从该地址空间中分配一个随机 IP。只有新注册的设备才会收到新 IP;现有设备不会受到任何连接影响。要为现有设备分配新 IP,您必须删除其注册,然后在其 Zero Trust 组织中重新注册设备。
目前每个账户限制最多拥有 30 个自定义设备 IP 配置文件。
您可以配置 IP 配置文件以匹配以下选择器或标准。仅当用户通过登录身份提供商 (IdP) 注册设备时,基于身份的选择器才可用。
根据用户的电子邮件应用设备配置文件。
| UI 名称 | API 示例值 |
|---|---|
| User email | identity.email == "user-name@company.com" |
根据用户在 IdP 中被配置为成员的 IdP 组电子邮件地址,应用设备 IP 配置文件。
| UI 名称 | API 示例 |
|---|---|
| User group emails | identity.groups.email == "contractors@company.com" |
根据用户在 IdP 中被配置为成员的 IdP 组 ID,应用设备 IP 配置文件。
| UI 名称 | API 示例 |
|---|---|
| User group IDs | identity.groups.id == "12jf495bhjd7893ml09o" |
根据用户在 IdP 中被配置为成员的 IdP 组名称,应用设备 IP 配置文件。
| UI 名称 | API 示例 |
|---|---|
| User group names | identity.groups.name == "\"finance\"" |
| UI 名称 | API 示例 |
|---|---|
| User Name | identity.name == "user-name" |
根据来自 SAML IdP 的属性名称和值应用设备 IP 配置文件。
| UI 名称 | API 示例 |
|---|---|
| SAML Attributes(SAML 属性) | identity.saml_attributes == "\"group=finance\"" |
运算符决定了设备 IP 配置文件如何匹配选择器。
| 运算符 | 含义 |
|---|---|
| in | 匹配至少一个定义的值 |
| not in | 不匹配任何定义的值 |
| is | 等于定义的值 |
| matches | 正则表达式评估为 true |
在值字段中,当使用等值比较运算符(例如 is)时,您可以输入单个值;当使用包含比较运算符(例如 in)时,您可以输入多个值。此外,您可以使用正则表达式来为受支持的选择器指定值范围。
正则表达式使用 Rust 进行评估。Rust 的实现与其他地方使用的正则表达式库略有不同。有关更多信息,请参阅我们的通配符指南。要评估您的正则表达式是否匹配,可以使用 Rustexp ↗。
如果您想匹配多个值,可以使用管道符号(|)作为 OR 运算符。您不需要在管道符号之前使用转义字符(\)。例如,当 user's email domain 匹配 @acme.com 或 @widgets.com 时,以下表达式的计算结果为 true:
| 选择器 | 运算符 | 值 |
|---|---|---|
| User email | matches | @acme.com|@widgets.com |
除了正则表达式外,您还可以使用逻辑运算符来匹配多个值。
要在表达式中评估多个条件,请选择一个逻辑运算符:
| 运算符 | 含义 |
|---|---|
| And | 匹配表达式中的所有条件 |
| Or(或) | 匹配表达式中的任一条件 |
Cloudflare One Client 按照在 Cloudflare One 仪表板中显示的顺序自上而下检查 IP 配置文件(最先检查优先级数字最低的配置文件)。Client 遵循“首次匹配”原则 —— 一旦设备匹配到某个 IP 配置文件,Client 就会停止评估,随后的任何 IP 配置文件都无法覆盖该决策。您可以根据所需的优先级顺序在 Cloudflare One 仪表板中重新排列 IP 配置文件。
要检查分配给特定设备注册的虚拟 IP 地址:
-
在 Cloudflare 仪表板 ↗中,转到 Zero Trust > Team & Resources(团队和资源) > Devices(设备)。
-
选择您的设备 > View details(查看详情)。
-
向下滚动到 用户。您将看到与该设备关联的注册及其分配的 IPv4 和 IPv6 地址。
要检查设备客户端虚拟网络接口所使用的设备 IP:
在 Windows 上,运行 ipconfig。当开启 Cloudflare One 客户端时,您将看到一个名为 CloudflareWARP 的适配器,其中包含您的设备 IP。
ipconfigWindows IP Configuration
Unknown adapter CloudflareWARP:
Connection-specific DNS Suffix . :
Description . . . . . . . . . . . : Cloudflare WARP Interface Tunnel
Physical Address. . . . . . . . . :
DHCP Enabled. . . . . . . . . . . : No
Autoconfiguration Enabled . . . . : Yes
IPv6 Address. . . . . . . . . . . : 2606:4700:110:8f79:145:f180:fc4:8106(Preferred)
Link-local IPv6 Address . . . . . : fe80::83b:d647:4bed:d388%49(Preferred)
IPv4 Address. . . . . . . . . . . : 172.16.0.2(Preferred)
Subnet Mask . . . . . . . . . . . : 255.255.255.255
Default Gateway . . . . . . . . . :
DNS Servers . . . . . . . . . . . : 127.0.2.2
127.0.2.3
NetBIOS over Tcpip. . . . . . . . : Enabled在 macOS 上,运行 ifconfig。当开启 Cloudflare One 客户端时,您将看到一个包含您设备 IP 的 utun 接口。
ifconfig<redacted>
utun3: flags=8051<UP,POINTOPOINT,RUNNING,MULTICAST> mtu 1280
inet 172.16.0.2 --> 172.16.0.2 netmask 0xffffffff
inet6 fe80::f6d4:88ff:fe82:6d9e%utun3 prefixlen 64 scopeid 0x17
inet6 2606:4700:110:8c7d:7369:7526:a59b:5636 prefixlen 128
nd6 options=201<PERFORMNUD,DAD>在 Linux 上,运行 ifconfig 或 ip addr。当开启 Cloudflare One 客户端时,您将看到一个包含您设备 IP 的 utun 接口。
ip addr<redacted>
3: CloudflareWARP: <POINTOPOINT,MULTICAST,NOARP,UP,LOWER_UP> mtu 1280 qdisc mq state UNKNOWN group default qlen 500
link/none
inet 172.16.0.2/32 scope global CloudflareWARP
valid_lft forever preferred_lft forever
inet6 2606:4700:110:8a2e:a5f7:a8de:a1f9:919/128 scope global
valid_lft forever preferred_lft forever
inet6 fe80::117e:276b:8a79:c498/64 scope link stable-privacy
valid_lft forever preferred_lft forever在上面的示例中,设备 IPv4 地址是 172.16.0.2。
监控您的 IPv4 子网的使用消耗情况,以确保您有足够的地址供新设备注册。如果设备匹配到没有可用 IP 的子网,它们将无法注册。
使用 Cloudflare One 仪表板查看已分配和可用 IP 的高级概览:
- 在 Cloudflare 仪表板 ↗中,转到 Zero Trust > Team & Resources(团队和资源) > Devices(设备) > Device profiles(设备配置文件)。
- 找到 Device IP subnets(设备 IP 子网) 表。
- IPs assigned(已分配 IP) 列显示了当前分配给活动设备注册的 IP 总数与 CIDR 块的总容量。
如果您的子网接近容量上限,您可以扩充您的子网以增加可用 IP 的数量。或者,您可以通过删除现有设备注册来释放 IP,特别是那些可能仍在占用 IP 空间尽管设备已不再使用的撤销注册。
要获取子网中所有设备注册的列表(包括已撤销的注册),请使用 Cloudflare API。例如,以下脚本获取所有设备注册及其设备 IP,并输出指定 CIDR 块内的所有注册。
按 IP 过滤注册的示例脚本
-
创建一个名为
filter-device-ips.py的新文件,其中包含以下代码:import requests import ipaddress import json # --- Configuration --- AUTH_EMAIL = "<CLOUDFLARE_ACCOUNT_EMAIL>" AUTH_KEY = "<CLOUDFLARE_API_KEY>" # Refer to https://developers.cloudflare.com/fundamentals/api/get-started/keys/. API token authentication is not currently supported for fetching device IPs. ACCOUNT_ID = "<CLOUDLFARE_ACCOUNT_ID" # Refer to https://developers.cloudflare.com/fundamentals/account/find-account-and-zone-ids/. TARGET_CIDR = "100.64.0.0/10" # --- API request headers --- headers = { "X-Auth-Email": AUTH_EMAIL, "X-Auth-Key": AUTH_KEY, "Content-Type": "application/json" } def get_all_registrations(): """Fetches all device registrations including revoked registrations. """ devices = {} url = f"https://api.cloudflare.com/client/v4/accounts/{ACCOUNT_ID}/devices/registrations" params = {"per_page": 50, "status": "all"} while True: response = requests.get(url, headers=headers, params=params).json() if not response.get('success'): print(f"Error fetching registrations: {response.get('errors')}") break for d in response.get('result', []): # We use the ID as the key to link with IP data later devices[d['id']] = d cursor = response.get('result_info', {}).get('cursor') if not cursor: break params['cursor'] = cursor return devices def filter_by_cidr(device_map, network): """Fetch device IPs and return devices that fall within the target CIDR block.""" matches = [] device_ids = list(device_map.keys()) # API limits IP correlation to batches of 20 for i in range(0, len(device_ids), 20): batch = device_ids[i:i+20] # Construct parameters for the IP endpoint params = {f"device_ids[{idx}]": d_id for idx, d_id in enumerate(batch)} url = f"https://api.cloudflare.com/client/v4/accounts/{ACCOUNT_ID}/teamnet/devices/ips" res = requests.get(url, headers=headers, params=params).json() if not res.get('success'): print(f"Error fetching IPs: {res.get('errors')}") continue for item in res.get('result', []): d_id = item.get('device_id') ip_data = item.get('device_ips', {}) ipv4_str = ip_data.get('ipv4') if ipv4_str: try: if ipaddress.IPv4Address(ipv4_str) in network: if d_id in device_map: full_data = device_map[d_id] full_data['device_ips'] = ip_data matches.append(full_data) except ValueError: continue return matches if __name__ == "__main__": try: net = ipaddress.IPv4Network(TARGET_CIDR, strict=False) print(f"[*] Fetching registrations (status=all)...") all_devices = get_all_registrations() print(f"[*] Found {len(all_devices)} total registrations.") print(f"[*] Checking IP ranges for match...") filtered_list = filter_by_cidr(all_devices, net) if filtered_list: print(f"\n--- Found {len(filtered_list)} Device(s) in {TARGET_CIDR} ---\n") for dev in filtered_list: print(json.dumps(dev, indent=2)) print("-" * 50) else: print(f"\nNo devices found within the {TARGET_CIDR} range.") except Exception as e: print(f"Script Error: {e}") -
在脚本配置部分,输入您的 Cloudflare API 凭据和您的 IP 子网范围。
-
打开终端并导航到脚本目录。要运行该脚本,请键入:
python3 filter-device-ips.py
Cloudflare 不支持编辑现有的 IPv4 子网定义。要为您的设备分配不同的 IPv4 子网:
- 在 Cloudflare 仪表板 ↗中,转到 Zero Trust > Team & Resources(团队和资源) > Devices(设备) > Device profiles(设备配置文件)。
- 在 Device IP profile(设备 IP 配置文件) 下,找到与旧子网关联的设备组,然后选择 Edit(编辑)。
- 选择 **Create new subnet IP range(创建新子网 IP 范围)**以定义新子网。
- 选择 Save(保存)。
新子网将显示在 Device IP subnets 表中。您现在可以删除旧子网。只有当设备重新注册时,它们才会从新子网获取 IP;现有注册将保留其当前 IP。