3x-ui agent: 轻量节点 agent 化

- Agent 通过 token 向主控注册,心跳/拉取 xray 配置/上报流量
- 主控按节点下发完整 xray 配置(含出站+路由),agent 只应用不自建
- Agent 心跳同步更新节点在线状态;后台探针跳过 agent 托管节点
- 「添加节点」支持 Agent 类型,自动生成 token 并弹窗展示
- VLESS/SS2022 入站;同机测试支持 api_port 隔离
- 新增 install-master.sh / install-agent.sh 一键安装脚本
- systemd + OpenWrt procd 服务文件,docs/AGENT.md
This commit is contained in:
Muse
2026-10-19 12:29:38 +00:00
parent f727d04f65
commit 0ba1ec0596
19 changed files with 1444 additions and 10 deletions
+19 -1
View File
@@ -144,7 +144,9 @@ func (a *NodeController) add(c *gin.Context) {
if !ok {
return
}
if n.OutboundTag == "" {
isAgent := n.NodeType == "agent"
// Agent nodes have no panel to probe; they authenticate via agent token.
if n.OutboundTag == "" && !isAgent {
if err := a.ensureReachable(c, n, 0); err != nil {
jsonMsg(c, I18nWeb(c, "pages.nodes.toasts.add"), err)
return
@@ -164,6 +166,22 @@ func (a *NodeController) add(c *gin.Context) {
return
}
}
// For agent nodes, issue an agent token bound to the new node and
// return it so the UI can display it (shown only once).
if isAgent {
nodeID := view.Id
token, _, err := issueAgentToken(&nodeID, n.Name)
if err != nil {
jsonMsg(c, I18nWeb(c, "pages.nodes.toasts.add"), err)
return
}
jsonMsgObj(c, I18nWeb(c, "pages.nodes.toasts.add"), gin.H{
"node": view,
"agentToken": token,
"nodeType": "agent",
}, nil)
return
}
jsonMsgObj(c, I18nWeb(c, "pages.nodes.toasts.add"), view, nil)
}