识别 iCloud Private Relay 和 Cloudflare WARP,然后放行
借助 Apple 公布的 285,091 行出口列表和实时 API 查询识别 iCloud Private Relay,了解 Cloudflare WARP 为何没有公开列表,并放行中继用户。

我们在 2026 年 10 月 12 日 09:40 UTC 下载了 Apple 的列表。其中有 285,091 个前缀,41,734 个 IPv4 和 243,357 个 IPv6,覆盖 235 个国家代码。在 Cloudflare 的 104.28.0.0/16 中,65,536 个地址里有 19,723 个在列表上。其余 45,813 个不在,因此针对这个网段,或针对 Cloudflare 整个网络编写的规则,无法把 Private Relay 用户与经由该网络路由的其他流量区分开。
下文我们会剖析 Apple 的文件,并给出一个经过测试、支持 IPv4 和 IPv6 的 Python 匹配器。我们会解释关于 WARP 能知道什么、不能知道什么,并展示对中继地址的真实查询结果,其中包括两处我们自己的地理定位与 Apple 不一致的地方。文章最后给出一张策略表。如需了解更全面的匿名化信号,请先阅读 VPN 和代理检测的工作原理。

如何识别 iCloud Private Relay:匹配 Apple 自己的列表
Apple 在一个 CSV 中公布了所有 Private Relay 出口前缀,因此精确匹配即可告诉您某个 IP 是中继出口。Apple 的网络和服务器运营方指南建议服务器使用该列表,或使用提供商的标志:
"Your server can recognize traffic from Private Relay by using the above list of Private Relay IP addresses or by checking how it's categorized by your geo IP database provider."(您的服务器可以使用上面的 Private Relay IP 地址列表,或查看您的地理 IP 数据库提供商如何对其分类,来识别来自 Private Relay 的流量。)
同一页面还列出了应关注的字段:“其他相关字段可能包括:'is_relay'、'is_hosting'、'privacy_service' 或 'privacy_proxy'。”换句话说,Apple 希望您要么使用它的列表,要么使用类似我们 API 所返回的字段。
这个列表还有一点与大多数 IP 列表不同:它很干净。Apple 的 2021 年 12 月 Private Relay 概述指出,中继 IP 地址“除提供 Private Relay 服务外,不会用于或共享于任何其他目的”。因此精确匹配不会误伤他人。没有其他人的流量会从这些地址发出。
Apple 的出口 CSV 里有什么
该文件位于 https://mask-api.icloud.com/egress-ip-ranges.csv。我们下载了它,并用 Python 的 ipaddress 模块解析了每一行。
| 指标 | 数值(2026-10-12 09:40 UTC 获取) |
|---|---|
| 行数(前缀) | 285,091 |
| IPv4 前缀 | 41,734 |
| IPv6 前缀 | 243,357 |
| 覆盖的 IPv4 地址 | 105,647 |
| 不同国家代码 | 235 |
| 列 | 5 列:前缀、国家、地区、城市,以及末尾一个空字段 |
| 文件大小 | 12,047,231 字节 |
| 重叠前缀 | 无 |
每一行都是一条 geofeed 记录。以下是文件中的两行真实数据:
172.224.226.0/27,GB,GB-EN,London,
104.28.46.99/32,ZM,,Lusaka,
第二行的地区为空,因此您的解析器必须接受空值。还有一个计数陷阱:wc -l 输出 285,090,少了一行,因为文件末尾没有换行符。请改为统计解析出的行数。
轮询该文件的成本很低。服务器返回了 ETag "6acc40fb-b7d37f",并对我们的条件请求返回 304 Not Modified。Apple 没有说明列表的更新频率,所以我们不做猜测。请选择适合您的刷新周期。
为什么按 ASN 或 /16 制定规则不够
中继出口与其他流量共享网络。在 104.28.0.0/16 中,65,536 个地址里有 19,723 个在 Apple 的列表上,其余的不在。Apple 的概述称,第二跳中继“由第三方合作伙伴运营,它们是全球最大的一批内容分发网络(CDN)”。我们抽样的三个中继位于其中两家:Cloudflare(AS13335)和 Akamai(AS36183)。
拦截 AS13335 会波及远多于中继用户的流量。把它加入允许列表,则会放进远多于中继的流量。前缀匹配才是精确的工具,您可以检测任意 IP 是否为 VPN 或中继,看看单个地址会被如何分类。
为什么中继 IP 不是 VPN IP
Private Relay 向网站隐藏用户的 IP,但让用户保持在真实所在的地区,只覆盖部分流量,并且仅限付费账户下通过验证的 Apple 设备使用。这就是不应把它当作 VPN 来评分的原因。
这一设计把信息拆分到由不同公司运营的两跳中继上。Apple 运营第一跳,它能看到用户的地址,但看不到网站。合作伙伴运营第二跳,它能看到网站,但看不到用户。Apple 的运营方页面指出,这样一来,没有任何一方(包括 Apple)能看到用户浏览的细节。
| 跳 | 能否看到用户的 IP | 能否看到访问哪个网站 |
|---|---|---|
| 用户的 iPhone、iPad 或 Mac | 能 | 能 |
| 第一跳中继(Apple) | 能 | 不能 |
| 第二跳中继(合作伙伴网络,例如 Cloudflare 或 Akamai) | 不能 | 能 |
| 您的服务器 | 不能,只能看到中继 IP | 它本身就是该网站 |
Apple 运营方页面中的四句话会改变您对待这些地址的方式:
- 范围。“Private Relay 保护用户在 Safari 中的网页浏览、DNS 解析查询以及不安全的 http 应用流量。”中继 IP 并不意味着一定是 Safari 会话。发出明文 http 请求的应用也会以同样的方式到达。
- 地区。“Private Relay 会保留用户所在的地区,因此您的服务器可以信任其看到的 IP 地址所对应的地区。”2021 年的概述补充说,它“不允许用户伪装成从其他国家或地区连接”。
- 验证。“所有使用 Private Relay 的连接都会验证客户端是 iPhone、iPad 或 Mac,并且客户拥有有效的 iCloud+ 订阅。”
- 稳定性。“在用户与您的网站交互的浏览会话期间,中继 IP 地址将保持稳定。”
VPN 允许用户选择任意国家,并覆盖整台设备。Cloudflare 对自家产品也很坦率。它在发布 WARP 时写道:“从技术上讲,WARP 是一种 VPN。”下文会再讨论 WARP。
一个实际的陷阱:部分中继出口位于数据中心,因此托管标志可能会触发。我们查询 Apple 列表上的中继 172.224.226.1,返回 is_hosting: true。这就是中继会显示为数据中心 IP 的原因,也是一刀切地拦截托管 IP 会误伤 Apple 用户的原因。
在 Python 中将 IP 与 Apple 的列表匹配
把 CSV 加载为排好序的整数区间,每个 IP 版本一个列表,然后对其做二分查找。用条件请求刷新,如果下载失败或内容看起来不对,就保留上一份可用的副本。
这是我们在 2026-10-12 用 Python 3.9.6 实际运行的脚本,只使用标准库。
"""Match an IP against Apple's iCloud Private Relay egress list. Standard library only."""
import bisect, csv, ipaddress, os, tempfile, time, urllib.error, urllib.request
URL = "https://mask-api.icloud.com/egress-ip-ranges.csv"
CSV_PATH, ETAG_PATH, MIN_ROWS = "egress.csv", "egress.etag", 100_000
def load(path):
"""Parse the CSV into one sorted range list per IP version, then validate it."""
ranges = {4: [], 6: []}
with open(path, newline="") as f:
for row in csv.reader(f):
if len(row) != 5:
raise ValueError(f"bad row: {row}")
net = ipaddress.ip_network(row[0], strict=False)
ranges[net.version].append((int(net.network_address), int(net.broadcast_address), *row[:4]))
index = {}
for version, rs in ranges.items():
rs.sort()
if any(b[0] <= a[1] for a, b in zip(rs, rs[1:])):
raise ValueError(f"overlapping IPv{version} prefixes")
index[version] = ([r[0] for r in rs], rs)
return index, len(ranges[4]) + len(ranges[6])
def refresh(index=None, rows=0):
"""Fetch a new copy only if it changed. On any failure, keep serving the last good one."""
headers = {}
if index and os.path.exists(ETAG_PATH):
headers["If-None-Match"] = open(ETAG_PATH).read().strip()
fd, tmp = tempfile.mkstemp(dir=".", suffix=".part")
os.close(fd)
try:
with urllib.request.urlopen(urllib.request.Request(URL, headers=headers), timeout=60) as resp:
with open(tmp, "wb") as out:
out.write(resp.read())
etag = resp.headers.get("ETag", "")
new_index, new_rows = load(tmp)
if new_rows < max(MIN_ROWS, 0.9 * rows):
raise ValueError(f"only {new_rows} rows, keeping the old file")
os.replace(tmp, CSV_PATH) # atomic swap
with open(ETAG_PATH, "w") as f:
f.write(etag)
print(f"downloaded new list: {new_rows:,} prefixes")
return new_index, new_rows
except urllib.error.HTTPError as e:
print("not modified, keeping current list" if e.code == 304 else f"refresh failed: {e}")
except Exception as e:
print(f"refresh failed: {e}")
finally:
if os.path.exists(tmp):
os.remove(tmp)
return index, rows
def match(index, ip):
"""Return Apple's row for a relay egress IP, or None."""
try:
addr = ipaddress.ip_address(ip.strip())
except (ValueError, AttributeError):
return None
if addr.version == 6 and addr.ipv4_mapped:
addr = addr.ipv4_mapped # ::ffff:104.28.46.99 becomes 104.28.46.99
starts, rs = index[addr.version]
n = int(addr)
i = bisect.bisect_right(starts, n) - 1
if i >= 0 and n <= rs[i][1]:
return dict(zip(("prefix", "country", "region", "city"), rs[i][2:]))
return None
if __name__ == "__main__":
t0 = time.time()
index, rows = load(CSV_PATH) if os.path.exists(CSV_PATH) else (None, 0)
index, rows = refresh(index, rows)
print(f"{rows:,} prefixes ready in {time.time() - t0:.1f}s")
for ip in ["104.28.46.99", "172.224.226.1", "2a02:26f7:c880::1", "::ffff:104.28.28.41",
"162.159.192.1", "102.129.235.17", "not-an-ip"]:
print(f"{ip:22} {match(index, ip)}")
第一次运行在 09:41 UTC,下载了文件并输出:
downloaded new list: 285,091 prefixes
285,091 prefixes ready in 12.8s
104.28.46.99 {'prefix': '104.28.46.99/32', 'country': 'ZM', 'region': '', 'city': 'Lusaka'}
172.224.226.1 {'prefix': '172.224.226.0/27', 'country': 'GB', 'region': 'GB-EN', 'city': 'London'}
2a02:26f7:c880::1 {'prefix': '2a02:26f7:c880::/54', 'country': 'GB', 'region': 'GB-EN', 'city': 'London'}
::ffff:104.28.28.41 {'prefix': '104.28.28.41/32', 'country': 'AU', 'region': 'AU-SA', 'city': 'Adelaide'}
162.159.192.1 None
102.129.235.17 None
not-an-ip None
162.159.192.1 是 WARP 的连接地址,102.129.235.17 是一台商业 VPN 服务器,因此两者都不应匹配,结果也确实都没有匹配。我们还测试了失败路径:
- 文件未变化。第二次运行发送了保存的 ETag,收到 304,并输出 "not modified, keeping current list"。加载本地文件并建立索引耗时 4.3 秒,因此应在启动时建立一次索引,而不是每个请求都建。
- 下载出错。我们把
URL指向一个不存在的路径(Apple 的服务器返回 400)。另外,我们把最小行数调到高于实际行数。两次脚本都记录了失败,删除了临时文件,并继续用旧副本应答。 - 映射地址。
::ffff:104.28.28.41匹配到了它对应的 IPv4 行。双栈服务器常以这种形式记录 IPv4 客户端。
由于文件中没有重叠前缀,每次查询做一次二分查找就够了。加载器会拒绝今后任何含有重叠的文件,此时刷新会回退到上一份可用的副本。
如何识别 Cloudflare WARP,以及为什么没有列表
您无法把 WARP 与公开列表匹配,因为 Cloudflare 不公布这样的列表。WARP 只能由标注了已知网段的提供商识别,或在用户自己的设备上识别。
Cloudflare 的出口策略文档说得很直白:“Cloudflare 不公布 Cloudflare One Client 的出口 IP 段。”论坛帖子里流传的“WARP IP 段”其实是另一回事。Cloudflare 的防火墙指南谈到 162.159.192.0/24 时写道:“此 IP 用于消费者版 WARP 客户端(1.1.1.1 with WARP),Zero Trust 服务不需要它。”那是 WARP 应用连接的地址。您的 Web 服务器永远不会把这些地址视为客户端 IP。
网站能否通过其他途径获得用户的真实地址?在正常浏览中不能。Cloudflare 的 WARP 常见问题写道:“1.1.1.1 + WARP 会把您的原始 IP 地址替换为一个 Cloudflare IP,该 IP 稳定而准确地代表您的大致位置。无论网站是否在 Cloudflare 网络上,都会如此。”
同一份常见问题记录了两处泄露。“WARP 不代理 WebRTC 流量。”以及:“如果您授予某个网站访问麦克风或摄像头的权限,流量将绕过 WARP,您的原始 IP 地址将可见。”
在设备本身上,https://www.cloudflare.com/cdn-cgi/trace 会输出一个 warp= 字段。在我们这台未运行 WARP 的机器上,它显示 warp=off。只有打开该页面的人才能看到它,因此它有助于支持团队排查客户的连接问题,但对给访问者评分的服务器毫无帮助。
对于 Cloudflare 公布的 WARP 连接网段,我们的 API 返回 relay_provider: "Cloudflare WARP"。查询 162.159.192.1 返回 is_relay: true、relay_provider: "Cloudflare WARP"、is_hosting: true 和 is_anycast: true,评分为 24,动作为 allow。那是 WARP 应用连接的地址,而不是您的服务器会看到的访问者地址。
对于不在 Apple 列表上的 Cloudflare 地址,我们的 API 返回什么
不在 Apple 列表上的 Cloudflare 隐私网络出口地址,会被标注为 "Cloudflare";而 Cloudflare 公布的 WARP 连接网段会被标注为 "Cloudflare WARP"。以 104.28.210.10 为例。它与我们的两个 Apple 中继位于同一个 /16,但不在 Apple 的列表上。以下是我们在 2026-10-12 09:40 UTC 查询结果的精简副本,数值未经修改:
{
"ip": "104.28.210.10",
"asn": {
"asn": 13335,
"org": "CLOUDFLARENET - Cloudflare, Inc.",
"user_type": "consumer_privacy_network"
},
"geo": {
"country_code": "CA",
"city": "Toronto"
},
"detection": {
"is_vpn": false,
"is_hosting": false,
"is_relay": true,
"is_anonymous": false,
"relay_provider": "Cloudflare"
},
"scoring": {
"fraud_score": 9,
"recommended_action": "allow",
"detection_methods": ["relay_ip"]
}
}
| IP | 是否在 Apple 列表上? | relay_provider | 其他字段 | 评分、动作、方法 |
|---|---|---|---|---|
| 104.28.210.10 | 否 | Cloudflare | AS13335, consumer_privacy_network, is_vpn false, is_hosting false | 9, allow, relay_ip |
| 104.28.28.41 | 是(AU,Adelaide) | iCloud Private Relay | AS13335, consumer_privacy_network | 9, allow, relay_ip |
| 162.159.192.1 | 否(WARP 连接地址) | Cloudflare WARP | is_hosting true, is_anycast true | 24, allow, datacenter_ip + no_ptr_datacenter + relay_ip |
| 102.129.235.17(VPN,作对比) | 否 | 无 | is_vpn true, is_anonymous true | 92, block, known_vpn_server + openvpn_open + ipsec_open |
请把 "Cloudflare" 理解为“一个未归属于 Apple 的 Cloudflare 消费者隐私出口地址”。它并不表示已确认的 WARP 用户,我们也不这样声称。我们的 API 参考目前只列出两个 relay_provider 值:“iCloud Private Relay” 和 “Cloudflare WARP”,因此第三个值目前尚未写入文档。我们已请后端团队补充文档。
有用的结论在前两行。在同一个 Cloudflare /16 内,精确的 CSV 匹配把 Apple 的中继(104.28.28.41)与其他 Cloudflare 隐私出口(104.28.210.10)区分开来。我们的标签在两者上都与 Apple 的列表一致。两者都评分 9、动作为 allow,所以无论哪种情况,您的策略都一样。VPN 那一行同样没有提供商名称:我们的探测发现了它,但它不在我们掌握的任何提供商列表上,这就是 VPN 可能无法被识别出名称的原因。
Private Relay 与 WARP 对比
| 问题 | iCloud Private Relay | Cloudflare WARP |
|---|---|---|
| 运营方 | Apple,第二跳中继由合作伙伴网络运营 | Cloudflare |
| 谁可以使用 | 使用通过验证的 iPhone、iPad 或 Mac 的 iCloud+ 订阅用户 | 任何安装免费 1.1.1.1 应用的人 |
| 覆盖范围 | Safari、DNS 查询、不安全的 http 应用流量 | 设备的流量,但 WebRTC 以及被授予摄像头或麦克风权限的网站除外 |
| 公开出口列表 | 有,Apple 的 CSV | 无 |
| 位置 | 保留地区;默认是粗略的城市级位置,用户可选择更宽泛的范围 | 一个代表用户大致位置的 Cloudflare IP |
| 服务器如何识别 | 与 Apple 的 CSV 精确匹配,或使用提供商的中继标志 | 只能依靠提供商的标签 |
两者都可能位于 AS13335 上,因此仅凭网络无法区分其中任何一个。
我们对中继 IP 的查询结果
在我们的查询中,Private Relay 地址被识别为中继,而不是匿名或 VPN,在没有其他证据的情况下会落入 allow。我们端到端追踪了 104.28.46.99。Apple 的记录显示为赞比亚卢萨卡。下面是带密钥发送时的请求:
curl https://api.geoiphub.com/v1/lookup/104.28.46.99 \
-H "x-api-key: YOUR_API_KEY"
我们在 2026-10-12 09:40 UTC 不带密钥运行了它,API 允许少量这样的使用。以下是响应的精简副本,数值未经修改:
{
"ip": "104.28.46.99",
"asn": {
"asn": 13335,
"org": "CLOUDFLARENET - Cloudflare, Inc.",
"asn_type": "unknown",
"user_type": "consumer_privacy_network"
},
"geo": {
"country_code": "AO",
"region": "Luanda",
"city": "Luanda",
"geo_confidence": 0.8
},
"detection": {
"is_proxy": false,
"is_vpn": false,
"is_tor": false,
"is_hosting": false,
"is_relay": true,
"is_anonymous": false,
"anonymity_level": "medium",
"relay_provider": "iCloud Private Relay"
},
"scoring": {
"fraud_score": 9,
"recommended_action": "allow",
"detection_methods": ["relay_ip"]
}
}
中继被识别出名称,is_vpn 和 is_anonymous 均为 false,scoring.detection_methods 显示唯一触发的信号:relay_ip。评分为 9,因此动作为 allow。地理定位显示为安哥拉,与 Apple 的记录相矛盾;我们将在下一节讨论这一点。对这个地址的决定是:放行,把它当作共享地址进行限速,并以 Apple 的记录作为其位置。
以下是其他中继与一个真实 VPN 的对比:
| IP | Apple 的记录 | 我们在 2026-10-12 的结果 |
|---|---|---|
| 172.224.226.1 | GB, GB-EN, London | AS36183 Akamai,asn_type hosting;is_relay true,iCloud Private Relay,is_hosting true;评分 24,allow;datacenter_ip、no_ptr_datacenter、relay_ip;geo GB,London |
| 104.28.28.41 | AU, AU-SA, Adelaide | AS13335;is_relay true,iCloud Private Relay;评分 9,allow;relay_ip;geo AU,Sydney,0.8 |
| 102.129.235.17(VPN) | 不在列表上 | AS834 IPXO;is_vpn true,is_anonymous true;评分 92,block;known_vpn_server、openvpn_open、ipsec_open |
中继标志不会降低评分,反而会增加评分。在 104.28.46.99 上,relay_ip 是 detection_methods 中唯一的条目,因此 9 分全部来自它。172.224.226.1 评分 24,因为另外还触发了两个数据中心信号,距离 allow 的上限 25 只差一分。所以在没有其他证据的情况下,中继会落入 allow。如果有其他对该地址不利的因素,例如被列入滥用名单,评分就会上升,动作可能变为 review。评分的构成方式页面列出了各项信号。
API 会标注中继。Apple 的 CSV 是您的独立核对手段,上面的匹配器无需依赖我们即可运行。把中继当作 VPN 来评分,是 VPN 检测误报中的典型案例。
为什么 Private Relay 用户显示的城市不对,我们的数据也不例外
中继 IP 只保证用户所在的地区,默认情况下给出粗略的城市级位置。中继 IP 唯一权威的位置是 Apple 自己的记录,而我们的数据库并不总是与之一致。
Apple 的运营方页面称,中继 IP “默认准确代表客户端粗略的城市级位置”。用户可以把范围放宽。Apple 当前的 iPhone 使用手册列出了两个 IP 地址位置选项:“保持大致位置”(Maintain General Location)和“使用国家/地区和时区”(Use Country and Time Zone)。2021 年的概述对它们做了说明。第一个选项选取的地址“映射到大致城市级的区域,与用户实际连接的位置一致”。第二个选项选取的地址“分布在更宽泛、更偏区域性的范围内”,并且“所有中继 IP 地址仍会映射到用户原本所在的国家和时区”。
我们把三个中继的地理定位结果与 Apple 的记录进行了比较:
| IP | Apple 的记录 | 我们的地理定位 | 是否一致? |
|---|---|---|---|
| 104.28.46.99 | ZM,Lusaka | AO,Luanda(geo_confidence 0.8) | 否,国家不同 |
| 104.28.28.41 | AU, AU-SA, Adelaide | AU,Sydney(geo_confidence 0.8) | 国家一致,城市不一致 |
| 172.224.226.1 | GB, GB-EN, London | GB,London | 是 |
三个中有两个不一致。赞比亚对安哥拉属于国家级偏差,正是那种会触发许可或制裁规则的错误。阿德莱德对悉尼,国家对了,城市错了。三个 IP 算不上基准测试,但足以确立一条规则:对于中继 IP,位置应以 Apple 的记录为准,而不是任何地理数据库,包括我们自己的。按国家或地区做决策,把城市当作参考提示。我们已向后端团队记录了这两处不一致。
应该拦截 Private Relay 或 WARP 吗?放行,并对会话评分
不应该。Apple 会验证每一个中继客户端,并表示基于 IP 的反欺诈规则“可能需要调整”,因此请放行 Private Relay 流量,像对待共享的运营商地址一样对其限速,只在其他证据指向风险时才加强验证。
Apple 的运营方页面在这两点上都说得很直接:
"Traditional fraud detection that relies on IP addresses might need to be adjusted to ensure legitimate users aren't impacted."(依赖 IP 地址的传统欺诈检测可能需要调整,以确保合法用户不受影响。)
"Consider treating these addresses like larger carrier-grade NAT or enterprise IP addresses to better account for this type of traffic, since many Private Relay users may be assigned to a single relay IP address."(考虑像对待较大的运营商级 NAT 或企业 IP 地址那样对待这些地址,以更好地应对这类流量,因为许多 Private Relay 用户可能会被分配到同一个中继 IP 地址。)
Apple 还提供了验证页面的替代方案。它指出“常见的缓解措施包括 CAPTCHA 或直接拦截流量”,并表示“所有运行 iOS 16、iPadOS 16 或 macOS Monterey 及更高版本的 Apple 设备都支持 Private Access Tokens”,它让服务器能够在不识别用户身份的情况下确认设备是否合法。
欺诈者能利用中继吗?可以,但 Private Relay 需要一台 Apple 设备和付费的 iCloud+ 账户。Apple 表示,这项验证“旨在确保只有合法的 Apple 设备和信誉良好的账户才能使用 Private Relay”。这使它成为一种成本高昂的批量养号方式。WARP 是免费应用,因此对 WARP 会话,可以在其他信号上稍微加重权重,而不是拦截。更难处理的 IP 隐藏问题在别处,例如移动代理。
关于限速器还有一个细节:Apple 关于运营商级 NAT 的建议,说的是您如何对待这个地址,而不是某个标志。在三次中继查询中,我们的 threat.is_cgnat 都是 false。请改为依据 is_relay 或 CSV 匹配结果来处理共享地址。要检查您日志中的某个地址,可将其粘贴到免费的 IP 查询工具中。
| 您看到的情况 | 动作 | 原因 |
|---|---|---|
| IP 在 Apple 的 CSV 中或 is_relay 为 true,且没有其他风险证据 | 放行;按账户或会话限速,而不是按 IP | Apple 会验证设备和账户,许多用户共享同一个中继 IP |
| 中继或 WARP IP,加上有风险的账户信号(新账户、支付国家不在 IP 所在地区、注册速率异常) | 加强验证:在支持的情况下使用 Private Access Token,否则使用 2FA 或邮箱验证,而不是 CAPTCHA 墙 | IP 本身不提供证据,账户信号才是证据 |
| 同时落入 review 的中继 IP,例如因为它在滥用名单上 | 人工审核 | 该证据针对的是这个地址,而不是中继本身 |
| 被标注为 WARP 的 IP | 放行,并对会话评分 | 它免费且常见;它隐藏了用户,但并不能证明意图 |
| 针对中继流量的位置规则(许可、税务) | 依据 Apple 记录中的国家或地区决策,绝不依据城市 | Apple 保留地区;城市是粗略的,或因设置而更宽泛 |
本周可以在您自己的日志上做的三项检查:
- 统计被您拒之门外的中继用户。用上面的匹配器,把过去 30 天的注册、登录和拒绝记录与 Apple 的 CSV 关联。您的规则拒绝或质询了多少中继用户?
- 找出按 ASN 和托管 IP 设置的拦截。在您的规则中搜索 AS13335、AS36183 或
is_hosting。172.224.226.1 是一个is_hosting: true的中继,因此拦截托管 IP 会误伤中继用户。 - 检查按 IP 限额和城市级地理围栏。Apple 建议像对待运营商级 NAT 一样对待中继 IP,因此按一个家庭的规模设定的单 IP 限额会限制许多用户,而城市级围栏在粗略位置上会误判。
常见问题
如何知道 iCloud Private Relay 是否已开启?
在 iPhone 上,打开“设置”,轻点您的姓名,然后依次轻点 iCloud 和“专用代理”(Private Relay)。作为网站运营方,您看不到这项设置,只能看到 IP:如果它与 Apple 的出口列表匹配,该请求就来自 Private Relay。
iCloud Private Relay 是 VPN 吗?
不是。它只覆盖 Safari、DNS 以及不安全的 http 应用流量,让用户保持在自己所在的国家和地区,并且仅限订阅 iCloud+ 且通过验证的 Apple 设备使用。
Cloudflare WARP 会隐藏您的 IP 地址吗?
会。Cloudflare 表示,无论网站是否使用 Cloudflare,WARP 都会把原始 IP 替换为 Cloudflare 的 IP,但 WebRTC 流量以及被授予摄像头或麦克风权限的网站除外。
iCloud Private Relay 的 IP 地址列表在哪里?
Apple 在 mask-api.icloud.com/egress-ip-ranges.csv 公布该列表。2026 年 10 月 12 日,它包含 285,091 个 IPv4 和 IPv6 前缀,覆盖 235 个国家代码。
网站能看到 Private Relay 背后的真实 IP 吗?
按设计不能。网站只能看到中继 IP,只有 Apple 的第一跳中继能看到用户自己的地址。
应该拦截 iCloud Private Relay 吗?
不应该。Apple 表示,基于 IP 的反欺诈规则可能需要针对中继用户进行调整。放行它,像对待运营商级 NAT 一样对其限速,只在出现其他风险信号时才加强验证。
GeoIPHub API 背后的团队
由 GeoIPHub 团队撰写,即构建 GeoIPHub IP 情报 API 及其扫描器的团队。草稿在 AI 辅助下完成,并由团队编辑;除非标注为示例,API 示例均为针对线上 API 的真实查询。


