钉钉自定义机器人通过 Webhook 接收外部系统推送的群消息。真正接入时,难点通常不在发送一段 JSON,而在于先选对安全设置:自定义关键词验证消息内容,加签验证请求签名,IP 地址(段)限制请求来源。三者解决的是不同问题,不能只看“配置最简单”就直接上线。

本文以钉钉开放平台的“自定义机器人安全设置”文档为依据,逐项说明配置规则、请求侧实现、优势与局限,并给出从测试到生产的选型建议。自定义机器人面向群聊场景,不支持发送单聊消息;使用前需要先在目标群中完成机器人创建。

钉钉机器人消息接入安全设置详解:自定义关键词、加签与IP地址段怎么选?

图:三类安全设置分别对应内容校验、请求签名和网络来源限制,实际选择应结合消息风险与出口网络条件。

一、三种安全方式分别在校验什么

可以把安全设置理解为三道不同位置的门:

  • 自定义关键词:检查消息正文中是否出现预先配置的词,属于内容层过滤。

  • 加签:由发送端根据时间戳和 Secret 计算 HMAC-SHA256,钉钉据此验证请求是否被篡改以及是否来自掌握 Secret 的系统,属于请求层认证。

  • IP 地址(段):检查请求的公网出口 IP 是否在白名单或 CIDR 网段内,属于网络边界限制。

后台把它们列为三类安全设置类型。不同版本的管理界面可能在交互上略有差异,是否支持同时配置多项应以当前页面为准;不要把“可以配置”误解成“任何组合都自动更安全”,上线前要用真实 Webhook 做一次验证。

二、自定义关键词:最快上手,但不等于身份认证

工作规则

钉钉官方文档说明:最多可以设置 10 个关键词,发送的消息中至少包含其中 1 个关键词才会发送成功。例如设置“监控报警”,消息正文就需要出现这四个字。关键词匹配针对消息内容,通常适用于文本或 Markdown 的可见正文。

优势

  • 配置成本最低,不需要编写签名算法,也不依赖固定公网出口。

  • 排障直观:发送失败时先检查正文是否包含关键词即可。

  • 适合开发联调、低风险内部提醒,以及暂时无法改造发送程序的旧系统。

局限与风险

  • 关键词属于共享信息,拿到 Webhook 地址的人如果猜到关键词,仍可能构造消息。

  • 它只验证“内容像不像”,不验证请求来源,也不能防止消息在传输过程中被篡改。

  • 关键词过于通用会增加误放行概率;过于具体又可能导致业务文案调整后大量失败。

配置建议:测试阶段可以使用不易与普通聊天混淆的业务词,例如“订单异常通知”;生产环境不要只依赖关键词保护高敏感告警,也不要把 Secret、Webhook 或内部系统名直接放进关键词。

三、加签:生产环境更通用的安全基线

签名计算过程

加签是钉钉机器人与开发者服务之间的双向安全认证。官方规则是:取当前时间戳 timestamp(单位为毫秒)和机器人 Secret,按 timestamp + "\n" + secret 组成待签名字符串;使用 HMAC-SHA256 计算,再做 Base64 编码,最后对签名参数进行 URL Encode。请求调用时间与该时间戳的误差不能超过 1 小时。

计算结果中的 timestampsign 需要拼接到 Webhook URL 查询参数中。下面是 Python 3 的最小示例,Secret 只作占位展示:

import base64
import hashlib
import hmac
import time
import urllib.parse

timestamp = str(round(time.time() * 1000))
secret = "SECxxxxxxxxxxxxxxxxxxxxxxxx"
string_to_sign = f"{timestamp}\n{secret}"
digest = hmac.new(
    secret.encode("utf-8"),
    string_to_sign.encode("utf-8"),
    digestmod=hashlib.sha256,
).digest()
sign = urllib.parse.quote_plus(base64.b64encode(digest))
url = f"{webhook}&timestamp={timestamp}&sign={sign}"

注意示例中的 webhook 应是机器人原始 Webhook 地址,发送前再拼接参数;不要把真实 Secret 写入前端代码、日志或公共仓库。

优势

  • 能够验证发送端是否掌握 Secret,并对请求内容提供防篡改能力。

  • 不依赖固定 IP,云函数、弹性集群或多地部署更容易接入。

  • 只要各语言正确实现 HMAC-SHA256 和 URL Encode,就能在不同技术栈中复用。

局限与常见坑

  • 需要维护 Secret 的存储、轮换和权限;Secret 泄露后必须立即更换并回归验证。

  • 把秒级时间戳误写成毫秒级,或把换行符写错,都会导致签名校验失败。

  • Base64 后的签名必须 URL Encode;重复编码或漏编码同样会失败。

  • 服务器时钟漂移超过 1 小时会触发时间窗校验问题,应使用可靠的时间同步服务。

四、IP 地址(段):把网络边界纳入校验

配置 IP 地址(段)后,只有来自指定 IP 范围的请求才会被正常处理。这里填写的是开发者服务的出口公网 IP,不是内网地址。官方支持两种 IPv4 写法:

  • 1.1.1.1:单个出口公网 IP。

  • 1.1.1.0/24:使用 CIDR 表示一段网段。

目前官方文档明确说明暂不支持 IPv6 地址白名单。对于云服务器、企业 NAT 或固定代理出口,先在部署环境确认实际公网出口,再把最小必要范围加入白名单。

优势

  • 在网络层过滤未知来源,规则清晰,适合有固定出口的企业系统。

  • 不需要把关键词放进业务内容,也不需要在每个请求里计算签名。

  • 对“Webhook 地址意外泄露”有额外缓冲:来源 IP 不匹配时请求仍会被拦截。

局限与运维成本

  • 出口 IP 变化、云厂商扩缩容、跨地域部署或代理切换都会造成误拦截。

  • 放大网段虽然省事,但会扩大允许范围;应优先使用单 IP 或最小 CIDR。

  • IPv6 场景目前无法直接用该白名单策略覆盖,需要结合其他安全设置。

五、优劣势对照与选型建议

方式主要校验对象优点不足更适合
自定义关键词消息正文最快配置、无需改代码容易被猜测,不能证明来源测试、低风险内部通知
加签时间戳 + Secret + 请求签名防篡改,适配动态 IP需实现算法并管理 Secret公网服务、生产告警、跨云部署
IP 地址(段)出口公网 IP网络层拦截,规则直观依赖固定出口,暂不支持 IPv6自建机房、固定 NAT、企业专线

一个实用的决策顺序是:先判断消息风险,再确认出口网络是否固定,最后评估发送程序是否方便维护 Secret。低风险联调可以先用关键词;生产环境通常优先考虑加签;如果服务有稳定且可管理的公网出口,再按当前后台能力增加 IP 地址(段)限制。若页面只允许选择一种,就以实际界面规则为准,不要为了“看起来更安全”盲目扩大白名单。

六、接入排障:按校验层定位问题

  1. 关键词方式失败:检查正文是否真的包含配置词,尤其注意 Markdown、模板变量替换后是否改变了文案。

  2. 加签方式失败:确认时间戳是毫秒、待签名字符串只有一个换行、Secret 没有多余空格,并检查 Base64 结果是否只 URL Encode 一次。

  3. IP 方式失败:从部署机器查询实际公网出口,核对是否经过 NAT、代理或负载均衡;不要把 192.168.x.x10.x.x.x 等内网地址直接填入。

  4. 偶发失败:查看服务器时钟、网络出口和 Secret 轮换记录,避免只在应用日志中记录完整 Webhook URL。

七、上线前安全清单

  • 把 Webhook 和 Secret 放在环境变量或密钥管理系统中,禁止提交到 Git。

  • 为不同业务、不同环境创建独立机器人,避免一个泄露点影响全部通知链路。

  • 配置 IP 白名单时坚持最小范围,网段变更要有发布和回滚记录。

  • 对机器人返回码、失败次数和告警延迟做监控;轮换 Secret 后立即做一条真实消息回归。

  • 定期检查群成员、机器人管理员和 Webhook 使用范围,及时删除不再使用的机器人。

结语

自定义关键词解决“消息内容是否符合约定”,加签解决“请求是否由持有 Secret 的服务生成且未被篡改”,IP 地址(段)解决“请求是否来自允许的网络出口”。三种方式没有脱离场景的绝对优劣:关键词重在低门槛,加签重在通用性,IP 白名单重在网络边界。按照风险、出口和运维能力做选择,才能让钉钉机器人既能稳定送达,也不会把 Webhook 变成新的安全盲点。

官方参考:钉钉开放平台:自定义机器人安全设置