Files
NexusGate/scripts/agent-install.sh
T

152 lines
8.1 KiB
Bash
Executable File
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/usr/bin/env bash
set -Eeuo pipefail
REPO="${NG_REPO:-a2899882/NexusGate}"
BRANCH="${NG_BRANCH:-main}"
CONTROLLER=""
TOKEN=""
die() { printf '错误:%s\n' "$*" >&2; exit 1; }
info() { printf '\033[1;36m[NexusGate Agent]\033[0m %s\n' "$*"; }
while [[ $# -gt 0 ]]; do
case "$1" in
--server) CONTROLLER="${2:-}"; shift 2 ;;
--token) TOKEN="${2:-}"; shift 2 ;;
--repo) REPO="${2:-}"; shift 2 ;;
--branch) BRANCH="${2:-}"; shift 2 ;;
*) die "未知参数:$1" ;;
esac
done
[[ "${EUID}" -eq 0 ]] || die "请使用 root 运行"
[[ "$CONTROLLER" =~ ^https?:// ]] || die "--server 必须是完整的 HTTP(S) 地址"
[[ -n "$TOKEN" ]] || die "缺少 --token"
if command -v apt-get >/dev/null; then
export DEBIAN_FRONTEND=noninteractive
apt-get update -qq && apt-get install -y -qq ca-certificates curl unzip nodejs openssl logrotate
elif command -v dnf >/dev/null; then
dnf install -y ca-certificates curl unzip nodejs openssl logrotate
elif command -v apk >/dev/null; then
apk add --no-cache bash ca-certificates curl unzip nodejs openrc openssl logrotate
else
die "当前安装器支持 Debian/Ubuntu、RHEL 系和 Alpine"
fi
node_major="$(node -p 'process.versions.node.split(`.`)[0]')"
[[ "$node_major" -ge 18 ]] || die "需要 Node.js 18 或更高版本"
case "$(uname -m)" in
x86_64|amd64) xray_arch="64" ;;
aarch64|arm64) xray_arch="arm64-v8a" ;;
armv7l) xray_arch="arm32-v7a" ;;
*) die "暂不支持的架构:$(uname -m)" ;;
esac
tmp_dir="$(mktemp -d /tmp/nexusgate-agent.XXXXXX)"
trap 'rm -rf -- "$tmp_dir"' EXIT
info "下载 Xray-core"
xray_asset="Xray-linux-${xray_arch}.zip"
curl -fL --retry 3 "https://github.com/XTLS/Xray-core/releases/latest/download/${xray_asset}" -o "$tmp_dir/xray.zip"
unzip -q "$tmp_dir/xray.zip" xray -d "$tmp_dir/xray"
install -m 0755 "$tmp_dir/xray/xray" /usr/local/bin/xray
install -d -m 0755 /opt/nexusgate-agent
curl -fL --retry 3 "https://raw.githubusercontent.com/${REPO}/${BRANCH}/agent/agent.js" -o /opt/nexusgate-agent/agent.js
curl -fL --retry 3 "https://raw.githubusercontent.com/${REPO}/${BRANCH}/agent/run.sh" -o /opt/nexusgate-agent/run.sh
curl -fL --retry 3 "https://raw.githubusercontent.com/${REPO}/${BRANCH}/scripts/agent-update.sh" -o /usr/local/sbin/ng-agent-update
curl -fL --retry 3 "https://raw.githubusercontent.com/${REPO}/${BRANCH}/scripts/agent-uninstall.sh" -o /usr/local/sbin/ng-agent-uninstall
curl -fL --retry 3 "https://raw.githubusercontent.com/${REPO}/${BRANCH}/scripts/agent-doctor.sh" -o /usr/local/sbin/ng-agent-doctor
curl -fL --retry 3 "https://raw.githubusercontent.com/${REPO}/${BRANCH}/scripts/agent-cert.sh" -o /usr/local/sbin/ng-agent-cert
curl -fL --retry 3 "https://raw.githubusercontent.com/${REPO}/${BRANCH}/scripts/agent-singbox.sh" -o /usr/local/sbin/ng-agent-singbox
curl -fL --retry 3 "https://raw.githubusercontent.com/${REPO}/${BRANCH}/scripts/agent-logrotate.conf" -o "$tmp_dir/logrotate.conf"
curl -fL --retry 3 "https://raw.githubusercontent.com/${REPO}/${BRANCH}/scripts/agent-logrotate-setup.sh" -o "$tmp_dir/logrotate-setup.sh"
cat > /usr/local/sbin/ng-agent <<'EOF'
#!/usr/bin/env bash
set -Eeuo pipefail
case "${1:-}" in
update) exec ng-agent-update ;;
uninstall) shift; exec ng-agent-uninstall "$@" ;;
doctor|status) exec ng-agent-doctor ;;
cert) shift; exec ng-agent-cert "$@" ;;
engine) shift; exec ng-agent-singbox "$@" ;;
*) printf 'NexusGate Agent: ng-agent doctor | ng-agent cert | ng-agent engine install | ng-agent update | ng-agent uninstall\n' ;;
esac
EOF
chmod 0644 /opt/nexusgate-agent/agent.js
chmod 0755 /opt/nexusgate-agent/run.sh /usr/local/sbin/ng-agent-update /usr/local/sbin/ng-agent-uninstall /usr/local/sbin/ng-agent-doctor /usr/local/sbin/ng-agent-cert /usr/local/sbin/ng-agent-singbox /usr/local/sbin/ng-agent
install -d -m 0700 /etc/nexusgate /etc/nexusgate/xray /etc/nexusgate/xray/resources /etc/nexusgate/sing-box
install -d -m 0750 /var/log/nexusgate
install -m 0644 "$tmp_dir/logrotate.conf" /etc/nexusgate/agent-logrotate.conf
install -m 0755 "$tmp_dir/logrotate-setup.sh" /usr/local/sbin/ng-agent-logrotate-setup
if [[ ! -f /etc/nexusgate/xray/config.json ]]; then
printf '{"log":{"loglevel":"warning"},"inbounds":[],"outbounds":[]}\n' > /etc/nexusgate/xray/config.json
fi
chmod 0600 /etc/nexusgate/xray/config.json
if [[ "${NG_INSTALL_ANYTLS:-0}" == 1 ]]; then
NG_REPO="$REPO" NG_BRANCH="$BRANCH" ng-agent-singbox install || die 'AnyTLS 引擎安装失败;修复后运行 ng-agent engine install'
else
info '基础节点只安装 Xray;需要 AnyTLS 时在入口机运行 ng-agent engine install。'
fi
info "向控制面注册"
enroll_json="$(TOKEN_VALUE="$TOKEN" node -e 'process.stdout.write(JSON.stringify({token:process.env.TOKEN_VALUE,hostname:require("node:os").hostname(),version:"0.6.8",system:{platform:process.platform,arch:process.arch}}))')"
response="$(curl -fsS -H 'content-type: application/json' --data "$enroll_json" "${CONTROLLER%/}/api/agent/enroll")" || die "注册失败,请检查地址和令牌"
agent_key="$(RESPONSE_VALUE="$response" node -e 'const r=JSON.parse(process.env.RESPONSE_VALUE); if(!r.agentKey) process.exit(1); process.stdout.write(r.agentKey)')" || die "控制面返回无效"
{
printf 'NG_CONTROLLER=%q\n' "${CONTROLLER%/}"
printf 'NG_AGENT_KEY=%q\n' "$agent_key"
printf 'NG_XRAY_BIN=/usr/local/bin/xray\n'
printf 'NG_CONFIG_DIR=/etc/nexusgate/xray\n'
printf 'NG_KEY_FILE=/etc/nexusgate/keys.json\n'
} > /etc/nexusgate/agent.env
chmod 0600 /etc/nexusgate/agent.env
if command -v systemctl >/dev/null && [[ -d /run/systemd/system ]]; then
curl -fL --retry 3 "https://raw.githubusercontent.com/${REPO}/${BRANCH}/systemd/nexusgate-agent.service" -o /etc/systemd/system/nexusgate-agent.service
curl -fL --retry 3 "https://raw.githubusercontent.com/${REPO}/${BRANCH}/systemd/nexusgate-xray.service" -o /etc/systemd/system/nexusgate-xray.service
curl -fL --retry 3 "https://raw.githubusercontent.com/${REPO}/${BRANCH}/systemd/nexusgate-sing-box.service" -o /etc/systemd/system/nexusgate-sing-box.service
systemctl daemon-reload
systemctl enable nexusgate-xray.service nexusgate-agent.service
systemctl restart nexusgate-xray.service
rm -f -- /etc/nexusgate/last-heartbeat.json
systemctl restart nexusgate-agent.service
service_manager="systemd"
elif command -v rc-service >/dev/null; then
install -d -m 0755 /etc/init.d
curl -fL --retry 3 "https://raw.githubusercontent.com/${REPO}/${BRANCH}/openrc/nexusgate-agent" -o /etc/init.d/nexusgate-agent
curl -fL --retry 3 "https://raw.githubusercontent.com/${REPO}/${BRANCH}/openrc/nexusgate-xray" -o /etc/init.d/nexusgate-xray
curl -fL --retry 3 "https://raw.githubusercontent.com/${REPO}/${BRANCH}/openrc/nexusgate-sing-box" -o /etc/init.d/nexusgate-sing-box
chmod 0755 /etc/init.d/nexusgate-agent /etc/init.d/nexusgate-xray /etc/init.d/nexusgate-sing-box
rc-update add nexusgate-xray default >/dev/null
rc-update add nexusgate-agent default >/dev/null
# Alpine runs the dedicated hourly task through BusyBox crond.
if [[ -e /etc/init.d/crond ]]; then
rc-update add crond default >/dev/null 2>&1 || true
rc-service crond start >/dev/null 2>&1 || true
fi
rc-service nexusgate-xray restart
rm -f -- /etc/nexusgate/last-heartbeat.json
rc-service nexusgate-agent restart
service_manager="OpenRC"
else
die "未检测到 systemd 或 OpenRC"
fi
ng-agent-logrotate-setup
for _ in {1..35}; do
[[ -s /etc/nexusgate/last-heartbeat.json ]] && break
sleep 1
done
if [[ ! -s /etc/nexusgate/last-heartbeat.json ]]; then
if [[ "$service_manager" == systemd ]]; then journalctl -u nexusgate-agent.service -n 35 --no-pager || true; fi
die 'Agent 注册成功但没有向控制面上报心跳;运行 ng-agent doctor 排查后再重试'
fi
printf '\n\033[1;32mAgent 安装、注册和首次心跳完成(%s)。\033[0m\n' "$service_manager"
printf '后续更新 Agent:ng-agent-update\n'
printf '卸载 Agent:ng-agent uninstall\n'
printf '检查 Agent 与 Xray:ng-agent doctor\n'
if [[ "$service_manager" == systemd ]] && ! systemctl is-active --quiet nexusgate-agent.service; then
journalctl -u nexusgate-agent.service -n 35 --no-pager || true
die 'Agent 注册已完成,但服务没有运行;请执行 ng-agent doctor 检查原因'
fi