#!/bin/bash # Установщик автономного менеджера SSH туннелей # Использование: bash <(curl -s https://git.softuniq.eu/OpenDoor/vps_ssh_tunel/raw/branch/main/install_ssh_tunnel.sh) # Цвета для вывода 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_FILE="/tmp/ssh_tunnel_install.log" log_message() { echo -e "${2:-$NC}[$(date '+%Y-%m-%d %H:%M:%S')] $1${NC}" | tee -a "$LOG_FILE" } clear echo -e "${BOLD}${CYAN}════════════════════════════════════════════════════════════════${NC}" echo -e "${BOLD}${CYAN} УСТАНОВКА АВТОНОМНОГО МЕНЕДЖЕРА SSH ТУННЕЛЕЙ ${NC}" echo -e "${BOLD}${CYAN}════════════════════════════════════════════════════════════════${NC}" echo "" # Проверка прав root if [[ $EUID -ne 0 ]]; then echo -e "${RED}ОШИБКА: Этот скрипт требует прав root (sudo).${NC}" echo "Пожалуйста, запустите снова:" echo -e "${BOLD}sudo bash <(curl -s https://git.softuniq.eu/OpenDoor/vps_ssh_tunel/raw/branch/main/install_ssh_tunnel.sh)${NC}" exit 1 fi # Функция безопасного ввода safe_read() { local prompt="$1" local default="$2" local var_name="$3" local is_password="$4" while true; do if [ "$is_password" = "yes" ]; then read -s -p "$prompt" input echo else read -p "$prompt" input fi input="${input:-$default}" if [ -n "$input" ]; then eval "$var_name=\"$input\"" return 0 else echo -e "${RED}Поле не может быть пустым!${NC}" fi done } # Функция проверки ошибок check_error() { if [ $? -ne 0 ]; then log_message "ОШИБКА: $1" "$RED" log_message "Подробности в логе: $LOG_FILE" "$YELLOW" return 1 fi return 0 } # Определение дистрибутива detect_distro() { log_message "Определение операционной системы..." "$CYAN" if [ -f /etc/os-release ]; then . /etc/os-release OS=$ID VERSION=$VERSION_ID elif [ -f /etc/redhat-release ]; then OS="rhel" VERSION=$(cat /etc/redhat-release | sed 's/.*release \([0-9]\).*/\1/') else OS=$(uname -s) VERSION=$(uname -r) fi log_message "Система: $OS $VERSION" "$GREEN" } # Установка зависимостей install_dependencies() { log_message "Установка необходимых зависимостей..." "$CYAN" case $OS in ubuntu|debian) log_message "Обновление списка пакетов..." "$BLUE" apt-get update 2>&1 | tee -a "$LOG_FILE" log_message "Установка autossh, openssh-client и утилит..." "$BLUE" apt-get install -y autossh openssh-client net-tools curl git sshpass 2>&1 | tee -a "$LOG_FILE" check_error "Не удалось установить пакеты" ;; centos|rhel|fedora|rocky|almalinux) log_message "Установка autossh, openssh-clients и утилит..." "$BLUE" if command -v dnf &> /dev/null; then dnf install -y autossh openssh-clients net-tools curl git sshpass 2>&1 | tee -a "$LOG_FILE" else yum install -y autossh openssh-clients net-tools curl git sshpass 2>&1 | tee -a "$LOG_FILE" fi check_error "Не удалось установить пакеты" ;; *) log_message "Неизвестный дистрибутив. Попытка установки вручную..." "$YELLOW" # Попытка установить autossh из исходников if ! command -v autossh &> /dev/null; then log_message "Установка autossh вручную..." "$BLUE" curl -sSL http://www.harding.motd.ca/autossh/autossh-1.4g.tgz | tar -xz cd autossh-1.4g || exit 1 ./configure make make install cd .. fi ;; esac log_message "Зависимости успешно установлены!" "$GREEN" } # Настройка SSH setup_ssh() { log_message "Настройка SSH системы..." "$CYAN" # Создание директорий SSH если их нет mkdir -p /root/.ssh chmod 700 /root/.ssh # Запрос данных VPS echo "" echo -e "${BOLD}${YELLOW}════════════════════════════════════════════════════════════════${NC}" echo -e "${BOLD}${YELLOW} НАСТРОЙКА ПОДКЛЮЧЕНИЯ К VPS ${NC}" echo -e "${BOLD}${YELLOW}════════════════════════════════════════════════════════════════${NC}" echo "" # Запрос данных VPS while true; do echo -e "${CYAN}Введите данные для подключения к VPS:${NC}" safe_read "IP адрес или доменное имя VPS: " "" VPS_HOST no safe_read "Порт SSH (по умолчанию 22): " "22" VPS_PORT no echo "" echo -e "${CYAN}Выберите пользователя для подключения:${NC}" echo "1) root (рекомендуется для полного доступа)" echo "2) Другой пользователь" safe_read "Ваш выбор [1-2]: " "1" USER_CHOICE no if [ "$USER_CHOICE" == "1" ]; then VPS_USER="root" echo -e "${YELLOW}Будет использоваться пользователь: root${NC}" else safe_read "Введите имя пользователя: " "" VPS_USER no fi echo "" echo -e "${CYAN}Проверка введенных данных:${NC}" echo -e " VPS: ${YELLOW}$VPS_USER@$VPS_HOST:$VPS_PORT${NC}" echo "" safe_read "Все верно? (y/n): " "y" CONFIRM no if [[ "$CONFIRM" =~ ^[Yy]$ ]]; then break else echo -e "${YELLOW}Повторите ввод данных...${NC}" echo "" fi done # Проверка подключения log_message "Проверка подключения к $VPS_USER@$VPS_HOST:$VPS_PORT..." "$BLUE" echo -e "${CYAN}Пытаюсь подключиться к VPS...${NC}" if timeout 10 bash -c "echo > /dev/tcp/$VPS_HOST/$VPS_PORT" 2>/dev/null; then log_message "Порт $VPS_PORT доступен" "$GREEN" else log_message "Не удалось подключиться к порту $VPS_PORT" "$RED" echo -e "${YELLOW}Проверьте:${NC}" echo -e " 1) Правильность адреса VPS" echo -e " 2) Открыт ли порт $VPS_PORT на VPS" echo -e " 3) Работает ли SSH сервер на VPS" echo -e " 4) Не блокирует ли брандмауэр подключение" safe_read "Продолжить все равно? (y/n): " "n" CONTINUE no if [[ ! "$CONTINUE" =~ ^[Yy]$ ]]; then exit 1 fi fi # Генерация SSH ключа echo "" log_message "Генерация SSH ключа RSA 4096 бит..." "$CYAN" if [ -f "/root/.ssh/id_rsa" ]; then echo -e "${YELLOW}SSH ключ уже существует.${NC}" safe_read "Сгенерировать новый? (y/n): " "n" GEN_NEW no if [[ "$GEN_NEW" =~ ^[Yy]$ ]]; then ssh-keygen -t rsa -b 4096 -N "" -f /root/.ssh/id_rsa -q log_message "Новый SSH ключ сгенерирован" "$GREEN" fi else ssh-keygen -t rsa -b 4096 -N "" -f /root/.ssh/id_rsa -q log_message "SSH ключ сгенерирован" "$GREEN" fi # Настройка SSH конфигурации для стабильного подключения log_message "Настройка конфигурации SSH для стабильного подключения..." "$BLUE" # Создание конфига для root с улучшенными настройками cat > /root/.ssh/config << EOF # Основная конфигурация SSH Host tunnel-vps HostName $VPS_HOST Port $VPS_PORT User $VPS_USER IdentityFile ~/.ssh/id_rsa StrictHostKeyChecking no UserKnownHostsFile /dev/null ServerAliveInterval 30 ServerAliveCountMax 3 ConnectTimeout 30 TCPKeepAlive yes IdentitiesOnly yes ExitOnForwardFailure yes # Увеличенные настройки для локальной сети IPQoS throughput Compression yes ControlMaster auto ControlPath ~/.ssh/control-%r@%h:%p ControlPersist 10m # Дополнительные настройки стабильности 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 Host * # Глобальные настройки для всех хостов StrictHostKeyChecking no UserKnownHostsFile /dev/null ServerAliveInterval 30 ServerAliveCountMax 3 TCPKeepAlive yes Compression yes ControlMaster auto ControlPath ~/.ssh/control-%r@%h:%p ControlPersist 10m ConnectTimeout 30 # Настройки для локальной сети GSSAPIAuthentication no AddressFamily inet # Увеличение размера буферов SendEnv LANG LC_* HashKnownHosts yes # Настройки переподключения RekeyLimit 1G 1h EOF chmod 600 /root/.ssh/config # Настройка SSH демона для локальных подключений log_message "Настройка SSH демона для локальных подключений..." "$BLUE" # Бэкап оригинального конфига SSHD_CONFIG="/etc/ssh/sshd_config" if [ -f "$SSHD_CONFIG" ]; then cp "$SSHD_CONFIG" "${SSHD_CONFIG}.backup.$(date +%Y%m%d%H%M%S)" # Улучшенные настройки для стабильности SSHD_SETTINGS=( "ClientAliveInterval 30" "ClientAliveCountMax 3" "TCPKeepAlive yes" "PasswordAuthentication yes" "PermitRootLogin yes" "GatewayPorts yes" "AllowTcpForwarding yes" "X11Forwarding yes" "PrintMotd no" "AcceptEnv LANG LC_*" "Subsystem sftp /usr/lib/openssh/sftp-server" "UsePAM yes" "AllowUsers root" ) for setting in "${SSHD_SETTINGS[@]}"; do key=$(echo "$setting" | cut -d' ' -f1) if grep -q "^$key" "$SSHD_CONFIG"; then sed -i "s/^$key.*/$setting/" "$SSHD_CONFIG" else echo "$setting" >> "$SSHD_CONFIG" fi done # Перезапускаем SSH демон if systemctl restart sshd 2>/dev/null || service ssh restart 2>/dev/null; then log_message "SSH демон перезапущен с новыми настройки" "$GREEN" else log_message "Не удалось перезапустить SSH демон" "$YELLOW" fi fi # Копирование ключа на VPS echo "" log_message "Копирование SSH ключа на VPS ($VPS_USER@$VPS_HOST)..." "$CYAN" echo -e "${YELLOW}Для копирования ключа потребуется пароль от $VPS_USER на VPS${NC}" # Запрос пароля для копирования ключа safe_read "Введите пароль для $VPS_USER@$VPS_HOST (или нажмите Enter для пропуска): " "" VPS_PASSWORD yes if [ -n "$VPS_PASSWORD" ]; then echo "" echo -e "${CYAN}Попытка копирования ключа с использованием пароля...${NC}" # Установка SSH_ASKPASS для автоматического ввода пароля export SSH_ASKPASS="$(mktemp)" cat > "$SSH_ASKPASS" << EOF #!/bin/bash echo "$VPS_PASSWORD" EOF chmod +x "$SSH_ASKPASS" export DISPLAY=:0 # Пытаемся скопировать ключ с использованием sshpass if command -v sshpass &> /dev/null; then 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_FILE"; then log_message "SSH ключ успешно скопирован на VPS!" "$GREEN" else log_message "Не удалось скопировать ключ через sshpass" "$YELLOW" echo -e "${YELLOW}Попробуйте скопировать ключ вручную${NC}" fi else echo -e "${YELLOW}sshpass не установлен, пропускаю автоматическое копирование${NC}" fi # Очистка временного файла rm -f "$SSH_ASKPASS" else echo -e "${YELLOW}Пароль не введен, пропускаю автоматическое копирование ключа${NC}" fi # Альтернативный метод копирования ключа echo "" echo -e "${CYAN}Альтернативный способ добавления ключа:${NC}" echo -e "${YELLOW}Если автоматическое копирование не удалось, выполните следующие шаги:${NC}" echo "" echo -e "1. Скопируйте содержимое публичного ключа:" echo -e "${BOLD}cat /root/.ssh/id_rsa.pub${NC}" echo "" echo -e "2. Подключитесь к VPS:" echo -e "${BOLD}ssh -p $VPS_PORT $VPS_USER@$VPS_HOST${NC}" echo "" echo -e "3. На VPS выполните:" echo -e "${BOLD}mkdir -p ~/.ssh && chmod 700 ~/.ssh${NC}" echo -e "${BOLD}echo 'ВАШ_ПУБЛИЧНЫЙ_КЛЮЧ' >> ~/.ssh/authorized_keys${NC}" echo -e "${BOLD}chmod 600 ~/.ssh/authorized_keys${NC}" echo "" safe_read "Нажмите Enter после добавления ключа на VPS..." "" WAIT no # Тестовое подключение log_message "Тестовое подключение к VPS..." "$BLUE" echo -e "${CYAN}Пытаюсь подключиться без пароля...${NC}" if timeout 15 ssh -p "$VPS_PORT" \ -o BatchMode=yes \ -o ConnectTimeout=10 \ -o StrictHostKeyChecking=no \ "$VPS_USER@$VPS_HOST" \ "echo 'SSH подключение успешно!'" 2>&1; then log_message "Тестовое подключение прошло успешно!" "$GREEN" echo -e "${GREEN}✓ SSH ключ настроен корректно${NC}" else log_message "Тестовое подключение не удалось" "$YELLOW" echo -e "${YELLOW}⚠ Не удалось подключиться без пароля${NC}" echo -e "${YELLOW}Убедитесь, что ключ добавлен в authorized_keys на VPS${NC}" safe_read "Продолжить установку? (y/n): " "y" CONTINUE_INSTALL no if [[ ! "$CONTINUE_INSTALL" =~ ^[Yy]$ ]]; then exit 1 fi fi # Настройка для не-root пользователей if [[ $EUID -eq 0 ]] && [ -d "/home/" ] && [ "$(ls -A /home/ 2>/dev/null)" ]; then echo "" safe_read "Настроить SSH для обычных пользователей системы? (y/n): " "n" SETUP_USERS no if [[ "$SETUP_USERS" =~ ^[Yy]$ ]]; then log_message "Настройка SSH для всех пользователей системы..." "$CYAN" for HOME_DIR in /home/*; do if [ -d "$HOME_DIR" ] && [ "$HOME_DIR" != "/home/*" ]; then USER=$(basename "$HOME_DIR") USER_SSH_DIR="$HOME_DIR/.ssh" echo -e "${CYAN}Настройка пользователя: $USER${NC}" mkdir -p "$USER_SSH_DIR" chmod 700 "$USER_SSH_DIR" chown "$USER:$USER" "$USER_SSH_DIR" # Копируем конфиг cp /root/.ssh/config "$USER_SSH_DIR/config" 2>/dev/null if [ -f "$USER_SSH_DIR/config" ]; then chown "$USER:$USER" "$USER_SSH_DIR/config" chmod 600 "$USER_SSH_DIR/config" echo -e " ${GREEN}✓ Конфиг скопирован${NC}" fi safe_read " Скопировать SSH ключ для пользователя $USER? (y/n): " "n" COPY_FOR_USER no if [[ "$COPY_FOR_USER" =~ ^[Yy]$ ]]; then cp /root/.ssh/id_rsa* "$USER_SSH_DIR/" 2>/dev/null chown -R "$USER:$USER" "$USER_SSH_DIR" chmod 600 "$USER_SSH_DIR/id_rsa" 2>/dev/null chmod 644 "$USER_SSH_DIR/id_rsa.pub" 2>/dev/null echo -e " ${GREEN}✓ Ключ скопирован для $USER${NC}" fi fi done fi fi # Сохранение настроек VPS для использования в скриптах log_message "Сохранение настроек VPS..." "$BLUE" mkdir -p /etc/ssh_tunnel cat > /etc/ssh_tunnel/vps_settings.conf << EOF # Настройки VPS для автономных туннелей VPS_HOST="$VPS_HOST" VPS_PORT="$VPS_PORT" VPS_USER="$VPS_USER" CONFIGURED_ON="$(date '+%Y-%m-%d %H:%M:%S')" EOF chmod 600 /etc/ssh_tunnel/vps_settings.conf log_message "Настройки SSH сохранены в /etc/ssh_tunnel/vps_settings.conf" "$GREEN" } # Установка основного скрипта управления install_main_script() { log_message "Установка основного скрипта управления туннелями..." "$CYAN" # Создание директорий mkdir -p /opt/ssh_tunnel_manager mkdir -p /var/log/ssh_tunnel mkdir -p /etc/ssh_tunnel # Загрузка настроек VPS если есть if [ -f /etc/ssh_tunnel/vps_settings.conf ]; then source /etc/ssh_tunnel/vps_settings.conf fi # Создание основного скрипта менеджера с корректным завершением EOF cat > /opt/ssh_tunnel_manager/manager.sh << 'EOFMGR' #!/bin/bash # Основной скрипт менеджера SSH туннелей # Версия 4.0 - Стабильное меню # Конфигурация CONFIG_DIR="/etc/ssh_tunnel" LOG_DIR="/var/log/ssh_tunnel" SERVICE_DIR="/etc/systemd/system" SCRIPT_DIR="/opt/ssh_tunnel_manager" # Цвета RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' BLUE='\033[0;34m' CYAN='\033[0;36m' PURPLE='\033[0;35m' NC='\033[0m' BOLD='\033[1m' # Глобальные переменные VPS_HOST="" VPS_PORT="22" VPS_USER="" # Загрузка настроек VPS если есть load_vps_settings() { if [ -f "/etc/ssh_tunnel/vps_settings.conf" ]; then source "/etc/ssh_tunnel/vps_settings.conf" return 0 fi return 1 } # Функция безопасного ввода safe_read() { local prompt="$1" local default="$2" local var_name="$3" read -p "$prompt" input input="${input:-$default}" if [ -n "$input" ]; then eval "$var_name=\"$input\"" return 0 else return 1 fi } # Очистка входного буфера clear_input_buffer() { while read -t 0.1 -n 1000 discard; do :; done } # Функция проверки подключения check_ssh_connection() { if [ -z "$VPS_HOST" ] || [ -z "$VPS_USER" ]; then echo -e "${RED}Настройки VPS не найдены!${NC}" return 1 fi echo -e "${CYAN}Проверка подключения к ${VPS_USER}@${VPS_HOST}:${VPS_PORT}...${NC}" if timeout 10 ssh -p "$VPS_PORT" \ -o BatchMode=yes \ -o ConnectTimeout=5 \ -o StrictHostKeyChecking=no \ "${VPS_USER}@${VPS_HOST}" \ "echo 'Connected' && exit 0" 2>/dev/null; then echo -e "${GREEN}✓ Подключение успешно${NC}" return 0 else echo -e "${RED}✗ Не удалось подключиться${NC}" return 1 fi } # Функция настройки нового VPS setup_new_vps() { echo -e "${BOLD}${CYAN}Настройка нового VPS подключения${NC}" echo -e "${YELLOW}========================================${NC}" read -p "Введите IP адрес или домен VPS: " NEW_VPS_HOST read -p "Введите порт SSH (22): " NEW_VPS_PORT NEW_VPS_PORT=${NEW_VPS_PORT:-22} read -p "Введите имя пользователя: " NEW_VPS_USER if [ -z "$NEW_VPS_HOST" ] || [ -z "$NEW_VPS_USER" ]; then echo -e "${RED}Ошибка: не все поля заполнены${NC}" return 1 fi # Проверка подключения echo -e "${CYAN}Проверка подключения...${NC}" if timeout 5 ssh -p "$NEW_VPS_PORT" \ -o ConnectTimeout=3 \ -o StrictHostKeyChecking=no \ "$NEW_VPS_USER@$NEW_VPS_HOST" \ "echo 'OK'" 2>/dev/null; then echo -e "${GREEN}✓ Подключение работает${NC}" else echo -e "${YELLOW}⚠ Не удалось проверить подключение${NC}" read -p "Все равно продолжить? (y/n): " CONTINUE if [[ ! "$CONTINUE" =~ ^[Yy]$ ]]; then return 1 fi fi # Сохранение настроек cat > /etc/ssh_tunnel/vps_settings.conf << CONFIGVPS # Настройки VPS для автономных туннелей VPS_HOST="$NEW_VPS_HOST" VPS_PORT="$NEW_VPS_PORT" VPS_USER="$NEW_VPS_USER" CONFIGURED_ON="$(date '+%Y-%m-%d %H:%M:%S')" CONFIGVPS echo -e "${GREEN}Настройки сохранены!${NC}" VPS_HOST="$NEW_VPS_HOST" VPS_PORT="$NEW_VPS_PORT" VPS_USER="$NEW_VPS_USER" read -p "Нажмите Enter для продолжения..." } # Создание туннеля create_tunnel() { echo -e "${CYAN}Создание нового туннеля...${NC}" if [ -z "$VPS_HOST" ]; then echo -e "${RED}Сначала настройте VPS (опция 9)${NC}" sleep 2 return fi read -p "Введите локальный порт (например 22): " LOCAL_PORT read -p "Введите удаленный порт на VPS (например 10022): " REMOTE_PORT if [ -z "$LOCAL_PORT" ] || [ -z "$REMOTE_PORT" ]; then echo -e "${RED}Ошибка: не все поля заполнены${NC}" return fi echo -e "${CYAN}Создание туннеля $LOCAL_PORT -> $REMOTE_PORT на ${VPS_HOST}...${NC}" # Создание конфигурации TUNNEL_ID="tunnel_${REMOTE_PORT}_$(date +%s)" CONFIG_FILE="/etc/ssh_tunnel/${TUNNEL_ID}.conf" cat > "$CONFIG_FILE" << CONFTUN TUNNEL_ID="$TUNNEL_ID" VPS_HOST="$VPS_HOST" VPS_PORT="$VPS_PORT" VPS_USER="$VPS_USER" LOCAL_PORT="$LOCAL_PORT" REMOTE_PORT="$REMOTE_PORT" CREATED="$(date '+%Y-%m-%d %H:%M:%S')" CONFTUN echo -e "${GREEN}Туннель создан! Конфиг: $CONFIG_FILE${NC}" # Создание службы SERVICE_FILE="/etc/systemd/system/ssh-tunnel-${TUNNEL_ID}.service" cat > "$SERVICE_FILE" << SERVICETUN [Unit] Description=SSH Tunnel: $TUNNEL_ID After=network-online.target Wants=network-online.target [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" \\ -R \${REMOTE_PORT}:localhost:\${LOCAL_PORT} \\ \${VPS_USER}@\${VPS_HOST} -p \${VPS_PORT} Restart=always RestartSec=10 User=root StandardOutput=append:/var/log/ssh_tunnel/${TUNNEL_ID}.log StandardError=append:/var/log/ssh_tunnel/${TUNNEL_ID}.log [Install] WantedBy=multi-user.target SERVICETUN systemctl daemon-reload systemctl enable "ssh-tunnel-${TUNNEL_ID}.service" 2>/dev/null systemctl start "ssh-tunnel-${TUNNEL_ID}.service" 2>/dev/null echo -e "${GREEN}Служба создана и запущена!${NC}" echo -e "${CYAN}Для подключения используйте:${NC}" echo -e "${BOLD}ssh -p $REMOTE_PORT ${VPS_USER}@${VPS_HOST}${NC}" read -p "Нажмите Enter для продолжения..." } # Быстрый SSH туннель quick_ssh_tunnel() { echo -e "${CYAN}Создание быстрого SSH туннеля...${NC}" if [ -z "$VPS_HOST" ]; then echo -e "${RED}Сначала настройте VPS (опция 9)${NC}" sleep 2 return fi LOCAL_PORT="22" REMOTE_PORT="10022" echo -e "${YELLOW}Будет создан туннель: localhost:22 -> ${VPS_HOST}:${REMOTE_PORT}${NC}" TUNNEL_ID="ssh_tunnel_${REMOTE_PORT}" CONFIG_FILE="/etc/ssh_tunnel/${TUNNEL_ID}.conf" cat > "$CONFIG_FILE" << CONFFAST TUNNEL_ID="$TUNNEL_ID" VPS_HOST="$VPS_HOST" VPS_PORT="$VPS_PORT" VPS_USER="$VPS_USER" LOCAL_PORT="$LOCAL_PORT" REMOTE_PORT="$REMOTE_PORT" CREATED="$(date '+%Y-%m-%d %H:%M:%S')" TYPE="ssh" CONFFAST SERVICE_FILE="/etc/systemd/system/ssh-tunnel-${TUNNEL_ID}.service" cat > "$SERVICE_FILE" << SERVICEFAST [Unit] Description=SSH Tunnel: $TUNNEL_ID After=network-online.target Wants=network-online.target [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" \\ -R \${REMOTE_PORT}:localhost:\${LOCAL_PORT} \\ \${VPS_USER}@\${VPS_HOST} -p \${VPS_PORT} Restart=always RestartSec=10 User=root StandardOutput=append:/var/log/ssh_tunnel/${TUNNEL_ID}.log StandardError=append:/var/log/ssh_tunnel/${TUNNEL_ID}.log [Install] WantedBy=multi-user.target SERVICEFAST systemctl daemon-reload systemctl enable "ssh-tunnel-${TUNNEL_ID}.service" 2>/dev/null systemctl start "ssh-tunnel-${TUNNEL_ID}.service" 2>/dev/null echo -e "${GREEN}SSH туннель создан!${NC}" echo -e "${CYAN}Для подключения используйте:${NC}" echo -e "${BOLD}ssh -p $REMOTE_PORT ${VPS_USER}@${VPS_HOST}${NC}" read -p "Нажмите Enter для продолжения..." } # Управление туннелями manage_tunnels() { while true; do clear echo -e "${BOLD}${CYAN}Управление туннелями${NC}" echo -e "${YELLOW}=====================${NC}" echo "" # Список туннелей count=0 declare -A tunnels # Исправленный цикл без синтаксической ошибки for conf in /etc/ssh_tunnel/*.conf; do if [ ! -f "$conf" ]; then continue fi ((count++)) tunnels[$count]="$conf" tunnel_name=$(basename "$conf" .conf) echo -e "${CYAN}[$count]${NC} $tunnel_name" done if [ $count -eq 0 ]; then echo -e "${YELLOW}Нет настроенных туннелей${NC}" fi echo "" echo -e "${CYAN}[s]${NC} Показать статус всех туннелей" echo -e "${CYAN}[r]${NC} Перезапустить все туннели" echo -e "${CYAN}[b]${NC} Назад в главное меню" echo "" clear_input_buffer read -p "Выберите опцию: " choice case $choice in b|B) return ;; s|S) echo -e "${CYAN}Статус туннелей:${NC}" systemctl list-units --type=service --state=active | grep ssh-tunnel || echo "Нет активных туннелей" read -p "Нажмите Enter для продолжения..." ;; r|R) echo -e "${CYAN}Перезапуск всех туннелей...${NC}" for conf in /etc/ssh_tunnel/*.conf; do if [ ! -f "$conf" ]; then continue fi tunnel_name=$(basename "$conf" .conf) systemctl restart "ssh-tunnel-${tunnel_name}.service" 2>/dev/null echo -e " ${GREEN}✓${NC} $tunnel_name перезапущен" done read -p "Нажмите Enter для продолжения..." ;; *) if [[ $choice =~ ^[0-9]+$ ]] && [ $choice -ge 1 ] && [ $choice -le $count ]; then manage_single_tunnel "${tunnels[$choice]}" else echo -e "${RED}Неверный выбор${NC}" sleep 1 fi ;; esac done } # Управление одним туннелем manage_single_tunnel() { local conf="$1" local tunnel_name=$(basename "$conf" .conf) source "$conf" 2>/dev/null || { echo -e "${RED}Ошибка загрузки конфигурации${NC}" return } while true; do clear echo -e "${BOLD}${CYAN}Управление туннелем: $tunnel_name${NC}" echo -e "${YELLOW}=================================${NC}" echo "" echo -e "${CYAN}Информация:${NC}" echo -e " Локальный порт: ${LOCAL_PORT:-не указан}" echo -e " Удаленный порт: ${REMOTE_PORT:-не указан}" echo -e " VPS: ${VPS_USER:-не указан}@${VPS_HOST:-не указан}:${VPS_PORT:-22}" echo "" # Проверка статуса if systemctl is-active --quiet "ssh-tunnel-${tunnel_name}.service" 2>/dev/null; then echo -e "${GREEN}✓ Служба активна${NC}" else echo -e "${RED}✗ Служба неактивна${NC}" fi echo "" echo -e "${CYAN}[1]${NC} Перезапустить туннель" echo -e "${CYAN}[2]${NC} Остановить туннель" echo -e "${CYAN}[3]${NC} Запустить туннель" echo -e "${CYAN}[4]${NC} Показать логи" echo -e "${CYAN}[5]${NC} Удалить туннель" echo -e "${CYAN}[6]${NC} Назад" echo "" clear_input_buffer read -p "Выберите действие: " action case $action in 1) systemctl restart "ssh-tunnel-${tunnel_name}.service" 2>/dev/null echo -e "${GREEN}Туннель перезапущен${NC}" sleep 1 ;; 2) systemctl stop "ssh-tunnel-${tunnel_name}.service" 2>/dev/null echo -e "${YELLOW}Туннель остановлен${NC}" sleep 1 ;; 3) systemctl start "ssh-tunnel-${tunnel_name}.service" 2>/dev/null echo -e "${GREEN}Туннель запущен${NC}" sleep 1 ;; 4) echo -e "${CYAN}Логи туннеля:${NC}" tail -20 "/var/log/ssh_tunnel/${tunnel_name}.log" 2>/dev/null || echo "Логи отсутствуют" read -p "Нажмите Enter для продолжения..." ;; 5) read -p "Вы уверены, что хотите удалить туннель $tunnel_name? (y/n): " confirm if [[ "$confirm" =~ ^[Yy]$ ]]; then systemctl stop "ssh-tunnel-${tunnel_name}.service" 2>/dev/null systemctl disable "ssh-tunnel-${tunnel_name}.service" 2>/dev/null rm -f "/etc/systemd/system/ssh-tunnel-${tunnel_name}.service" rm -f "$conf" rm -f "/var/log/ssh_tunnel/${tunnel_name}.log" 2>/dev/null systemctl daemon-reload echo -e "${GREEN}Туннель удален${NC}" return fi ;; 6) return ;; *) echo -e "${RED}Неверный выбор${NC}" sleep 1 ;; esac done } # Настройка автозапуска setup_autostart() { while true; do clear echo -e "${BOLD}${CYAN}Настройка автозапуска${NC}" echo -e "${YELLOW}======================${NC}" echo "" echo -e "${CYAN}[1]${NC} Включить автозапуск всех туннелей" echo -e "${CYAN}[2]${NC} Выключить автозапуск всех туннелей" echo -e "${CYAN}[3]${NC} Проверить статус автозапуска" echo -e "${CYAN}[4]${NC} Назад" echo "" clear_input_buffer read -p "Выберите действие: " action case $action in 1) for conf in /etc/ssh_tunnel/*.conf; do if [ ! -f "$conf" ]; then continue fi tunnel_name=$(basename "$conf" .conf) systemctl enable "ssh-tunnel-${tunnel_name}.service" 2>/dev/null && \ echo -e "${GREEN}✓ Автозапуск включен для $tunnel_name${NC}" || \ echo -e "${RED}✗ Ошибка для $tunnel_name${NC}" done read -p "Нажмите Enter для продолжения..." ;; 2) for conf in /etc/ssh_tunnel/*.conf; do if [ ! -f "$conf" ]; then continue fi tunnel_name=$(basename "$conf" .conf) systemctl disable "ssh-tunnel-${tunnel_name}.service" 2>/dev/null && \ echo -e "${YELLOW}✗ Автозапуск выключен для $tunnel_name${NC}" || \ echo -e "${RED}✗ Ошибка для $tunnel_name${NC}" done read -p "Нажмите Enter для продолжения..." ;; 3) echo -e "${CYAN}Статус автозапуска:${NC}" systemctl list-unit-files --type=service | grep ssh-tunnel || echo "Нет служб туннелей" read -p "Нажмите Enter для продолжения..." ;; 4) return ;; *) echo -e "${RED}Неверный выбор${NC}" sleep 1 ;; esac done } # Просмотр логов 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} Все логи туннелей" echo -e "${CYAN}[3]${NC} Системные логи" echo -e "${CYAN}[4]${NC} Лог монитора" echo -e "${CYAN}[5]${NC} Реальный мониторинг" echo -e "${CYAN}[6]${NC} Назад" echo "" clear_input_buffer read -p "Выберите действие: " choice case $choice in 1) echo -e "${CYAN}Доступные логи:${NC}" for log in $LOG_DIR/*.log; do if [ ! -f "$log" ]; then continue fi echo " $(basename $log)" done echo "" read -p "Введите имя лог-файла: " log_file if [ -f "$LOG_DIR/$log_file" ]; then less "$LOG_DIR/$log_file" else echo -e "${RED}Файл не найден${NC}" sleep 1 fi ;; 2) echo -e "${CYAN}Все логи туннелей:${NC}" for log in $LOG_DIR/*.log; do if [ ! -f "$log" ]; then continue fi echo -e "\n${YELLOW}=== $(basename $log) ===${NC}" tail -5 "$log" done read -p "Нажмите Enter для продолжения..." ;; 3) echo -e "${CYAN}Системные логи туннелей:${NC}" journalctl -u ssh-tunnel-* --since "1 hour ago" -n 10 2>/dev/null || echo "Логи отсутствуют" read -p "Нажмите Enter для продолжения..." ;; 4) if [ -f "$LOG_DIR/monitor.log" ]; then echo -e "${CYAN}Лог монитора:${NC}" tail -20 "$LOG_DIR/monitor.log" else echo -e "${YELLOW}Лог монитора отсутствует${NC}" fi read -p "Нажмите Enter для продолжения..." ;; 5) echo -e "${CYAN}Реальный мониторинг логов (Ctrl+C для выхода)${NC}" trap 'echo -e "\n${YELLOW}Мониторинг остановлен${NC}"' INT tail -f $LOG_DIR/*.log 2>/dev/null ;; 6) return ;; *) echo -e "${RED}Неверный выбор${NC}" sleep 1 ;; esac done } # Тестирование подключений test_connections() { echo -e "${CYAN}Тестирование подключений...${NC}" echo "1) Тест подключения к VPS" echo "2) Тест портов туннелей" echo "3) Назад" clear_input_buffer read -p "Выберите тест: " test_choice case $test_choice in 1) check_ssh_connection ;; 2) echo -e "${CYAN}Тест портов туннелей:${NC}" for conf in /etc/ssh_tunnel/*.conf; do if [ ! -f "$conf" ]; then continue fi source "$conf" 2>/dev/null tunnel_name=$(basename "$conf" .conf) echo -n " $tunnel_name (локальный $LOCAL_PORT): " if timeout 2 nc -z localhost "$LOCAL_PORT" 2>/dev/null; then echo -e "${GREEN}✓ Открыт${NC}" else echo -e "${RED}✗ Закрыт${NC}" fi done ;; 3) return ;; *) echo -e "${RED}Неверный выбор${NC}" ;; esac read -p "Нажмите Enter для продолжения..." } # Настройка маршрутизации setup_routing() { echo -e "${CYAN}Настройка маршрутизации...${NC}" echo "1) Показать текущие правила iptables" echo "2) Добавить правило перенаправления порта" echo "3) Сохранить правила" echo "4) Назад" clear_input_buffer read -p "Выберите действие: " routing_choice case $routing_choice in 1) echo -e "${CYAN}Текущие правила iptables:${NC}" iptables -t nat -L -n -v 2>/dev/null || echo "iptables не установлен" ;; 2) read -p "Входной порт: " in_port read -p "IP назначения: " dest_ip read -p "Порт назначения: " dest_port if [ -n "$in_port" ] && [ -n "$dest_ip" ] && [ -n "$dest_port" ]; then iptables -t nat -A PREROUTING -p tcp --dport "$in_port" -j DNAT --to-destination "$dest_ip:$dest_port" 2>/dev/null iptables -t nat -A POSTROUTING -p tcp -d "$dest_ip" --dport "$dest_port" -j MASQUERADE 2>/dev/null echo -e "${GREEN}Правило добавлено${NC}" else echo -e "${RED}Не все поля заполнены${NC}" fi ;; 3) if command -v iptables-save &> /dev/null; then mkdir -p /etc/iptables iptables-save > /etc/iptables/rules.v4 2>/dev/null && \ echo -e "${GREEN}Правила сохранены${NC}" || \ echo -e "${RED}Ошибка сохранения${NC}" else echo -e "${RED}iptables-save не найден${NC}" fi ;; 4) return ;; *) echo -e "${RED}Неверный выбор${NC}" ;; esac read -p "Нажмите Enter для продолжения..." } # Настройки SSH setup_ssh_config() { echo -e "${CYAN}Настройка SSH...${NC}" echo "1) Показать текущую конфигурацию SSH" echo "2) Перезапустить SSH демон" echo "3) Проверить конфигурацию" echo "4) Назад" clear_input_buffer read -p "Выберите действие: " ssh_choice case $ssh_choice in 1) echo -e "${CYAN}Текущая конфигурация SSH:${NC}" grep -E "^(ClientAlive|TCPKeepAlive|ServerAlive|Port|PasswordAuthentication|PermitRootLogin)" /etc/ssh/sshd_config 2>/dev/null || echo "Конфигурация не найдена" ;; 2) if systemctl restart sshd 2>/dev/null || service ssh restart 2>/dev/null; then echo -e "${GREEN}SSH демон перезапущен${NC}" else echo -e "${RED}Ошибка перезапуска SSH демона${NC}" fi ;; 3) if sshd -t 2>/dev/null; then echo -e "${GREEN}✓ Конфигурация SSH корректна${NC}" else echo -e "${RED}✗ Ошибка в конфигурации SSH${NC}" fi ;; 4) return ;; *) echo -e "${RED}Неверный выбор${NC}" ;; esac read -p "Нажмите Enter для продолжения..." } # Основное меню show_menu() { # Загрузка настроек load_vps_settings while true; do clear echo -e "${BOLD}${CYAN}════════════════════════════════════════════════════════════════${NC}" echo -e "${BOLD}${CYAN} АВТОНОМНЫЙ МЕНЕДЖЕР SSH ТУННЕЛЕЙ v4.0 ${NC}" echo -e "${BOLD}${CYAN}════════════════════════════════════════════════════════════════${NC}" # Отображение текущих настроек VPS if [ -n "$VPS_HOST" ]; then echo -e "${CYAN}Текущий VPS: ${VPS_USER}@${VPS_HOST}:${VPS_PORT}${NC}" else echo -e "${RED}VPS не настроен! Выберите опцию 9 для настройки.${NC}" fi echo "" # Проверка статуса подключения if [ -n "$VPS_HOST" ]; then echo -e "${CYAN}Статус подключения:${NC}" if check_ssh_connection; then echo -e "${GREEN}✓ Соединение с VPS активно${NC}" else echo -e "${RED}✗ Нет соединения с VPS${NC}" fi echo "" fi echo -e "${BOLD}${YELLOW}[1]${NC} Создать новый автономный туннель" echo -e "${BOLD}${YELLOW}[2]${NC} Быстрый туннель (SSH 22 порт)" echo -e "${BOLD}${YELLOW}[3]${NC} Управление существующими туннелями" echo -e "${BOLD}${YELLOW}[4]${NC} Настройка автозапуска" echo -e "${BOLD}${YELLOW}[5]${NC} Просмотр логов и мониторинг" echo -e "${BOLD}${YELLOW}[6]${NC} Тестирование подключений" echo -e "${BOLD}${YELLOW}[7]${NC} Настройка маршрутизации" echo -e "${BOLD}${YELLOW}[8]${NC} Настройки SSH" echo -e "${BOLD}${YELLOW}[9]${NC} Настройка/смена VPS" echo -e "${BOLD}${YELLOW}[0]${NC} Выход" echo "" clear_input_buffer read -p "Выберите опцию [0-9]: " choice case $choice in 1) create_tunnel ;; 2) quick_ssh_tunnel ;; 3) manage_tunnels ;; 4) setup_autostart ;; 5) view_logs ;; 6) test_connections ;; 7) setup_routing ;; 8) setup_ssh_config ;; 9) setup_new_vps ;; 0) echo -e "${GREEN}Выход...${NC}" exit 0 ;; *) echo -e "${RED}Неверный выбор. Попробуйте еще раз.${NC}" sleep 1 ;; esac done } # Главный цикл if [ "$0" = "$BASH_SOURCE" ] || [ "$0" = "./manager.sh" ]; then show_menu fi EOFMGR # Создание файла с цветами cat > /opt/ssh_tunnel_manager/colors.sh << 'EOFCOLORS' #!/bin/bash # Файл цветов для менеджера туннелей RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' BLUE='\033[0;34m' CYAN='\033[0;36m' PURPLE='\033[0;35m' NC='\033[0m' BOLD='\033[1m' EOFCOLORS # Делаем скрипт исполняемым chmod +x /opt/ssh_tunnel_manager/manager.sh chmod +x /opt/ssh_tunnel_manager/colors.sh # Создание символической ссылки ln -sf /opt/ssh_tunnel_manager/manager.sh /usr/local/bin/tunnel-manager 2>/dev/null log_message "Основной скрипт установлен в /opt/ssh_tunnel_manager/" "$GREEN" } # Настройка systemd служб setup_systemd_services() { log_message "Настройка systemd служб для автономной работы..." "$CYAN" # Основная служба мониторинга cat > /etc/systemd/system/tunnel-monitor.service << EOFSERVICE [Unit] Description=Мониторинг и восстановление SSH туннелей After=network-online.target Wants=network-online.target [Service] Type=simple ExecStart=/opt/ssh_tunnel_manager/monitor.sh Restart=always RestartSec=30 User=root StandardOutput=append:/var/log/ssh_tunnel/monitor.log StandardError=append:/var/log/ssh_tunnel/monitor.log [Install] WantedBy=multi-user.target EOFSERVICE # Скрипт мониторинга cat > /opt/ssh_tunnel_manager/monitor.sh << 'EOFMONITOR' #!/bin/bash # Скрипт мониторинга туннелей LOG_FILE="/var/log/ssh_tunnel/monitor.log" CONFIG_DIR="/etc/ssh_tunnel" log() { echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" >> "$LOG_FILE" } check_tunnel() { local config_file="$1" local tunnel_name=$(basename "$config_file" .conf) if [ ! -f "$config_file" ]; then return 1 fi source "$config_file" # Проверяем, работает ли туннель if ps aux | grep -v grep | grep -q "autossh.*$REMOTE_PORT.*$VPS_HOST"; then # Проверяем доступность порта if timeout 2 nc -z localhost "$LOCAL_PORT" 2>/dev/null; then log "Туннель $tunnel_name: OK" return 0 fi fi log "Туннель $tunnel_name: FAILED - перезапуск" # Перезапускаем службу if systemctl is-active --quiet "ssh-tunnel-$tunnel_name.service" 2>/dev/null; then systemctl restart "ssh-tunnel-$tunnel_name.service" else # Запускаем туннель напрямую /usr/bin/autossh -M 0 -N \ -o "ExitOnForwardFailure=yes" \ -o "ServerAliveInterval=30" \ -o "ServerAliveCountMax=3" \ -R "${REMOTE_PORT}:localhost:${LOCAL_PORT}" \ "${VPS_USER}@${VPS_HOST}" -p "${VPS_PORT}" & fi return 1 } log "Запуск монитора SSH туннелей" while true; do # Проверяем все конфигурации for config in "$CONFIG_DIR"/*.conf; do if [ -f "$config" ]; then check_tunnel "$config" fi done sleep 60 done EOFMONITOR chmod +x /opt/ssh_tunnel_manager/monitor.sh # Создание таймера для периодической проверки cat > /etc/systemd/system/tunnel-check.timer << EOFTIMER [Unit] Description=Периодическая проверка SSH туннелей [Timer] OnBootSec=5min OnUnitActiveSec=5min AccuracySec=1min [Install] WantedBy=timers.target EOFTIMER # Включение служб systemctl daemon-reload 2>/dev/null systemctl enable tunnel-monitor.service 2>/dev/null systemctl enable tunnel-check.timer 2>/dev/null systemctl start tunnel-monitor.service 2>/dev/null systemctl start tunnel-check.timer 2>/dev/null log_message "Systemd службы настроены" "$GREEN" } # Создание примера туннеля create_example_tunnel() { log_message "Создание примера SSH туннеля..." "$CYAN" if [ -n "$VPS_HOST" ] && [ -n "$VPS_USER" ]; then safe_read "Создать пример туннеля для SSH (порт 22 -> 10022)? (y/n): " "y" CREATE_EXAMPLE no if [[ "$CREATE_EXAMPLE" =~ ^[Yy]$ ]]; then cat > /etc/ssh_tunnel/example_ssh.conf << EOFEXAMPLE # Пример туннеля для SSH доступа TUNNEL_NAME="example_ssh" VPS_HOST="$VPS_HOST" VPS_PORT="$VPS_PORT" VPS_USER="$VPS_USER" LOCAL_PORT="22" REMOTE_PORT="10022" ENABLED="true" EOFEXAMPLE # Создание службы для примера cat > /etc/systemd/system/ssh-tunnel-example_ssh.service << EOFEXSERVICE [Unit] Description=Пример SSH туннеля (22->10022) After=network-online.target [Service] Type=simple EnvironmentFile=/etc/ssh_tunnel/example_ssh.conf 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" \\ -R \${REMOTE_PORT}:localhost:\${LOCAL_PORT} \\ \${VPS_USER}@\${VPS_HOST} -p \${VPS_PORT} Restart=always RestartSec=10 User=root StandardOutput=append:/var/log/ssh_tunnel/example_ssh.log StandardError=append:/var/log/ssh_tunnel/example_ssh.log [Install] WantedBy=multi-user.target EOFEXSERVICE systemctl daemon-reload 2>/dev/null systemctl enable ssh-tunnel-example_ssh.service 2>/dev/null systemctl start ssh-tunnel-example_ssh.service 2>/dev/null log_message "Пример туннеля создан!" "$GREEN" echo -e "${CYAN}Для подключения используйте:${NC}" echo -e "${BOLD}ssh -p 10022 $VPS_USER@$VPS_HOST${NC}" echo "" echo -e "${YELLOW}Проверьте подключение:${NC}" echo -e " systemctl status ssh-tunnel-example_ssh.service" echo -e " tail -f /var/log/ssh_tunnel/example_ssh.log" fi fi } # Завершение установки finish_installation() { echo "" echo -e "${BOLD}${GREEN}════════════════════════════════════════════════════════════════${NC}" echo -e "${BOLD}${GREEN} УСТАНОВКА УСПЕШНО ЗАВЕРШЕНА! ${NC}" echo -e "${BOLD}${GREEN}════════════════════════════════════════════════════════════════${NC}" echo "" log_message "Итоги установки:" "$CYAN" echo -e "${GREEN}✓${NC} Зависимости установлены" echo -e "${GREEN}✓${NC} SSH ключи сгенерированы и настроены" echo -e "${GREEN}✓${NC} SSH конфигурация улучшена для стабильности" echo -e "${GREEN}✓${NC} Основной скрипт установлен" echo -e "${GREEN}✓${NC} Systemd службы настроены" echo -e "${GREEN}✓${NC} Автозапуск включен" echo "" if [ -n "$VPS_HOST" ]; then echo -e "${BOLD}Информация о подключении:${NC}" echo -e " VPS: $VPS_USER@$VPS_HOST:$VPS_PORT" echo -e " SSH ключ: /root/.ssh/id_rsa" echo -e " Конфиг SSH: /root/.ssh/config" echo "" fi echo -e "${BOLD}Команды для управления:${NC}" echo -e " ${CYAN}tunnel-manager${NC} - запуск менеджера туннелей" echo -e " ${CYAN}systemctl status tunnel-monitor${NC} - статус монитора" echo -e " ${CYAN}journalctl -u tunnel-monitor -f${NC} - просмотр логов" echo "" echo -e "${BOLD}Автономная работа гарантирована!${NC}" echo -e "Система автоматически запустится после перезагрузки." echo "" echo -e "${YELLOW}Полный лог установки: $LOG_FILE${NC}" echo "" # Запрос на перезагрузку safe_read "Перезагрузить систему для применения всех настроек? (y/n): " "n" REBOOT_NOW no if [[ "$REBOOT_NOW" =~ ^[Yy]$ ]]; then log_message "Перезагрузка системы по запросу пользователя..." "$YELLOW" echo -e "${YELLOW}Система перезагрузится через 5 секунд...${NC}" sleep 5 reboot else echo "" echo -e "${GREEN}Для запуска менеджера выполните:${NC}" echo -e "${BOLD}tunnel-manager${NC}" echo "" fi } # Главная функция установки main_installation() { log_message "Начало установки автономного менеджера SSH туннелей" "$CYAN" # Определяем дистрибутив detect_distro # Устанавливаем зависимости install_dependencies # Настраиваем SSH (теперь будет запрашивать данные) setup_ssh # Устанавливаем основной скрипт install_main_script # Настраиваем systemd службы setup_systemd_services # Создаем пример туннеля create_example_tunnel # Завершаем установку finish_installation } # Запуск установки main_installation