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:
@@ -18,6 +18,7 @@ import (
|
||||
"github.com/mhsanaei/3x-ui/v3/internal/crypto/nodetoken"
|
||||
"github.com/mhsanaei/3x-ui/v3/internal/database"
|
||||
"github.com/mhsanaei/3x-ui/v3/internal/logger"
|
||||
"github.com/mhsanaei/3x-ui/v3/internal/agent"
|
||||
"github.com/mhsanaei/3x-ui/v3/internal/sub"
|
||||
"github.com/mhsanaei/3x-ui/v3/internal/tunnelmonitor"
|
||||
"github.com/mhsanaei/3x-ui/v3/internal/util/crypto"
|
||||
@@ -66,6 +67,44 @@ func initNodeTokenCrypto() error {
|
||||
}
|
||||
|
||||
// runWebServer initializes and starts the web server for the 3x-ui panel.
|
||||
func runAgent(args []string) {
|
||||
agentCmd := flag.NewFlagSet("agent", flag.ExitOnError)
|
||||
var configPath string
|
||||
agentCmd.StringVar(&configPath, "config", "/etc/x-ui/agent.json", "Path to agent config file")
|
||||
agentCmd.Parse(args)
|
||||
|
||||
// Agent mode always uses the panel's directory layout for the xray binary,
|
||||
// geo files and config.json. Scoped to agent mode only so the panel's own
|
||||
// relative "bin" default is untouched.
|
||||
if os.Getenv("XUI_BIN_FOLDER") == "" {
|
||||
_ = os.Setenv("XUI_BIN_FOLDER", agent.DefaultBinFolder)
|
||||
}
|
||||
|
||||
cfg, err := agent.LoadConfig(configPath)
|
||||
if err != nil {
|
||||
log.Fatalf("Failed to load agent config from %s: %v", configPath, err)
|
||||
}
|
||||
|
||||
// Initialize logger
|
||||
logger.InitLogger(logging.INFO)
|
||||
log.Printf("Starting 3x-ui agent (node: %s)", cfg.NodeName)
|
||||
|
||||
ag := agent.New(cfg)
|
||||
|
||||
// Handle shutdown signals
|
||||
sigCh := make(chan os.Signal, 1)
|
||||
signal.Notify(sigCh, syscall.SIGINT, syscall.SIGTERM)
|
||||
go func() {
|
||||
<-sigCh
|
||||
log.Println("Shutting down agent...")
|
||||
ag.Stop()
|
||||
}()
|
||||
|
||||
if err := ag.Run(); err != nil {
|
||||
log.Fatalf("Agent error: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func runWebServer() {
|
||||
log.Printf("Starting %v %v", config.GetName(), config.GetPanelVersion())
|
||||
|
||||
@@ -644,6 +683,8 @@ func main() {
|
||||
return
|
||||
}
|
||||
runWebServer()
|
||||
case "agent":
|
||||
runAgent(os.Args[2:])
|
||||
case "migrate":
|
||||
migrateDb()
|
||||
case "encrypt-tokens":
|
||||
@@ -742,6 +783,7 @@ func commandHelp() string {
|
||||
return `
|
||||
Commands:
|
||||
run run web panel
|
||||
agent run in agent mode (lightweight node, no web panel)
|
||||
migrate migrate from other/old x-ui
|
||||
migrate-db SQLite <-> .dump (--dump/--restore) or copy into PostgreSQL (--dsn)
|
||||
encrypt-tokens encrypt node bearer tokens with the configured active key
|
||||
|
||||
Reference in New Issue
Block a user