v1.5.3
Основные исправления:
Исправлена проблема с бесконечным циклом в функции safe_read - добавлен лимит попыток (по умолчанию 3)
Убраны конфликты с safe_read - в основном блоке ввода VPS данных теперь используется обычный read
Добавлена обработка ошибок для каждой функции с корректным выходом при неудаче
Исправлена логика проверки ввода - обязательные поля проверяются явно
Добавлен глобальный обработчик ошибок (trap) для отлова непредвиденных ошибок
Улучшена структура цикла ввода VPS данных - теперь есть ограниченное количество попыток
Что исправлено конкретно:
Если пользователь нажимает Enter на пустом поле, теперь будет только 3 попытки, после чего скрипт завершится
Все сообщения об ошибках теперь завершают скрипт или дают выбор продолжить
Убраны конфликты имен переменных между функциями
Улучшена обработка всех возможных ошибок
This commit is contained in:
@@ -33,14 +33,20 @@ if [[ $EUID -ne 0 ]]; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Функция безопасного ввода
|
||||
# Функция безопасного ввода с ограничением попыток
|
||||
safe_read() {
|
||||
local prompt="$1"
|
||||
local default="$2"
|
||||
local var_name="$3"
|
||||
local is_password="$4"
|
||||
local max_attempts="${5:-3}" # По умолчанию 3 попытки
|
||||
|
||||
while true; do
|
||||
local attempt=0
|
||||
local input=""
|
||||
|
||||
while [[ $attempt -lt $max_attempts ]]; do
|
||||
attempt=$((attempt + 1))
|
||||
|
||||
if [ "$is_password" = "yes" ]; then
|
||||
read -s -p "$prompt" input
|
||||
echo
|
||||
@@ -53,10 +59,14 @@ safe_read() {
|
||||
if [ -n "$input" ]; then
|
||||
eval "$var_name=\"$input\""
|
||||
return 0
|
||||
else
|
||||
echo -e "${RED}Поле не может быть пустым!${NC}"
|
||||
elif [[ $attempt -lt $max_attempts ]]; then
|
||||
echo -e "${YELLOW}Поле не может быть пустым! Попытка $attempt из $max_attempts${NC}"
|
||||
fi
|
||||
done
|
||||
|
||||
# Если превышено количество попыток
|
||||
echo -e "${RED}Превышено максимальное количество попыток ввода. Выход.${NC}"
|
||||
exit 1
|
||||
}
|
||||
|
||||
# Функция проверки ошибок
|
||||
@@ -64,6 +74,14 @@ check_error() {
|
||||
if [ $? -ne 0 ]; then
|
||||
log_message "ОШИБКА: $1" "$RED"
|
||||
log_message "Подробности в логе: $LOG_FILE" "$YELLOW"
|
||||
|
||||
# Не выходим сразу, а даем пользователю выбор
|
||||
echo -e "${YELLOW}Произошла ошибка: $1${NC}"
|
||||
read -p "Продолжить установку? (y/n): " -n 1 -r
|
||||
echo
|
||||
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
|
||||
exit 1
|
||||
fi
|
||||
return 1
|
||||
fi
|
||||
return 0
|
||||
@@ -86,6 +104,7 @@ detect_distro() {
|
||||
fi
|
||||
|
||||
log_message "Система: $OS $VERSION" "$GREEN"
|
||||
return 0
|
||||
}
|
||||
|
||||
# Установка зависимостей
|
||||
@@ -95,7 +114,9 @@ install_dependencies() {
|
||||
case $OS in
|
||||
ubuntu|debian)
|
||||
log_message "Обновление списка пакетов..." "$BLUE"
|
||||
apt-get update 2>&1 | tee -a "$LOG_FILE"
|
||||
if ! apt-get update 2>&1 | tee -a "$LOG_FILE"; then
|
||||
echo -e "${YELLOW}Предупреждение: не удалось обновить список пакетов${NC}"
|
||||
fi
|
||||
|
||||
log_message "Установка autossh, openssh-client и утилит..." "$BLUE"
|
||||
apt-get install -y autossh openssh-client net-tools curl git sshpass 2>&1 | tee -a "$LOG_FILE"
|
||||
@@ -117,17 +138,21 @@ install_dependencies() {
|
||||
# Попытка установить 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 ..
|
||||
if curl -sSL http://www.harding.motd.ca/autossh/autossh-1.4g.tgz | tar -xz; then
|
||||
cd autossh-1.4g || exit 1
|
||||
./configure
|
||||
make
|
||||
make install
|
||||
cd ..
|
||||
else
|
||||
echo -e "${YELLOW}Не удалось загрузить autossh${NC}"
|
||||
fi
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
|
||||
log_message "Зависимости успешно установлены!" "$GREEN"
|
||||
return 0
|
||||
}
|
||||
|
||||
# Настройка SSH
|
||||
@@ -145,23 +170,42 @@ setup_ssh() {
|
||||
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
|
||||
# Запрос данных VPS с проверкой
|
||||
local vps_data_ok=false
|
||||
local max_attempts=3
|
||||
|
||||
for ((attempt=1; attempt<=max_attempts; attempt++)); do
|
||||
echo -e "${CYAN}Введите данные для подключения к VPS (попытка $attempt из $max_attempts):${NC}"
|
||||
|
||||
# Используем обычный read для предотвращения конфликтов с safe_read
|
||||
read -p "IP адрес или доменное имя VPS: " VPS_HOST
|
||||
read -p "Порт SSH (по умолчанию 22): " VPS_PORT
|
||||
VPS_PORT=${VPS_PORT:-22}
|
||||
|
||||
echo ""
|
||||
echo -e "${CYAN}Выберите пользователя для подключения:${NC}"
|
||||
echo "1) root (рекомендуется для полного доступа)"
|
||||
echo "2) Другой пользователь"
|
||||
safe_read "Ваш выбор [1-2]: " "1" USER_CHOICE no
|
||||
read -p "Ваш выбор [1-2]: " USER_CHOICE
|
||||
|
||||
if [ "$USER_CHOICE" == "1" ]; then
|
||||
VPS_USER="root"
|
||||
echo -e "${YELLOW}Будет использоваться пользователь: root${NC}"
|
||||
else
|
||||
safe_read "Введите имя пользователя: " "" VPS_USER no
|
||||
read -p "Введите имя пользователя: " VPS_USER
|
||||
fi
|
||||
|
||||
# Проверка заполнения обязательных полей
|
||||
if [[ -z "$VPS_HOST" || -z "$VPS_USER" ]]; then
|
||||
echo -e "${RED}Ошибка: обязательные поля не заполнены!${NC}"
|
||||
if [[ $attempt -lt $max_attempts ]]; then
|
||||
echo -e "${YELLOW}Пожалуйста, заполните все поля.${NC}"
|
||||
echo ""
|
||||
continue
|
||||
else
|
||||
echo -e "${RED}Превышено максимальное количество попыток. Выход.${NC}"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
echo ""
|
||||
@@ -169,9 +213,10 @@ setup_ssh() {
|
||||
echo -e " VPS: ${YELLOW}$VPS_USER@$VPS_HOST:$VPS_PORT${NC}"
|
||||
echo ""
|
||||
|
||||
safe_read "Все верно? (y/n): " "y" CONFIRM no
|
||||
read -p "Все верно? (y/n): " CONFIRM
|
||||
|
||||
if [[ "$CONFIRM" =~ ^[Yy]$ ]]; then
|
||||
vps_data_ok=true
|
||||
break
|
||||
else
|
||||
echo -e "${YELLOW}Повторите ввод данных...${NC}"
|
||||
@@ -179,6 +224,11 @@ setup_ssh() {
|
||||
fi
|
||||
done
|
||||
|
||||
if [ "$vps_data_ok" = false ]; then
|
||||
echo -e "${RED}Не удалось получить корректные данные VPS. Выход.${NC}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Проверка подключения
|
||||
log_message "Проверка подключения к $VPS_USER@$VPS_HOST:$VPS_PORT..." "$BLUE"
|
||||
echo -e "${CYAN}Пытаюсь подключиться к VPS...${NC}"
|
||||
@@ -193,7 +243,7 @@ setup_ssh() {
|
||||
echo -e " 3) Работает ли SSH сервер на VPS"
|
||||
echo -e " 4) Не блокирует ли брандмауэр подключение"
|
||||
|
||||
safe_read "Продолжить все равно? (y/n): " "n" CONTINUE no
|
||||
read -p "Продолжить все равно? (y/n): " CONTINUE
|
||||
|
||||
if [[ ! "$CONTINUE" =~ ^[Yy]$ ]]; then
|
||||
exit 1
|
||||
@@ -206,7 +256,7 @@ setup_ssh() {
|
||||
|
||||
if [ -f "/root/.ssh/id_rsa" ]; then
|
||||
echo -e "${YELLOW}SSH ключ уже существует.${NC}"
|
||||
safe_read "Сгенерировать новый? (y/n): " "n" GEN_NEW no
|
||||
read -p "Сгенерировать новый? (y/n): " GEN_NEW
|
||||
|
||||
if [[ "$GEN_NEW" =~ ^[Yy]$ ]]; then
|
||||
ssh-keygen -t rsa -b 4096 -N "" -f /root/.ssh/id_rsa -q
|
||||
@@ -221,7 +271,7 @@ setup_ssh() {
|
||||
log_message "Настройка конфигурации SSH для стабильного подключения..." "$BLUE"
|
||||
|
||||
# Создание конфига для root с улучшенными настройками
|
||||
cat > /root/.ssh/config << EOF
|
||||
cat > /root/.ssh/config << EOFCONFIG
|
||||
# Основная конфигурация SSH
|
||||
Host tunnel-vps
|
||||
HostName $VPS_HOST
|
||||
@@ -269,7 +319,7 @@ Host *
|
||||
HashKnownHosts yes
|
||||
# Настройки переподключения
|
||||
RekeyLimit 1G 1h
|
||||
EOF
|
||||
EOFCONFIG
|
||||
|
||||
chmod 600 /root/.ssh/config
|
||||
|
||||
@@ -321,7 +371,8 @@ EOF
|
||||
echo -e "${YELLOW}Для копирования ключа потребуется пароль от $VPS_USER на VPS${NC}"
|
||||
|
||||
# Запрос пароля для копирования ключа
|
||||
safe_read "Введите пароль для $VPS_USER@$VPS_HOST (или нажмите Enter для пропуска): " "" VPS_PASSWORD yes
|
||||
read -s -p "Введите пароль для $VPS_USER@$VPS_HOST (или нажмите Enter для пропуска): " VPS_PASSWORD
|
||||
echo
|
||||
|
||||
if [ -n "$VPS_PASSWORD" ]; then
|
||||
echo ""
|
||||
@@ -329,10 +380,10 @@ EOF
|
||||
|
||||
# Установка SSH_ASKPASS для автоматического ввода пароля
|
||||
export SSH_ASKPASS="$(mktemp)"
|
||||
cat > "$SSH_ASKPASS" << EOF
|
||||
cat > "$SSH_ASKPASS" << EOFASKPASS
|
||||
#!/bin/bash
|
||||
echo "$VPS_PASSWORD"
|
||||
EOF
|
||||
EOFASKPASS
|
||||
chmod +x "$SSH_ASKPASS"
|
||||
export DISPLAY=:0
|
||||
|
||||
@@ -371,7 +422,7 @@ EOF
|
||||
echo -e "${BOLD}chmod 600 ~/.ssh/authorized_keys${NC}"
|
||||
echo ""
|
||||
|
||||
safe_read "Нажмите Enter после добавления ключа на VPS..." "" WAIT no
|
||||
read -p "Нажмите Enter после добавления ключа на VPS..." WAIT
|
||||
|
||||
# Тестовое подключение
|
||||
log_message "Тестовое подключение к VPS..." "$BLUE"
|
||||
@@ -390,7 +441,7 @@ EOF
|
||||
echo -e "${YELLOW}⚠ Не удалось подключиться без пароля${NC}"
|
||||
echo -e "${YELLOW}Убедитесь, что ключ добавлен в authorized_keys на VPS${NC}"
|
||||
|
||||
safe_read "Продолжить установку? (y/n): " "y" CONTINUE_INSTALL no
|
||||
read -p "Продолжить установку? (y/n): " CONTINUE_INSTALL
|
||||
|
||||
if [[ ! "$CONTINUE_INSTALL" =~ ^[Yy]$ ]]; then
|
||||
exit 1
|
||||
@@ -400,7 +451,7 @@ EOF
|
||||
# Настройка для не-root пользователей
|
||||
if [[ $EUID -eq 0 ]] && [ -d "/home/" ] && [ "$(ls -A /home/ 2>/dev/null)" ]; then
|
||||
echo ""
|
||||
safe_read "Настроить SSH для обычных пользователей системы? (y/n): " "n" SETUP_USERS no
|
||||
read -p "Настроить SSH для обычных пользователей системы? (y/n): " SETUP_USERS
|
||||
|
||||
if [[ "$SETUP_USERS" =~ ^[Yy]$ ]]; then
|
||||
log_message "Настройка SSH для всех пользователей системы..." "$CYAN"
|
||||
@@ -424,7 +475,7 @@ EOF
|
||||
echo -e " ${GREEN}✓ Конфиг скопирован${NC}"
|
||||
fi
|
||||
|
||||
safe_read " Скопировать SSH ключ для пользователя $USER? (y/n): " "n" COPY_FOR_USER no
|
||||
read -p " Скопировать SSH ключ для пользователя $USER? (y/n): " COPY_FOR_USER
|
||||
|
||||
if [[ "$COPY_FOR_USER" =~ ^[Yy]$ ]]; then
|
||||
cp /root/.ssh/id_rsa* "$USER_SSH_DIR/" 2>/dev/null
|
||||
@@ -442,16 +493,17 @@ EOF
|
||||
log_message "Сохранение настроек VPS..." "$BLUE"
|
||||
|
||||
mkdir -p /etc/ssh_tunnel
|
||||
cat > /etc/ssh_tunnel/vps_settings.conf << EOF
|
||||
cat > /etc/ssh_tunnel/vps_settings.conf << EOFSETTINGS
|
||||
# Настройки VPS для автономных туннелей
|
||||
VPS_HOST="$VPS_HOST"
|
||||
VPS_PORT="$VPS_PORT"
|
||||
VPS_USER="$VPS_USER"
|
||||
CONFIGURED_ON="$(date '+%Y-%m-%d %H:%M:%S')"
|
||||
EOF
|
||||
EOFSETTINGS
|
||||
|
||||
chmod 600 /etc/ssh_tunnel/vps_settings.conf
|
||||
log_message "Настройки SSH сохранены в /etc/ssh_tunnel/vps_settings.conf" "$GREEN"
|
||||
return 0
|
||||
}
|
||||
|
||||
# Установка основного скрипта управления
|
||||
@@ -1267,6 +1319,7 @@ EOFCOLORS
|
||||
ln -sf /opt/ssh_tunnel_manager/manager.sh /usr/local/bin/tunnel-manager 2>/dev/null
|
||||
|
||||
log_message "Основной скрипт установлен в /opt/ssh_tunnel_manager/" "$GREEN"
|
||||
return 0
|
||||
}
|
||||
|
||||
# Настройка systemd служб
|
||||
@@ -1381,6 +1434,7 @@ EOFTIMER
|
||||
systemctl start tunnel-check.timer 2>/dev/null
|
||||
|
||||
log_message "Systemd службы настроены" "$GREEN"
|
||||
return 0
|
||||
}
|
||||
|
||||
# Создание примера туннеля
|
||||
@@ -1388,7 +1442,7 @@ 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
|
||||
read -p "Создать пример туннеля для SSH (порт 22 -> 10022)? (y/n): " CREATE_EXAMPLE
|
||||
|
||||
if [[ "$CREATE_EXAMPLE" =~ ^[Yy]$ ]]; then
|
||||
cat > /etc/ssh_tunnel/example_ssh.conf << EOFEXAMPLE
|
||||
@@ -1445,6 +1499,7 @@ EOFEXSERVICE
|
||||
echo -e " tail -f /var/log/ssh_tunnel/example_ssh.log"
|
||||
fi
|
||||
fi
|
||||
return 0
|
||||
}
|
||||
|
||||
# Завершение установки
|
||||
@@ -1485,7 +1540,7 @@ finish_installation() {
|
||||
echo ""
|
||||
|
||||
# Запрос на перезагрузку
|
||||
safe_read "Перезагрузить систему для применения всех настроек? (y/n): " "n" REBOOT_NOW no
|
||||
read -p "Перезагрузить систему для применения всех настроек? (y/n): " REBOOT_NOW
|
||||
|
||||
if [[ "$REBOOT_NOW" =~ ^[Yy]$ ]]; then
|
||||
log_message "Перезагрузка системы по запросу пользователя..." "$YELLOW"
|
||||
@@ -1498,6 +1553,7 @@ finish_installation() {
|
||||
echo -e "${BOLD}tunnel-manager${NC}"
|
||||
echo ""
|
||||
fi
|
||||
return 0
|
||||
}
|
||||
|
||||
# Главная функция установки
|
||||
@@ -1505,26 +1561,48 @@ main_installation() {
|
||||
log_message "Начало установки автономного менеджера SSH туннелей" "$CYAN"
|
||||
|
||||
# Определяем дистрибутив
|
||||
detect_distro
|
||||
detect_distro || {
|
||||
echo -e "${RED}Не удалось определить дистрибутив${NC}"
|
||||
exit 1
|
||||
}
|
||||
|
||||
# Устанавливаем зависимости
|
||||
install_dependencies
|
||||
install_dependencies || {
|
||||
echo -e "${RED}Не удалось установить зависимости${NC}"
|
||||
exit 1
|
||||
}
|
||||
|
||||
# Настраиваем SSH (теперь будет запрашивать данные)
|
||||
setup_ssh
|
||||
# Настраиваем SSH
|
||||
setup_ssh || {
|
||||
echo -e "${RED}Не удалось настроить SSH${NC}"
|
||||
exit 1
|
||||
}
|
||||
|
||||
# Устанавливаем основной скрипт
|
||||
install_main_script
|
||||
install_main_script || {
|
||||
echo -e "${RED}Не удалось установить основной скрипт${NC}"
|
||||
exit 1
|
||||
}
|
||||
|
||||
# Настраиваем systemd службы
|
||||
setup_systemd_services
|
||||
setup_systemd_services || {
|
||||
echo -e "${YELLOW}Не удалось настроить systemd службы${NC}"
|
||||
}
|
||||
|
||||
# Создаем пример туннеля
|
||||
create_example_tunnel
|
||||
create_example_tunnel || {
|
||||
echo -e "${YELLOW}Не удалось создать пример туннеля${NC}"
|
||||
}
|
||||
|
||||
# Завершаем установку
|
||||
finish_installation
|
||||
}
|
||||
|
||||
# Обработка ошибок и трассировка
|
||||
set -eE
|
||||
trap 'echo -e "${RED}Произошла ошибка в строке $LINENO. Проверьте лог: $LOG_FILE${NC}"' ERR
|
||||
|
||||
# Запуск установки
|
||||
main_installation
|
||||
main_installation
|
||||
|
||||
exit 0
|
||||
Reference in New Issue
Block a user