fix: prevent false panel detection on GFK server reinstall

On reinstall, setup_xray_for_gfk() detected paqctl's own previously-
installed standalone Xray as a panel and added a spurious second SOCKS5
mapping (e.g. 14000:443,14001:10443 instead of just 14000:443).

Root cause: uninstall didn't stop xray.service, so pgrep found it on
reinstall and triggered the panel path.

Fixes:
- Add _is_paqctl_standalone_xray() to distinguish paqctl's standalone
  Xray (only socks inbounds on 127.0.0.1) from a real panel
- setup_xray_for_gfk() now stops and reconfigures standalone Xray
  instead of falsely adding panel SOCKS5
- uninstall properly stops/disables standalone xray.service
- Add missing stop_xray() to embedded management script
This commit is contained in:
SamNet-dev
2026-02-08 19:35:25 -06:00
parent a17ed1c37f
commit 361235daca

View File

@@ -1464,6 +1464,28 @@ EOF
log_success "Xray configured (SOCKS5 on 127.0.0.1:$listen_port)" log_success "Xray configured (SOCKS5 on 127.0.0.1:$listen_port)"
} }
# Check if running xray is paqctl's own standalone install (not a real panel)
# Returns 0 if standalone (all inbounds are socks on 127.0.0.1), 1 if panel
_is_paqctl_standalone_xray() {
[ -f "$XRAY_CONFIG_FILE" ] || return 1
command -v python3 &>/dev/null || return 1
python3 -c "
import json, sys
try:
with open(sys.argv[1]) as f:
cfg = json.load(f)
inbounds = cfg.get('inbounds', [])
if not inbounds:
sys.exit(1)
for i in inbounds:
if i.get('protocol') != 'socks' or i.get('listen', '0.0.0.0') != '127.0.0.1':
sys.exit(1)
sys.exit(0)
except:
sys.exit(1)
" "$XRAY_CONFIG_FILE" 2>/dev/null
}
# Add a SOCKS5 inbound to an existing xray config (panel) without touching other inbounds # Add a SOCKS5 inbound to an existing xray config (panel) without touching other inbounds
_add_xray_gfk_socks() { _add_xray_gfk_socks() {
local port="$1" local port="$1"
@@ -1554,6 +1576,13 @@ setup_xray_for_gfk() {
target_port=$(echo "${GFK_PORT_MAPPINGS:-14000:443}" | cut -d: -f2 | cut -d, -f1) target_port=$(echo "${GFK_PORT_MAPPINGS:-14000:443}" | cut -d: -f2 | cut -d, -f1)
if pgrep -x xray &>/dev/null || pgrep -x xray-linux-amd64 &>/dev/null; then if pgrep -x xray &>/dev/null || pgrep -x xray-linux-amd64 &>/dev/null; then
# Check if this is paqctl's own standalone Xray (not a real panel)
if _is_paqctl_standalone_xray; then
log_info "Existing Xray is paqctl's standalone install — reconfiguring..."
stop_xray
sleep 1
# Fall through to standalone install path below
else
XRAY_PANEL_DETECTED=true XRAY_PANEL_DETECTED=true
log_info "Existing Xray detected — adding SOCKS5 alongside panel..." log_info "Existing Xray detected — adding SOCKS5 alongside panel..."
@@ -1620,6 +1649,7 @@ setup_xray_for_gfk() {
log_warn "For direct SOCKS5: use 127.0.0.1:${socks_vio} as your proxy on client" log_warn "For direct SOCKS5: use 127.0.0.1:${socks_vio} as your proxy on client"
return 0 return 0
fi fi
fi
install_xray || return 1 install_xray || return 1
configure_xray_socks "$target_port" || return 1 configure_xray_socks "$target_port" || return 1
@@ -6112,6 +6142,26 @@ EOF
log_success "Xray configured (SOCKS5 on 127.0.0.1:$listen_port)" log_success "Xray configured (SOCKS5 on 127.0.0.1:$listen_port)"
} }
_is_paqctl_standalone_xray() {
[ -f "$XRAY_CONFIG_FILE" ] || return 1
command -v python3 &>/dev/null || return 1
python3 -c "
import json, sys
try:
with open(sys.argv[1]) as f:
cfg = json.load(f)
inbounds = cfg.get('inbounds', [])
if not inbounds:
sys.exit(1)
for i in inbounds:
if i.get('protocol') != 'socks' or i.get('listen', '0.0.0.0') != '127.0.0.1':
sys.exit(1)
sys.exit(0)
except:
sys.exit(1)
" "$XRAY_CONFIG_FILE" 2>/dev/null
}
_add_xray_gfk_socks() { _add_xray_gfk_socks() {
local port="$1" local port="$1"
python3 -c " python3 -c "
@@ -6142,6 +6192,14 @@ with open(config_path, 'w') as f:
log_success "Added GFK SOCKS5 inbound on 127.0.0.1:$port" log_success "Added GFK SOCKS5 inbound on 127.0.0.1:$port"
} }
stop_xray() {
if command -v systemctl &>/dev/null && [ -d /run/systemd/system ]; then
systemctl stop xray 2>/dev/null || true
else
pkill -x xray 2>/dev/null || true
fi
}
start_xray() { start_xray() {
log_info "Starting Xray service..." log_info "Starting Xray service..."
if command -v systemctl &>/dev/null && [ -d /run/systemd/system ]; then if command -v systemctl &>/dev/null && [ -d /run/systemd/system ]; then
@@ -6185,6 +6243,13 @@ setup_xray_for_gfk() {
target_port=$(echo "${GFK_PORT_MAPPINGS:-14000:443}" | cut -d: -f2 | cut -d, -f1) target_port=$(echo "${GFK_PORT_MAPPINGS:-14000:443}" | cut -d: -f2 | cut -d, -f1)
if pgrep -x xray &>/dev/null || pgrep -x xray-linux-amd64 &>/dev/null; then if pgrep -x xray &>/dev/null || pgrep -x xray-linux-amd64 &>/dev/null; then
# Check if this is paqctl's own standalone Xray (not a real panel)
if _is_paqctl_standalone_xray; then
log_info "Existing Xray is paqctl's standalone install — reconfiguring..."
stop_xray
sleep 1
# Fall through to standalone install path below
else
XRAY_PANEL_DETECTED=true XRAY_PANEL_DETECTED=true
log_info "Existing Xray detected — adding SOCKS5 alongside panel..." log_info "Existing Xray detected — adding SOCKS5 alongside panel..."
@@ -6251,6 +6316,7 @@ setup_xray_for_gfk() {
log_warn "For direct SOCKS5: use 127.0.0.1:${socks_vio} as your proxy on client" log_warn "For direct SOCKS5: use 127.0.0.1:${socks_vio} as your proxy on client"
return 0 return 0
fi fi
fi
install_xray || return 1 install_xray || return 1
configure_xray_socks "$target_port" || return 1 configure_xray_socks "$target_port" || return 1
@@ -6338,8 +6404,13 @@ uninstall_paqctl() {
# Stop standalone GFK xray and clean up config # Stop standalone GFK xray and clean up config
pkill -f "xray run -c.*gfk-socks.json" 2>/dev/null || true pkill -f "xray run -c.*gfk-socks.json" 2>/dev/null || true
rm -f /usr/local/etc/xray/gfk-socks.json 2>/dev/null rm -f /usr/local/etc/xray/gfk-socks.json 2>/dev/null
# If xray is paqctl's standalone install, stop and disable it entirely
if _is_paqctl_standalone_xray; then
log_info "Stopping paqctl's standalone Xray..."
systemctl stop xray 2>/dev/null || true
systemctl disable xray 2>/dev/null || true
elif [ -f "$XRAY_CONFIG_FILE" ] && command -v python3 &>/dev/null; then
# Remove gfk-socks inbound from panel's xray config if present # Remove gfk-socks inbound from panel's xray config if present
if [ -f "$XRAY_CONFIG_FILE" ] && command -v python3 &>/dev/null; then
python3 -c " python3 -c "
import json, sys import json, sys
try: try: