3x-ui 式共享节点改造:nodes 状态机 + nodeClients 各自凭据
- 移除 VMess 协议 - VLESS/SS2022 按用户流量统计(AnyTLS 日志解析,SS 节点级) - sing-box v2ray_api stats 支持 - 内存优化:面板 128M,agent 64M,sing-box 64M
This commit is contained in:
+58
-37
@@ -8,13 +8,25 @@ die() { printf '错误:%s\n' "$*" >&2; exit 1; }
|
||||
info() { printf '\033[1;36m[NexusGate]\033[0m %s\n' "$*"; }
|
||||
need_root() { [[ "${EUID}" -eq 0 ]] || die "请使用 root 运行"; }
|
||||
|
||||
IS_OPENWRT=false
|
||||
[[ -f /etc/openwrt_release ]] && IS_OPENWRT=true
|
||||
if $IS_OPENWRT; then DATA_DIR=/etc/nexusgate/data; else DATA_DIR=/var/lib/nexusgate; fi
|
||||
|
||||
panel_stop() { if $IS_OPENWRT; then /etc/init.d/nexusgate stop; else systemctl stop nexusgate; fi }
|
||||
panel_start() { if $IS_OPENWRT; then /etc/init.d/nexusgate start; else systemctl start nexusgate; fi }
|
||||
panel_restart() { if $IS_OPENWRT; then /etc/init.d/nexusgate restart; else systemctl restart nexusgate; fi }
|
||||
panel_status() { if $IS_OPENWRT; then /etc/init.d/nexusgate status; else systemctl status nexusgate --no-pager; fi }
|
||||
panel_logs() { local n="${1:-120}"; if $IS_OPENWRT; then logread 2>/dev/null | grep -a nexusgate | tail -n "$n"; else journalctl -u nexusgate -n "$n" --no-pager; fi }
|
||||
caddy_reload() { if $IS_OPENWRT; then /etc/init.d/caddy reload; else systemctl reload caddy; fi }
|
||||
own_data() { if ! $IS_OPENWRT; then chown -R nexusgate:nexusgate "$DATA_DIR"; chmod 0700 "$DATA_DIR"; fi }
|
||||
|
||||
backup() {
|
||||
need_root
|
||||
local output="${1:-/root/nexusgate-backup-$(date +%Y%m%d-%H%M%S).tar.gz}"
|
||||
local stage
|
||||
stage="$(mktemp -d /tmp/nexusgate-backup.XXXXXX)"
|
||||
trap 'rm -rf -- "$stage"' RETURN
|
||||
cp -a /var/lib/nexusgate "$stage/data"
|
||||
cp -a "$DATA_DIR" "$stage/data"
|
||||
cp -a /etc/nexusgate.env "$stage/nexusgate.env"
|
||||
[[ -f /etc/caddy/Caddyfile.d/nexusgate.caddy ]] && cp -a /etc/caddy/Caddyfile.d/nexusgate.caddy "$stage/nexusgate.caddy"
|
||||
tar -czf "$output" -C "$stage" .
|
||||
@@ -35,15 +47,14 @@ restore() {
|
||||
[[ -f "$stage/data/nexusgate.json" && -f "$stage/nexusgate.env" ]] || die "备份包不完整"
|
||||
safety="/root/nexusgate-before-restore-$(date +%Y%m%d-%H%M%S).tar.gz"
|
||||
backup "$safety"
|
||||
systemctl stop nexusgate
|
||||
find /var/lib/nexusgate -mindepth 1 -maxdepth 1 -exec rm -rf -- {} +
|
||||
cp -a "$stage/data/." /var/lib/nexusgate/
|
||||
chown -R nexusgate:nexusgate /var/lib/nexusgate
|
||||
chmod 0700 /var/lib/nexusgate
|
||||
panel_stop
|
||||
find "$DATA_DIR" -mindepth 1 -maxdepth 1 -exec rm -rf -- {} +
|
||||
cp -a "$stage/data/." "$DATA_DIR/"
|
||||
own_data
|
||||
cp -a "$stage/nexusgate.env" /etc/nexusgate.env && chmod 0600 /etc/nexusgate.env
|
||||
if [[ -f "$stage/nexusgate.caddy" ]]; then cp -a "$stage/nexusgate.caddy" /etc/caddy/Caddyfile.d/nexusgate.caddy; fi
|
||||
systemctl start nexusgate
|
||||
systemctl reload caddy || true
|
||||
panel_start
|
||||
caddy_reload || true
|
||||
info "恢复完成;恢复前快照:$safety"
|
||||
}
|
||||
|
||||
@@ -58,22 +69,25 @@ update_panel() {
|
||||
curl -fL --retry 3 "https://github.com/${REPO}/archive/refs/heads/${BRANCH}.tar.gz" -o "$stage/source.tgz"
|
||||
mkdir -p "$stage/source" && tar -xzf "$stage/source.tgz" -C "$stage/source" --strip-components=1
|
||||
[[ -f "$stage/source/server.js" ]] || die "更新包不完整"
|
||||
systemctl stop nexusgate
|
||||
panel_stop
|
||||
cp -a "$stage/source/." /opt/nexusgate/
|
||||
install -m 0644 /opt/nexusgate/systemd/nexusgate.service /etc/systemd/system/nexusgate.service
|
||||
if $IS_OPENWRT; then
|
||||
install -m 0755 /opt/nexusgate/openrc/nexusgate /etc/init.d/nexusgate
|
||||
else
|
||||
install -m 0644 /opt/nexusgate/systemd/nexusgate.service /etc/systemd/system/nexusgate.service
|
||||
systemctl daemon-reload
|
||||
fi
|
||||
install -m 0755 /opt/nexusgate/scripts/nexusgate.sh /usr/local/sbin/nexusgate
|
||||
chown -R nexusgate:nexusgate /var/lib/nexusgate
|
||||
chmod 0700 /var/lib/nexusgate
|
||||
[[ ! -f /var/lib/nexusgate/nexusgate.json ]] || chmod 0600 /var/lib/nexusgate/nexusgate.json
|
||||
systemctl daemon-reload && systemctl start nexusgate
|
||||
own_data
|
||||
[[ ! -f "$DATA_DIR/nexusgate.json" ]] || chmod 0600 "$DATA_DIR/nexusgate.json"
|
||||
panel_start
|
||||
local healthy=false
|
||||
for _ in {1..30}; do
|
||||
if curl -fsS http://127.0.0.1:8787/healthz >/dev/null 2>&1; then healthy=true; break; fi
|
||||
sleep 1
|
||||
done
|
||||
if [[ "$healthy" != true ]]; then
|
||||
systemctl status nexusgate --no-pager || true
|
||||
journalctl -u nexusgate -n 100 --no-pager || true
|
||||
panel_logs 35 || true
|
||||
die "更新后控制面启动失败;可使用上方备份恢复"
|
||||
fi
|
||||
if [[ -f /etc/nexusgate/agent.env ]]; then
|
||||
@@ -94,16 +108,16 @@ change_domain() {
|
||||
[[ "$domain" =~ ^[A-Za-z0-9.-]+$ ]] || die "域名格式不正确"
|
||||
sed -i -E "1s/^[^ ]+/${domain}/" /etc/caddy/Caddyfile.d/nexusgate.caddy
|
||||
caddy fmt --overwrite /etc/caddy/Caddyfile.d/nexusgate.caddy
|
||||
caddy validate --config /etc/caddy/Caddyfile && systemctl reload caddy
|
||||
caddy validate --config /etc/caddy/Caddyfile && caddy_reload
|
||||
info "域名已更新为 https://${domain}"
|
||||
}
|
||||
|
||||
certificate_status() {
|
||||
need_root
|
||||
caddy validate --config /etc/caddy/Caddyfile
|
||||
systemctl reload caddy
|
||||
caddy_reload
|
||||
info "Caddy 已校验并重新加载;证书会在到期前自动续签"
|
||||
journalctl -u caddy -n 30 --no-pager
|
||||
if $IS_OPENWRT; then logread 2>/dev/null | grep -a caddy | tail -n 30; else journalctl -u caddy -n 30 --no-pager; fi
|
||||
}
|
||||
|
||||
change_account() {
|
||||
@@ -119,18 +133,18 @@ change_account() {
|
||||
[[ "$first" == "$second" ]] || die "两次输入不一致"
|
||||
[[ -n "$next" || -n "$first" ]] || die "账号与密码都没有更改"
|
||||
[[ -z "$first" || ${#first} -ge 10 ]] || die "密码至少需要 10 个字符"
|
||||
systemctl stop nexusgate
|
||||
panel_stop
|
||||
set +e
|
||||
NG_DATA_FILE=/var/lib/nexusgate/nexusgate.json NG_NEW_USERNAME="$next" NG_NEW_PASSWORD="$first" node /opt/nexusgate/scripts/reset-password.js "$current"
|
||||
NG_DATA_FILE="$DATA_DIR/nexusgate.json" NG_NEW_USERNAME="$next" NG_NEW_PASSWORD="$first" node /opt/nexusgate/scripts/reset-password.js "$current"
|
||||
local result=$?
|
||||
unset first second
|
||||
set -e
|
||||
if [[ $result -eq 0 ]]; then
|
||||
chown nexusgate:nexusgate /var/lib/nexusgate/nexusgate.json
|
||||
chmod 0600 /var/lib/nexusgate/nexusgate.json
|
||||
if ! $IS_OPENWRT; then chown nexusgate:nexusgate "$DATA_DIR/nexusgate.json"; fi
|
||||
chmod 0600 "$DATA_DIR/nexusgate.json"
|
||||
sed -i '/^NG_ADMIN_PASSWORD=/d' /etc/nexusgate.env
|
||||
fi
|
||||
systemctl start nexusgate
|
||||
panel_start
|
||||
[[ $result -eq 0 ]] || die "管理员账号更新失败"
|
||||
info "管理员账号已更新,现有登录会话将在服务重启后失效"
|
||||
}
|
||||
@@ -142,13 +156,20 @@ uninstall_panel() {
|
||||
[[ "$confirm" == "UNINSTALL" ]] || die "已取消卸载"
|
||||
archive="/root/nexusgate-before-uninstall-$(date +%Y%m%d-%H%M%S).tar.gz"
|
||||
backup "$archive"
|
||||
systemctl disable --now nexusgate.service >/dev/null 2>&1 || true
|
||||
rm -f -- /etc/systemd/system/nexusgate.service /etc/nexusgate.env /etc/caddy/Caddyfile.d/nexusgate.caddy /usr/local/sbin/ng /usr/local/sbin/nexusgate
|
||||
rm -rf -- /opt/nexusgate /var/lib/nexusgate
|
||||
systemctl daemon-reload
|
||||
systemctl reload caddy >/dev/null 2>&1 || true
|
||||
userdel nexusgate >/dev/null 2>&1 || true
|
||||
groupdel nexusgate >/dev/null 2>&1 || true
|
||||
if $IS_OPENWRT; then
|
||||
/etc/init.d/nexusgate stop >/dev/null 2>&1 || true
|
||||
/etc/init.d/nexusgate disable >/dev/null 2>&1 || true
|
||||
rm -f -- /etc/init.d/nexusgate
|
||||
else
|
||||
systemctl disable --now nexusgate.service >/dev/null 2>&1 || true
|
||||
rm -f -- /etc/systemd/system/nexusgate.service
|
||||
systemctl daemon-reload
|
||||
userdel nexusgate >/dev/null 2>&1 || true
|
||||
groupdel nexusgate >/dev/null 2>&1 || true
|
||||
fi
|
||||
rm -f -- /etc/nexusgate.env /etc/caddy/Caddyfile.d/nexusgate.caddy /usr/local/sbin/ng /usr/local/sbin/nexusgate
|
||||
rm -rf -- /opt/nexusgate "$DATA_DIR"
|
||||
caddy_reload >/dev/null 2>&1 || true
|
||||
printf '\nNexusGate 已卸载。可恢复备份:%s\n' "$archive"
|
||||
}
|
||||
|
||||
@@ -164,9 +185,9 @@ menu() {
|
||||
4) backup ;;
|
||||
5) restore ;;
|
||||
6) change_account ;;
|
||||
7) systemctl status nexusgate --no-pager ;;
|
||||
8) need_root; systemctl restart nexusgate caddy; info '已重启' ;;
|
||||
9) journalctl -u nexusgate -n 120 --no-pager ;;
|
||||
7) panel_status ;;
|
||||
8) need_root; panel_restart; caddy_reload; info '已重启' ;;
|
||||
9) panel_logs 120 ;;
|
||||
10) uninstall_panel ;;
|
||||
0) exit 0 ;;
|
||||
*) die '无效选择' ;;
|
||||
@@ -174,9 +195,9 @@ menu() {
|
||||
}
|
||||
|
||||
case "${1:-menu}" in
|
||||
status) systemctl status nexusgate --no-pager ;;
|
||||
restart) need_root; systemctl restart nexusgate caddy ;;
|
||||
logs) journalctl -u nexusgate -n "${2:-120}" --no-pager ;;
|
||||
status) panel_status ;;
|
||||
restart) need_root; panel_restart; caddy_reload ;;
|
||||
logs) panel_logs "${2:-120}" ;;
|
||||
backup) backup "${2:-}" ;;
|
||||
restore) restore "${2:-}" ;;
|
||||
update) update_panel ;;
|
||||
|
||||
Reference in New Issue
Block a user