☰
三步跑通 Webhook 配置:自动部署、签名验证与文件接收完整实战
2026/11/4 2:20:01 网站建设 项目流程

三步跑通 Webhook 配置:自动部署、签名验证与文件接收完整实战

【免费下载链接】webhookwebhook is a lightweight incoming webhook server to run shell commands项目地址: https://gitcode.com/gh_mirrors/we/webhook

改完一行代码,你还要切到终端敲 SSH、git pull、重启服务?把这套动作交给 webhook 配置,推送事件一发生,服务器就自动跑起来。webhook 是一个用 Go 写的轻量级入站 webhook 服务器:它在自己的端口上监听 HTTP 请求,命中你设定的 trigger-rule 后,就执行 execute-command 指定的 shell 命令,还能把请求里的 payload、header 原样喂给脚本。你只负责写好 hook,其余交给它。

准备与快速上手

开始前确认下面几项即可,没有隐藏的运行时依赖:

项要求
系统Linux / macOS / FreeBSD / Windows
依赖单文件二进制,无额外依赖;从源码编译需 Go 1.21+
安装包管理器直接装,或git clone https://gitcode.com/gh_mirrors/we/webhook后go build
配置文件hooks.json(JSON)或hooks.yaml(YAML),二者选一

跑通第一次的最短路径只有三步:写一个最小 hook、启动服务、用 curl 打一下。下面这一整段可以直接抄:

cat > hooks.json <<'EOF' [ { "id": "deploy", "execute-command": "/var/scripts/redeploy.sh" } ] EOF webhook -hooks hooks.json -verbose # 另开一个终端触发: curl -X POST http://localhost:9000/hooks/deploy

服务默认监听 9000 端口,-verbose会把执行日志打到控制台,方便你确认命令确实被调起。

最小闭环跑通后,下面用一个更完整的真实场景把它串起来——代码托管平台一推送,就自动触发部署。

代码托管触发自动部署:从配置到验证

以 GitHub 为例,目标是「只有 master 分支、且签名校验通过的 push 才触发部署」。完整配置如下,这也是全文唯一的一段大配置,用到的字段我会顺着讲:

[ { "id": "redeploy", "execute-command": "/var/scripts/redeploy.sh", "response-message": "开始执行部署脚本", "pass-arguments-to-command": [ { "source": "payload", "name": "head_commit.id" }, { "source": "payload", "name": "pusher.name" } ], "trigger-rule": { "and": [ { "match": { "type": "payload-hmac-sha1", "secret": "mysecret", "parameter": { "source": "header", "name": "X-Hub-Signature" } } }, { "match": { "type": "value", "value": "refs/heads/master", "parameter": { "source": "payload", "name": "ref" } } } ] } } ]

id决定了 HTTP 端点,最终地址是http://yourserver:9000/hooks/redeploy。execute-command指定命中后要跑的命令;想固定执行目录,可以再加command-working-directory指向/var/www。response-message是命令执行前立刻返回给调用方的提示文案。pass-arguments-to-command把 payload 里的head_commit.id和pusher.name作为命令行参数依次追加给脚本,脚本内用$1、$2取到提交 ID 与推送者。真正的安全闸门在trigger-rule:这里的and要求两条都成立才触发,第一条用payload-hmac-sha1拿请求头X-Hub-Signature和共享密钥mysecret做 HMAC-SHA1 校验,挡住伪造请求;第二条比对payload.ref是否等于refs/heads/master,实现只认主分支。

触发与验证很简单:在 GitHub 仓库的 webhook 设置里把 URL 指向上面的端点、填入与secret一致的签名密钥,然后 push 一次 master,再 push 一次别的分支。第一次-verbose里应能看到命令被调起,第二次应当直接返回不触发。

第一个完整示例跑通后,接下来可以把 webhook 用在更多场景里,配置片段都很短,按需取用。

更多实用场景

💬 聊天工具里一行命令触发操作

在 Slack 里配一条 slash command,把它指向某个 hook,成员在频道敲一行命令就能触发后台脚本:

[ { "id": "slack-command", "execute-command": "/var/scripts/slack.sh", "response-message": "正在处理您的请求", "trigger-rule": { "match": { "type": "value", "value": "SLACK-TOKEN", "parameter": { "source": "payload", "name": "token" } } } } ]

这里把校验值放在 payload 的token字段,与 Slack 注册时生成的 token 比对,天然挡掉了外部调用。response-message会作为即时回执返回到频道,适合做「已收到,处理中」的反馈。

📦 接收并处理文件上传表单

有时请求里带的是文件而不是纯文本,pass-file-to-command会把它落成一个临时文件,文件名通过环境变量交给脚本:

[ { "id": "file-handler", "execute-command": "/bin/ls", "pass-file-to-command": [ { "source": "payload", "name": "binary", "envname": "FILE_DATA", "base64decode": true } ] } ]

base64decode为 true 时,base64 编码的二进制会先解码再写盘;脚本里用$FILE_DATA就能拿到文件路径,命令结束后临时文件自动清理。配合command-working-directory可以把文件固定落到某个目录。

解析 XML 节点与 multipart 表单

遇到 XML 请求体时,节点用点号路径访问:属性名带-前缀,元素文本带#前缀,同名元素按数组下标取。比如下面就能直接判断第一个 user 的 name 是否为 Jeff:

[ { "id": "xml-deploy", "execute-command": "/root/my-server/deploy.sh", "trigger-rule": { "match": { "type": "value", "parameter": { "source": "payload", "name": "app.users.user.0.-name" }, "value": "Jeff" } } } ]

而 Plex、JIRA 这类平台常用 multipart/form-data,且真正有用的 JSON 被塞在某个 part 里(比如叫payload)。这时在 hook 里加一条parse-parameters-as-json,指向{ "source": "payload", "name": "payload" },webhook 就会先解析它,之后你在 trigger-rule 里就能用payload.event这样的路径取值,而不必自己拆表单。更多取值方式可参考 引用请求值。

配置写得再多,也得清楚它内部到底怎么流转,排错时才不会慌。

原理速览

一次请求的内部路径是线性的:事件到达→规则校验→执行命令→返回响应。webhook 先把请求解析成 header、query、payload 三张表(payload 自动识别 JSON / 表单 / XML),再用trigger-rule逐条判定;只有规则满足,才通过命令行参数或环境变量把值交给execute-command执行,最后把response-message或命令输出写回响应体。理解这条链路后,规则不命中、参数取不到这两类问题基本都能对号入座。

原理清楚了,落到生产环境就要把安全和坑一次捋清楚。

🔒 生产环境要点

上线前过一遍这份清单,每条都是一句能直接落地的动作:

  • 🔑 签名密钥别硬编码进 hooks.json:用-template把配置当 Go 模板渲染,通过getenv从环境变量读取 secret,密钥与文件分离。
  • 🛡️ 默认允许任意 HTTP 方法,风险高:用http-methods把端点锁到POST,只放行必要的方法。
  • 📦 JSON 数组会被包进root:如果你的 payload 是一个数组,引用时一律写成root.0.xxx,否则取不到值。
  • 🧪 调试先开-verbose再看规则:命令没跑多半是 trigger-rule 没过,而不是命令本身的问题,先确认日志里规则判定结果。
  • 🌐 反代后 IP 白名单会失效:ip-whitelist在校验代理地址而非真实客户端,客户端 IP 限制要放到 Nginx/Apache 里做。
  • 🔄 改配置无需重启:加-hotreload自动监听 hooks 文件,或发kill -HUP <pid>热加载。

收尾与下一步

把签名校验、多分支路由和文件接收都接上之后,你可以继续往「事件网关」的方向走:用模板把密钥和端点做成可复用配置,用 HTTPS 和-socket把它藏到反代后面。字段全集见 Hook 定义,规则写法见 Hook 规则,从这两个文档出发基本能覆盖所有接入形态。

【免费下载链接】webhookwebhook is a lightweight incoming webhook server to run shell commands项目地址: https://gitcode.com/gh_mirrors/we/webhook

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询