Memos 如何用 --webhook-private-network-allowlist 放行内网 Webhook 目的地?
【免费下载链接】memosOpen-source, self-hosted note-taking tool built for quick capture. Markdown-native, lightweight, and fully yours.项目地址: https://gitcode.com/GitHub_Trending/me/memos
在自建环境中,你经常希望 Memos 把 memo 变更事件推送到内网的自建服务(例如内部自动化脚本、通知网关),但 Memos 的 Webhook 投递默认拦截所有私有/保留 IP 目的地以防止 SSRF,这类 Webhook 会创建失败或投递失败。--webhook-private-network-allowlist启动参数(等价环境变量MEMOS_WEBHOOK_PRIVATE_NETWORK_ALLOWLIST)可以精确放行你需要的内网主机名、IP 或网段,而不用全局关闭私有网络防护。
默认拦截范围:哪些 Webhook 目的地会被拒
Memos 在发起 Webhook 连接时会在拨号阶段解析目标主机名并拒绝落入保留/私有地址段的目的地(internal/webhook/webhook.go 中的safeClient),该校验在 DNS 解析后直接连接已校验的 IP,因此也能抵御 DNS 重绑定。默认被拦截的地址段(internal/webhook/validate.go 中的reservedNetworks)包括:
0.0.0.0/8("本网络",实际拨号到本机)127.0.0.0/8(IPv4 环回)10.0.0.0/8、172.16.0.0/12、192.168.0.0/16(RFC-1918 私有地址)169.254.0.0/16(链路本地,含云环境 IMDS 的 169.254.169.254)::/128、::1/128、fc00::/7、fe80::/10(IPv6 未指定地址、环回、唯一本地、链路本地)
未放行的私有目的地在创建/更新 Webhook 时会被 API 拒绝(InvalidArgument:webhook URL must not resolve to a reserved or private IP address),即使绕过创建,投递时也会在拨号阶段报webhook: connection to reserved/private IP address is not allowed,并在日志中记录为Failed to dispatch webhook asynchronously告警。
配置允许列表
准备条件:Memos 已可正常启动。以 Docker 为例,README 给出的最小启动方式是:
docker run -d \ --name memos \ -p 5230:5230 \ -v ~/.memos:/var/opt/memos \ neosmemo/memos:stable在此基础上,给 Memos 服务端追加允许列表。两种等价的提供方式:
- 命令行参数(docs/configuration-provisioning.md 与 cmd/memos/main.go):
--webhook-private-network-allowlist hooks.internal,10.20.0.0/16- 环境变量
MEMOS_WEBHOOK_PRIVATE_NETWORK_ALLOWLIST(Docker 部署时可用-e注入,例如-e MEMOS_WEBHOOK_PRIVATE_NETWORK_ALLOWLIST=hooks.internal,10.20.0.0/16)。
条目格式规则(internal/webhook/validate.go 中ConfigurePrivateDestinationAllowlist的注释与实现):
- 每个条目必须是以下三者之一:精确主机名、单个 IP 地址、或 CIDR;
- 主机名按大小写不敏感匹配,条目两侧空白会被去除;
- 单个 IP 会被当作单地址 CIDR 处理;CIDR 会被规范化掩码到网络地址;
- 带作用域(zone)的 IP 地址(如
fe80::1%eth0)不支持,会报错; - 多个条目可以重复传参,也可以用逗号分隔;逗号分隔的写法在测试
TestPrivateWebhookAllowlistSplitsFlagAndEnvironmentForms(cmd/memos/main_test.go)中被验证:hooks.internal, 10.0.0.0/8与独立条目192.168.1.10会被拆分为三个条目。
只放行真正需要的目标:允许列表只对落入上述保留段的目的生效,公网目的地不受它影响。
启动时的校验行为
允许列表在启动阶段整体校验:只有当所有条目都合法时新策略才会生效;出现非法条目(空条目、带 zone 的 IP、无法解析的主机名等)时,启动会失败并输出形如webhook: invalid private destination allowlist entry "..."的错误,原策略保持不变(对全新进程而言即启动中止)。因此修改参数或环境变量后必须重启 Memos 进程才生效,改错了先根据启动报错修正条目,不要带着非法条目继续排查其他问题。
验证放行是否生效
- 在用户设置中通过 UI 或 API 创建一个指向内网服务的 Webhook(例如
http://hooks.internal/hook,该 URL 需落在你放行的主机名或网段内,且使用 http/https 协议)。创建成功即说明允许列表对该目的地已生效。 - 反向验证:再尝试创建一条指向未放行私有地址的 Webhook,应被拒绝并返回
webhook URL must not resolve to a reserved or private IP address。 - 触发一次 memo 相关事件,观察内网接收端是否收到 POST 请求。若投递仍失败,查看 Memos 日志中的
Failed to dispatch webhook asynchronously告警,确认报错是否为webhook: connection to reserved/private IP address is not allowed(目的地未放行)还是普通连接错误(网络不通等)。
与已弃用参数 --allow-private-webhooks 的关系
旧参数--allow-private-webhooks及环境变量MEMOS_ALLOW_PRIVATE_WEBHOOKS为升级兼容仍可使用,但已弃用:它会在启动时打印--allow-private-webhooks is deprecated and disables webhook private-network protection; use --webhook-private-network-allowlist警告,并把私有网络目的地防护整体关闭,而不是精确放行。从旧参数迁移时,按内网服务实际使用的主机名/IP 网段改写为--webhook-private-network-allowlist后移除旧参数。
限制
- 允许列表是进程级全局配置,对实例内所有用户的 Webhook 生效,无法按用户或按 Webhook 粒度配置;
- 条目只能是主机名、IP 或 CIDR,不支持子域名通配,新接入的内网主机需要补充条目并重启;
- 该校验只在拨号前按解析出的 IP 判断一次,不改变 Webhook 请求的超时、重试等投递行为。
【免费下载链接】memosOpen-source, self-hosted note-taking tool built for quick capture. Markdown-native, lightweight, and fully yours.项目地址: https://gitcode.com/GitHub_Trending/me/memos
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考