使用EdgeOne API 自动更新源站防护回源IP网段

2026-07-05 网站/博客搭建

2026-10-03 更新:本文改用腾讯云 EdgeOne 官方文档、官方 API 文档与各 CDN 厂商官方 IP 列表重写,删去原先的本机实测内容;接口名、字段名、限频与签名规则均抄自官方文档。

站点挂在 CDN 后面时,源站通常只放行 CDN 的回源网段——这就是 EdgeOne 的"源站防护"。它带来一个必须长期维护的东西:回源 IP 网段会变,而你的防火墙白名单不会自己变。手工维护迟早出事,本文按官方文档把自动化的接口、流程和坑讲清楚。

一、为什么这件事必须自动化

腾讯云 EdgeOne 官方文档把关键约束写得很明确:

  • 源站防护的本质是让 EdgeOne 只通过一组指定的回源 IP 网段访问源站;把这些网段加进源站防火墙白名单,可以降低攻击者绕过 EdgeOne 直接打源站的风险。
  • 回源 IP 网段会不定期变更(官方说明:非特殊情况下平均 3–6 个月更新一次),变更前 14 天、7 天、3 天、1 天会通过站内信、短信、邮件等一种或多种方式通知。
  • 收到通知后须在不超过 14 个自然日内完成更新;未按时更新时,EdgeOne 会按《源站防护启用特别约定》强制切换到最新版本,由此产生的回源失败等后果由用户承担。
  • 源站防护仅支持已绑定付费套餐的站点,免费版不支持。

也就是说,"等通知来了再手动改"是一条有截止日期的路径,而自动化的成本只是一次查询接口。

二、要用的官方接口(新版)

接口 作用 关键参数/字段
DescribeOriginACL 查询源站防护详情 入参 ZoneId;返回 CurrentOriginACL(EntireAddresses / Version / ActiveTime)与 NextOriginACL(Version / PlannedActiveTime / EntireAddresses / AddedAddresses / RemovedAddresses / NoChangeAddresses)
ConfirmOriginACLUpdate 确认已更新到最新网段 入参 ZoneId;确认后相关变更通知停止推送
EnableOriginACL 首次开启源站防护 单次可提交七层域名最多 200 个、四层代理最多 100 个,混合最多 200 个;可选 OriginACLFamily
ModifyOriginACL 对实例启用/关闭某个回源网段 单次上限同上,超出需分批
DisableOriginACL 关闭源站防护 关闭后资源不再仅使用源站防护提供的网段回源
DescribeAvailableOriginACLFamily 查询可配置的控制域 标准控制域(gaz / mlc / emc)与精简控制域(plat-*)的版本号与网段差异

官方给出的自动化建议就一句话:每三天轮询一次 DescribeOriginACL;如果 NextOriginACL 有返回值,就把最新回源 IP 网段同步到源站防火墙配置。

⚠️ 老接口不要再依赖:DescribeOriginProtection 的官方文档明确写着"自 2025 年 6 月 27 日起,旧版接口停止更新迭代,后续新增功能将仅在新版接口中提供"。它的入参形态也不同(ZoneIds 是复数数组,还有 Filters / Offset / Limit),两套接口混用很容易写出"看起来成功了但拿的是旧数据"的脚本。

限频:源站防护相关接口的文档标注默认请求频率限制为 20 次/秒;腾讯云 API 的限频维度是 API + 接入地域 + 子账号,超限时响应里会带 RequestLimitExceeded 错误码,正确处理方式是退避重试。(三天一次的轮询远远用不到这个量级,但批量对账时要注意。)

三、认证:用官方 SDK,别自己拼签名

腾讯云 API 走 TC3-HMAC-SHA256(签名方法 v3)。官方文档的四步是:

CanonicalRequest = HTTPRequestMethod + '\n' + CanonicalURI + '\n' + CanonicalQueryString + '\n'
                 + CanonicalHeaders + '\n' + SignedHeaders + '\n' + HashedRequestPayload

StringToSign     = Algorithm + '\n' + RequestTimestamp + '\n' + CredentialScope + '\n' + HashedCanonicalRequest

SecretDate    = HMAC_SHA256("TC3" + SecretKey, Date)
SecretService = HMAC_SHA256(SecretDate, Service)
SecretSigning = HMAC_SHA256(SecretService, "tc3_request")
Signature     = HexEncode(HMAC_SHA256(SecretSigning, StringToSign))

两个容易写错的地方(官方文档明确提示):

  • CredentialScope 的日期部分必须是 UTC+0 日期(由 X-TC-Timestamp 换算),写成服务器本地时区会在凌晨时段调用失败;
  • 请求时间戳与服务器时间的偏差不能超过 5 分钟,否则直接报签名过期。

官方 SDK 已经封装了签名与请求,官方也建议优先用 SDK。Python 侧就是:

pip install tencentcloud-sdk-python
from tencentcloud.common import credential
cred = credential.Credential("SecretId", "SecretKey")   # 建议从环境变量或密钥管理读取

查一次,看有没有新版

同一个动作也可以用 tccli 或裸 HTTP 调(Host: teo.tencentcloudapi.com、X-TC-Action: DescribeOriginACL、Version: 2022-09-01),但签名要自己算,不如直接用 SDK。

四、拿到网段之后落到哪里

4.1 防火墙:用一次下发替换整条链

白名单的本质是"除回源网段外,其余来源访问 80/443 一律拒绝"。逐条 iptables -A 的问题是:更新过程中会出现新旧规则并存的中间态(可能放行了不该放的,也可能误删了正在用的),而且几百条规则逐条执行很慢。

更稳的做法是按链一次性下发(iptables-restore 的原子替换语义),先放行回环与本地网段、再放行回源网段,两条 DROP 收尾:

# whitelist.rules —— 由同步脚本按最新网段生成(网段列表省略,示意结构)
*filter
:EDGEONE_WHITELIST - [0:0]
-A EDGEONE_WHITELIST -i lo -j RETURN
-A EDGEONE_WHITELIST -s <你的内网网段> -j RETURN
-A EDGEONE_WHITELIST -s <回源网段 1> -p tcp -m multiport --dports 80,443 -j ACCEPT
-A EDGEONE_WHITELIST -s <回源网段 1> -p udp -m udp --dport 443 -j ACCEPT
# …按网段展开…
-A EDGEONE_WHITELIST -p tcp -m multiport --dports 80,443 -j DROP
-A EDGEONE_WHITELIST -p udp -m udp --dport 443 -j DROP
COMMIT
# 原子替换整条链(示例链名,换成你自己的)
sudo iptables-restore --noflush /path/to/whitelist.rules
sudo ip6tables-restore --noflush /path/to/whitelist-v6.rules

规则条数的对账关系很简单:放行条数 = 网段数 × 2 + 2 条 DROP + 链首固定规则,脚本跑完就按这个核对,比"看日志没报错"可靠。

4.2 Web 服务器:回源网段同时也是"可信代理"

只有源站信任回源节点,才能从 X-Forwarded-For 里取到真实访客 IP,否则日志里记的是 CDN 节点的地址,封禁和统计都会失真。这件事在各家 Web 服务器上对应一组"可信代理/真实 IP"配置项(Caddy 的 trusted_proxies、nginx 的 set_real_ip_from 与 real_ip_header、Apache 的 RemoteIPInternalProxy 等),具体写法以各项目官方文档为准,本文不展开。要强调的是它的数据源和防火墙白名单是同一份网段列表,更新时必须一起同步,否则会出现"防火墙放行了新节点,但日志里还是看不到真实 IP"。

五、可套用的自动化流程

  1. 低频轮询(官方建议三天一次):调 DescribeOriginACL,比较返回的 Version 与本地记录;
  2. 判新版:NextOriginACL 非空即表示有可更新的网段,把 AddedAddresses / RemovedAddresses 打印出来留痕;
  3. 生成并应用:用新网段重新生成防火墙规则与可信代理配置,验证后下发;
  4. 自检:本地回源探测 + 站点可用性检查(含 CDN 入口与回源入口两条路径);
  5. 确认:调用 ConfirmOriginACLUpdate,停止变更通知;
  6. 失败即告警:任何一步失败都保留旧网段、发通知,别做"删了旧的再说"的操作。

⚠️ 关于切换期要不要新旧并存:官方文档只说明"有一个新版本、需要同步过去",并没有规定切换期如何处理新旧网段的关系。实践里常见的做法是更新前先把两个版本的网段都放行、确认生效后再收掉旧的(避免把自己关在门外),但这属于运维取舍,不是官方规定,实施前请结合自己的回滚能力判断。

六、其他 CDN 的同类做法(可对照复用)

这套"定期拉官方网段 → 更新白名单"的模式是通用做法,主流厂商都提供机器可读的权威清单:

  • Cloudflare:官方声明 cloudflare.com/ips/ 是当前 IP 范围的权威来源,另有纯文本端点 ips-v4 / ips-v6 与 API GET /ips(返回 ipv4_cidrs / ipv6_cidrs,带 etag 可用于判断是否变化),页面上还维护着 Update History。
  • AWS / CloudFront:ip-ranges.json 为机器可读端点(含 syncToken、createDate、prefixes、ipv6_prefixes;CloudFront 以 region=GLOBAL + service=CLOUDFRONT 标识),官方建议保存历次版本并比对发布时间来判断是否变化;若源站在 VPC 内,也可直接用 CloudFront 维护的 managed prefix list。
  • Fastly:GET /public-ip-list 无需鉴权,返回 addresses 与 ipv6_addresses;官方说明变更会提前以 "IP address announcement" 在状态页公告。
  • Google:gstatic.com/ipranges/goog.json(Google 拥有的地址)与 cloud.json(客户可用范围);官方另说明 Google API 的 IP 范围是动态分配、变化频繁。
  • Akamai:Origin IP ACL 维护一份"小而稳定"的 CIDR 列表,提供 .txt / .csv 下载,变更通过 Firewall Rules Notification 公告(官方示例里就有一批 IPv4 CIDR 被移除、需要提前更新防火墙)。

共同点是:厂商都会公布"官方清单",也都明确它会变。任何把它当一次性配置的做法都迟早过期。

七、几个真会绊住你的点

  • 两套接口混用:新版 DescribeOriginACL 用单数 ZoneId,旧版 DescribeOriginProtection 用复数 ZoneIds;旧版已停止迭代,迁移到新版。
  • 限频与错误码:超限返回 RequestLimitExceeded,要做退避重试,而不是把它当"没有新版"处理。
  • 签名时区:CredentialScope 的日期必须是 UTC;时间戳偏差超过 5 分钟会直接失败。
  • 首次启用的条数上限:单次七层 200 / 四层 100 / 合计 200,超出部分与新增资源用 ModifyOriginACL 分批处理。
  • 别把回源段当成"绝对安全":官方文档明确提示回源 IP 网段内也可能有少数不归属 EdgeOne 的 IP,建议叠加回源鉴权或双向认证做二次校验。
  • 白名单改动的自锁风险:规则下发过程中一旦把正在用的回源节点挡掉,站点会立刻 5xx。自检要覆盖"回源入口"这条路径,而不只是本地回环。

八、换成你的环境要改哪几处

本站用的 换成你的 始终不变的部分
EdgeOne(腾讯云,teo 产品) 其他 CDN:改成对应厂商的官方 IP 列表端点(见第六节) "定期拉官方清单 + 差量应用 + 自检确认"的流程
DescribeOriginACL + ZoneId 厂商对应的查询接口 / JSON 端点 版本号比对、变更留痕
自定义拒绝式白名单链 你的防火墙链名 / 安全组规则 放行回环与内网 → 放行回源段 → 目标端口 DROP 的顺序
七天/三天轮询 按厂商的公告周期调整(EdgeOne 官方建议三天) 低频轮询、失败告警、成功确认

参考来源