diff --git a/.github/workflows/bash-syntax.yml b/.github/workflows/bash-syntax.yml index c9e047b..2e27cee 100644 --- a/.github/workflows/bash-syntax.yml +++ b/.github/workflows/bash-syntax.yml @@ -35,5 +35,8 @@ jobs: - name: Test step 3 SSH configuration parsing run: bash tests/test-step3-sshd-parsing.sh + - name: Test step 5 repeated-run actions + run: bash tests/test-step5-actions.sh + - name: Test step 8 AI agent catalog run: bash tests/test-step8-agent-catalog.sh diff --git a/README.md b/README.md index 836439f..8a3fc1e 100644 --- a/README.md +++ b/README.md @@ -63,7 +63,7 @@ The wizard downloads any missing module from the `main` branch and validates it | `ochenstarik-server-2.sh` | Base packages, SSH port, IPv4/IPv6 mode, UFW, and port management | Yes | | `ochenstarik-server-user-3.sh` | Administrative user, SSH key permissions, SSH migration, sudo, and fail2ban | Run after step 2 | | `ochenstarik-server-tg-4.sh` | Telegram notifications for successful SSH logins | Optional | -| `ochenstarik-server-vpn-5.sh` | System VPN through Xray with a selectable subscription port | Optional | +| `ochenstarik-server-vpn-5.sh` | System VPN through Xray; repeated runs can connect, disconnect, reconfigure, or show status | Optional | | `ochenstarik-server-panel-warp-6.sh` | 3x-ui panel and local Cloudflare WARP proxy | Optional | | `ochenstarik-server-backup-7.sh` | Protected initial snapshot and selected daily, weekly, or monthly schedules | Optional | | `ochenstarik-server-ai-agents-8.sh` | Installs selected AI agents: Hermes, OpenClaw, OpenHands, OpenCode, Aider, AutoGPT, or Pi Coding Agent | Optional | @@ -92,6 +92,19 @@ Replace `SCRIPT_NAME.sh` with the required filename from the table. 8. Optionally create the permanent initial backup and configure rotating schedules. 9. Optionally install one or more AI agents for the administrative user. +## VPN connection control + +After the first successful setup, running `ochenstarik-server-vpn-5.sh` again opens an action menu: connect using saved settings, disconnect while keeping the configuration, replace the subscription, or show status. The same actions are available directly: + +```bash +sudo ./ochenstarik-server-vpn-5.sh --enable +sudo ./ochenstarik-server-vpn-5.sh --disable +sudo ./ochenstarik-server-vpn-5.sh --reconfigure +sudo ./ochenstarik-server-vpn-5.sh --status +``` + +Disconnecting removes the system routing rules but keeps Xray and its configuration so the VPN can be reconnected without entering the subscription again. + ## Optional AI agents Step 8 offers a multiple selection of seven popular agents: Hermes Agent, OpenClaw, OpenHands, OpenCode, Aider, AutoGPT, and Pi Coding Agent. Installers are downloaded only from each project's official HTTPS endpoint, checked with `bash -n`, and launched as the selected regular user rather than directly as `root`. diff --git a/docs/readme/README.ar.md b/docs/readme/README.ar.md index 7b29938..e7ad69b 100644 --- a/docs/readme/README.ar.md +++ b/docs/readme/README.ar.md @@ -25,7 +25,7 @@ sudo ./ochenstarik-server-install.sh 2. الحزم الأساسية ومنفذ SSH وIPv4/IPv6 وUFW. 3. المستخدم الإداري ومفتاح SSH والصلاحيات وsudo وfail2ban. 4. إشعارات Telegram عند تسجيل الدخول عبر SSH. -5. VPN للنظام باستخدام Xray. +5. VPN للنظام باستخدام Xray مع إمكانية الاتصال أو الفصل عند إعادة التشغيل. 6. لوحة 3x-ui ووكيل Cloudflare WARP المحلي. 7. النسخة الأولية والنسخ اليومية أو الأسبوعية أو الشهرية. 8. وكلاء ذكاء اصطناعي اختياريون: Hermes أو OpenClaw أو OpenHands أو OpenCode أو Aider أو AutoGPT أو Pi Coding Agent. diff --git a/docs/readme/README.de.md b/docs/readme/README.de.md index 35b4ba5..d662b7e 100644 --- a/docs/readme/README.de.md +++ b/docs/readme/README.de.md @@ -25,7 +25,7 @@ Die erste Frage wählt die Sprache des Installers; English ist voreingestellt. D 2. Basispakete, SSH-Port, IPv4/IPv6 und UFW. 3. Administrator, SSH-Schlüssel, Rechte, sudo und fail2ban. 4. Telegram-Benachrichtigungen für SSH-Anmeldungen. -5. System-VPN über Xray. +5. System-VPN über Xray mit Verbinden und Trennen bei späteren Ausführungen. 6. 3x-ui und lokaler Cloudflare-WARP-Proxy. 7. Erstsicherung sowie tägliche, wöchentliche oder monatliche Sicherungen. 8. Optionale KI-Agenten: Hermes, OpenClaw, OpenHands, OpenCode, Aider, AutoGPT oder Pi Coding Agent. diff --git a/docs/readme/README.es.md b/docs/readme/README.es.md index 75ac21b..81bb8ca 100644 --- a/docs/readme/README.es.md +++ b/docs/readme/README.es.md @@ -25,7 +25,7 @@ La primera pregunta selecciona el idioma del instalador; English es el valor pre 2. Paquetes básicos, puerto SSH, IPv4/IPv6 y UFW. 3. Usuario administrador, clave SSH, permisos, sudo y fail2ban. 4. Notificaciones de Telegram para accesos SSH. -5. VPN del sistema mediante Xray. +5. VPN del sistema mediante Xray, con conexión y desconexión en ejecuciones posteriores. 6. Panel 3x-ui y proxy local Cloudflare WARP. 7. Instantánea inicial y copias diarias, semanales o mensuales. 8. Agentes de IA opcionales: Hermes, OpenClaw, OpenHands, OpenCode, Aider, AutoGPT o Pi Coding Agent. diff --git a/docs/readme/README.fr.md b/docs/readme/README.fr.md index 802052c..39cf2d5 100644 --- a/docs/readme/README.fr.md +++ b/docs/readme/README.fr.md @@ -25,7 +25,7 @@ La première question sélectionne la langue de l’installateur ; English est l 2. Paquets de base, port SSH, IPv4/IPv6 et UFW. 3. Administrateur, clé SSH, permissions, sudo et fail2ban. 4. Notifications Telegram des connexions SSH. -5. VPN système via Xray. +5. VPN système via Xray, avec connexion et déconnexion lors des exécutions suivantes. 6. Panneau 3x-ui et proxy local Cloudflare WARP. 7. Instantané initial et sauvegardes quotidiennes, hebdomadaires ou mensuelles. 8. Agents IA facultatifs : Hermes, OpenClaw, OpenHands, OpenCode, Aider, AutoGPT ou Pi Coding Agent. diff --git a/docs/readme/README.hi.md b/docs/readme/README.hi.md index 794e489..6d40873 100644 --- a/docs/readme/README.hi.md +++ b/docs/readme/README.hi.md @@ -25,7 +25,7 @@ sudo ./ochenstarik-server-install.sh 2. मूल पैकेज, SSH पोर्ट, IPv4/IPv6 और UFW। 3. प्रशासक, SSH कुंजी, अनुमतियाँ, sudo और fail2ban। 4. SSH लॉगिन के लिए Telegram सूचनाएँ। -5. Xray के माध्यम से सिस्टम VPN। +5. Xray के माध्यम से सिस्टम VPN, दोबारा चलाने पर कनेक्ट या डिस्कनेक्ट करने की सुविधा। 6. 3x-ui पैनल और स्थानीय Cloudflare WARP प्रॉक्सी। 7. प्रारंभिक स्नैपशॉट और दैनिक, साप्ताहिक या मासिक बैकअप। 8. वैकल्पिक AI एजेंट: Hermes, OpenClaw, OpenHands, OpenCode, Aider, AutoGPT या Pi Coding Agent। diff --git a/docs/readme/README.ja.md b/docs/readme/README.ja.md index dac8270..9788e28 100644 --- a/docs/readme/README.ja.md +++ b/docs/readme/README.ja.md @@ -25,7 +25,7 @@ sudo ./ochenstarik-server-install.sh 2. 基本パッケージ、SSH ポート、IPv4/IPv6、UFW。 3. 管理者、SSH 鍵、アクセス権、sudo、fail2ban。 4. SSH ログインの Telegram 通知。 -5. Xray によるシステム VPN。 +5. Xray によるシステム VPN。再実行時に接続または切断できます。 6. 3x-ui パネルとローカル Cloudflare WARP プロキシ。 7. 初回スナップショットと日次、週次、月次バックアップ。 8. オプションの AI エージェント:Hermes、OpenClaw、OpenHands、OpenCode、Aider、AutoGPT、Pi Coding Agent。 diff --git a/docs/readme/README.pt.md b/docs/readme/README.pt.md index 18a7da4..07da52f 100644 --- a/docs/readme/README.pt.md +++ b/docs/readme/README.pt.md @@ -25,7 +25,7 @@ A primeira pergunta seleciona o idioma do instalador; English é o padrão. Depo 2. Pacotes básicos, porta SSH, IPv4/IPv6 e UFW. 3. Administrador, chave SSH, permissões, sudo e fail2ban. 4. Notificações Telegram para logins SSH. -5. VPN do sistema por Xray. +5. VPN do sistema por Xray, com conexão e desconexão nas execuções seguintes. 6. Painel 3x-ui e proxy local Cloudflare WARP. 7. Snapshot inicial e backups diários, semanais ou mensais. 8. Agentes de IA opcionais: Hermes, OpenClaw, OpenHands, OpenCode, Aider, AutoGPT ou Pi Coding Agent. diff --git a/docs/readme/README.ru.md b/docs/readme/README.ru.md index 7e34a6c..a412b41 100644 --- a/docs/readme/README.ru.md +++ b/docs/readme/README.ru.md @@ -279,6 +279,8 @@ sudo tail -f /var/log/ochenstarik-ssh-login-telegram.log Скрипт устанавливает Xray и необходимые пакеты, принимает прямую ссылку `vless://` либо HTTPS-ссылку подписки 3x-ui и настраивает маршрутизацию через `nftables`. Если подписка содержит VLESS-ссылки на нескольких портах, скрипт выводит доступные порты и просит выбрать нужный. Поддерживается VLESS с транспортом TCP/RAW и REALITY. +При повторном запуске появляется меню: подключить VPN с сохранёнными настройками, отключить его без удаления конфигурации, заменить подписку либо показать состояние. + ```bash curl -fLO https://raw.githubusercontent.com/ochenstarik-ui/lightweight-server/main/ochenstarik-server-vpn-5.sh chmod 700 ochenstarik-server-vpn-5.sh @@ -295,12 +297,17 @@ sudo /usr/local/sbin/ochenstarik-xray-routing status curl -4 https://api.ipify.org ``` -Отключение системного VPN: +Прямые команды управления: ```bash +sudo ./ochenstarik-server-vpn-5.sh --enable sudo ./ochenstarik-server-vpn-5.sh --disable +sudo ./ochenstarik-server-vpn-5.sh --reconfigure +sudo ./ochenstarik-server-vpn-5.sh --status ``` +Отключение удаляет правила системной маршрутизации, но сохраняет Xray и настройки для быстрого повторного подключения. + ## 6. Панель 3x-ui и локальный proxy Cloudflare WARP Файл: `ochenstarik-server-panel-warp-6.sh`. diff --git a/docs/readme/README.zh-CN.md b/docs/readme/README.zh-CN.md index c99f436..af38f14 100644 --- a/docs/readme/README.zh-CN.md +++ b/docs/readme/README.zh-CN.md @@ -25,7 +25,7 @@ sudo ./ochenstarik-server-install.sh 2. 基础软件包、SSH 端口、IPv4/IPv6 和 UFW。 3. 管理员、SSH 密钥、权限、sudo 和 fail2ban。 4. SSH 登录的 Telegram 通知。 -5. 通过 Xray 配置系统 VPN。 +5. 通过 Xray 配置系统 VPN,重复运行时可连接或断开。 6. 3x-ui 面板和本地 Cloudflare WARP 代理。 7. 初始快照以及每日、每周或每月备份。 8. 可选 AI 代理:Hermes、OpenClaw、OpenHands、OpenCode、Aider、AutoGPT 或 Pi Coding Agent。 diff --git a/ochenstarik-server-vpn-5.sh b/ochenstarik-server-vpn-5.sh index 085c42c..91bf9e1 100644 --- a/ochenstarik-server-vpn-5.sh +++ b/ochenstarik-server-vpn-5.sh @@ -44,17 +44,107 @@ stop_rollback_timer() { ochenstarik-xray-rollback.service >/dev/null 2>&1 || true } -[[ "$EUID" -eq 0 ]] || die "Запустите этот скрипт от имени root" +vpn_is_configured() { + [[ -f "$XRAY_CONFIG" && ! -L "$XRAY_CONFIG" \ + && -x "$ROUTE_HELPER" && ! -L "$ROUTE_HELPER" \ + && -f "$ROUTE_SERVICE" && ! -L "$ROUTE_SERVICE" ]] +} -if [[ "${1:-}" == "--disable" ]]; then +select_existing_action() { + local choice + printf '\nОбнаружена существующая конфигурация системного VPN.\n' + printf ' 1) Подключить VPN с сохранёнными настройками\n' + printf ' 2) Отключить VPN, сохранив настройки\n' + printf ' 3) Переустановить VPN или заменить подписку\n' + printf ' 4) Показать состояние VPN\n' + while :; do + read -rp 'Выберите действие [1]: ' choice || die "Ввод прерван" + choice="${choice:-1}" + case "$choice" in + 1) ACTION=enable; return 0 ;; + 2) ACTION=disable; return 0 ;; + 3) ACTION=reconfigure; return 0 ;; + 4) ACTION=status; return 0 ;; + *) warn "Введите номер от 1 до 4" ;; + esac + done +} + +disable_vpn() { + stop_rollback_timer systemctl disable --now ochenstarik-xray-routing.service >/dev/null 2>&1 || true - [[ ! -x "$ROUTE_HELPER" ]] || "$ROUTE_HELPER" stop - log "Системная маршрутизация через Xray отключена" + [[ ! -x "$ROUTE_HELPER" || -L "$ROUTE_HELPER" ]] || "$ROUTE_HELPER" stop + log "Системная маршрутизация через Xray отключена; конфигурация сохранена" if command -v curl >/dev/null 2>&1; then printf 'Текущий внешний IP: %s\n' "$(public_ipv4)" fi - exit 0 -fi +} + +enable_vpn() { + local direct_ip vpn_ip + vpn_is_configured || die "Сохранённая конфигурация VPN не найдена; выполните установку" + command -v xray >/dev/null 2>&1 || die "Xray не установлен" + xray run -test -config "$XRAY_CONFIG" || die "Xray отклонил сохранённую конфигурацию" + systemctl stop ochenstarik-xray-routing.service >/dev/null 2>&1 || true + "$ROUTE_HELPER" stop + direct_ip="$(public_ipv4)" + valid_ipv4 "$direct_ip" || die "Не удалось определить прямой внешний IPv4 перед подключением" + systemctl daemon-reload + systemctl enable --now xray.service + systemctl restart xray.service + systemctl enable --now ochenstarik-xray-routing.service + systemctl restart ochenstarik-xray-routing.service + systemctl is-active --quiet xray.service || die "Служба Xray не запущена" + systemctl is-active --quiet ochenstarik-xray-routing.service \ + || die "Системная маршрутизация через VPN не запущена" + vpn_ip="$(public_ipv4)" + if ! valid_ipv4 "$vpn_ip" || [[ "$vpn_ip" == "$direct_ip" ]]; then + systemctl stop ochenstarik-xray-routing.service >/dev/null 2>&1 || true + "$ROUTE_HELPER" stop + die "Проверка внешнего IP не пройдена; VPN автоматически отключён" + fi + log "Системный VPN подключён с сохранёнными настройками" + printf 'Прямой внешний IP: %s\n' "$direct_ip" + printf 'Внешний IP через VPN: %s\n' "$vpn_ip" +} + +show_vpn_status() { + if systemctl is-active --quiet ochenstarik-xray-routing.service; then + printf 'Системный VPN: подключён\n' + else + printf 'Системный VPN: отключён\n' + fi + printf 'Xray: %s\n' "$(systemctl is-active xray.service 2>/dev/null || true)" + printf 'Маршрутизация: %s\n' \ + "$(systemctl is-active ochenstarik-xray-routing.service 2>/dev/null || true)" + if [[ -x "$ROUTE_HELPER" && ! -L "$ROUTE_HELPER" ]] \ + && systemctl is-active --quiet ochenstarik-xray-routing.service; then + "$ROUTE_HELPER" status || warn "Не удалось полностью прочитать правила маршрутизации" + fi + if command -v curl >/dev/null 2>&1; then + printf 'Текущий внешний IP: %s\n' "$(public_ipv4)" + fi +} + +[[ "$EUID" -eq 0 ]] || die "Запустите этот скрипт от имени root" + +ACTION="" +case "${1:-}" in + "") vpn_is_configured && select_existing_action || ACTION=reconfigure ;; + --enable) ACTION=enable ;; + --disable) ACTION=disable ;; + --reconfigure) ACTION=reconfigure ;; + --status) ACTION=status ;; + *) die "Использование: $0 [--enable|--disable|--reconfigure|--status]" ;; +esac + +case "$ACTION" in + enable) enable_vpn; exit 0 ;; + disable) disable_vpn; exit 0 ;; + status) show_vpn_status; exit 0 ;; + reconfigure) ;; + *) die "Некорректное действие VPN: $ACTION" ;; +esac export DEBIAN_FRONTEND=noninteractive log "Установка системных зависимостей" @@ -359,7 +449,8 @@ printf 'IP через локальный прокси Xray: %s\n' "$PROXY_IP" [[ "$PROXY_IP" != "$BEFORE_IP" ]] \ || die "IP через Xray совпадает с исходным; системная маршрутизация не включена" -SSH_PORT="$(sshd -T 2>/dev/null | awk '$1 == "port" { print $2; exit }' || true)" +SSHD_EFFECTIVE_CONFIG="$(sshd -T 2>/dev/null || true)" +SSH_PORT="$(awk '$1 == "port" { print $2; exit }' <<< "$SSHD_EFFECTIVE_CONFIG")" [[ "$SSH_PORT" =~ ^[0-9]+$ ]] || SSH_PORT="20202" install -d -m 700 -o root -g root "$STATE_DIR" @@ -516,5 +607,8 @@ printf 'IP через Xray: %s\n' "$PROXY_IP" printf 'IP после VPN: %s\n' "$AFTER_IP" printf 'SSH-порт %s и ответы сервисов 443/63636 оставлены напрямую.\n' "$SSH_PORT" printf 'Публичный IPv6 заблокирован, чтобы исключить обход VPN.\n' -printf '\nОтключить системный VPN:\n %s --disable\n' "$0" +printf '\nПодключить VPN повторно:\n %s --enable\n' "$0" +printf 'Отключить VPN с сохранением настроек:\n %s --disable\n' "$0" +printf 'Заменить подписку:\n %s --reconfigure\n' "$0" +printf 'Показать состояние VPN:\n %s --status\n' "$0" printf 'Проверить маршрутизацию:\n %s status\n' "$ROUTE_HELPER" diff --git a/tests/test-step5-actions.sh b/tests/test-step5-actions.sh new file mode 100644 index 0000000..fd54321 --- /dev/null +++ b/tests/test-step5-actions.sh @@ -0,0 +1,22 @@ +#!/usr/bin/env bash +set -Eeuo pipefail + +cd -- "$(dirname -- "${BASH_SOURCE[0]}")/.." +source <(awk '/^\[\[ "\$EUID"/{exit} {print}' ochenstarik-server-vpn-5.sh) + +ACTION="" +select_existing_action <<< '' >/dev/null +[[ "$ACTION" == enable ]] + +for pair in '1 enable' '2 disable' '3 reconfigure' '4 status'; do + read -r input expected <<< "$pair" + ACTION="" + select_existing_action <<< "$input" >/dev/null + [[ "$ACTION" == "$expected" ]] +done + +for option in --enable --disable --reconfigure --status; do + grep -Fq -- "$option" ochenstarik-server-vpn-5.sh +done + +printf 'Step 5 repeated-run action tests passed.\n'