From dcfaf6ace6f283005fadc849e8c225a5449534a7 Mon Sep 17 00:00:00 2001 From: Muse Date: Wed, 21 Oct 2026 22:05:09 +0000 Subject: [PATCH] =?UTF-8?q?feat(install-agent):=20=E5=90=AF=E5=8A=A8?= =?UTF-8?q?=E5=89=8D=E6=8E=A2=E6=B5=8B=E4=B8=BB=E6=8E=A7=E6=B3=A8=E5=86=8C?= =?UTF-8?q?=E6=8E=A5=E5=8F=A3(404/=E8=BF=9E=E4=B8=8D=E4=B8=8A=E5=8D=B3?= =?UTF-8?q?=E4=B8=AD=E6=AD=A2),=E6=94=B9=E4=B8=BA=20systemd/OpenRC=20?= =?UTF-8?q?=E6=9C=8D=E5=8A=A1=E5=8C=96=E5=AE=89=E8=A3=85=E5=B8=A6=E8=87=AA?= =?UTF-8?q?=E5=90=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- install-agent.sh | 205 ++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 184 insertions(+), 21 deletions(-) diff --git a/install-agent.sh b/install-agent.sh index cf834bb..e93dfd4 100755 --- a/install-agent.sh +++ b/install-agent.sh @@ -2,11 +2,17 @@ # 3x-ui-agent 节点一键安装脚本 # 用法: bash install-agent.sh --master http://MASTER_IP:2053 --token YOUR_AGENT_TOKEN [--name my-node] # 要求: Debian/Ubuntu/Alpine/CentOS (amd64/arm64), root 运行 +# +# 测试用环境变量(一般无需设置): +# XUI_ROOT 安装路径前缀(假根目录验证用),默认空 = 真实路径 +# XUI_INIT_SYSTEM 强制 init 系统: systemd | openrc | none,默认 auto 探测 +# XUI_URL agent 二进制下载地址覆盖 set -e -RED='\033[0;31m'; GREEN='\033[0;32m'; NC='\033[0m' +RED='\033[0;31m'; GREEN='\033[0;32m'; YELLOW='\033[0;33m'; NC='\033[0m' info() { echo -e "${GREEN}[INFO]${NC} $1"; } +warn() { echo -e "${YELLOW}[WARN]${NC} $1"; } error() { echo -e "${RED}[ERROR]${NC} $1"; exit 1; } [[ $EUID -ne 0 ]] && error "请用 root 运行" @@ -35,15 +41,20 @@ esac XUI_URL="${XUI_URL:-https://git.881218.xyz/rogue/3x-ui-agent/releases/download/v3.7.0-agent.1/x-ui-linux-${BIN_ARCH}}" XRAY_VER="26.6.27" +ROOT="${XUI_ROOT:-}" +XUI_HOME="${ROOT}/usr/local/x-ui" +CONF_DIR="${ROOT}/etc/x-ui" +AGENT_BIN="${XUI_HOME}/x-ui" + info "创建目录..." -mkdir -p /usr/local/x-ui/bin /etc/x-ui +mkdir -p "${XUI_HOME}/bin" "${CONF_DIR}" info "下载 agent 二进制..." -curl -fL -o /usr/local/x-ui/x-ui "$XUI_URL" || error "agent 下载失败" -chmod +x /usr/local/x-ui/x-ui +curl -fL -o "${AGENT_BIN}" "$XUI_URL" || error "agent 下载失败" +chmod +x "${AGENT_BIN}" info "下载 xray v${XRAY_VER}..." -cd /usr/local/x-ui/bin +cd "${XUI_HOME}/bin" case "$BIN_ARCH" in amd64) XRAY_ZIP="Xray-linux-64.zip";; arm64) XRAY_ZIP="Xray-linux-arm64-v8a.zip";; @@ -55,29 +66,181 @@ rm -f "$XRAY_ZIP" info "下载 geo 文件..." curl -fL -o geoip.dat "https://github.com/Loyalsoldier/v2ray-rules-dat/releases/latest/download/geoip.dat" || error "geoip 下载失败" curl -fL -o geosite.dat "https://github.com/Loyalsoldier/v2ray-rules-dat/releases/latest/download/geosite.dat" || error "geosite 下载失败" +cd - >/dev/null info "写入 agent 配置..." -cat > /etc/x-ui/agent.json < "${CONF_DIR}/agent.json" </dev/null) || code="000" + case "$code" in + 404) + echo "" + echo -e "${RED}============================================================${NC}" + echo -e "${RED} 主控返回 404:注册接口不存在,安装中止。${NC}" + echo -e "${RED} 主控地址大概率少了面板基础路径(如 /rogue)。${NC}" + echo -e "${RED} 当前地址: ${MASTER}${NC}" + echo -e "${RED} 若面板实际地址带基础路径,请改用 --master ${MASTER%/}/rogue${NC}" + echo -e "${RED} 之类的完整地址(以面板真实基础路径为准)改对后重跑本脚本。${NC}" + echo -e "${RED}============================================================${NC}" + exit 1 + ;; + 000) + echo "" + echo -e "${RED}============================================================${NC}" + echo -e "${RED} 连不上主控,安装中止。${NC}" + echo -e "${RED} 请检查:网络是否通、域名解析是否正常、主控地址与端口是否写对、${NC}" + echo -e "${RED} 以及主控 HTTPS 证书是否有效(agent 不接受自签证书)。${NC}" + echo -e "${RED} 目标: $url${NC}" + echo -e "${RED}============================================================${NC}" + exit 1 + ;; + *) + info "主控探测通过 (HTTP $code,注册路由存在)" + ;; + esac +} + +probe_master + +detect_init_system() { + case "${XUI_INIT_SYSTEM:-auto}" in + systemd|openrc|none) echo "${XUI_INIT_SYSTEM}"; return;; + esac + if [ -d /run/systemd/system ] && command -v systemctl >/dev/null 2>&1; then + echo systemd; return + fi + if command -v rc-update >/dev/null 2>&1 && command -v rc-service >/dev/null 2>&1; then + echo openrc; return + fi + echo none +} + +# 以 systemd 服务方式安装并启动(开机自启) +start_via_systemd() { + local unit_dir="${ROOT}/etc/systemd/system" + mkdir -p "$unit_dir" + cat > "${unit_dir}/x-ui-agent.service" <<'EOF' +[Unit] +Description=3x-ui agent +After=network.target + +[Service] +ExecStart=/usr/local/x-ui/x-ui agent +Restart=on-failure +RestartSec=5 + +[Install] +WantedBy=multi-user.target +EOF + info "已生成 systemd 服务文件: ${unit_dir}/x-ui-agent.service" + if [ -n "$ROOT" ]; then + info "(XUI_ROOT 模式:跳过 systemctl 实际操作)" + return 0 + fi + systemctl stop x-ui-agent 2>/dev/null || true + pkill -f "${AGENT_BIN} agent" 2>/dev/null || true; sleep 1 + systemctl daemon-reload + systemctl enable x-ui-agent + systemctl restart x-ui-agent + sleep 2 + if systemctl is-active --quiet x-ui-agent; then + info "agent 已由 systemd 托管启动(开机自启)" + echo "" + echo " 主控: $MASTER" + echo " 节点名: $NAME" + echo " 日志: journalctl -u x-ui-agent -f" + echo " agent 会在 30 秒内从主控拉取配置" + else + error "agent 服务启动失败,查看: systemctl status x-ui-agent" + fi +} + +# 以 OpenRC 服务方式安装并启动(开机自启,Alpine 等) +start_via_openrc() { + local init_dir="${ROOT}/etc/init.d" + mkdir -p "$init_dir" + cat > "${init_dir}/x-ui-agent" <<'EOF' +#!/sbin/openrc-run + +name="x-ui-agent" +description="3x-ui lightweight node agent" +command="/usr/local/x-ui/x-ui" +command_args="agent" +command_background="yes" +pidfile="/run/x-ui-agent.pid" +output_log="/var/log/x-ui-agent.log" +error_log="/var/log/x-ui-agent.log" + +depend() { + need net +} +EOF + chmod +x "${init_dir}/x-ui-agent" + info "已生成 OpenRC 服务文件: ${init_dir}/x-ui-agent" + if [ -n "$ROOT" ]; then + info "(XUI_ROOT 模式:跳过 rc-update/rc-service 实际操作)" + return 0 + fi + rc-service x-ui-agent stop 2>/dev/null || true + pkill -f "${AGENT_BIN} agent" 2>/dev/null || true; sleep 1 + rc-update add x-ui-agent default + rc-service x-ui-agent restart + sleep 2 + if rc-service x-ui-agent status >/dev/null 2>&1; then + info "agent 已由 OpenRC 托管启动(开机自启)" + echo "" + echo " 主控: $MASTER" + echo " 节点名: $NAME" + echo " 日志: tail -f /var/log/x-ui-agent.log" + echo " agent 会在 30 秒内从主控拉取配置" + else + error "agent 服务启动失败,查看: rc-service x-ui-agent status" + fi +} + +# 无服务管理器时回落 nohup(无开机自启,明确警告) +start_via_nohup() { + warn "未检测到 systemd / OpenRC,退回 nohup 方式启动" + warn "注意:nohup 方式没有开机自启,机器重启后 agent 不会自动恢复,需手动重跑本脚本!" + pkill -f "${AGENT_BIN} agent" 2>/dev/null || true; sleep 1 + # -config 显式给出(生产环境即其默认路径 /etc/x-ui/agent.json,行为不变), + # 这样 XUI_ROOT 假根验证时 agent 也能找到刚写下的配置。 + nohup "${AGENT_BIN}" agent -config "${CONF_DIR}/agent.json" > /tmp/agent.log 2>&1 & + sleep 8 + if grep -q "Starting 3x-ui agent" /tmp/agent.log 2>/dev/null; then + info "agent 启动成功!" + echo "" + echo " 主控: $MASTER" + echo " 节点名: $NAME" + echo " 日志: tail -f /tmp/agent.log" + echo " agent 会在 30 秒内从主控拉取配置" + else + error "启动失败,查看日志: cat /tmp/agent.log" + fi +} info "启动 agent..." -pkill -f "/usr/local/x-ui/x-ui agent" 2>/dev/null || true; sleep 1 -nohup /usr/local/x-ui/x-ui agent > /tmp/agent.log 2>&1 & -sleep 8 - -if grep -q "Starting 3x-ui agent" /tmp/agent.log 2>/dev/null; then - info "agent 启动成功!" - echo "" - echo " 主控: $MASTER" - echo " 节点名: $NAME" - echo " 日志: tail -f /tmp/agent.log" - echo " agent 会在 30 秒内从主控拉取配置" -else - error "启动失败,查看日志: cat /tmp/agent.log" -fi +case "$(detect_init_system)" in + systemd) start_via_systemd;; + openrc) start_via_openrc;; + *) start_via_nohup;; +esac