Skip to content

fix(web-admin): NAT 节点优先显示连接来源的公网地址 - #9

Merged
stqfdyr merged 2 commits into
mainfrom
fix/nat-public-address
Sep 16, 2026
Merged

stqfdyr merged 2 commits into
mainfrom
fix/nat-public-address

Conversation

@stqfdyr

@stqfdyr stqfdyr commented Sep 15, 2026 •

Copy link
Copy Markdown
Collaborator

问题

agent 上报的是网卡地址。NAT 机器(例如 NAT LXC)的网卡上只有内网 IPv4,后台节点列表于是只显示 10.10.2.250 这类地址。

hub 其实已经记录了连接来源地址 ip(国家查询用的就是它),但后台只在 agent 未上报网卡地址时才使用。

修改

只改后台前端,agent 与 hub 不动,不引入外部查询。

web-admin/src/lib/api.ts 新增 addresses(),Admin.tsx 改为调用它:

  • 网卡 IPv4 属于内网(10/8、172.16/12、192.168/16)、CGNAT(100.64/10)、回环或链路本地,而来源是公网 IPv4 时,来源地址排在最前,内网地址随后,均可点击复制
  • hub 与节点同网或同机时,来源同样是本地地址,显示不变
  • 网卡本身是公网地址时,显示不变
  • 经 IPv6 连接时也不变:判断只覆盖 IPv4 一侧。网卡上的 IPv6 若是 ULA(fc00::/7)而来源是公网 IPv6,来源地址不会被提上来;NAT66 少见,未为此加分支
  • agent 未上报网卡地址时仍回退到来源地址

hub 对来源地址做过 to_canonical,IPv4 一律是点分形式,前端无需处理 ::ffff: 映射。

评论中提到的手工填写地址未做:需要新增数据库字段与表单,自动方案已覆盖 NAT 的情况。

测试

api.test.ts 补充断言:NAT(RFC 1918 与 CGNAT)、同网、同机、公网网卡、IPv6 连接、旧版 agent、无来源地址、空节点。npm test、npm run build 通过。

Fixes #1

agent 上报的是网卡地址,NAT 机器的网卡上只有内网 IPv4,面板因此只显示
10.x 之类的地址。hub 已记录连接来源地址 ip,此前只在 agent 未上报网卡地址
时使用。

网卡 IPv4 属于内网、CGNAT、回环或链路本地,而来源是公网 IPv4 时,来源地址
排在最前,内网地址随后,两者均可点击复制。hub 与节点同网时来源同样是内网
地址,显示不变。不引入任何外部查询。

Fixes #1
CarlJia referenced this pull request in CarlJia/monitor Sep 15, 2026
应用 code-review 拆分 findings #6/#9/#11/#14,纯机械搬移无逻辑变更:
- src/plugin.rs (1471) -> src/plugin/{mod,manifest,host,registry,test_util}.rs
- src/api.rs (3862) -> api.rs (2708) + api_plugins.rs (1183)
- src/db.rs (3119) -> db.rs (2575) + db_plugins.rs (565)
- Admin.tsx (2087) -> Admin.tsx (1638) + Plugins.tsx (476)
ip 为空而网卡地址存在时走的是 if (!ip) return reported 这一支,此前只有
空节点一例经过它。少了这道判断,末尾的 [ip] 会返回 [undefined]。
@stqfdyr
stqfdyr merged commit fde2981 into main Sep 16, 2026
1 check passed
@stqfdyr
stqfdyr deleted the fix/nat-public-address branch September 16, 2026 03:20
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>
stqfdyr added a commit to monitor-probe/monitor-document that referenced this pull request Sep 16, 2026
面板对 NAT 节点优先显示连接来源的公网地址(monitor-probe/monitor#9),这个地址
与限流用的是同一个值。没有 X-Forwarded-For 时它是代理地址,NAT 节点看不到公网
地址、国家码也查不出;本地反代前再套 CDN 时它是边缘地址,面板会把边缘地址当成
节点的公网地址显示。两处说明补上这一点。
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

【bug】lxc nat 获取到的ip是内网ip,不是公网ip。

1 participant