Files
NexusGate/NEXT-ROUND-NOTES.md
aaaamoooo 5cfc5bebd7
CI / test (push) Waiting to run
CI / anytls-smoke (push) Waiting to run
docs(v4): batch report for items 24/25 + notes entries as authored
2026-10-21 13:45:15 +00:00

24 KiB
Raw Permalink Blame History

amo 下一版修改清单

用户 2026-10-21 上线当晚起陆续口述,攒齐后统一施工。

0. 施工口径变更(2026-10-21 04:36 用户拍板)

Node 实现(server.js / lib / agent.js)冻结退役:本版起 Go 单一真源,只改 panel-go + agent-go + 共用前端,不再双写、不再对 Node 做 difftest;验收金标准改为冻结 Go 现状行为作回归基线。Node 代码留仓作历史与回滚参考,不删。

1. 客户页顶部加统计条(2026-10-21 03:53,用户附 3x-ui 截图)

照 3x-ui 客户端页顶部那排,在 amo「客户与订阅」页上部加统计条,六个数:

  • 客户端(总数)
  • 在线(当前在线数,沿用现有 3 分钟 presence 窗口口径)
  • 耗尽(流量已用满的客户数)
  • 即将耗尽(接近用满的客户数,阈值口径施工时对齐 3x-ui)
  • 关闭(已停用客户数)
  • 启用(已启用客户数)

出处:用户在路由器 3x-ui(:55889/rogue)客户端页截图,顶栏现网数字为 26 / 6 / 0 / 0 / 0 / 26。

2. 客户凭据改为全节点共用一套(2026-10-21 03:56,用户附 amo 凭据页截图)

现状(amo):凭据长在每个节点绑定上——同一客户在 HWSG / ZouSG-V6 / ZouSG-V4 / LEGJP-V4 / LEGJP-V6 各有一套不同的 UUID、密码、Reality Short ID。

目标(照 3x-ui):凭据收归客户级——一个客户一套 UUID + 密码 + Short ID,名下所有节点共用;节点绑定不再各存一套。

实证(2026-10-21 查用户 2026-10-20 发的路由器 3x-ui 备份库,只读):clients 表 uuid/password/sub_id 只存一份(email 唯一);client_inbounds 是纯关联表,无任何凭据列。26 个客户中 19 个挂了多个入站,最多的 rogue 挂 20 个入站、共用同一套凭据。此模型与日后 3x-ui→amo 正式迁移正好 1:1 对齐。

施工前要定的点:

  • 节点侧 Reality 密钥对是服务器身份,不动,仍按节点托管(keyStore)。
  • 存量不是问题:用户 2026-10-21 确认现网 amo 里服务器/客户/节点全是测试数据(随便加的),切换凭据模型时测试数据直接按新模型重建,无需收敛迁移;真实用户仍在 3x-ui 侧(待正式迁移)。

3. 内容区左右间距调小到与 3x-ui 一致(2026-10-21 04:02,用户附 amo 节点页 + 3x-ui 主机页对照图)

amo 各页主内容区两侧留白偏大;把左右间距(padding/最大宽度约束)调小,调到与 3x-ui 一样的贴边宽度。所有页面统一,不是一页一调。

4. 服务器页「核心版本」加真实探测(2026-10-21 04:11 用户)

现状:服务器页核心版本恒显"—"(agent 心跳没报这个字段)。 改法:agent 探测本机 sing-box 版本随心跳上报,面板落到核心版本列显示。 实现口径(已与用户对过内存账):版本探测只在 agent 启动 / 引擎安装更新 / 二进制文件变化时跑一次 sing-box version 并缓存,心跳只多带一个短字符串字段;不许每轮心跳起子进程。老 agent 无此字段时继续显"—",向后兼容。

5. 删除「延迟」(2026-10-21 04:12 用户)

服务器页的延迟列删掉,统计条里的"平均延迟"一并去掉;系统状态页如有同名占位同删。 理由(用户原话口径):延迟要不断探测上报、没什么用、还费内存——明确不做延迟探测功能,占位列也不要留。

6. 行操作小图标加悬停名称提示(2026-10-21 04:15,用户附客户行图标特写)

列表行内的功能小图标(二维码、详情、重置、编辑、删除等)鼠标悬停时显示对应功能名称(tooltip/title)。客户页先行,全站同类图标统一补齐。 样式照 3x-ui(用户 2026-10-21 附特写):黑底白字圆角气泡带小尖角、出现在图标上方;被悬停的图标本身带浅灰背景高亮。名称与 3x-ui 对齐:二维码 / 详情(i 图标)/ 重置流量(⇄ 图标)/ 编辑 / 删除。

7. 节点端口「范围内随机」保存后反复重掷(2026-10-21 04:19,用户附编辑节点截图)

现状:新建节点时入口端口为"范围内随机",分配到随机端口;若不手工改成固定,之后每次编辑该节点(哪怕只改其他参数)点保存,端口都会被重新随机分配成另一个——端口静默漂移,客户端随之失效。

要求:随机只在新建时掷一次;已分配的端口在后续编辑中必须保持不变,除非用户显式改端口模式/数值。实现口径施工时定(如:编辑既有节点时端口模式默认按已分配端口固定呈现),验收要点:编辑既有节点任意字段保存后端口逐字不变。

8. 中转模型与 3x-ui 不对齐:缺"A 入站经内网 IP 中转到 B 节点"(2026-10-21 04:26,用户附中转节点编辑截图)

现状:amo 的中转是"入口 → 出口设备"模型(转发拓扑 + 出口 SOCKS5),与 3x-ui 的"出站 + 路由规则"完全不同。 缺口:无法实现用户在 3x-ui 上的既有用法——A 服务器的入站节点通过内网 IP 直接中转到 B 服务器的节点(线路鸡 → 落地鸡内网中转)。 要求:下一版补齐这种中转形态(这是用户现网在用的模式,迁移前置之一)。

设计方向(2026-10-21 04:28 已与用户对过):出口目标二选一——① 受管设备(现状,面板管两边);② 新增"手动落地端点":填地址(内网 IP/域名)+ 端口 + 协议 + 凭据(VLESS=UUID、SS2022=密码、SOCKS5=账密),面板只在 A 侧生成出站+路由(sing-box outbound + route),B 侧不要求装 agent、可以是 3x-ui 的现成节点。凭据只存主控、随部署下发。 补充(用户 2026-10-21 确认的理解):第三方/别人提供的节点同样可作落地——只要有 IP+协议+ID+密码即可,来源不限(自家内网鸡、3x-ui 节点、别人给的节点都行);前提是 A 能直达该地址端口。一个 vless:// / ss:// 分享链接本身就含全这四样,施工时可顺带做"粘贴链接自动填表"。

9. 删除右上角头像圆图标(2026-10-21 04:34,用户附顶栏特写)

顶栏右侧的圆形头像(显用户名首字母"G")是纯装饰 span,无任何点击事件(退出登录在侧栏底部另有按钮)——删掉。已查证同排的「刷新」按钮有效(绑定 load() 重新拉数重渲染,与 45 秒自动刷新同一套),保留不动。

10. 删除顶栏全局搜索框(2026-10-21 04:39,用户附顶栏截图)

顶栏"搜索服务器、客户、节点…"输入框是写死 disabled 的摆设、无任何功能;且每页都有自己的可用搜索框,此框多余——删除(顶栏共用一处,删一处全站生效)。

11. 菜单与命名调整 + 页面合并(2026-10-21 04:47,用户附节点页全图)

  • 左侧菜单「客户与订阅」→ 改名「用户订阅」(页面标题/面包屑同步)
  • 左侧菜单「服务器」→ 改名「节点管理」
  • 左侧菜单「转发与节点」→ 改名「入站&出站」(页面标题/面包屑同步)
  • 该页「+ 新建节点」按钮 → 改为「添加入站」;页内计数文案「9 个节点」→「9 个入站」(同页其他"节点"计数文案同步对齐)
  • 左侧菜单「设置与运维」→ 改名「设置」
  • 「安装与命令」页面的全部内容合并进「设置」页面,合并后删除「安装与命令」页面(菜单项与路由一并摘除)

12. 核心版本显示为空——根因已明,下批再修(2026-10-21 11:52 用户定:小问题,下次一起修)

v2 上线后现网四台核心版本列全空。已查实根因:节点 sing-box 是自编版(agent-singbox.sh 固定 v1.13.21),构建未打版本戳,二进制 version 输出 sing-box version unknown,agent 探针按设计把 unknown 当无版本。代码链(探针→心跳→落库→渲染)无误。 已定修法(未施工):agent 探针解析为空时兜底读安装记录 /etc/nexusgate/sing-box/version;agent-singbox.sh 安装成功后写该记录(去 v 前缀);现网四台补写 1.13.21 即可(安装脚本写死的版本,有据)。长期根治:下次重编 sing-box 时打版本戳。

13. 删除系统状态页「最近活动」模块(2026-10-21 04:56,用户附截图)

首页(系统状态页)底部的「最近活动」面板整个删除(该面板是改版时为保旧功能补回的,用户现明确不要)。只删展示模块,后端活动/审计记录本身保留不动。

14. 设置页「任务队列」表格排紧凑(2026-10-21 04:58,用户附截图)

现状毛病:列宽分配失衡——任务 ID 被挤到换行两行、状态"已完成"竖排三行、时间两行,而错误列大片空白。 要求:重配列宽与换行——ID/状态/时间等短内容不换行、单行呈现;空白列不占大宽度;整表紧凑。合并进设置页后保持此排版。

15. 凭据页签删掉按绑定逐行的 Reality 公钥区块(2026-10-21 14:13 用户附截图)

用户原话:红框里的节点 Reality 公钥好像没什么意义,不需要显示出来,只需要显示上面的凭据就可以了。 处理:编辑客户「凭据」页签删除整个按绑定逐行列表(节点名/状态/协议/Reality 公钥+复制按钮),只保留订阅令牌 + 凭据(全部节点共用)三件套(UUID/密码/Reality Short ID)。仅前端展示删除:公钥数据本身(主控 keyStore 托管、订阅生成、部署下发)一律不动。

16. 节点表单加 REALITY 目标扫描器(2026-10-21 14:21 用户附 3x-ui 扫描器截图)

用户原话:查找目标点一下,就会扫描出很多可用的域名可以用,点一下使用即可,很方便。 规格(照 3x-ui 扫描器形态):

  • 入口:编辑/新建节点的 Reality 目标预设旁加「查找目标」按钮,打开扫描器弹窗。
  • 输入:域名 / IP / CIDR,可留空——留空则探测内置常用候选池(microsoft/google/nvidia/amazon/samsung/intel 等,与现有目标预设同源扩充)。
  • 探测:主控侧对每个候选做 TLS 握手,列表展示 目标/状态(可用与否)/TLS 版本/ALPN/密钥交换(须支持 X25519 或 X25519MLKEM768)/证书主域名(SAN)/延迟;不可用行给出简短原因。
  • 回填:每行「使用」按钮,点击即把该目标回填为节点的 Reality SNI / 目标地址与端口并关弹窗。
  • 注意:v1 与 3x-ui 一致在主控侧扫描,延迟/可达性是主控视角(路由器经代理出网,与海外节点的真实视角有偏差,UI 上不夸大表述);节点侧探测(走 agent job)留作二期,不在本条范围。

17. 节点编辑页显示 Reality 公钥+私钥(2026-10-21 14:22 用户附 3x-ui 入站安全页截图)

用户原话:之前用户页面删掉的那个公钥展示,把它和私钥一起和 3x-ui 加到对应的节点页面显示吧。 处理(与第 15 条配套):编辑节点弹窗(Reality 协议时)增加密钥对展示区:公钥、私钥各一行,带复制按钮,数据取自主控 keyStore 托管的该服务器密钥对。注意 amo 的密钥对是服务器级身份(同机多个 Reality 节点共用同一对),节点页显示的是其所属服务器的那一对,不要做成节点级新生成。本条只要求显示;是否加「换一对」(相当于 3x-ui 获取新证书,会触发该服务器全部 Reality 节点重部署+订阅公钥变更)本轮不做,用户未要求。 第 15 条相应修订:客户凭据页签删的是"按绑定逐行重复展示公钥"的区块;公钥信息自此只在节点页出现一份。

18. 入站监听钉死公网 IP,内网中转打不通(2026-10-21 15:04 实测确诊;同日已热修上线并真机验收:commit aa2ee62,路由器面板已换装(旧二进制备份 .bak-hotfix-pre),PPFL1-SK5 重部署后 ss 见 0.0.0.0:47814,纯 amo 中转链实测通、出口正确。aa2ee62 尚未推 Gitea,随下一批一并推。)

证据:用户 PPF 两机内网中转(L3 入口 VLESS → 手动落地 L1 的 SOCKS5 入站,落地地址填内网 10.240.64.2:47814)在 amo 不通;同一对机器在原版 3x-ui 正常(xray 入站默认听全部地址)。L1 本机 ss 实测:47814 只绑公网 IP 140.235.229.19,未绑 0.0.0.0/内网地址,进程为 nexusgate-sing-box(节点本身部署成功)。 根因:panel-go/protocols.go listenAddress() 在 ipv4 模式返回服务器登记的 PublicAddress(ipv6 模式同理返回 PublicAddressV6),入站只听公网网卡,内网地址无人监听。 修法(2026-10-21 15:07 用户定现在热修;15:09 范围终版):默认监听全改通配——ipv4→0.0.0.0、ipv6→"::"、dual→"::"(不变);显式 BindAddress 覆盖保留。v6 也改通配的理由(用户原话):有的节点鸡有很多个 v6 公网地址,只绑登记的那一个会漏掉其余 v6 地址上的连接。代价用户已知并接受:通配 v6 套接字在 Linux 默认会顺带收 v4 映射连接,仅 v6 节点事实上 v4 也可达。改动在主控侧 listenAddress()(BuildNodeResource/BuildNodeExitResource 共用),agent 无需改;换面板后对节点重新部署即生效。

19. SOCKS5 用户名上收到客户共用凭据区(2026-10-21 15:42 用户指认,与第 15 条配套)

现状:客户的 SOCKS5 用户名(ng:cus_<客户ID>,即 NodeEmail)目前仅在客户凭据页签的"按绑定逐行"区块里随节点行显示(如 PPFL1-SK5 行),而该区块第 15 条要删。删后此用户名将无任何界面可见,但手动落地端点填表等场景必须人读它(用户本次中转测试就靠抄它)。 处理:删绑定区块时,把「用户名」作为第四行加进凭据页签上部的共用凭据区(UUID / 密码 / ShortID / 用户名),带复制按钮;值由 ng:+客户ID 确定性生成,纯展示、无新存储。订阅与入站生成逻辑不变。

20. 入站先建后绑:放开"必须先分配客户才能部署"(2026-10-21 16:11 用户提出,方案已拍板)

现状:orchestrator.go 部署校验写死 len(activeNodeClients)==0 时 400 拒绝("请先给节点分配至少一个客户再部署");节点能建能存,卡的是部署/启用。改成 3x-ui 式:先把入站建起来部署,关联客户随时增减(绑定变更本来就会触发重新部署)。 方案(用户 18:01 按推荐方案确认):删除该校验,零客户节点可部署(VLESS/SS/AnyTLS/Hysteria2 等空用户只是无人能连,无副作用);唯 socks5-auth 例外保留拦截——sing-box 的 socks 入站在 users 为空时不做认证=无密码开放代理(xray 空账号是拒绝,语义不同),且监听已改通配、公网可达,拦截提示语写明此原因。 验收:零客户建一个 VLESS 节点部署成功且在节点机监听;随后绑客户自动重新部署可连;零客户建 socks5-auth 节点部署被拦且提示正确;绑客户后部署成功。

21. SOCKS5 节点改固定账号密码(3x-ui 式,入站级)(2026-10-21 18:06 用户拍板)

用户原话:socks5 节点改成 3x-ui 那样固定的账号和密码,直接在入站里固定;不然多人共享同一个内网中转的 socks5 节点,流量会全部算在同一个用户名下。 诊断(已核代码):现模型 socks5-auth 入站 users 按绑定客户逐个派生(ng:cus_+共用密码),但中转链入口侧出站只有一组静态 ExitCredentials,全体客户的流量到落地侧都以那一组身份认证,落地侧"按人分账"是假的、全记一人头上(还会误触其限额)。入口侧才是真分账点(客户各自 UUID 认证)。 改法:

  • 节点(协议=socks5-auth)新增入站级固定 socksUser/socksPassword:建节点时可填、留空自动生成随机对;节点编辑表单在 socks 协议时显示这两项(可改、带复制);入站 users 只放这一组。
  • 订阅:socks 节点链接携带这组固定账号密码(所有绑定客户同一份),绑定只控制订阅里出不出现该节点,不再派生凭据。
  • 记账:该固定账号的流量记为节点级(不归任何客户);面板展示口径随之调整,别再把落地 socks 流量摊给客户。中转链的按人记账在入口侧完成(现状已如此)。
  • 存量:现网 socks 节点(PPFL1-SK5 等,测试数据)迁移时生成一组固定凭据替换 users;入口手动落地端点里填的 ng 账号随之作废,改填节点固定账号(文档/提示同步)。 连带修订:
  • 第 19 条作废(被本条取代):客户凭据区不再加"用户名"行——socks 用户名从此在节点上,客户凭据页签的绑定区块可径直删除,无需上收。
  • 第 20 条修订:socks5-auth 的零客户拦截例外取消——入站恒有固定账号,不存在空 users 变开放代理的问题,先建后绑对全部协议一致放开。

22. 面板切菜单慢:每请求全量克隆的成本(2026-10-21 18:12 用户报,晚间实测定位)

现象:路由器上点菜单约 3 秒才切换;3x-ui 同机同路(内网/隧道)都快。 实测证据(已逐项排除):DB 文件仅 225KB;两条访问路径都慢(非隧道问题);favicon(同进程静态文件)6–21ms 而全部 /api 接口 250–1560ms 且与响应大小无关(1.2KB 的 system 也要约 1s);放宽 GOMEMLIMIT 28MiB→64MiB、GOGC 50→100 无改善(GC 无关,已恢复原参数,RSS 回 14MB 级);SIGQUIT 协程转储无空转循环(全在 IO/通道等待);整机 load 约 3(4 核),面板单请求成本高是主因、整机繁忙是放大器。 机制:每个 admin GET 请求至少两次全量 Snapshot()——RequireAdmin 为找一个用户克隆整库一次,handler 再克隆一次;Clone() 走 JSON marshal+unmarshal 全量往返;切一页 = 2–5 个这种请求串行排队(同一把 store 锁,还要和 agent 心跳的 Transaction 克隆+落盘竞争)。3x-ui 每请求只做索引查询,故同机快。 修法(下一批,性能专项):

  1. RequireAdmin 不再全量克隆找用户:用户表小规模缓存/按会话直接映射,请求级只克隆一次并在 handler 间共享 snapshot。
  2. 读路径去全量 JSON 往返:以不可变快照+按需部分解析或写时复制替代 Clone() 的全量 marshal/unmarshal(保数据文件格式与事务语义不变,金标准必须全过)。
  3. 前端切页不重拉全量:servers/nodes/customers 等基础数据做页间缓存(带失效点:写操作后失效),渲染不等全量 Promise.all 才上屏。 验收口径:路由器真机、同数据量下 devtools 复测,常用页切换的接口耗时回到几十 ms 级;RSS 不回涨(保持 28MiB/50 参数)。 附带教训(已发生):给用户的 sed 命令里 .* 被其客户端吞成 .,把 GOMEMLIMIT 改成 96MiB8MiB 导致 Go 运行时启动崩溃循环——已恢复;今后改值命令只用全字面替换,不用通配。

23. 绑定变更合并下发:连续加人只重启一次(2026-10-21 18:34 用户提出、18:36 拍板并入本批)

现状(已核代码):给节点分配/移除客户(assignCustomer/unassignCustomer)只要节点非草稿就立刻 RebuildNode 并排 apply_resource 任务,agent 重写 sing-box 配置重启生效——每加/减一个人,该节点全体用户断一次重连;连加十人重启十次。sing-box 无动态加人接口,单次重启消不掉,只能合并。 改法:绑定类变更触发的重建按下发合并——同一节点在短窗口(10 秒量级)内的多次 RebuildNode 只产生一次 apply_resource,以窗口结束时的最终状态为准。 约束:①手动点部署(/api/nodes/:id/deploy)保持立即执行,不进合并窗口;②删除/移除流程语义不变,窗口内节点被删除时待发 apply 必须正确作废、不许复活;③面板在窗口内重启不能把节点卡在未下发状态(待发状态可落盘或启动对账补发,二选一并在报告注明);④凭据重置等其他触发 RebuildNode 的路径按同一合并口径(按节点合并即可)。 验收:同一节点快速连加 5 个客户,最终只执行 1 次 apply_resource 且 5 人齐全;窗口内删节点不复活;手动部署仍立即;既有测试与金标准不回归。 口径补充(同日用户问答确认):合并窗口为固定窗口(从该节点第一次待发变更起算,不滑动延长);代价=新加入用户最多晚约 10 秒 + 一次 apply 时间才能连通该节点,窗口内老配置照常服务、老用户无感。此代价用户已知悉并接受。

24. 列表页勾选是空壳:补齐批量操作(2026-10-21 20:55 用户实测指出)

现象(用户附 3x-ui 对照图):3x-ui 勾选行后顶部出现「已选 N 项 + 删除」,可一键删除全部选中;amo 三个列表页(节点管理/入站&出站/用户订阅)的行勾选框与表头全选都在,全选也能勾上,但选中后界面毫无变化、无任何批量动作可用。 已核代码(public/app.js):data-row-check 渲染在 servers/customers/nodes 三页;唯一的 data-check-all 处理只是把全选状态镜像到每行 checkbox(约 1426 行);row-check 本身无 change 处理、全站无任何代码读取勾选集合(grep 无 已选/bulk 字样)。 修法:每页维护选中集合,选中 ≥1 时在工具条区显示批量操作条「已选 N 项」+ 动作:批量删除、批量启用、批量停用(按各页既有单项语义:节点 启用=部署/停用=移除、客户与服务器走各自启停);删除一次确认弹窗说清数量与不可逆;逐项执行既有单项接口/端点,守卫规则与单项完全一致(如服务器有未删节点拒绝、节点有运行中任务拒绝),结果汇总回报成功/失败数与失败原因;操作后刷新列表并清空选择。切页/重渲染后选择状态的去留施工时定并在报告注明。 范围补充(同日用户强调):所有页面都要改——凡是带行勾选框/全选框的列表页全部补齐批量操作,不许只做一页;施工时以 data-row-check / data-check-all 在 public/app.js 的全部出现处逐一排查销账(当前已知:节点管理、入站&出站、用户订阅三页),报告中逐页列明。

25. agent 鉴权令牌化:压掉待机 CPU 的 scrypt 主项(2026-10-21 21:01 用户拍板,与第 24 条同批)

背景(v3 第 22 条归因):面板待机 CPU 的主项是 agent 每次请求都跑一次 scrypt VerifySecret 验 KeyHash(沙箱单次约 88ms、20 台模拟稳态 32.3%);二开版 3x-ui 无此问题——慢哈希只用于人类登录,agent 通信走 API 令牌比对(已查其代码证实)。 修法(用户原话口径:往令牌制靠):agent 首次(或令牌失效时)仍走指纹定位 + scrypt 验一次身份,面板随即签发一张短期令牌(随机值,面板只存其快速哈希如 SHA-256 + 过期时间,绑定该 agent 身份);agent 后续请求带令牌,面板只做快速哈希比对,不再跑 scrypt。令牌过期/不符自动回退 scrypt 路径并重签。吊销语义不降级:删除/吊销 agent、重置其密钥时令牌一并失效。 兼容:旧 agent(不支持令牌)继续走 scrypt 路径可用、只是不提速;新 agent 对旧面板自动回退。鉴权强度不许降级:令牌随机强度与现有密钥同级、比对用常时比较、传输通道沿用现状(现制下密钥本就逐请求在同一通道上传输,令牌不弱于此)。 验收:①稳态 CPU 按 v3 同法复测(20 台 agent 模拟、无界面请求)——目标个位数 %,报告给改动前后同口径数字;②功能回归:agent 注册/心跳/任务拉取/用量上报全链路冒烟、面板或 agent 单侧重启后自动恢复(重签或凭令牌续用)、吊销后令牌立即失效、旧 agent 混跑可用;③全量测试与金标准不回归。 部署提示:面板与 agent 双侧都改;面板先行兼容旧 agent,agent 逐台换新后逐台提速。