diff --git a/install_ssh_tunnel.sh b/install_ssh_tunnel.sh index b05986e..77fc8be 100644 --- a/install_ssh_tunnel.sh +++ b/install_ssh_tunnel.sh @@ -109,6 +109,7 @@ safe_read() { read_input() { local prompt="$1" local timeout="${2:-0}" + local input if [[ -t 0 ]]; then if [[ $timeout -gt 0 ]]; then @@ -131,6 +132,8 @@ read_input() { # Функция чтения скрытого ввода (для паролей) read_secret() { local prompt="$1" + local secret + if [[ -t 0 ]]; then read -s -p "$prompt" secret echo @@ -157,11 +160,13 @@ show_public_key() { echo -e "${GREEN}Ключ RSA:${NC}" cat /root/.ssh/id_rsa.pub echo "" + else + echo -e "${RED}Публичный ключ не найден. Сначала выполните установку.${NC}" fi read_input "Нажмите Enter для продолжения..." } -# Функция проверки SSH подключения +# Функция проверки SSH подключения с подробным выводом check_ssh_connection() { if ! load_vps_settings; then log_message "Сначала необходимо настроить VPS (опция 1)." "$RED" @@ -169,11 +174,56 @@ check_ssh_connection() { fi echo -e "${CYAN}Проверка подключения к $VPS_USER@$VPS_HOST:$VPS_PORT...${NC}" - if timeout 10 ssh -p "$VPS_PORT" -o BatchMode=yes -o ConnectTimeout=5 "$VPS_USER@$VPS_HOST" "echo 'SSH Connection OK'" 2>/dev/null; then - echo -e "${GREEN}✓ SSH подключение работает${NC}" + echo -e "${YELLOW}Используется ключ: /root/.ssh/id_rsa${NC}" + + # Проверяем существование ключа + if [ ! -f "/root/.ssh/id_rsa" ]; then + echo -e "${RED}✗ SSH ключ не найден. Выполните установку менеджера.${NC}" + return 1 + fi + + # Проверяем права на ключ + if [ "$(stat -c %a /root/.ssh/id_rsa 2>/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 "" + 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 -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 } @@ -208,15 +258,15 @@ install_manager() { check_error "Не удалось обновить список пакетов" log_message "Установка autossh, openssh-client и sshpass..." "$BLUE" - apt-get install -y autossh openssh-client sshpass 2>&1 | tee -a "$LOG_DIR/manager.log" + 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 2>&1 | tee -a "$LOG_DIR/manager.log" + 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 2>&1 | tee -a "$LOG_DIR/manager.log" + yum install -y autossh openssh-clients sshpass nc 2>&1 | tee -a "$LOG_DIR/manager.log" check_error "Не удалось установить пакеты (yum)" fi else @@ -233,8 +283,30 @@ install_manager() { # Копирование скрипта в системный путь log_message "Копирование скрипта в $SCRIPT_PATH..." "$BLUE" - cp "$0" "$SCRIPT_PATH" + # Получаем путь к текущему скрипту + 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 ключа @@ -278,14 +350,141 @@ EOFCONFIG 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" - return 1 + 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 + +# 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 10 +MaxStartups 10:30:100 + +# Allow tunnel creation +AllowStreamLocalForwarding yes +PermitTunnel yes + +# Subsystem +Subsystem sftp /usr/lib/openssh/sftp-server +EOFSSHD + log_message "Создан базовый конфигурационный файл SSH сервера." "$GREEN" + fi fi # Создание резервной копии @@ -293,27 +492,56 @@ configure_local_sshd() { 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" ) + # Применяем настройки for setting in "${SETTINGS[@]}"; do - key=$(echo "$setting" | cut -d' ' -f1) + 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 - if systemctl restart sshd 2>/dev/null || service ssh restart 2>/dev/null; then - log_message "SSHD перезапущен с новыми настройками (GatewayPorts, AllowTcpForwarding)." "$GREEN" + 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 } @@ -334,6 +562,8 @@ setup_vps() { fi echo -e "${BOLD}${CYAN}--- Настройка VPS ---${NC}" + echo -e "${YELLOW}Это настройка удаленного сервера (VPS), куда будут пробрасываться туннели${NC}" + echo "" local VPS_HOST_TEMP local VPS_PORT_TEMP @@ -364,12 +594,14 @@ setup_vps() { 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 @@ -390,20 +622,26 @@ EOFSETTINGS # Запрос пароля для 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: ") + 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" 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" @@ -416,13 +654,9 @@ EOFSETTINGS fi # Тестовое подключение + echo "" log_message "Проверка подключения к $VPS_USER@$VPS_HOST:$VPS_PORT..." "$BLUE" - if timeout 10 ssh -p "$VPS_PORT" -o BatchMode=yes "$VPS_USER@$VPS_HOST" "echo 'Connection OK'" 2>/dev/null; then - log_message "Тестовое подключение успешно! Ключ работает." "$GREEN" - else - log_message "ОШИБКА: Тестовое подключение не удалось." "$RED" - log_message "Убедитесь, что публичный ключ скопирован, порт $VPS_PORT открыт, и SSH-сервер на VPS запущен." "$YELLOW" - fi + check_ssh_connection read_input "Нажмите Enter для продолжения..." } @@ -438,6 +672,8 @@ add_tunnel() { 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="" @@ -447,8 +683,21 @@ add_tunnel() { safe_read "Введите удаленный порт на VPS, через который будет доступен локальный порт (например, 10022): " "" REMOTE_PORT safe_read "Введите имя туннеля (например, 'ssh_access'): " "" TUNNEL_NAME - if [ -z "$LOCAL_PORT" ] || [ -z "$REMOTE_PORT" ] || [ -z "$TUNNEL_NAME" ]; then - log_message "ОШИБКА: Все поля обязательны." "$RED" + # Проверка ввода + 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 @@ -461,11 +710,21 @@ add_tunnel() { 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" @@ -483,6 +742,7 @@ EOFCONF Description=SSH Reverse Tunnel: $TUNNEL_NAME ($LOCAL_PORT -> $REMOTE_PORT) After=network-online.target Wants=network-online.target +StartLimitIntervalSec=0 [Service] Type=simple @@ -498,6 +758,7 @@ ExecStart=/usr/bin/autossh -M 0 -N \ -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 @@ -517,11 +778,21 @@ EOFSERVICE if systemctl is-active --quiet "$SERVICE_NAME.service"; then log_message "Туннель '$TUNNEL_NAME' успешно запущен и включен в автозагрузку." "$GREEN" - log_message "Для доступа к локальному порту $LOCAL_PORT через VPS используйте:" "$YELLOW" - log_message "ssh -p $REMOTE_PORT $VPS_USER@$VPS_HOST" "$BOLD" + 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 для продолжения..." @@ -610,7 +881,8 @@ view_logs() { 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}[4]${NC} Лог менеджера" + echo -e "${CYAN}[5]${NC} Назад" echo "" choice=$(read_input "Выберите действие: ") @@ -619,7 +891,7 @@ view_logs() { 1) local LOG_DIR="/var/log/tunnel-manager" echo -e "${CYAN}Доступные логи:${NC}" - find "$LOG_DIR" -maxdepth 1 -type f -name "tunnel-*.log" -printf " %f\n" + 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 @@ -646,6 +918,10 @@ view_logs() { read_input "Нажмите Enter для продолжения..." ;; 4) + echo -e "${CYAN}Лог менеджера:${NC}" + less "/var/log/tunnel-manager/manager.log" + ;; + 5) return ;; *) @@ -664,7 +940,9 @@ test_connections() { echo -e "${YELLOW}========================${NC}" echo "1) Тест подключения к VPS" echo "2) Тест локальных портов туннелей" - echo "3) Назад" + echo "3) Тест SSH ключа" + echo "4) Тест доступности портов на VPS" + echo "5) Назад" echo "" test_choice=$(read_input "Выберите тест: ") @@ -706,6 +984,60 @@ test_connections() { 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 ;; *) @@ -788,7 +1120,10 @@ setup_ssh_config() { echo "1) Показать текущие настройки sshd (для туннелей)" echo "2) Перезапустить SSH демон" echo "3) Проверить конфигурацию sshd" - echo "4) Назад" + echo "4) Установить/переустановить SSH сервер" + echo "5) Настроить sshd для локальных подключений" + echo "6) Показать статус SSH сервера" + echo "7) Назад" echo "" ssh_choice=$(read_input "Выберите действие: ") @@ -796,7 +1131,13 @@ setup_ssh_config() { case $ssh_choice in 1) echo -e "${CYAN}Текущие настройки sshd (GatewayPorts, AllowTcpForwarding):${NC}" - grep -E "^(GatewayPorts|AllowTcpForwarding)" /etc/ssh/sshd_config 2>/dev/null || log_message "Настройки не найдены" "$YELLOW" + if [ -f "/etc/ssh/sshd_config" ]; then + grep -E "^(GatewayPorts|AllowTcpForwarding|PermitTunnel|AllowStreamLocalForwarding|PermitRootLogin)" /etc/ssh/sshd_config 2>/dev/null || + echo "Настройки не найдены или файл конфигурации отсутствует" + else + echo "Файл /etc/ssh/sshd_config не найден" + echo "SSH сервер, вероятно, не установлен" + fi read_input "Нажмите Enter для продолжения..." ;; 2) @@ -804,18 +1145,44 @@ setup_ssh_config() { log_message "SSH демон перезапущен." "$GREEN" else log_message "ОШИБКА: Не удалось перезапустить SSH демон." "$RED" + echo -e "${YELLOW}Попробуйте установить SSH сервер (опция 4)${NC}" fi read_input "Нажмите Enter для продолжения..." ;; 3) - if sudo sshd -t 2>/dev/null; then - log_message "Конфигурация SSH корректна." "$GREEN" + 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" + 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 ;; *) @@ -865,31 +1232,75 @@ manage_tunnels_menu() { echo -e "${BOLD}${CYAN}--- Управление туннелем $TUNNEL_ID_MANAGE ---${NC}" echo -e "${YELLOW}===========================================${NC}" - # Показать текущий статус - manage_tunnel "$TUNNEL_ID_MANAGE" "status" + # Загружаем конфигурацию туннеля + 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 " d) Удалить" + 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";; - p) manage_tunnel "$TUNNEL_ID_MANAGE" "stop";; - r) manage_tunnel "$TUNNEL_ID_MANAGE" "restart";; - d) + 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 @@ -909,14 +1320,31 @@ main_menu() { while true; do clear echo -e "${BOLD}${CYAN}========================================================${NC}" - echo -e "${BOLD}${CYAN} SSH Tunnel Manager v1.0 (by Manus) ${NC}" + echo -e "${BOLD}${CYAN} SSH Tunnel Manager v1.1 (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 @@ -930,10 +1358,11 @@ main_menu() { echo -e "6) ${BOLD}Настройка маршрутизации (iptables)${NC}" echo -e "7) ${BOLD}Настройки SSH Демона (sshd)${NC}" echo -e "8) ${BOLD}Показать публичный ключ${NC} (Для копирования на VPS)" - echo -e "9) ${BOLD}Выход${NC}" + echo -e "9) ${BOLD}Переустановка/обновление${NC}" + echo -e "0) ${BOLD}Выход${NC}" echo "" - choice=$(read_input "Выберите опцию [1-9]: ") + choice=$(read_input "Выберите опцию [0-9]: ") case $choice in 1) setup_vps ;; @@ -945,6 +1374,11 @@ main_menu() { 7) setup_ssh_config ;; 8) show_public_key ;; 9) + echo -e "${YELLOW}Выполняется переустановка...${NC}" + install_manager + read_input "Нажмите Enter для продолжения..." + ;; + 0) log_message "Выход из менеджера." "$GREEN" exit 0 ;; @@ -959,8 +1393,9 @@ main_menu() { # --- Точка входа --- # Главное изменение: если скрипт запущен без аргументов, выполняем автоматическую установку и запуск меню if [[ $# -eq 0 ]]; then - echo -e "${BOLD}${CYAN}SSH Tunnel Manager v1.0${NC}" + echo -e "${BOLD}${CYAN}SSH Tunnel Manager v1.1${NC}" echo -e "Автоматический запуск установки и меню..." + echo "" # Проверяем, установлен ли уже скрипт if [ -f "/usr/local/bin/tunnel-manager" ]; then @@ -969,6 +1404,8 @@ if [[ $# -eq 0 ]]; then main_menu else echo -e "${GREEN}Начинаем установку...${NC}" + echo -e "${YELLOW}Установка займет несколько минут...${NC}" + sleep 2 install_manager echo -e "${GREEN}Установка завершена. Запуск меню...${NC}" sleep 2 @@ -983,7 +1420,7 @@ else main_menu ;; *) - echo -e "${BOLD}${CYAN}SSH Tunnel Manager v1.0${NC}" + echo -e "${BOLD}${CYAN}SSH Tunnel Manager v1.1${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"