diff --git a/README.md b/README.md index 8886a11..55cfff8 100644 --- a/README.md +++ b/README.md @@ -109,20 +109,25 @@ YOUR COMPUTER YOUR VPS INTERNET
Using GFK with an Existing Xray Panel (3x-ui, Marzban, etc.) -If you already have an Xray panel on your server, GFK works alongside it without conflicts. GFK is a raw TCP forwarder — it tunnels traffic to whatever service is running on your target port. +If your foreign server already has an Xray panel (3x-ui, Marzban, etc.), paqctl detects it and works alongside it. Your panel stays untouched — paqctl only adds what's needed. -**How paqctl handles existing Xray:** +**What paqctl does when it detects Xray:** -| Scenario | What happens | +| Scenario | What paqctl does | |---|---| -| **No Xray installed** | paqctl installs Xray with a SOCKS5 proxy automatically | -| **Xray panel running, target port is listening** | paqctl skips Xray setup, GFK forwards to your panel's inbound | -| **Xray running, target port NOT listening** | paqctl warns you — configure your panel to listen on that port | -| **Xray installed but not running** | paqctl installs its own SOCKS5 (same as fresh install) | +| **No Xray installed** | Installs Xray with SOCKS5 proxy automatically (nothing to configure) | +| **Xray panel running** | Keeps your panel, adds a SOCKS5 inbound on a free port (e.g. 10443), appends an extra port mapping automatically | +| **Xray installed but not running** | Installs its own SOCKS5 (same as fresh install) | -**Step-by-step setup (panel on both servers):** +When a panel is detected, paqctl gives you **two connections** automatically: +- **Panel mapping** (`14000:443`) — for server-to-server panel traffic (vmess/vless) +- **SOCKS5 mapping** (`14001:10443`) — for direct proxy use from Windows/Mac (no v2rayN needed) -Assume your **foreign server** has a panel with vmess/vless inbound on port `443`, and your **Iran server** has a panel with outbound to the foreign server. +--- + +### Setup A: Server-to-Server (Iran panel to Foreign panel) + +This is for when you have a panel on **both** servers (Iran + foreign) and want to route the Iran panel's outbound through the GFK tunnel instead of a direct connection. **1. Install paqctl on the foreign server (server role):** ```bash @@ -130,14 +135,14 @@ curl -fsSL https://raw.githubusercontent.com/SamNet-dev/paqctl/main/paqctl.sh | ``` - Choose **server** role - Set port mapping: `14000:443` (where `443` is your panel's inbound port) -- paqctl detects Xray is running and skips SOCKS5 — your panel stays untouched +- paqctl detects Xray and adds SOCKS5 alongside your panel (e.g. `14001:10443`) **2. Install paqctl on the Iran server (client role):** ```bash curl -fsSL https://raw.githubusercontent.com/SamNet-dev/paqctl/main/paqctl.sh | sudo bash ``` - Choose **client** role -- Set the **same** port mapping: `14000:443` +- Use the **exact same** port mappings shown in the server output (e.g. `14000:443,14001:10443`) - Use the same auth code from the server setup **3. Update your Iran panel outbound to route through GFK:** @@ -175,21 +180,43 @@ In your Iran panel (3x-ui, Marzban, etc.), change the outbound that connects to ``` The key changes: -- `address`: from `FOREIGN_SERVER_IP` to `127.0.0.1` -- `port`: from `443` to `14000` (the VIO port from your mapping) +- `address`: from `FOREIGN_SERVER_IP` to `127.0.0.1` (traffic goes through GFK on the same machine) +- `port`: from `443` to `14000` (the VIO port, NOT the original server port) -**4. Traffic flow:** +**Traffic flow:** ``` End user --> Iran panel inbound --> Iran panel outbound (127.0.0.1:14000) --> GFK client (VIO port) --> QUIC tunnel over violated TCP --> Foreign GFK server --> 127.0.0.1:443 (foreign panel inbound) --> Internet ``` +--- + +### Setup B: Direct Client (Windows/Mac to Foreign server) + +This is for when you **don't have an Iran server** — you connect directly from your Windows or Mac to the foreign server through GFK. paqctl auto-adds a SOCKS5 proxy so you can use it as a simple browser proxy. + +**1. Install paqctl on the foreign server** (same as above) + +**2. On your Windows/Mac**, install the GFK client and use the SOCKS5 mapping: +- The server output will show something like: `Mappings: 14000:443,14001:10443` +- Use `14001` as your proxy port — this is the direct SOCKS5 (no panel/v2rayN needed) +- Configure your browser or system proxy to `SOCKS5 127.0.0.1:14001` + +**Traffic flow:** +``` +Browser (SOCKS5 127.0.0.1:14001) --> GFK client + --> QUIC tunnel over violated TCP + --> Foreign GFK server --> 127.0.0.1:10443 (SOCKS5 proxy) --> Internet +``` + +--- + **Multiple ports:** If your panel uses multiple ports, map them all: ``` 14000:443,14001:8080,14002:2020 ``` -Then create separate outbounds in your Iran panel for each port (14000, 14001, 14002). +paqctl will add SOCKS5 on the next available port and append it automatically. > **Note:** The "Firewall: VIO port blocked" status message (shown in green) is **normal and correct**. It means the firewall is properly configured for GFK's raw socket to work. @@ -1195,20 +1222,25 @@ MIT License - See [LICENSE](LICENSE) file.
استفاده از GFK با پنل Xray موجود (3x-ui، Marzban و غیره) -اگر از قبل پنل Xray روی سرور خود دارید، GFK بدون تداخل در کنار آن کار می‌کند. GFK یک فورواردر خام TCP است — ترافیک را به هر سرویسی که روی پورت مقصد شما اجرا می‌شود تونل می‌کند. +اگر سرور خارج شما از قبل پنل Xray دارد (3x-ui، Marzban و غیره)، paqctl آن را تشخیص می‌دهد و در کنار آن کار می‌کند. پنل شما دست نخورده می‌ماند — paqctl فقط چیزهای لازم را اضافه می‌کند. -**رفتار paqctl با Xray موجود:** +**رفتار paqctl هنگام تشخیص Xray:** -| سناریو | چه اتفاقی می‌افتد | +| سناریو | عملکرد paqctl | |---|---| -| **Xray نصب نیست** | paqctl به صورت خودکار Xray با پروکسی SOCKS5 نصب می‌کند | -| **پنل Xray در حال اجراست، پورت مقصد فعال است** | paqctl نصب Xray را رد می‌کند، GFK به اینباند پنل شما فوروارد می‌کند | -| **Xray در حال اجراست، پورت مقصد فعال نیست** | paqctl هشدار می‌دهد — پنل خود را روی آن پورت تنظیم کنید | -| **Xray نصب شده ولی اجرا نمی‌شود** | paqctl SOCKS5 خودش را نصب می‌کند (مثل نصب جدید) | +| **Xray نصب نیست** | Xray با پروکسی SOCKS5 به صورت خودکار نصب می‌شود (نیازی به تنظیم نیست) | +| **پنل Xray در حال اجراست** | پنل را نگه می‌دارد، یک اینباند SOCKS5 روی پورت آزاد اضافه می‌کند (مثلاً 10443)، و یک مپینگ اضافی اضافه می‌شود | +| **Xray نصب شده ولی اجرا نمی‌شود** | SOCKS5 خودش را نصب می‌کند (مثل نصب جدید) | -**راهنمای گام به گام (پنل روی هر دو سرور):** +وقتی پنل تشخیص داده می‌شود، paqctl **دو اتصال** به صورت خودکار می‌دهد: +- **مپینگ پنل** (`14000:443`) — برای ترافیک سرور به سرور (vmess/vless) +- **مپینگ SOCKS5** (`14001:10443`) — برای استفاده مستقیم از ویندوز/مک (بدون نیاز به v2rayN) -فرض کنید **سرور خارج** پنلی با اینباند vmess/vless روی پورت `443` دارد و **سرور ایران** پنلی با اوتباند به سرور خارج دارد. +--- + +### روش A: سرور به سرور (پنل ایران به پنل خارج) + +این روش برای وقتی است که روی **هر دو سرور** (ایران + خارج) پنل دارید و می‌خواهید اوتباند پنل ایران از تونل GFK عبور کند. **۱. نصب paqctl روی سرور خارج (نقش server):** ```bash @@ -1216,17 +1248,17 @@ curl -fsSL https://raw.githubusercontent.com/SamNet-dev/paqctl/main/paqctl.sh | ``` - نقش **server** را انتخاب کنید - مپینگ پورت: `14000:443` (که `443` پورت اینباند پنل شماست) -- paqctl تشخیص می‌دهد Xray در حال اجراست و نصب SOCKS5 را رد می‌کند — پنل شما دست نخورده می‌ماند +- paqctl تشخیص می‌دهد Xray در حال اجراست و SOCKS5 را در کنار پنل اضافه می‌کند (مثلاً `14001:10443`) **۲. نصب paqctl روی سرور ایران (نقش client):** ```bash curl -fsSL https://raw.githubusercontent.com/SamNet-dev/paqctl/main/paqctl.sh | sudo bash ``` - نقش **client** را انتخاب کنید -- **همان** مپینگ پورت: `14000:443` +- **دقیقاً همان** مپینگ‌هایی که در خروجی سرور نمایش داده شد را استفاده کنید (مثلاً `14000:443,14001:10443`) - همان کد احراز هویت سرور را استفاده کنید -**۳. اوتباند پنل ایران را به‌روزرسانی کنید تا از GFK عبور کند:** +**۳. اوتباند پنل ایران را تغییر دهید:** در پنل ایران (3x-ui، Marzban و غیره)، اوتباندی که به سرور خارج متصل می‌شود را تغییر دهید: @@ -1261,21 +1293,43 @@ curl -fsSL https://raw.githubusercontent.com/SamNet-dev/paqctl/main/paqctl.sh | ``` تغییرات کلیدی: -- `address`: از `IP_SERVER_KHAREJ` به `127.0.0.1` -- `port`: از `443` به `14000` (پورت VIO از مپینگ شما) +- `address`: از `IP_SERVER_KHAREJ` به `127.0.0.1` (ترافیک از GFK روی همان ماشین عبور می‌کند) +- `port`: از `443` به `14000` (پورت VIO، نه پورت اصلی سرور) -**۴. مسیر ترافیک:** +**مسیر ترافیک:** ``` کاربر --> اینباند پنل ایران --> اوتباند پنل ایران (127.0.0.1:14000) --> GFK client (پورت VIO) --> تونل QUIC روی TCP نقض‌شده --> GFK server خارج --> 127.0.0.1:443 (اینباند پنل خارج) --> اینترنت ``` +--- + +### روش B: کلاینت مستقیم (ویندوز/مک به سرور خارج) + +این روش برای وقتی است که **سرور ایران ندارید** — مستقیماً از ویندوز یا مک خود به سرور خارج از طریق GFK متصل می‌شوید. paqctl به صورت خودکار یک پروکسی SOCKS5 اضافه می‌کند تا بتوانید به عنوان پروکسی مرورگر استفاده کنید. + +**۱. نصب paqctl روی سرور خارج** (مثل بالا) + +**۲. روی ویندوز/مک خود** کلاینت GFK را نصب کنید و از مپینگ SOCKS5 استفاده کنید: +- خروجی سرور چیزی شبیه این نشان می‌دهد: `Mappings: 14000:443,14001:10443` +- از `14001` به عنوان پورت پروکسی استفاده کنید — این SOCKS5 مستقیم است (نیازی به پنل/v2rayN نیست) +- پروکسی مرورگر یا سیستم را روی `SOCKS5 127.0.0.1:14001` تنظیم کنید + +**مسیر ترافیک:** +``` +مرورگر (SOCKS5 127.0.0.1:14001) --> GFK client + --> تونل QUIC روی TCP نقض‌شده + --> GFK server خارج --> 127.0.0.1:10443 (پروکسی SOCKS5) --> اینترنت +``` + +--- + **چند پورت:** اگر پنل شما از چند پورت استفاده می‌کند، همه را مپ کنید: ``` 14000:443,14001:8080,14002:2020 ``` -سپس برای هر پورت (14000، 14001، 14002) اوتباند جداگانه در پنل ایران بسازید. +paqctl به صورت خودکار SOCKS5 را روی پورت آزاد بعدی اضافه و مپ می‌کند. > **توجه:** پیام وضعیت "Firewall: VIO port blocked" (که با رنگ سبز نمایش داده می‌شود) **عادی و صحیح** است. این به معنای آن است که فایروال به درستی برای کار raw socket در GFK تنظیم شده است. diff --git a/paqctl.sh b/paqctl.sh index ef36869..a5da724 100644 --- a/paqctl.sh +++ b/paqctl.sh @@ -1407,6 +1407,40 @@ EOF log_success "Xray configured (SOCKS5 on 127.0.0.1:$listen_port)" } +# Add a SOCKS5 inbound to an existing xray config (panel) without touching other inbounds +_add_xray_gfk_socks() { + local port="$1" + python3 -c " +import json, sys +port = int(sys.argv[1]) +config_path = sys.argv[2] +try: + with open(config_path, 'r') as f: + cfg = json.load(f) +except: + cfg = {'inbounds': [], 'outbounds': [{'tag': 'direct', 'protocol': 'freedom', 'settings': {}}]} +cfg.setdefault('inbounds', []) +cfg['inbounds'] = [i for i in cfg['inbounds'] if i.get('tag') != 'gfk-socks'] +cfg['inbounds'].append({ + 'tag': 'gfk-socks', + 'port': port, + 'listen': '127.0.0.1', + 'protocol': 'socks', + 'settings': {'auth': 'noauth', 'udp': True}, + 'sniffing': {'enabled': True, 'destOverride': ['http', 'tls']} +}) +if not any(o.get('protocol') == 'freedom' for o in cfg.get('outbounds', [])): + cfg.setdefault('outbounds', []).append({'tag': 'direct', 'protocol': 'freedom', 'settings': {}}) +with open(config_path, 'w') as f: + json.dump(cfg, f, indent=2) +" "$port" "$XRAY_CONFIG_FILE" 2>/dev/null + if [ $? -ne 0 ]; then + log_error "Failed to add SOCKS5 inbound to existing Xray config" + return 1 + fi + log_success "Added GFK SOCKS5 inbound on 127.0.0.1:$port" +} + start_xray() { log_info "Starting Xray service..." @@ -1456,22 +1490,18 @@ stop_xray() { } setup_xray_for_gfk() { - # Get the first target port from GFK_PORT_MAPPINGS (e.g., "14000:443" -> 443) local target_port target_port=$(echo "${GFK_PORT_MAPPINGS:-14000:443}" | cut -d: -f2 | cut -d, -f1) - # If xray is already running (e.g. user has a panel), skip SOCKS5 setup. - # GFK is a raw TCP forwarder — traffic goes to whatever is on the target port. - # The user's panel/services handle the actual proxying. if pgrep -x xray &>/dev/null; then XRAY_PANEL_DETECTED=true - log_info "Existing Xray detected — skipping SOCKS5 setup (panel will handle traffic)" + log_info "Existing Xray detected — adding SOCKS5 alongside panel..." # Clean up any leftover standalone GFK xray from prior installs pkill -f "xray run -c.*gfk-socks.json" 2>/dev/null || true rm -f "${XRAY_CONFIG_DIR}/gfk-socks.json" 2>/dev/null - # Check all target ports from mappings + # Check all existing target ports from mappings local mapping pairs IFS=',' read -ra pairs <<< "${GFK_PORT_MAPPINGS:-14000:443}" for mapping in "${pairs[@]}"; do @@ -1480,17 +1510,54 @@ setup_xray_for_gfk() { if ss -tln 2>/dev/null | grep -q ":${tp} "; then log_success "Port $tp is listening — GFK will forward VIO port $vio_port to this port" else - log_warn "Port $tp is NOT listening on this server — make sure your xray panel inbound is configured on port $tp" + log_warn "Port $tp is NOT listening — make sure your panel inbound is on port $tp" fi done + # Find free port for SOCKS5 (starting at 10443) + local socks_port=10443 + while ss -tln 2>/dev/null | grep -q ":${socks_port} "; do + socks_port=$((socks_port + 1)) + if [ "$socks_port" -gt 65000 ]; then + log_warn "Could not find free port for SOCKS5 — panel-only mode" + echo "" + local first_vio + first_vio=$(echo "${GFK_PORT_MAPPINGS:-14000:443}" | cut -d: -f1 | cut -d, -f1) + log_warn "For panel-to-panel: configure Iran panel outbound to 127.0.0.1:${first_vio}" + return 0 + fi + done + + # Add SOCKS5 inbound to existing xray config + _add_xray_gfk_socks "$socks_port" || { + log_warn "Could not add SOCKS5 to panel config — panel-only mode" + return 0 + } + + # Restart xray to load new config + systemctl restart xray 2>/dev/null || pkill -SIGHUP xray 2>/dev/null || true + sleep 2 + + # Find next VIO port (highest existing + 1) and append SOCKS5 mapping + local max_vio=0 + for mapping in "${pairs[@]}"; do + local v="${mapping%%:*}" + [ "$v" -gt "$max_vio" ] && max_vio="$v" + done + local socks_vio=$((max_vio + 1)) + GFK_PORT_MAPPINGS="${GFK_PORT_MAPPINGS},${socks_vio}:${socks_port}" + GFK_SOCKS_PORT="$socks_port" + GFK_SOCKS_VIO_PORT="$socks_vio" + + log_success "SOCKS5 proxy added on port $socks_port (VIO port $socks_vio)" + echo "" + log_info "Port mappings updated: ${GFK_PORT_MAPPINGS}" + log_warn "Use these SAME mappings on the client side" echo "" - log_warn "ACTION REQUIRED: On your Iran server, configure the panel outbound:" - log_warn " → Set address to: 127.0.0.1" local first_vio first_vio=$(echo "${GFK_PORT_MAPPINGS:-14000:443}" | cut -d: -f1 | cut -d, -f1) - log_warn " → Set port to: ${first_vio} (VIO port, NOT the original server port)" - log_warn " See README for detailed panel configuration guide" + log_warn "For panel-to-panel: configure Iran panel outbound to 127.0.0.1:${first_vio}" + log_warn "For direct SOCKS5: use 127.0.0.1:${socks_vio} as your proxy on client" return 0 fi @@ -5713,6 +5780,36 @@ EOF log_success "Xray configured (SOCKS5 on 127.0.0.1:$listen_port)" } +_add_xray_gfk_socks() { + local port="$1" + python3 -c " +import json, sys +port = int(sys.argv[1]) +config_path = sys.argv[2] +try: + with open(config_path, 'r') as f: + cfg = json.load(f) +except: + cfg = {'inbounds': [], 'outbounds': [{'tag': 'direct', 'protocol': 'freedom', 'settings': {}}]} +cfg.setdefault('inbounds', []) +cfg['inbounds'] = [i for i in cfg['inbounds'] if i.get('tag') != 'gfk-socks'] +cfg['inbounds'].append({ + 'tag': 'gfk-socks', 'port': port, 'listen': '127.0.0.1', 'protocol': 'socks', + 'settings': {'auth': 'noauth', 'udp': True}, + 'sniffing': {'enabled': True, 'destOverride': ['http', 'tls']} +}) +if not any(o.get('protocol') == 'freedom' for o in cfg.get('outbounds', [])): + cfg.setdefault('outbounds', []).append({'tag': 'direct', 'protocol': 'freedom', 'settings': {}}) +with open(config_path, 'w') as f: + json.dump(cfg, f, indent=2) +" "$port" "$XRAY_CONFIG_FILE" 2>/dev/null + if [ $? -ne 0 ]; then + log_error "Failed to add SOCKS5 inbound to existing Xray config" + return 1 + fi + log_success "Added GFK SOCKS5 inbound on 127.0.0.1:$port" +} + start_xray() { log_info "Starting Xray service..." if command -v systemctl &>/dev/null && [ -d /run/systemd/system ]; then @@ -5751,12 +5848,16 @@ start_xray() { setup_xray_for_gfk() { local target_port target_port=$(echo "${GFK_PORT_MAPPINGS:-14000:443}" | cut -d: -f2 | cut -d, -f1) + if pgrep -x xray &>/dev/null; then XRAY_PANEL_DETECTED=true - log_info "Existing Xray detected — skipping SOCKS5 setup (panel will handle traffic)" + log_info "Existing Xray detected — adding SOCKS5 alongside panel..." + + # Clean up any leftover standalone GFK xray from prior installs pkill -f "xray run -c.*gfk-socks.json" 2>/dev/null || true rm -f "${XRAY_CONFIG_DIR}/gfk-socks.json" 2>/dev/null - # Check all target ports from mappings + + # Check all existing target ports from mappings local mapping pairs IFS=',' read -ra pairs <<< "${GFK_PORT_MAPPINGS:-14000:443}" for mapping in "${pairs[@]}"; do @@ -5765,18 +5866,57 @@ setup_xray_for_gfk() { if ss -tln 2>/dev/null | grep -q ":${tp} "; then log_success "Port $tp is listening — GFK will forward VIO port $vio_port to this port" else - log_warn "Port $tp is NOT listening on this server — make sure your xray panel inbound is configured on port $tp" + log_warn "Port $tp is NOT listening — make sure your panel inbound is on port $tp" fi done + + # Find free port for SOCKS5 (starting at 10443) + local socks_port=10443 + while ss -tln 2>/dev/null | grep -q ":${socks_port} "; do + socks_port=$((socks_port + 1)) + if [ "$socks_port" -gt 65000 ]; then + log_warn "Could not find free port for SOCKS5 — panel-only mode" + echo "" + local first_vio + first_vio=$(echo "${GFK_PORT_MAPPINGS:-14000:443}" | cut -d: -f1 | cut -d, -f1) + log_warn "For panel-to-panel: configure Iran panel outbound to 127.0.0.1:${first_vio}" + return 0 + fi + done + + # Add SOCKS5 inbound to existing xray config + _add_xray_gfk_socks "$socks_port" || { + log_warn "Could not add SOCKS5 to panel config — panel-only mode" + return 0 + } + + # Restart xray to load new config + systemctl restart xray 2>/dev/null || pkill -SIGHUP xray 2>/dev/null || true + sleep 2 + + # Find next VIO port (highest existing + 1) and append SOCKS5 mapping + local max_vio=0 + for mapping in "${pairs[@]}"; do + local v="${mapping%%:*}" + [ "$v" -gt "$max_vio" ] && max_vio="$v" + done + local socks_vio=$((max_vio + 1)) + GFK_PORT_MAPPINGS="${GFK_PORT_MAPPINGS},${socks_vio}:${socks_port}" + GFK_SOCKS_PORT="$socks_port" + GFK_SOCKS_VIO_PORT="$socks_vio" + + log_success "SOCKS5 proxy added on port $socks_port (VIO port $socks_vio)" + echo "" + log_info "Port mappings updated: ${GFK_PORT_MAPPINGS}" + log_warn "Use these SAME mappings on the client side" echo "" - log_warn "ACTION REQUIRED: On your Iran server, configure the panel outbound:" - log_warn " → Set address to: 127.0.0.1" local first_vio first_vio=$(echo "${GFK_PORT_MAPPINGS:-14000:443}" | cut -d: -f1 | cut -d, -f1) - log_warn " → Set port to: ${first_vio} (VIO port, NOT the original server port)" - log_warn " See README for detailed panel configuration guide" + log_warn "For panel-to-panel: configure Iran panel outbound to 127.0.0.1:${first_vio}" + log_warn "For direct SOCKS5: use 127.0.0.1:${socks_vio} as your proxy on client" return 0 fi + install_xray || return 1 configure_xray_socks "$target_port" || return 1 start_xray || return 1 @@ -5816,7 +5956,7 @@ _install_gfk_components() { # Generate TLS certificates for QUIC generate_gfk_certs || return 1 - # Setup Xray (server only — skipped if panel detected) + # Setup Xray (server only — adds SOCKS5 alongside panel if detected) if [ "$ROLE" = "server" ]; then setup_xray_for_gfk || return 1 fi @@ -6772,8 +6912,12 @@ main() { download_gfk || { log_error "Failed to download GFK"; exit 1; } generate_gfk_certs || { log_error "Failed to generate certificates"; exit 1; } if [ "$ROLE" = "server" ]; then - # Install Xray to provide SOCKS5 proxy on the target port (skipped if panel detected) + # Install Xray SOCKS5 proxy (adds alongside panel if detected) setup_xray_for_gfk || { log_error "Failed to setup Xray"; exit 1; } + # Regenerate config if mappings changed (panel detected → SOCKS5 added) + if [ "${XRAY_PANEL_DETECTED:-false}" = "true" ]; then + generate_gfk_config || { log_error "Failed to regenerate GFK config"; exit 1; } + fi elif [ "$ROLE" = "client" ]; then install_microsocks || { log_error "Failed to install microsocks"; exit 1; } create_gfk_client_wrapper || { log_error "Failed to create client wrapper"; exit 1; } @@ -6868,11 +7012,13 @@ main() { echo -e " QUIC port: ${BOLD}${GFK_QUIC_PORT}${NC}" if [ "${XRAY_PANEL_DETECTED:-false}" = "true" ]; then echo -e " Xray: ${BOLD}Existing panel detected (forwarding to port ${_xray_port})${NC}" + echo -e " SOCKS5: ${BOLD}127.0.0.1:${GFK_SOCKS_PORT:-N/A} (auto-added, VIO port ${GFK_SOCKS_VIO_PORT:-N/A})${NC}" echo "" - echo -e " ${GREEN}✓ GFK will forward traffic to your existing panel${NC}" + echo -e " ${GREEN}✓ GFK forwards to panel + SOCKS5 proxy added${NC}" local _first_vio _first_vio=$(echo "${GFK_PORT_MAPPINGS:-14000:443}" | cut -d: -f1 | cut -d, -f1) - echo -e " ${YELLOW}! ACTION: Configure Iran panel outbound → 127.0.0.1:${_first_vio}${NC}" + echo -e " ${YELLOW}! Panel users: configure Iran outbound → 127.0.0.1:${_first_vio}${NC}" + echo -e " ${YELLOW}! Direct SOCKS5: use 127.0.0.1:${GFK_SOCKS_VIO_PORT:-} on client${NC}" else echo -e " Xray: ${BOLD}127.0.0.1:${_xray_port} (SOCKS5)${NC}" echo ""