Repository navigation
fix: 双栈监听下识别 IPv4 映射的本地反代 - #7
Merged
Merged
Conversation
hub 默认监听 [::],IPv4 peer 以 ::ffff:a.b.c.d 的形式出现,behind_local_proxy 不认这种写法,于是 X-Forwarded-For 被整个忽略。容器里经 cloudflared、本机 nginx 连 127.0.0.1 都会命中:节点地址变成反代自己的地址,国家查询落空,登录与注册限流 所有访客共用一个桶。 client_ip 先对 peer 与转发地址做 to_canonical,再判断。 Fixes #6
CarlJia
referenced
this pull request
in CarlJia/monitor
Sep 15, 2026
- #2/P1: housekeeping 首轮跳过离线判定,消除重启后假离线告警 - #3/P1: 宿主函数加墙钟 deadline,堵住 host 调用循环绕过 fuel/timeout 的沙箱缺口 - #4: host_http_post 有界读取响应体(64 KiB 硬上限) - #5: db_restore 后重建插件 Registry - #7: 插件删除行+kv 清理单事务化 - #8: enable 失败回滚 enabled 并修面板徽标优先级 - #10: delete_node 级联清理 notification_log - #12: 解压炸弹防线补齐 4 类测试 - #13: settings GET 回显通知阈值默认值,读改写回环可闭环 - #16: http 响应写回抽纯函数并补 5 分支测试 - #17: 新增 DELETE kv 路由,前端 KvDialog 去除清空临时方案 - #18: DispatchEntry.result 枚举与文档对齐 - #19: 日志卡片选中插件被删后不再弹假 404
CarlJia
referenced
this pull request
in CarlJia/monitor
Sep 16, 2026
独立评审(7 路本地 + codex 对抗尝试)后的修复。P0/P1 全部经独立校验器确认。 阻断项: - #1/#4 wasm 在运行时上下文里被同步调用,宿主函数里的嵌套 block_on 会 panic;release 档 panic=abort 直接终止进程,启用财务插件即崩。 call_hook/call_json_hook 补 block_in_place(与 run_one 同一形态), call_plugin_json 去掉多余的外层 block_on。新增 run_blocking:只在多线程 运行时上包一层,纯同步/单线程路径直接跑。 - #2 SSRF 预检只覆盖首个 URL,而共享 client 默认跟随重定向(含 https->http 降级),任一公网开放重定向即可绕过。新增 App::plugin_http (Policy::none()),插件出网与宿主隔离。 - #7 注册表读锁横跨插件执行,插件回头发事件重入同一把锁会死锁。 dispatch_ticks/call_json/dispatch_one 改为只在取快照时借锁。 迁移与数据边界: - #5 删列闸门按 plugin_id 限定(不再被第三方插件的 node: 前缀打开)。 - #15 四条 DROP COLUMN 收进一个事务,完成判据与待删清单同源。 - #16 Db::open 补 version > SCHEMA_VERSION 守卫(与 check_backup 一致)。 - #17 GATED_VERSION 用绝对常量,不再随 SCHEMA_VERSION 漂移。 - #6 删列前记一行非默认值行数,运维在日志里看得到这次丢了什么。 - #18/#23 plugin_data 配额统一按字节,检查与写入同一事务(BEGIN IMMEDIATE)。 - #20 无到期字段的插件事件按 payload 内容哈希(FNV-1a)定键,不再永久去重。 - #21/#22 SSRF 预检的 DNS 解析与请求超时都按剩余预算收缩。 - #24 data_list/nodes_query 用各自的上限,放不下报 -6 而不是静默截断。 契约与文档: - #13/#14 插件端点先判加载状态(400)再判能力声明(404);错误体统一纯文本。 - #8/#9/#29 README 的 nodes_query 字段、data_list 格式、tick 周期按实现改写。 - #26 表单控件按字段名推断的规则写进协议(#27 同步修掉清空价格存成 0)。 - #25 破坏性 ABI/API 变更按 SemVer 升到 2.0.0,README 补升级说明。 - #28 tg-notify 错误码表补 -9 对应的 19。 测试与 CI: - #10 删除空测试体;#11 nodes_query 测试播种节点并断言在线状态。 - #19 插件 crate 接进 CI(独立 crate,根 cargo test 覆盖不到)。 - #12 插件区分「宿主查询失败」与「确实没有节点」,清理拿不到存活集合拒删。 - #3 抽出 plugin_http_fetch,http_post/http_get 不再逐行重复。 验证:hub 166 passed;finance-stats 8;tg-notify 3;web-admin build+lint。 Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
问题
hub 默认监听双栈
[::]:28080,IPv4 连接的 peer 地址是::ffff:a.b.c.d。behind_local_proxy只认 IPv6 的回环、ULA 与 link-local,不认 IPv4 映射地址,于是本地反代发来的X-Forwarded-For被整个忽略,client_ip返回反代自己的地址。受影响的部署:
proxy_pass http://127.0.0.1:28080后果有三处,都经
client_ip:connected from ::ffff:172.18.0.4修改
client_ip先对 peer 与X-Forwarded-For取到的地址做IpAddr::to_canonical,再判断。三个调用点(登录、agent 连接、agent 注册)一并修复。没有改为读取
CF-Connecting-IP:在 nginx/caddy 后面这个头会被原样转发,调用方可以自行伪造。测试
单元测试补了 IPv4 映射 peer 的断言,修改前失败,输出与 issue 中的地址一致。
端到端对比 1.0.0 与本分支,步骤相同:
compose(monitor + cloudflared,
enable_ipv6: true,真实 Cloudflare Tunnel),客户端一台走 IPv6、一台走 IPv4::ffff:172.18.0.3裸二进制
[::]+ nginx($proxy_add_x_forwarded_for),攻击者在 XFF 里伪造管理员地址直接暴露公网、无反代(回归检查):两版结果一致,伪造的 XFF 既不能锁定他人,也不能绕过自身的锁定。
Fixes #6