不能依赖ip白名单,因企业微信和钉钉webhook源ip不固定且官方不承诺稳定ip段;应采用签名验证(如timestamp+sign+secret/hmac-sha256)并在后端校验,nginx仅作反向代理与基础防护。

不能直接“只允许企业微信或钉钉机器人 IP 访问”,因为它们的 Webhook 请求**不固定源 IP**,且官方明确不公开、不承诺稳定 IP 段。硬写死 IP 列表不仅不可靠,还会导致消息推送失败。
为什么不能靠 IP 白名单?
企业微信和钉钉的 Webhook 发送端由其自建集群动态调度:
- 钉钉 Webhook:官方文档说明“发送请求的 IP 不固定,且不会提前告知”;实际观测中,同一 webhook 可能从不同出口 IP(如 10x.x.x.x、11x.x.x.x、12x.x.x.x 等)发起请求;
- 企业微信:Webhook 调用走的是微信服务器集群,IP 地址池庞大且动态轮换,未开放白名单 IP 段,也无 SLA 保证;
- 若强行配置静态 IP 白名单,一旦上游 IP 变更,Webhook 就静默失败,排查困难,生产环境风险极高。
真正可靠的做法:签名验证 + 请求来源识别
放弃 IP 控制,转而用协议层验证——这是官方推荐、生产验证过的安全方案:
由于微信的大热,为了更好的方便使用微信的用户查询一些信息,这篇文章是入门级的微信公众平台开发教程,需要的朋友可以参考下 这篇入门教程将引导你完成如下任务: 创建百度云平台应用启用微信公众平台开发模式获取订阅、文字、图片、语音、视频消息回复文本、图文及音乐消息程序开发
- 企业微信 Webhook:启用「加解密模式」或使用「access_token + timestamp + nonce + sign」四元组签名校验(需后端实现 SHA256 签名比对);
-
钉钉 Webhook:必须配置「加签」(即 secret),每次请求携带
timestamp和sign参数,服务端用 secret + timestamp 拼接再 HMAC-SHA256 计算并比对; - Nginx 层不参与鉴权,仅做反向代理或限流;真实校验逻辑放在后端服务(如 Python/Node.js/Java)中执行,校验通过才处理消息,否则返回 401;
- 可额外记录
X-Forwarded-For或$remote_addr用于审计,但不作为准入依据。
辅助加固:Nginx 层能做的安全补充
虽不依赖 IP,但可在 Nginx 配合后端提升整体防护水位:
- 限制请求方法:只放行
POST,拒绝GET/PUT等无关方法; - 限制请求体大小:
client_max_body_size 10m;防止恶意大 payload; - 开启请求头过滤:用
map或if拦截明显伪造的User-Agent(如不含 “DingTalk” 或 “WeCom” 字样且无必要 header); - 配合速率限制:
limit_req zone=webhook burst=5 nodelay;防止单个合法 webhook 被滥用或误触发雪崩。
错误但常见的“伪安全”配置(请避免)
以下写法看似严谨,实则失效且误导:
-
allow 110.120.130.0/24; deny all;—— 钉钉从未公布该网段,也从未承诺长期使用; -
if ($http_user_agent !~ "DingTalk") { return 403; }—— User-Agent 易伪造,毫无安全意义; - 用
geo模块匹配“疑似企业微信 IP” —— 无权威来源支撑,维护成本高、误拦率高。










