#!/bin/bash # # SSH Tunnel Manager - Профессиональное решение для управления обратными SSH-туннелями # Использует autossh и systemd для обеспечения стабильного и постоянного соединения. # # Использование: # 1. Запуск одной командой (автоустановка + меню): curl -s https://.../install_ssh_tunnel.sh | sudo bash # 2. Установка: sudo bash tunnel-manager.sh install # 3. Запуск меню: sudo bash tunnel-manager.sh menu # # --- Глобальные переменные и конфигурация --- CONFIG_DIR="/etc/tunnel-manager" TUNNELS_DIR="$CONFIG_DIR/tunnels" LOG_DIR="/var/log/tunnel-manager" SERVICE_DIR="/etc/systemd/system" SCRIPT_PATH="/usr/local/bin/tunnel-manager" VPS_CONFIG="$CONFIG_DIR/vps_config" # --- Цвета для вывода --- RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' BLUE='\033[0;34m' CYAN='\033[0;36m' NC='\033[0m' BOLD='\033[1m' # --- Вспомогательные функции --- # Функция логирования и вывода сообщений log_message() { local message="$1" local color="${2:-$NC}" local timestamp=$(date '+%Y-%m-%d %H:%M:%S') # Вывод в консоль и запись в лог echo -e "${color}[$timestamp] $message${NC}" | tee -a "$LOG_DIR/manager.log" } # Функция проверки ошибок check_error() { local exit_code=$? if [ $exit_code -ne 0 ]; then log_message "ОШИБКА (код $exit_code): $1" "$RED" log_message "Подробности в логе: $LOG_DIR/manager.log" "$YELLOW" echo -e "${YELLOW}Произошла ошибка: $1${NC}" read -t 60 -p "Продолжить выполнение скрипта? (y/n): " -n 1 -r echo if [[ ! $REPLY =~ ^[Yy]$ ]]; then exit 1 fi return 1 fi return 0 } # Функция проверки прав root check_root() { if [[ $EUID -ne 0 ]]; then log_message "ОШИБКА: Этот скрипт требует прав root (sudo)." "$RED" log_message "Пожалуйста, запустите: sudo bash $0 $1" "$BOLD" exit 1 fi } # Функция безопасного ввода с ограничением попыток safe_read() { local prompt="$1" local default="$2" local var_name="$3" local max_attempts="${4:-3}" # По умолчанию 3 попытки local attempt=0 local input="" while [[ $attempt -lt $max_attempts ]]; do attempt=$((attempt + 1)) # Явное чтение из /dev/tty чтобы избежать проблем с pipe if [[ -t 0 ]]; then read -p "$prompt" input else read -p "$prompt" input /dev/null)" != "600" ]; then echo -e "${YELLOW}⚠ Предупреждение: Неправильные права на ключ (должны быть 600)${NC}" chmod 600 /root/.ssh/id_rsa 2>/dev/null fi # Выполняем тестовое подключение с подробным выводом echo -e "${BLUE}Выполняем тестовую команду на удаленном сервере...${NC}" if output=$(timeout 15 ssh -p "$VPS_PORT" \ -o BatchMode=yes \ -o ConnectTimeout=10 \ -o StrictHostKeyChecking=no \ -o UserKnownHostsFile=/dev/null \ -o IdentityFile=/root/.ssh/id_rsa \ "$VPS_USER@$VPS_HOST" "echo 'SSH Connection Test: SUCCESS'; whoami; hostname" 2>&1); then echo -e "${GREEN}✓ SSH подключение работает!${NC}" echo -e "${CYAN}Ответ от сервера:${NC}" echo "$output" return 0 else echo -e "${RED}✗ SSH подключение не работает${NC}" echo -e "${YELLOW}Возможные причины:${NC}" echo "1. Ключ не скопирован на VPS" echo "2. Порт $VPS_PORT закрыт на VPS" echo "3. SSH сервер на VPS не запущен" echo "4. Проблемы с сетью/файрволом" echo "5. На VPS отключена аутентификация по паролю, а ключ не настроен" echo "" echo -e "${YELLOW}Проверьте:${NC}" echo "1. Что ключ скопирован на VPS: ssh-copy-id -p $VPS_PORT $VPS_USER@$VPS_HOST" echo "2. Что порт $VPS_PORT открыт: nc -zv $VPS_HOST $VPS_PORT" echo "3. Что SSH сервер запущен на VPS" echo "4. Что на VPS разрешена аутентификация по паролю (PasswordAuthentication yes)" # Пробуем подключиться без ключа для диагностики echo -e "\n${YELLOW}Проверка доступности порта...${NC}" if timeout 3 nc -zv "$VPS_HOST" "$VPS_PORT" 2>&1; then echo -e "${GREEN}✓ Порт $VPS_PORT доступен${NC}" else echo -e "${RED}✗ Порт $VPS_PORT недоступен${NC}" fi return 1 fi } # Функция проверки и настройки SSH сервера на VPS check_and_configure_vps_sshd() { if ! load_vps_settings; then log_message "Сначала необходимо настроить VPS (опция 1)." "$RED" return 1 fi local VPS_PASSWORD="$1" echo -e "${CYAN}Проверка и настройка SSH сервера на VPS...${NC}" # Создаем временный скрипт для настройки VPS local SETUP_SCRIPT="/tmp/setup_vps_sshd_$(date +%s).sh" cat > "$SETUP_SCRIPT" << 'EOF_VPS_SETUP' #!/bin/bash # Настройка SSH сервера для поддержки многопользовательского доступа # и работы туннелей с сохранением доступа по паролю SSHD_CONFIG="/etc/ssh/sshd_config" BACKUP_FILE="${SSHD_CONFIG}.backup.$(date +%Y%m%d%H%M%S)" echo "=== Настройка SSH сервера на VPS ===" echo "Создание резервной копии: $BACKUP_FILE" cp "$SSHD_CONFIG" "$BACKUP_FILE" echo "Настройка параметров SSH для туннелей и многопользовательского доступа..." # Массив настроек, которые нужно применить declare -A SSH_SETTINGS SSH_SETTINGS=( ["PasswordAuthentication"]="yes" ["PubkeyAuthentication"]="yes" ["PermitRootLogin"]="yes" ["GatewayPorts"]="yes" ["AllowTcpForwarding"]="yes" ["PermitTunnel"]="yes" ["ClientAliveInterval"]="30" ["ClientAliveCountMax"]="3" ["MaxSessions"]="20" ["MaxStartups"]="20:30:100" ["TCPKeepAlive"]="yes" ["AllowStreamLocalForwarding"]="yes" ["X11Forwarding"]="yes" ["PrintMotd"]="no" ["PrintLastLog"]="yes" ["UsePAM"]="yes" ["UseDNS"]="no" ) # Применяем настройки for key in "${!SSH_SETTINGS[@]}"; do value="${SSH_SETTINGS[$key]}" # Проверяем существует ли настройка if grep -q "^#\?\s*$key" "$SSHD_CONFIG"; then # Заменяем существующую настройку sed -i "s/^#\?\s*$key.*/$key $value/" "$SSHD_CONFIG" echo "Обновлено: $key $value" else # Добавляем новую настройку echo "$key $value" >> "$SSHD_CONFIG" echo "Добавлено: $key $value" fi done # Добавляем настройки для поддержки IPv4 if ! grep -q "^AddressFamily" "$SSHD_CONFIG"; then echo "AddressFamily inet" >> "$SSHD_CONFIG" echo "Добавлено: AddressFamily inet" fi # Проверяем конфигурацию echo "" echo "Проверка конфигурации SSH..." if sshd -t; then echo "✓ Конфигурация корректна" # Перезапускаем SSH сервер echo "Перезапуск SSH сервера..." if systemctl restart sshd 2>/dev/null || service ssh restart 2>/dev/null || /etc/init.d/ssh restart 2>/dev/null; then echo "✓ SSH сервер перезапущен" echo "" echo "=== НАСТРОЙКИ ВЫПОЛНЕНЫ ===" echo "SSH сервер настроен для:" echo " - Поддержки обратных туннелей" echo " - Многопользовательского доступа" echo " - Аутентификации по паролю И по ключам" echo " - Одновременных подключений с нескольких IP" echo "" echo "Резервная копия: $BACKUP_FILE" else echo "✗ Не удалось перезапустить SSH сервер" echo "Выполните вручную: systemctl restart sshd" fi else echo "✗ Ошибка в конфигурации SSH" echo "Восстановление из резервной копии..." cp "$BACKUP_FILE" "$SSHD_CONFIG" fi EOF_VPS_SETUP # Копируем скрипт на VPS и выполняем echo "Копирование скрипта настройки на VPS..." if [ -n "$VPS_PASSWORD" ]; then # Используем sshpass для передачи пароля if command -v sshpass &> /dev/null; then # Копируем скрипт на VPS if sshpass -p "$VPS_PASSWORD" scp -P "$VPS_PORT" -o StrictHostKeyChecking=no "$SETUP_SCRIPT" "$VPS_USER@$VPS_HOST:/tmp/setup_vps_sshd.sh" 2>/dev/null; then echo "✓ Скрипт скопирован на VPS" # Выполняем скрипт на VPS echo "Выполнение настройки на VPS..." if sshpass -p "$VPS_PASSWORD" ssh -p "$VPS_PORT" -o StrictHostKeyChecking=no "$VPS_USER@$VPS_HOST" "chmod +x /tmp/setup_vps_sshd.sh && sudo /tmp/setup_vps_sshd.sh" 2>&1; then echo -e "${GREEN}✓ Настройка SSH сервера на VPS выполнена успешно${NC}" else echo -e "${YELLOW}⚠ Не удалось выполнить настройку автоматически${NC}" echo -e "${YELLOW}Выполните настройку вручную на VPS${NC}" fi else echo -e "${RED}✗ Не удалось скопировать скрипт на VPS${NC}" fi else echo -e "${YELLOW}⚠ sshpass не установлен. Невозможно автоматически настроить VPS${NC}" fi else echo -e "${YELLOW}⚠ Пароль не указан. Невозможно автоматически настроить VPS${NC}" echo -e "${YELLOW}Выполните настройку вручную:${NC}" cat "$SETUP_SCRIPT" fi # Удаляем временный скрипт rm -f "$SETUP_SCRIPT" echo "" echo -e "${CYAN}Рекомендуемые настройки для VPS (/etc/ssh/sshd_config):${NC}" echo " PasswordAuthentication yes" echo " PubkeyAuthentication yes" echo " PermitRootLogin yes" echo " MaxSessions 20" echo " MaxStartups 20:30:100" echo " GatewayPorts yes" echo " AllowTcpForwarding yes" echo "" echo -e "${YELLOW}После изменения настроек перезапустите SSH сервер:${NC}" echo " systemctl restart sshd" } # --- Основные функции --- # 1. Установка зависимостей и настройка системы install_manager() { check_root "install" log_message "Начало установки SSH Tunnel Manager..." "$CYAN" # Создание директорий log_message "Создание системных директорий..." "$BLUE" mkdir -p "$CONFIG_DIR" "$TUNNELS_DIR" "$LOG_DIR" chmod 700 "$CONFIG_DIR" "$TUNNELS_DIR" chmod 777 "$LOG_DIR" # Для удобства логирования # Установка зависимостей log_message "Установка необходимых зависимостей (autossh, openssh-client)..." "$BLUE" # Определение дистрибутива local OS if [ -f /etc/os-release ]; then . /etc/os-release OS=$ID fi log_message "Обнаружен дистрибутив: ${OS:-Unknown}" "$BLUE" if [[ "$OS" == "ubuntu" || "$OS" == "debian" ]]; then log_message "Обновление списка пакетов..." "$BLUE" apt-get update 2>&1 | tee -a "$LOG_DIR/manager.log" check_error "Не удалось обновить список пакетов" log_message "Установка autossh, openssh-client и sshpass..." "$BLUE" apt-get install -y autossh openssh-client sshpass netcat 2>&1 | tee -a "$LOG_DIR/manager.log" check_error "Не удалось установить пакеты (apt)" elif [[ "$OS" == "centos" || "$OS" == "rhel" || "$OS" == "fedora" || "$OS" == "rocky" || "$OS" == "almalinux" ]]; then log_message "Установка autossh, openssh-clients и sshpass..." "$BLUE" if command -v dnf &> /dev/null; then dnf install -y autossh openssh-clients sshpass nc 2>&1 | tee -a "$LOG_DIR/manager.log" check_error "Не удалось установить пакеты (dnf)" else yum install -y autossh openssh-clients sshpass nc 2>&1 | tee -a "$LOG_DIR/manager.log" check_error "Не удалось установить пакеты (yum)" fi else log_message "ОШИБКА: Не удалось определить менеджер пакетов (apt, dnf, yum)." "$RED" log_message "Пожалуйста, установите autossh и openssh-client вручную." "$YELLOW" return 1 fi if ! command -v autossh &> /dev/null; then log_message "ОШИБКА: autossh не установлен. Проверьте вывод установки." "$RED" return 1 fi log_message "Зависимости успешно установлены." "$GREEN" # Копирование скрипта в системный путь log_message "Копирование скрипта в $SCRIPT_PATH..." "$BLUE" # Получаем путь к текущему скрипту local SCRIPT_SOURCE if [[ -f "$0" ]]; then SCRIPT_SOURCE="$0" else # Если скрипт запущен через pipe, создаем временный файл SCRIPT_SOURCE="/tmp/tunnel-manager-$(date +%s).sh" cat > "$SCRIPT_SOURCE" << 'EOF' # Скрипт будет заменен содержимым установщика EOF fi # Копируем содержимое текущего скрипта cat > "$SCRIPT_PATH" << 'EOFHDR' #!/bin/bash # # SSH Tunnel Manager - Установленная версия # EOFHDR # Добавляем основное содержимое скрипта cat "$SCRIPT_SOURCE" >> "$SCRIPT_PATH" chmod +x "$SCRIPT_PATH" log_message "Установка завершена. Теперь можно использовать команду: sudo tunnel-manager menu" "$GREEN" # Генерация SSH ключа if [ ! -f "/root/.ssh/id_rsa" ]; then log_message "Генерация SSH ключа RSA 4096 бит для root..." "$BLUE" mkdir -p /root/.ssh ssh-keygen -t rsa -b 4096 -N "" -f /root/.ssh/id_rsa -q log_message "SSH ключ сгенерирован: /root/.ssh/id_rsa.pub" "$GREEN" else log_message "SSH ключ уже существует. Используем существующий." "$YELLOW" fi # Настройка SSH конфига для стабильности log_message "Настройка SSH клиента для стабильности..." "$BLUE" cat > /root/.ssh/config << EOFCONFIG Host * StrictHostKeyChecking no UserKnownHostsFile /dev/null ServerAliveInterval 30 ServerAliveCountMax 3 ConnectTimeout 30 TCPKeepAlive yes IdentitiesOnly yes ExitOnForwardFailure yes ControlMaster auto ControlPath ~/.ssh/control-%r@%h:%p ControlPersist 10m # Дополнительные настройки стабильности IPQoS throughput Compression yes GSSAPIAuthentication no AddressFamily inet Ciphers chacha20-poly1305@openssh.com,aes256-gcm@openssh.com,aes128-gcm@openssh.com,aes256-ctr,aes192-ctr,aes128-ctr MACs hmac-sha2-512-etm@openssh.com,hmac-sha2-256-etm@openssh.com,umac-128-etm@openssh.com KexAlgorithms curve25519-sha256,curve25519-sha256@libssh.org,diffie-hellman-group-exchange-sha256 EOFCONFIG chmod 600 /root/.ssh/config log_message "Конфигурация SSH клиента обновлена." "$GREEN" # Настройка локального SSHD configure_local_sshd } # Функция установки SSH сервера install_ssh_server() { log_message "Проверка установки SSH сервера..." "$BLUE" # Проверяем, установлен ли sshd if ! command -v sshd &> /dev/null && [ ! -f /etc/ssh/sshd_config ]; then log_message "SSH сервер не установлен. Устанавливаем..." "$YELLOW" # Определение дистрибутива local OS if [ -f /etc/os-release ]; then . /etc/os-release OS=$ID fi if [[ "$OS" == "ubuntu" || "$OS" == "debian" ]]; then apt-get install -y openssh-server 2>&1 | tee -a "$LOG_DIR/manager.log" elif [[ "$OS" == "centos" || "$OS" == "rhel" || "$OS" == "fedora" || "$OS" == "rocky" || "$OS" == "almalinux" ]]; then if command -v dnf &> /dev/null; then dnf install -y openssh-server 2>&1 | tee -a "$LOG_DIR/manager.log" else yum install -y openssh-server 2>&1 | tee -a "$LOG_DIR/manager.log" fi else log_message "Не удалось определить дистрибутив для установки SSH сервера." "$RED" return 1 fi # Проверяем установку if command -v sshd &> /dev/null; then log_message "SSH сервер успешно установлен." "$GREEN" else log_message "Не удалось установить SSH сервер." "$RED" return 1 fi else log_message "SSH сервер уже установлен." "$GREEN" fi # Запускаем и включаем автозагрузку if systemctl is-active sshd &> /dev/null; then log_message "SSH сервер уже запущен." "$GREEN" else systemctl start sshd 2>&1 | tee -a "$LOG_DIR/manager.log" systemctl enable sshd 2>&1 | tee -a "$LOG_DIR/manager.log" log_message "SSH сервер запущен и включен в автозагрузку." "$GREEN" fi return 0 } # Функция настройки локального SSH-демона для приема туннелей configure_local_sshd() { log_message "Настройка локального SSH-демона (sshd) для приема туннелей..." "$BLUE" # Устанавливаем SSH сервер если нужно install_ssh_server local SSHD_CONFIG="/etc/ssh/sshd_config" if [ ! -f "$SSHD_CONFIG" ]; then log_message "ОШИБКА: Файл конфигурации SSHD не найден: $SSHD_CONFIG" "$RED" log_message "Попытка найти альтернативный путь..." "$YELLOW" # Пробуем найти sshd_config SSHD_CONFIG=$(find /etc -name "sshd_config" 2>/dev/null | head -1) if [ -z "$SSHD_CONFIG" ]; then SSHD_CONFIG=$(find /etc/ssh -name "sshd_config" 2>/dev/null | head -1) fi if [ -z "$SSHD_CONFIG" ] || [ ! -f "$SSHD_CONFIG" ]; then log_message "Не удалось найти файл конфигурации SSHD. Создаем новый." "$YELLOW" mkdir -p /etc/ssh SSHD_CONFIG="/etc/ssh/sshd_config" # Создаем базовую конфигурацию cat > "$SSHD_CONFIG" << 'EOFSSHD' # SSH Server Configuration Port 22 Protocol 2 HostKey /etc/ssh/ssh_host_rsa_key HostKey /etc/ssh/ssh_host_ecdsa_key HostKey /etc/ssh/ssh_host_ed25519_key # Logging SyslogFacility AUTH LogLevel INFO # Authentication: LoginGraceTime 120 PermitRootLogin yes StrictModes yes PasswordAuthentication yes PubkeyAuthentication yes AuthenticationMethods publickey,password # Allow forwardings for tunnels AllowTcpForwarding yes GatewayPorts yes X11Forwarding yes X11DisplayOffset 10 X11UseLocalhost yes # Allow client to pass locale environment variables AcceptEnv LANG LC_* # Allow override in ~/.ssh/authorized_keys AuthorizedKeysFile .ssh/authorized_keys # Don't allow empty passwords PermitEmptyPasswords no # Change to no to disable s/key passwords ChallengeResponseAuthentication no # GSSAPI options GSSAPIAuthentication no GSSAPICleanupCredentials yes UsePAM yes # Allow client alive ClientAliveInterval 30 ClientAliveCountMax 3 # Max sessions MaxSessions 20 MaxStartups 20:30:100 # Allow tunnel creation AllowStreamLocalForwarding yes PermitTunnel yes # Subsystem Subsystem sftp /usr/lib/openssh/sftp-server EOFSSHD log_message "Создан базовый конфигурационный файл SSH сервера." "$GREEN" fi fi # Создание резервной копии cp "$SSHD_CONFIG" "${SSHD_CONFIG}.backup.$(date +%Y%m%d%H%M%S)" log_message "Создана резервная копия: ${SSHD_CONFIG}.backup.$(date +%Y%m%d%H%M%S)" "$YELLOW" # Настройки для приема обратных туннелей log_message "Настройка параметров для SSH туннелей..." "$BLUE" # Массив настроек local SETTINGS=( "GatewayPorts yes" "AllowTcpForwarding yes" "PermitTunnel yes" "AllowStreamLocalForwarding yes" "ClientAliveInterval 30" "ClientAliveCountMax 3" "TCPKeepAlive yes" "PasswordAuthentication yes" "PubkeyAuthentication yes" "MaxSessions 20" "MaxStartups 20:30:100" ) # Применяем настройки for setting in "${SETTINGS[@]}"; do local key=$(echo "$setting" | awk '{print $1}') local value=$(echo "$setting" | awk '{print $2}') # Проверяем существует ли настройка if grep -q "^#\?\s*$key" "$SSHD_CONFIG"; then # Заменяем существующую настройку sed -i "s/^#\?\s*$key.*/$setting/" "$SSHD_CONFIG" log_message "Обновлено: $setting" "$GREEN" else # Добавляем новую настройку echo "$setting" >> "$SSHD_CONFIG" log_message "Добавлено: $setting" "$GREEN" fi done # Проверяем и настраиваем PermitRootLogin if ! grep -q "^PermitRootLogin" "$SSHD_CONFIG"; then echo "PermitRootLogin yes" >> "$SSHD_CONFIG" log_message "Добавлено: PermitRootLogin yes" "$GREEN" fi # Перезапуск SSHD log_message "Перезапуск SSH демона..." "$BLUE" if systemctl restart sshd 2>/dev/null || service ssh restart 2>/dev/null || /etc/init.d/ssh restart 2>/dev/null; then log_message "SSHD перезапущен с новыми настройками." "$GREEN" # Проверяем статус if systemctl is-active sshd &> /dev/null || pgrep sshd &> /dev/null; then log_message "SSH сервер успешно запущен." "$GREEN" else log_message "Предупреждение: Не удалось проверить статус SSH сервера." "$YELLOW" fi else log_message "ПРЕДУПРЕЖДЕНИЕ: Не удалось перезапустить SSHD. Возможно, потребуется ручной перезапуск." "$YELLOW" log_message "Выполните: systemctl restart sshd или service ssh restart" "$YELLOW" fi } # 2. Настройка VPS (сервера) с автоматической настройкой SSH для многопользовательского доступа setup_vps() { check_root "setup_vps" log_message "Настройка подключения к удаленному VPS (серверу)..." "$CYAN" local current_host="" local current_port="22" local current_user="" if load_vps_settings; then current_host="$VPS_HOST" current_port="$VPS_PORT" current_user="$VPS_USER" log_message "Текущая конфигурация: $current_user@$current_host:$current_port" "$YELLOW" fi echo -e "${BOLD}${CYAN}--- Настройка VPS ---${NC}" echo -e "${YELLOW}Это настройка удаленного сервера (VPS), куда будут пробрасываться туннели${NC}" echo "" local VPS_HOST_TEMP local VPS_PORT_TEMP local VPS_USER_TEMP local USER_CHOICE # Ввод IP и Порта safe_read "Введите IP адрес или доменное имя VPS (текущий: $current_host): " "$current_host" VPS_HOST_TEMP safe_read "Введите порт SSH (по умолчанию 22, текущий: $current_port): " "$current_port" VPS_PORT_TEMP # Выбор пользователя echo -e "${CYAN}Выберите пользователя для подключения:${NC}" echo "1) root (рекомендуется для полного доступа)" echo "2) Другой пользователь" USER_CHOICE=$(read_input "Ваш выбор [1-2]: ") if [ "$USER_CHOICE" == "1" ]; then VPS_USER_TEMP="root" echo -e "${YELLOW}Будет использоваться пользователь: root${NC}" else safe_read "Введите имя пользователя на VPS (текущий: $current_user): " "$current_user" VPS_USER_TEMP fi VPS_HOST="$VPS_HOST_TEMP" VPS_PORT="$VPS_PORT_TEMP" VPS_USER="$VPS_USER_TEMP" if [ -z "$VPS_HOST" ] || [ -z "$VPS_USER" ]; then log_message "ОШИБКА: IP адрес и имя пользователя обязательны." "$RED" read_input "Нажмите Enter для продолжения..." return 1 fi # Дополнительная проверка, если пользователь выбрал "Другой пользователь", но не ввел имя if [ "$USER_CHOICE" == "2" ] && [ -z "$VPS_USER" ]; then log_message "ОШИБКА: Имя пользователя обязательно." "$RED" read_input "Нажмите Enter для продолжения..." return 1 fi # Сохранение настроек cat > "$VPS_CONFIG" << EOFSETTINGS # Настройки VPS для автономных туннелей VPS_HOST="$VPS_HOST" VPS_PORT="$VPS_PORT" VPS_USER="$VPS_USER" CONFIGURED_ON="$(date '+%Y-%m-%d %H:%M:%S')" EOFSETTINGS chmod 600 "$VPS_CONFIG" log_message "Настройки VPS сохранены в $VPS_CONFIG" "$GREEN" # Автоматическое копирование ключа log_message "Попытка автоматического копирования SSH-ключа на VPS..." "$CYAN" # Запрос пароля для sshpass с безопасным вводом local VPS_PASSWORD echo -e "${YELLOW}Для автоматического копирования ключа потребуется пароль от $VPS_USER на VPS.${NC}" echo -e "${YELLOW}Если вы не хотите вводить пароль, нажмите Enter и скопируйте ключ вручную.${NC}" # Используем read_secret для скрытого ввода VPS_PASSWORD=$(read_secret "Введите пароль для $VPS_USER@$VPS_HOST (оставьте пустым для пропуска): ") if [ -n "$VPS_PASSWORD" ]; then if command -v sshpass &> /dev/null; then # Используем sshpass для автоматического копирования ключа echo -e "${BLUE}Копирую ключ на VPS...${NC}" if sshpass -p "$VPS_PASSWORD" ssh-copy-id -p "$VPS_PORT" -i /root/.ssh/id_rsa.pub -o StrictHostKeyChecking=no "$VPS_USER@$VPS_HOST" 2>&1 | tee -a "$LOG_DIR/manager.log"; then log_message "SSH ключ успешно скопирован на VPS!" "$GREEN" # Предлагаем настроить SSH сервер на VPS для многопользовательского доступа echo "" echo -e "${CYAN}Настройка SSH сервера на VPS для поддержки:${NC}" echo " - Многопользовательского доступа" echo " - Одновременных подключений с нескольких мест" echo " - Аутентификации по паролю И по ключам" echo " - Обратных туннелей" echo "" CONFIGURE_VPS=$(read_input "Настроить SSH сервер на VPS автоматически? (y/N): ") if [[ "$CONFIGURE_VPS" =~ ^[Yy]$ ]]; then check_and_configure_vps_sshd "$VPS_PASSWORD" else echo -e "${YELLOW}Пропущена автоматическая настройка VPS${NC}" echo -e "${YELLOW}Важно! Убедитесь, что на VPS в /etc/ssh/sshd_config есть:${NC}" echo " PasswordAuthentication yes" echo " MaxSessions 20" echo " MaxStartups 20:30:100" fi else log_message "ОШИБКА: Не удалось скопировать ключ через sshpass." "$RED" log_message "Возможно, пароль неверен, или на VPS не установлен ssh-copy-id." "$YELLOW" log_message "Вам может потребоваться скопировать ключ вручную:" "$YELLOW" echo "" cat /root/.ssh/id_rsa.pub echo "" echo -e "${YELLOW}Выполните на VPS команду:${NC}" echo "mkdir -p ~/.ssh && echo '$(cat /root/.ssh/id_rsa.pub)' >> ~/.ssh/authorized_keys" fi else log_message "ПРЕДУПРЕЖДЕНИЕ: sshpass не установлен. Невозможно скопировать ключ автоматически." "$YELLOW" log_message "Вам потребуется скопировать ключ вручную:" "$YELLOW" cat /root/.ssh/id_rsa.pub fi else log_message "Пароль не введен. Вам потребуется скопировать ключ вручную:" "$YELLOW" cat /root/.ssh/id_rsa.pub fi # Тестовое подключение echo "" log_message "Проверка подключения к $VPS_USER@$VPS_HOST:$VPS_PORT..." "$BLUE" check_ssh_connection read_input "Нажмите Enter для продолжения..." } # Функция для ручной настройки VPS SSH сервера configure_vps_ssh_manually() { echo -e "${BOLD}${CYAN}--- Ручная настройка SSH сервера на VPS ---${NC}" echo "" echo -e "${YELLOW}Для правильной работы туннелей и многопользовательского доступа,${NC}" echo -e "${YELLOW}на VPS должны быть настроены следующие параметры в /etc/ssh/sshd_config:${NC}" echo "" echo -e "${GREEN}1. Разрешить аутентификацию по паролю:${NC}" echo " PasswordAuthentication yes" echo "" echo -e "${GREEN}2. Разрешить аутентификацию по ключам:${NC}" echo " PubkeyAuthentication yes" echo "" echo -e "${GREEN}3. Разрешить вход root:${NC}" echo " PermitRootLogin yes" echo "" echo -e "${GREEN}4. Настройки для туннелей:${NC}" echo " GatewayPorts yes" echo " AllowTcpForwarding yes" echo " PermitTunnel yes" echo "" echo -e "${GREEN}5. Настройки многопользовательского доступа:${NC}" echo " MaxSessions 20" echo " MaxStartups 20:30:100" echo "" echo -e "${GREEN}6. Дополнительные настройки:${NC}" echo " ClientAliveInterval 30" echo " ClientAliveCountMax 3" echo " TCPKeepAlive yes" echo "" if load_vps_settings; then echo -e "${CYAN}Ваш VPS: $VPS_USER@$VPS_HOST:$VPS_PORT${NC}" echo "" echo -e "${YELLOW}Команды для настройки VPS:${NC}" echo "ssh -p $VPS_PORT $VPS_USER@$VPS_HOST" echo "" echo -e "${YELLOW}После подключения выполните на VPS:${NC}" cat << 'EOF_VPS_COMMANDS' # Создайте резервную копию конфигурации sudo cp /etc/ssh/sshd_config /etc/ssh/sshd_config.backup # Отредактируйте файл конфигурации sudo nano /etc/ssh/sshd_config # Добавьте или измените следующие параметры: PasswordAuthentication yes PubkeyAuthentication yes PermitRootLogin yes GatewayPorts yes AllowTcpForwarding yes PermitTunnel yes MaxSessions 20 MaxStartups 20:30:100 ClientAliveInterval 30 ClientAliveCountMax 3 TCPKeepAlive yes # После сохранения проверьте конфигурацию sudo sshd -t # Если проверка прошла успешно, перезапустите SSH сервер sudo systemctl restart sshd # Или для старых систем: sudo service ssh restart EOF_VPS_COMMANDS else echo -e "${RED}Сначала настройте VPS в основном меню (опция 1)${NC}" fi read_input "Нажмите Enter для продолжения..." } # 3. Добавление нового туннеля add_tunnel() { check_root "add_tunnel" if ! load_vps_settings; then log_message "Сначала необходимо настроить VPS (опция 1)." "$RED" read_input "Нажмите Enter для продолжения..." return 1 fi echo -e "${BOLD}${CYAN}--- Добавление нового обратного туннеля (Local -> VPS) ---${NC}" log_message "VPS: $VPS_USER@$VPS_HOST:$VPS_PORT" "$YELLOW" echo -e "${YELLOW}Туннель будет пробрасывать локальный порт на этом компьютере через VPS${NC}" echo "" local LOCAL_PORT="" local REMOTE_PORT="" local TUNNEL_NAME="" safe_read "Введите локальный порт, который нужно пробросить (например, 22 для SSH): " "" LOCAL_PORT safe_read "Введите удаленный порт на VPS, через который будет доступен локальный порт (например, 10022): " "" REMOTE_PORT safe_read "Введите имя туннеля (например, 'ssh_access'): " "" TUNNEL_NAME # Проверка ввода if ! [[ "$LOCAL_PORT" =~ ^[0-9]+$ ]] || [ "$LOCAL_PORT" -lt 1 ] || [ "$LOCAL_PORT" -gt 65535 ]; then log_message "ОШИБКА: Локальный порт должен быть числом от 1 до 65535." "$RED" read_input "Нажмите Enter для продолжения..." return 1 fi if ! [[ "$REMOTE_PORT" =~ ^[0-9]+$ ]] || [ "$REMOTE_PORT" -lt 1 ] || [ "$REMOTE_PORT" -gt 65535 ]; then log_message "ОШИБКА: Удаленный порт должен быть числом от 1 до 65535." "$RED" read_input "Нажмите Enter для продолжения..." return 1 fi if [ -z "$TUNNEL_NAME" ]; then log_message "ОШИБКА: Имя туннеля обязательно." "$RED" read_input "Нажмите Enter для продолжения..." return 1 fi # Проверка имени туннеля TUNNEL_ID=$(echo "$TUNNEL_NAME" | tr '[:upper:]' '[:lower:]' | tr -cd '[:alnum:]_') if [ -f "$TUNNELS_DIR/$TUNNEL_ID.conf" ]; then log_message "ОШИБКА: Туннель с именем '$TUNNEL_ID' уже существует." "$RED" read_input "Нажмите Enter для продолжения..." return 1 fi # Проверяем, доступен ли локальный порт echo -e "${BLUE}Проверка доступности локального порта $LOCAL_PORT...${NC}" if timeout 2 nc -z localhost "$LOCAL_PORT" 2>/dev/null; then echo -e "${GREEN}✓ Локальный порт $LOCAL_PORT доступен${NC}" else echo -e "${YELLOW}⚠ Локальный порт $LOCAL_PORT не отвечает${NC}" echo -e "${YELLOW}Убедитесь, что служба слушает на этом порту${NC}" fi # Создание конфигурационного файла туннеля local CONFIG_FILE="$TUNNELS_DIR/$TUNNEL_ID.conf" cat > "$CONFIG_FILE" << EOFCONF # Конфигурация туннеля: $TUNNEL_NAME TUNNEL_ID="$TUNNEL_ID" TUNNEL_NAME="$TUNNEL_NAME" LOCAL_PORT="$LOCAL_PORT" REMOTE_PORT="$REMOTE_PORT" VPS_HOST="$VPS_HOST" VPS_PORT="$VPS_PORT" VPS_USER="$VPS_USER" CREATED="$(date '+%Y-%m-%d %H:%M:%S')" EOFCONF # Создание systemd unit-файла local SERVICE_NAME="tunnel-$TUNNEL_ID" local SERVICE_FILE="$SERVICE_DIR/$SERVICE_NAME.service" cat > "$SERVICE_FILE" << EOFSERVICE [Unit] Description=SSH Reverse Tunnel: $TUNNEL_NAME ($LOCAL_PORT -> $REMOTE_PORT) After=network-online.target Wants=network-online.target StartLimitIntervalSec=0 [Service] Type=simple EnvironmentFile=$CONFIG_FILE ExecStart=/usr/bin/autossh -M 0 -N \ -o "ExitOnForwardFailure=yes" \ -o "ServerAliveInterval=30" \ -o "ServerAliveCountMax=3" \ -o "StrictHostKeyChecking=no" \ -o "UserKnownHostsFile=/dev/null" \ -o "TCPKeepAlive=yes" \ -o "ConnectTimeout=30" \ -o "IdentityFile=/root/.ssh/id_rsa" \ -R $REMOTE_PORT:localhost:$LOCAL_PORT \ $VPS_USER@$VPS_HOST -p $VPS_PORT ExecReload=/bin/kill -HUP \$MAINPID Restart=always RestartSec=10 User=root StandardOutput=append:$LOG_DIR/$TUNNEL_ID.log StandardError=append:$LOG_DIR/$TUNNEL_ID.log [Install] WantedBy=multi-user.target EOFSERVICE log_message "Конфигурация туннеля '$TUNNEL_NAME' создана." "$GREEN" # Запуск и включение службы systemctl daemon-reload systemctl enable "$SERVICE_NAME.service" > /dev/null 2>&1 systemctl start "$SERVICE_NAME.service" if systemctl is-active --quiet "$SERVICE_NAME.service"; then log_message "Туннель '$TUNNEL_NAME' успешно запущен и включен в автозагрузку." "$GREEN" echo "" echo -e "${BOLD}${CYAN}Информация о туннеле:${NC}" echo -e " Имя: $TUNNEL_NAME" echo -e " Локальный порт: $LOCAL_PORT" echo -e " Удаленный порт на VPS: $REMOTE_PORT" echo -e " VPS: $VPS_USER@$VPS_HOST:$VPS_PORT" echo "" echo -e "${GREEN}Для доступа к локальному порту $LOCAL_PORT через VPS используйте:${NC}" echo -e "${BOLD} ssh -p $REMOTE_PORT $VPS_USER@$VPS_HOST${NC}" echo "" echo -e "${YELLOW}Логи туннеля: $LOG_DIR/$TUNNEL_ID.log${NC}" else log_message "ОШИБКА: Не удалось запустить туннель '$TUNNEL_NAME'." "$RED" log_message "Проверьте лог: tail -f $LOG_DIR/$TUNNEL_ID.log" "$YELLOW" log_message "Проверьте подключение к VPS и права SSH ключа." "$YELLOW" fi read_input "Нажмите Enter для продолжения..." } # 4. Управление туннелем (запуск, остановка, перезапуск, удаление) manage_tunnel() { local TUNNEL_ID="$1" local ACTION="$2" local SERVICE_NAME="tunnel-$TUNNEL_ID" if [ ! -f "$TUNNELS_DIR/$TUNNEL_ID.conf" ]; then log_message "ОШИБКА: Туннель с ID '$TUNNEL_ID' не найден." "$RED" return 1 fi case "$ACTION" in start|stop|restart) systemctl "$ACTION" "$SERVICE_NAME.service" log_message "Служба '$SERVICE_NAME' выполнила команду '$ACTION'." "$GREEN" ;; status) systemctl status "$SERVICE_NAME.service" ;; remove) log_message "Остановка и удаление туннеля '$TUNNEL_ID'..." "$YELLOW" systemctl stop "$SERVICE_NAME.service" systemctl disable "$SERVICE_NAME.service" > /dev/null 2>&1 rm -f "$SERVICE_DIR/$SERVICE_NAME.service" rm -f "$TUNNELS_DIR/$TUNNEL_ID.conf" rm -f "$LOG_DIR/$TUNNEL_ID.log" systemctl daemon-reload log_message "Туннель '$TUNNEL_ID' полностью удален." "$GREEN" ;; *) log_message "Неизвестное действие: $ACTION" "$RED" return 1 ;; esac } # 5. Список туннелей list_tunnels() { echo -e "${BOLD}${CYAN}--- Список настроенных туннелей ---${NC}" local count=0 local header="%-20s | %-10s | %-10s | %-20s | %-10s" local separator="---------------------|------------|------------|----------------------|------------" printf "$header\n" "ИМЯ ТУННЕЛЯ" "ЛОК. ПОРТ" "УД. ПОРТ" "СТАТУС" "АВТОЗАГРУЗКА" echo "$separator" for config_file in "$TUNNELS_DIR"/*.conf; do if [ -f "$config_file" ]; then source "$config_file" local SERVICE_NAME="tunnel-$TUNNEL_ID" local STATUS=$(systemctl is-active "$SERVICE_NAME.service" 2>/dev/null || echo "inactive") local ENABLED=$(systemctl is-enabled "$SERVICE_NAME.service" 2>/dev/null || echo "disabled") local STATUS_COLOR="$RED" if [ "$STATUS" == "active" ]; then STATUS_COLOR="$GREEN" elif [ "$STATUS" == "inactive" ]; then STATUS_COLOR="$YELLOW" fi printf "%-20s | %-10s | %-10s | ${STATUS_COLOR}%-20s${NC} | %-10s\n" \ "$TUNNEL_ID" "$LOCAL_PORT" "$REMOTE_PORT" "$STATUS" "$ENABLED" count=$((count + 1)) fi done if [ "$count" -eq 0 ]; then echo -e "${YELLOW}Туннели не найдены. Используйте опцию 2 для добавления нового.${NC}" fi echo "" } # Функция просмотра логов view_logs() { while true; do clear echo -e "${BOLD}${CYAN}Просмотр логов${NC}" echo -e "${YELLOW}=============${NC}" echo "" echo -e "${CYAN}[1]${NC} Логи конкретного туннеля" echo -e "${CYAN}[2]${NC} Все логи туннелей (последние 5 строк)" echo -e "${CYAN}[3]${NC} Системные логи (journalctl)" echo -e "${CYAN}[4]${NC} Лог менеджера" echo -e "${CYAN}[5]${NC} Назад" echo "" choice=$(read_input "Выберите действие: ") case $choice in 1) local LOG_DIR="/var/log/tunnel-manager" echo -e "${CYAN}Доступные логи:${NC}" ls -1 "$LOG_DIR"/*.log 2>/dev/null | xargs -n1 basename | grep -v "manager.log" || echo " Логи не найдены" echo "" log_file=$(read_input "Введите имя лог-файла (например, tunnel-ssh_access.log): ") if [ -f "$LOG_DIR/$log_file" ]; then less "$LOG_DIR/$log_file" else log_message "Файл не найден" "$RED" sleep 1 fi ;; 2) local LOG_DIR="/var/log/tunnel-manager" echo -e "${CYAN}Все логи туннелей (последние 5 строк):${NC}" for log in "$LOG_DIR"/tunnel-*.log; do if [ -f "$log" ]; then echo -e "\n${YELLOW}=== $(basename "$log") ===${NC}" tail -5 "$log" fi done read_input "Нажмите Enter для продолжения..." ;; 3) echo -e "${CYAN}Системные логи туннелей (последний час):${NC}" journalctl -u tunnel-* --since "1 hour ago" -n 20 2>/dev/null || log_message "Системные логи отсутствуют" "$YELLOW" read_input "Нажмите Enter для продолжения..." ;; 4) echo -e "${CYAN}Лог менеджера:${NC}" less "/var/log/tunnel-manager/manager.log" ;; 5) return ;; *) log_message "Неверный выбор" "$RED" sleep 1 ;; esac done } # Функция тестирования подключений test_connections() { while true; do clear echo -e "${BOLD}${CYAN}Тестирование подключений${NC}" echo -e "${YELLOW}========================${NC}" echo "1) Тест подключения к VPS" echo "2) Тест локальных портов туннелей" echo "3) Тест SSH ключа" echo "4) Тест доступности портов на VPS" echo "5) Назад" echo "" test_choice=$(read_input "Выберите тест: ") case $test_choice in 1) check_ssh_connection read_input "Нажмите Enter для продолжения..." ;; 2) echo -e "${CYAN}Тест локальных портов туннелей:${NC}" local TUNNEL_DIR="/etc/tunnel-manager/tunnels" local NC_CMD if command -v nc &> /dev/null; then NC_CMD="nc -z localhost" elif command -v ncat &> /dev/null; then NC_CMD="ncat -z localhost" else log_message "ОШИБКА: Утилита 'nc' или 'ncat' не найдена. Невозможно проверить порты." "$RED" read_input "Нажмите Enter для продолжения..." continue fi for conf in "$TUNNEL_DIR"/*.conf; do if [ -f "$conf" ]; then local LOCAL_PORT LOCAL_PORT=$(grep '^LOCAL_PORT=' "$conf" | cut -d'=' -f2 | tr -d '"') local TUNNEL_NAME TUNNEL_NAME=$(basename "$conf" .conf) echo -n " $TUNNEL_NAME (локальный порт $LOCAL_PORT): " if timeout 2 $NC_CMD "$LOCAL_PORT" 2>/dev/null; then echo -e "${GREEN}✓ Открыт${NC}" else echo -e "${RED}✗ Закрыт${NC}" fi fi done read_input "Нажмите Enter для продолжения..." ;; 3) echo -e "${CYAN}Тест SSH ключа:${NC}" if [ -f "/root/.ssh/id_rsa" ]; then echo -e "${GREEN}✓ SSH ключ существует${NC}" echo -e " Путь: /root/.ssh/id_rsa" echo -e " Права: $(stat -c %a /root/.ssh/id_rsa 2>/dev/null || echo "неизвестно")" if [ -f "/root/.ssh/id_rsa.pub" ]; then echo -e "${GREEN}✓ Публичный ключ существует${NC}" echo -e " Публичный ключ:" head -c 100 /root/.ssh/id_rsa.pub echo "..." else echo -e "${RED}✗ Публичный ключ не найден${NC}" fi else echo -e "${RED}✗ SSH ключ не найден${NC}" echo -e "${YELLOW}Выполните установку менеджера для генерации ключа${NC}" fi read_input "Нажмите Enter для продолжения..." ;; 4) if load_vps_settings; then echo -e "${CYAN}Тест доступности портов на VPS ($VPS_HOST):${NC}" # Проверяем SSH порт echo -n " SSH порт $VPS_PORT: " if timeout 3 nc -zv "$VPS_HOST" "$VPS_PORT" 2>&1 | grep -q "succeeded"; then echo -e "${GREEN}✓ Доступен${NC}" else echo -e "${RED}✗ Недоступен${NC}" fi # Проверяем порты туннелей for conf in "$TUNNELS_DIR"/*.conf; do if [ -f "$conf" ]; then local REMOTE_PORT REMOTE_PORT=$(grep '^REMOTE_PORT=' "$conf" | cut -d'=' -f2 | tr -d '"') local TUNNEL_NAME TUNNEL_NAME=$(basename "$conf" .conf) echo -n " $TUNNEL_NAME (порт $REMOTE_PORT): " if timeout 3 nc -zv "$VPS_HOST" "$REMOTE_PORT" 2>&1 | grep -q "succeeded"; then echo -e "${GREEN}✓ Доступен${NC}" else echo -e "${RED}✗ Недоступен${NC}" fi fi done else log_message "Сначала необходимо настроить VPS (опция 1)." "$RED" fi read_input "Нажмите Enter для продолжения..." ;; 5) return ;; *) log_message "Неверный выбор" "$RED" sleep 1 ;; esac done } # Функция настройки маршрутизации (iptables) setup_routing() { if ! command -v iptables &> /dev/null; then log_message "ОШИБКА: Утилита 'iptables' не найдена. Установите ее для использования этой функции." "$RED" read_input "Нажмите Enter для продолжения..." return fi while true; do clear echo -e "${BOLD}${CYAN}Настройка маршрутизации (iptables)${NC}" echo -e "${YELLOW}==================================${NC}" echo "1) Показать текущие правила NAT (PREROUTING)" echo "2) Добавить правило перенаправления порта (DNAT)" echo "3) Сохранить правила (требует iptables-persistent/netfilter-persistent)" echo "4) Назад" echo "" routing_choice=$(read_input "Выберите действие: ") case $routing_choice in 1) echo -e "${CYAN}Текущие правила iptables (NAT PREROUTING):${NC}" sudo iptables -t nat -L PREROUTING -n -v read_input "Нажмите Enter для продолжения..." ;; 2) IN_PORT=$(read_input "Входной порт (напр. 80): ") DEST_IP=$(read_input "IP назначения (напр. 192.168.1.10): ") DEST_PORT=$(read_input "Порт назначения (напр. 8080): ") if [ -n "$IN_PORT" ] && [ -n "$DEST_IP" ] && [ -n "$DEST_PORT" ]; then sudo iptables -t nat -A PREROUTING -p tcp --dport "$IN_PORT" -j DNAT --to-destination "$DEST_IP:$DEST_PORT" log_message "Правило DNAT добавлено: $IN_PORT -> $DEST_IP:$DEST_PORT" "$GREEN" else log_message "Не все поля заполнены." "$RED" fi read_input "Нажмите Enter для продолжения..." ;; 3) if command -v netfilter-persistent &> /dev/null; then sudo netfilter-persistent save log_message "Правила iptables сохранены с помощью netfilter-persistent." "$GREEN" elif command -v iptables-save &> /dev/null; then sudo mkdir -p /etc/iptables sudo iptables-save > /etc/iptables/rules.v4 log_message "Правила iptables сохранены в /etc/iptables/rules.v4." "$GREEN" else log_message "ОШИБКА: Не найдена утилита для сохранения правил (netfilter-persistent или iptables-save)." "$RED" fi read_input "Нажмите Enter для продолжения..." ;; 4) return ;; *) log_message "Неверный выбор" "$RED" sleep 1 ;; esac done } # Функция настройки SSH демона на VPS setup_vps_ssh_config() { while true; do clear echo -e "${BOLD}${CYAN}Настройки SSH Демона на VPS${NC}" echo -e "${YELLOW}==============================${NC}" if ! load_vps_settings; then log_message "Сначала необходимо настроить VPS (опция 1)." "$RED" read_input "Нажмите Enter для продолжения..." return fi echo -e "${CYAN}VPS: $VPS_USER@$VPS_HOST:$VPS_PORT${NC}" echo "" echo "1) Автоматическая настройка SSH сервера на VPS" echo "2) Ручная настройка SSH сервера на VPS (инструкции)" echo "3) Проверить текущие настройки SSH на VPS" echo "4) Назад" echo "" ssh_choice=$(read_input "Выберите действие: ") case $ssh_choice in 1) echo -e "${YELLOW}Для автоматической настройки потребуется пароль от VPS${NC}" VPS_PASSWORD=$(read_secret "Введите пароль для $VPS_USER@$VPS_HOST: ") if [ -n "$VPS_PASSWORD" ]; then check_and_configure_vps_sshd "$VPS_PASSWORD" else echo -e "${RED}Пароль не введен. Невозможно выполнить автоматическую настройку.${NC}" fi read_input "Нажмите Enter для продолжения..." ;; 2) configure_vps_ssh_manually ;; 3) echo -e "${CYAN}Текущие настройки SSH на VPS:${NC}" if [ -f "/root/.ssh/id_rsa" ]; then ssh -p "$VPS_PORT" -i /root/.ssh/id_rsa -o BatchMode=yes "$VPS_USER@$VPS_HOST" \ "grep -E '^(PasswordAuthentication|PubkeyAuthentication|PermitRootLogin|GatewayPorts|AllowTcpForwarding|MaxSessions|MaxStartups)' /etc/ssh/sshd_config 2>/dev/null || echo 'Не удалось получить настройки'" 2>/dev/null else echo -e "${YELLOW}SSH ключ не найден. Сначала выполните установку.${NC}" fi read_input "Нажмите Enter для продолжения..." ;; 4) return ;; *) log_message "Неверный выбор" "$RED" sleep 1 ;; esac done } # Функция настройки локального SSH демона setup_local_ssh_config() { while true; do clear echo -e "${BOLD}${CYAN}Настройки локального SSH Демона (sshd)${NC}" echo -e "${YELLOW}====================================${NC}" echo "1) Показать текущие настройки sshd (для туннелей)" echo "2) Перезапустить SSH демон" echo "3) Проверить конфигурацию sshd" echo "4) Установить/переустановить SSH сервер" echo "5) Настроить sshd для локальных подключений" echo "6) Показать статус SSH сервера" echo "7) Назад" echo "" ssh_choice=$(read_input "Выберите действие: ") case $ssh_choice in 1) echo -e "${CYAN}Текущие настройки sshd (GatewayPorts, AllowTcpForwarding):${NC}" if [ -f "/etc/ssh/sshd_config" ]; then grep -E "^(GatewayPorts|AllowTcpForwarding|PermitTunnel|AllowStreamLocalForwarding|PermitRootLogin|PasswordAuthentication)" /etc/ssh/sshd_config 2>/dev/null || echo "Настройки не найдены или файл конфигурации отсутствует" else echo "Файл /etc/ssh/sshd_config не найден" echo "SSH сервер, вероятно, не установлен" fi read_input "Нажмите Enter для продолжения..." ;; 2) if sudo systemctl restart sshd 2>/dev/null || sudo service ssh restart 2>/dev/null; then log_message "SSH демон перезапущен." "$GREEN" else log_message "ОШИБКА: Не удалось перезапустить SSH демон." "$RED" echo -e "${YELLOW}Попробуйте установить SSH сервер (опция 4)${NC}" fi read_input "Нажмите Enter для продолжения..." ;; 3) if command -v sshd &> /dev/null; then if sudo sshd -t 2>/dev/null; then log_message "Конфигурация SSH корректна." "$GREEN" else log_message "ОШИБКА: Ошибка в конфигурации SSH." "$RED" fi else log_message "SSH сервер не установлен." "$RED" fi read_input "Нажмите Enter для продолжения..." ;; 4) install_ssh_server read_input "Нажмите Enter для продолжения..." ;; 5) configure_local_sshd read_input "Нажмите Enter для продолжения..." ;; 6) echo -e "${CYAN}Статус SSH сервера:${NC}" if systemctl is-active sshd &> /dev/null; then echo -e "${GREEN}✓ SSH сервер запущен${NC}" systemctl status sshd --no-pager -l elif pgrep sshd &> /dev/null; then echo -e "${GREEN}✓ SSH процесс работает${NC}" ps aux | grep sshd | grep -v grep else echo -e "${RED}✗ SSH сервер не запущен${NC}" fi read_input "Нажмите Enter для продолжения..." ;; 7) return ;; *) log_message "Неверный выбор" "$RED" sleep 1 ;; esac done } # 6. Меню управления туннелями manage_tunnels_menu() { while true; do clear echo -e "${BOLD}${CYAN}--- Управление существующими туннелями ---${NC}" echo -e "${YELLOW}===========================================${NC}" local count=0 local TUNNEL_IDS=() for config_file in "$TUNNELS_DIR"/*.conf; do if [ -f "$config_file" ]; then local TUNNEL_ID=$(basename "$config_file" .conf) TUNNEL_IDS+=("$TUNNEL_ID") count=$((count + 1)) fi done if [ "$count" -eq 0 ]; then log_message "Туннели не найдены. Возврат в главное меню." "$YELLOW" sleep 2 return fi list_tunnels echo -e "${CYAN}Введите ID туннеля для управления (или 'b' для назад):${NC}" TUNNEL_ID_MANAGE=$(read_input "ID туннеля: ") if [ "$TUNNEL_ID_MANAGE" == "b" ]; then return fi if [[ " ${TUNNEL_IDS[@]} " =~ " ${TUNNEL_ID_MANAGE} " ]]; then while true; do clear echo -e "${BOLD}${CYAN}--- Управление туннелем $TUNNEL_ID_MANAGE ---${NC}" echo -e "${YELLOW}===========================================${NC}" # Загружаем конфигурацию туннеля if [ -f "$TUNNELS_DIR/$TUNNEL_ID_MANAGE.conf" ]; then source "$TUNNELS_DIR/$TUNNEL_ID_MANAGE.conf" echo -e "${GREEN}Информация о туннеле:${NC}" echo -e " Имя: $TUNNEL_NAME" echo -e " Локальный порт: $LOCAL_PORT" echo -e " Удаленный порт: $REMOTE_PORT" echo -e " VPS: $VPS_USER@$VPS_HOST:$VPS_PORT" echo -e " Создан: $CREATED" echo "" fi # Показываем текущий статус echo -e "${CYAN}Статус службы:${NC}" manage_tunnel "$TUNNEL_ID_MANAGE" "status" | head -20 echo -e "\n${CYAN}Выберите действие:${NC}" echo " s) Статус (обновить)" echo " t) Старт" echo " p) Стоп" echo " r) Перезапуск" echo " e) Включить автозагрузку" echo " d) Отключить автозагрузку" echo " x) Удалить" echo " l) Просмотр логов" echo " b) Назад" ACTION_CHOICE=$(read_input "Действие: ") case "$ACTION_CHOICE" in s) ;; # Статус уже показан t) manage_tunnel "$TUNNEL_ID_MANAGE" "start" sleep 2 ;; p) manage_tunnel "$TUNNEL_ID_MANAGE" "stop" sleep 2 ;; r) manage_tunnel "$TUNNEL_ID_MANAGE" "restart" sleep 2 ;; e) systemctl enable "tunnel-$TUNNEL_ID_MANAGE.service" 2>/dev/null log_message "Автозагрузка включена для туннеля $TUNNEL_ID_MANAGE" "$GREEN" sleep 1 ;; d) systemctl disable "tunnel-$TUNNEL_ID_MANAGE.service" 2>/dev/null log_message "Автозагрузка отключена для туннеля $TUNNEL_ID_MANage" "$YELLOW" sleep 1 ;; x) CONFIRM_REMOVE=$(read_input "Вы уверены, что хотите удалить туннель $TUNNEL_ID_MANAGE? (y/N): ") if [[ "$CONFIRM_REMOVE" =~ ^[Yy]$ ]]; then manage_tunnel "$TUNNEL_ID_MANAGE" "remove" sleep 2 return # Возврат в меню туннелей после удаления fi ;; l) if [ -f "/var/log/tunnel-manager/$TUNNEL_ID_MANAGE.log" ]; then less "/var/log/tunnel-manager/$TUNNEL_ID_MANAGE.log" else log_message "Лог файл не найден" "$RED" sleep 1 fi ;; b) break;; *) log_message "Неизвестная опция." "$RED";; esac read_input "Нажмите Enter для продолжения..."; done else log_message "Туннель с ID '$TUNNEL_ID_MANAGE' не найден." "$RED" sleep 1 fi done } # 7. Главное меню main_menu() { check_root "menu" while true; do clear echo -e "${BOLD}${CYAN}========================================================${NC}" echo -e "${BOLD}${CYAN} SSH Tunnel Manager v2.0 (by Manus) ${NC}" echo -e "${BOLD}${CYAN}========================================================${NC}" # Проверяем наличие SSH ключа if [ ! -f "/root/.ssh/id_rsa" ]; then echo -e "${RED}⚠ SSH ключ не найден. Выполните установку.${NC}" else echo -e "${GREEN}✓ SSH ключ настроен${NC}" fi # Проверяем настройки VPS if load_vps_settings; then echo -e "${GREEN}✓ VPS настроен: $VPS_USER@$VPS_HOST:$VPS_PORT${NC}" else echo -e "${RED}✗ VPS не настроен. Начните с опции 1.${NC}" fi # Проверяем SSH сервер if systemctl is-active sshd &> /dev/null || pgrep sshd &> /dev/null; then echo -e "${GREEN}✓ SSH сервер запущен${NC}" elif [ -f "/etc/ssh/sshd_config" ]; then echo -e "${YELLOW}⚠ SSH сервер не запущен${NC}" else echo -e "${RED}✗ SSH сервер не установлен${NC}" fi echo "" list_tunnels echo -e "${BOLD}${YELLOW}--- МЕНЮ УПРАВЛЕНИЯ ---${NC}" echo -e "1) ${BOLD}Настроить/сменить VPS${NC} (Указать адрес, пользователя, порт)" echo -e "2) ${BOLD}Добавить новый туннель${NC} (Local:Port -> VPS:Port)" echo -e "3) ${BOLD}Управление туннелем${NC} (Статус, Старт, Стоп, Перезапуск, Удаление)" echo -e "4) ${BOLD}Просмотр логов и мониторинг${NC}" echo -e "5) ${BOLD}Тестирование подключений${NC}" echo -e "6) ${BOLD}Настройка маршрутизации (iptables)${NC}" echo -e "7) ${BOLD}Настройки SSH Демона на VPS${NC} (Важно! Для многопользовательского доступа)" echo -e "8) ${BOLD}Настройки локального SSH Демона${NC}" echo -e "9) ${BOLD}Показать публичный ключ${NC} (Для копирования на VPS)" echo -e "0) ${BOLD}Выход${NC}" echo "" choice=$(read_input "Выберите опцию [0-9]: ") case $choice in 1) setup_vps ;; 2) add_tunnel ;; 3) manage_tunnels_menu ;; 4) view_logs ;; 5) test_connections ;; 6) setup_routing ;; 7) setup_vps_ssh_config ;; 8) setup_local_ssh_config ;; 9) show_public_key ;; 0) log_message "Выход из менеджера." "$GREEN" exit 0 ;; *) log_message "Неверный выбор. Попробуйте еще раз." "$RED" sleep 1 ;; esac done } # --- Точка входа --- # Главное изменение: если скрипт запущен без аргументов, выполняем автоматическую установку и запуск меню if [[ $# -eq 0 ]]; then echo -e "${BOLD}${CYAN}SSH Tunnel Manager v2.0${NC}" echo -e "Автоматический запуск установки и меню..." echo "" # Проверяем, установлен ли уже скрипт if [ -f "/usr/local/bin/tunnel-manager" ]; then echo -e "${YELLOW}Менеджер уже установлен. Запуск меню...${NC}" sleep 2 main_menu else echo -e "${GREEN}Начинаем установку...${NC}" echo -e "${YELLOW}Установка займет несколько минут...${NC}" sleep 2 install_manager echo -e "${GREEN}Установка завершена. Запуск меню...${NC}" sleep 2 main_menu fi else case "$1" in install) install_manager ;; menu) main_menu ;; *) echo -e "${BOLD}${CYAN}SSH Tunnel Manager v2.0${NC}" echo -e "Использование:" echo -e " 1. Запуск одной командой (автоустановка + меню):" echo -e " curl -s https://git.softuniq.eu/OpenDoor/vps_ssh_tunel/raw/branch/main/install_ssh_tunnel.sh | sudo bash" echo -e " 2. Только установка: sudo bash $0 install" echo -e " 3. Только меню: sudo bash $0 menu" echo "" echo -e "После установки можно использовать: sudo tunnel-manager menu" ;; esac fi exit 0