跳到主要内容

Tunnel Webhooks(反向隧道)

本文介绍如何在本地机器(不可从公网直接访问)上接收第三方 Webhook(例如 Stripe、GitHub 等)。

cert-ctrl 提供一个极简的 HTTPS 反向隧道方案:

  • cert-ctrl 客户端(agent)通过 WebSocket 连接到服务端:wss://<server>/api/tunnel
  • 服务端暴露一个公网 HTTPS 入口:https://<server>/hooks/<tunnel_id>
  • 外部请求进入后,会通过 WebSocket 隧道转发到你的客户端,再由客户端转发到你本地的 HTTP 服务

前置条件

  • 你已安装并登录 cert-ctrl 设备/客户端。
  • 你有一个本地 HTTP 服务用于处理 Webhook(例如 http://127.0.0.1:9000)。
  • 你的 cert-ctrl 客户端已启用 tunnel 功能(见下一节)。

启用 cert-ctrl 客户端 tunnel

tunnel 功能受配置开关控制。

示例配置(初版):

{
"enabled": false,
"remote_endpoint": "wss://api.cjj365.cc/api/tunnel",
"webhook_base_url": "https://hook.cjj365.cc/hooks",
"local_base_url": "http://127.0.0.1:9000",
"verify_tls": true,
"request_timeout_seconds": 45,
"ping_interval_seconds": 20,
"max_concurrent_requests": 12,
"max_payload_bytes": 5242880,
"header_allowlist": [
"content-type",
"user-agent"
]
}

开启方式:

  • 将 tunnel 配置中的 enabled 设为 true,或
  • 如果你使用 agent CLI,可通过 cert-ctrl conf set tunnel.enabled true 开启。

然后重启 agent(或按你的部署方式重新加载配置)。

获取 tunnel id

tunnel_id 会在 WebSocket 握手时由服务端分配。

  • 打开 Web UI 页面:隧道 Webhook 记录(Tunnel Webhook History)
  • 若客户端已连接,页面会显示 已连接的隧道 ID
  • 若显示 当前没有已连接的客户端,请启动/重启 agent 并刷新页面

发送 Webhook 请求

将当前连接的 tunnel_id 作为公网回调 URL 的一部分:

  • POST https://<server>/hooks/<tunnel_id>

示例(用 curl 自测):

curl -X POST "https://cjj365.cc/hooks/<tunnel_id>" \
-H "Content-Type: application/json" \
-d '{"hello":"world"}'

服务端响应会包含 x-tunnel-request-id 头,你可以用该 request id 在 Web UI 中定位对应记录。

常见问题

  • 当前没有已连接的客户端:没有活跃的 WebSocket 隧道会话。启动/重启 agent,并确认能访问 wss://<server>/api/tunnel
  • 502 Tunnel not connected:请求到达服务端,但指定的 tunnel_id 没有对应的活跃会话。
  • 504 Tunnel request timed out:客户端在 request_timeout_seconds 期限内没有返回响应。
  • 429 Tunnel at capacity:并发请求过多触发限流;可适当增加 max_concurrent_requests 或降低上游 Webhook 并发。