GitHub webhook新增48个IP:放行之后仍要验证签名

Dev
浏览 4

PR已经打开,部署机器人却没有动静。请求可能在抵达应用前就被防火墙挡住了。GitHub在10月29日发布的webhook地址更新,影响的正是这条入站路径。

接收端需要补充三个地址段

新增CIDR是9.234.98.160/28、9.234.98.176/28和9.234.106.48/28。适用于github.com所有套餐的webhook投递,包括GitHub Enterprise Cloud。静态白名单应保留原有地址段,再加入这三个。

每个/28包含16个地址,合计48个。图中是使用Python ipaddress实际运行的本地计算结果,不是账号数或服务器数。GitHub表示,如果已通过GET /meta的hooks定期更新列表,本次新增无需额外修改。

自行可视化的Python实际计算结果:三个/28前缀合计包含48个地址。
自行可视化的Python实际计算结果:三个/28前缀合计包含48个地址。

IP放行与签名验证回答不同问题

白名单决定哪些来源网络能访问接收端。这里应使用hooks,而不是描述另一条runner通信路径的actions。接收事件与CI向外部API发起请求,方向并不相同。

放行后,还要使用该webhook配置的secret验证X-Hub-Signature-256。GitHub根据secret和正文生成HMAC-SHA256。接收端应使用原始字节计算,并通过hmac.compare_digest或crypto.timingSafeEqual等恒定时间方法比较。允许的IP不能替代这一步。

JSON含义相同,字节未必相同

把{"action":"opened"}重新序列化为{"action": "opened"}就会多出一个空格。含义不变,签名却可能不同。本地示例使用公开演示secret,相同字节得到True,增加空格后为False。这不是实际GitHub投递的抓取结果。

使用公开演示secret在本地执行的HMAC示例:一个空格也会改变字节。不是实际webhook抓取画面。
使用公开演示secret在本地执行的HMAC示例:一个空格也会改变字节。不是实际webhook抓取画面。

应先保留原始正文,再进行转换,并检查代理或框架是否改动了内容。把secret放进payload URL只会新增泄露路径。请通过安全的服务器配置读取它。

恢复投递时避免重复完成的工作

网络修复后,查看失败记录并重新投递必要项目。请求重新投递时,X-GitHub-Delivery仍与原来相同。应区分已完成工作和失败后可恢复工作;丢弃所有见过的ID,也可能阻止正常恢复。

GitHub建议在十秒内返回2XX,并将耗时工作交给队列。让签名验证、持久接收与可重试状态衔接起来。这三个CIDR也就成为到达、验证和完成整条路径的一部分。

来源与延伸阅读

GitHub Changelog · 2026-10-29

GitHub Docs · Meta API

GitHub Docs · Webhook signatures

GitHub Docs · Webhook best practices