This commit is contained in:
NW
2025-12-22 19:51:55 +00:00
parent e9efead80d
commit d27e240e5e

View File

@@ -45,7 +45,7 @@ check_error() {
log_message "Подробности в логе: $LOG_DIR/manager.log" "$YELLOW"
echo -e "${YELLOW}Произошла ошибка: $1${NC}"
read -p "Продолжить выполнение скрипта? (y/n): " -n 1 -r
read -t 60 -p "Продолжить выполнение скрипта? (y/n): " -n 1 -r
echo
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
exit 1
@@ -77,7 +77,12 @@ safe_read() {
while [[ $attempt -lt $max_attempts ]]; do
attempt=$((attempt + 1))
read -p "$prompt" input
# Явное чтение из /dev/tty чтобы избежать проблем с pipe
if [[ -t 0 ]]; then
read -p "$prompt" input
else
read -p "$prompt" input </dev/tty
fi
input="${input:-$default}"
@@ -100,6 +105,42 @@ safe_read() {
exit 1
}
# Функция чтения ввода с поддержкой pipe
read_input() {
local prompt="$1"
local timeout="${2:-0}"
if [[ -t 0 ]]; then
if [[ $timeout -gt 0 ]]; then
read -t "$timeout" -p "$prompt" input
else
read -p "$prompt" input
fi
else
# Если stdin не терминал (например, при pipe), читаем из /dev/tty
if [[ $timeout -gt 0 ]]; then
read -t "$timeout" -p "$prompt" input </dev/tty
else
read -p "$prompt" input </dev/tty
fi
fi
echo "$input"
}
# Функция чтения скрытого ввода (для паролей)
read_secret() {
local prompt="$1"
if [[ -t 0 ]]; then
read -s -p "$prompt" secret
echo
else
read -s -p "$prompt" secret </dev/tty
echo
fi
echo "$secret"
}
# Функция загрузки настроек VPS
load_vps_settings() {
if [ -f "$VPS_CONFIG" ]; then
@@ -117,7 +158,7 @@ show_public_key() {
cat /root/.ssh/id_rsa.pub
echo ""
fi
read -p "Нажмите Enter для продолжения..."
read_input "Нажмите Enter для продолжения..."
}
# Функция проверки SSH подключения
@@ -308,7 +349,7 @@ setup_vps() {
echo "1) root (рекомендуется для полного доступа)"
echo "2) Другой пользователь"
read -p "Ваш выбор [1-2]: " USER_CHOICE
USER_CHOICE=$(read_input "Ваш выбор [1-2]: ")
if [ "$USER_CHOICE" == "1" ]; then
VPS_USER_TEMP="root"
@@ -350,9 +391,8 @@ EOFSETTINGS
local VPS_PASSWORD
echo -e "${YELLOW}Для автоматического копирования ключа потребуется пароль от $VPS_USER на VPS.${NC}"
# Используем read -s для скрытого ввода
read -s -p "Введите пароль для $VPS_USER@$VPS_HOST: " VPS_PASSWORD
echo
# Используем read_secret для скрытого ввода
VPS_PASSWORD=$(read_secret "Введите пароль для $VPS_USER@$VPS_HOST: ")
if [ -n "$VPS_PASSWORD" ]; then
if command -v sshpass &> /dev/null; then
@@ -383,6 +423,8 @@ EOFSETTINGS
log_message "ОШИБКА: Тестовое подключение не удалось." "$RED"
log_message "Убедитесь, что публичный ключ скопирован, порт $VPS_PORT открыт, и SSH-сервер на VPS запущен." "$YELLOW"
fi
read_input "Нажмите Enter для продолжения..."
}
# 3. Добавление нового туннеля
@@ -390,6 +432,7 @@ add_tunnel() {
check_root "add_tunnel"
if ! load_vps_settings; then
log_message "Сначала необходимо настроить VPS (опция 1)." "$RED"
read_input "Нажмите Enter для продолжения..."
return 1
fi
@@ -406,6 +449,7 @@ add_tunnel() {
if [ -z "$LOCAL_PORT" ] || [ -z "$REMOTE_PORT" ] || [ -z "$TUNNEL_NAME" ]; then
log_message "ОШИБКА: Все поля обязательны." "$RED"
read_input "Нажмите Enter для продолжения..."
return 1
fi
@@ -413,6 +457,7 @@ add_tunnel() {
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
@@ -478,6 +523,8 @@ EOFSERVICE
log_message "ОШИБКА: Не удалось запустить туннель '$TUNNEL_NAME'." "$RED"
log_message "Проверьте лог: tail -f $LOG_DIR/$TUNNEL_ID.log" "$YELLOW"
fi
read_input "Нажмите Enter для продолжения..."
}
# 4. Управление туннелем (запуск, остановка, перезапуск, удаление)
@@ -566,7 +613,7 @@ view_logs() {
echo -e "${CYAN}[4]${NC} Назад"
echo ""
read -p "Выберите действие: " choice
choice=$(read_input "Выберите действие: ")
case $choice in
1)
@@ -574,7 +621,7 @@ view_logs() {
echo -e "${CYAN}Доступные логи:${NC}"
find "$LOG_DIR" -maxdepth 1 -type f -name "tunnel-*.log" -printf " %f\n"
echo ""
read -p "Введите имя лог-файла (например, tunnel-ssh_access.log): " log_file
log_file=$(read_input "Введите имя лог-файла (например, tunnel-ssh_access.log): ")
if [ -f "$LOG_DIR/$log_file" ]; then
less "$LOG_DIR/$log_file"
else
@@ -591,12 +638,12 @@ view_logs() {
tail -5 "$log"
fi
done
read -p "Нажмите Enter для продолжения..."
read_input "Нажмите Enter для продолжения..."
;;
3)
echo -e "${CYAN}Системные логи туннелей (последний час):${NC}"
journalctl -u tunnel-* --since "1 hour ago" -n 20 2>/dev/null || log_message "Системные логи отсутствуют" "$YELLOW"
read -p "Нажмите Enter для продолжения..."
read_input "Нажмите Enter для продолжения..."
;;
4)
return
@@ -620,12 +667,12 @@ test_connections() {
echo "3) Назад"
echo ""
read -p "Выберите тест: " test_choice
test_choice=$(read_input "Выберите тест: ")
case $test_choice in
1)
check_ssh_connection
read -p "Нажмите Enter для продолжения..."
read_input "Нажмите Enter для продолжения..."
;;
2)
echo -e "${CYAN}Тест локальных портов туннелей:${NC}"
@@ -637,7 +684,7 @@ test_connections() {
NC_CMD="ncat -z localhost"
else
log_message "ОШИБКА: Утилита 'nc' или 'ncat' не найдена. Невозможно проверить порты." "$RED"
read -p "Нажмите Enter для продолжения..."
read_input "Нажмите Enter для продолжения..."
continue
fi
@@ -656,7 +703,7 @@ test_connections() {
fi
fi
done
read -p "Нажмите Enter для продолжения..."
read_input "Нажмите Enter для продолжения..."
;;
3)
return
@@ -673,7 +720,7 @@ test_connections() {
setup_routing() {
if ! command -v iptables &> /dev/null; then
log_message "ОШИБКА: Утилита 'iptables' не найдена. Установите ее для использования этой функции." "$RED"
read -p "Нажмите Enter для продолжения..."
read_input "Нажмите Enter для продолжения..."
return
fi
@@ -687,19 +734,18 @@ setup_routing() {
echo "4) Назад"
echo ""
read -p "Выберите действие: " routing_choice
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 -p "Нажмите Enter для продолжения..."
read_input "Нажмите Enter для продолжения..."
;;
2)
local IN_PORT DEST_IP DEST_PORT
read -p "Входной порт (напр. 80): " IN_PORT
read -p "IP назначения (напр. 192.168.1.10): " DEST_IP
read -p "Порт назначения (напр. 8080): " DEST_PORT
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"
@@ -707,7 +753,7 @@ setup_routing() {
else
log_message "Не все поля заполнены." "$RED"
fi
read -p "Нажмите Enter для продолжения..."
read_input "Нажмите Enter для продолжения..."
;;
3)
if command -v netfilter-persistent &> /dev/null; then
@@ -720,7 +766,7 @@ setup_routing() {
else
log_message "ОШИБКА: Не найдена утилита для сохранения правил (netfilter-persistent или iptables-save)." "$RED"
fi
read -p "Нажмите Enter для продолжения..."
read_input "Нажмите Enter для продолжения..."
;;
4)
return
@@ -745,13 +791,13 @@ setup_ssh_config() {
echo "4) Назад"
echo ""
read -p "Выберите действие: " ssh_choice
ssh_choice=$(read_input "Выберите действие: ")
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"
read -p "Нажмите Enter для продолжения..."
read_input "Нажмите Enter для продолжения..."
;;
2)
if sudo systemctl restart sshd 2>/dev/null || sudo service ssh restart 2>/dev/null; then
@@ -759,7 +805,7 @@ setup_ssh_config() {
else
log_message "ОШИБКА: Не удалось перезапустить SSH демон." "$RED"
fi
read -p "Нажмите Enter для продолжения..."
read_input "Нажмите Enter для продолжения..."
;;
3)
if sudo sshd -t 2>/dev/null; then
@@ -767,7 +813,7 @@ setup_ssh_config() {
else
log_message "ОШИБКА: Ошибка в конфигурации SSH." "$RED"
fi
read -p "Нажмите Enter для продолжения..."
read_input "Нажмите Enter для продолжения..."
;;
4)
return
@@ -807,7 +853,7 @@ manage_tunnels_menu() {
list_tunnels
echo -e "${CYAN}Введите ID туннеля для управления (или 'b' для назад):${NC}"
read -p "ID туннеля: " TUNNEL_ID_MANAGE
TUNNEL_ID_MANAGE=$(read_input "ID туннеля: ")
if [ "$TUNNEL_ID_MANAGE" == "b" ]; then
return
@@ -830,7 +876,7 @@ manage_tunnels_menu() {
echo " d) Удалить"
echo " b) Назад"
read -p "Действие: " ACTION_CHOICE
ACTION_CHOICE=$(read_input "Действие: ")
case "$ACTION_CHOICE" in
s) ;; # Статус уже показан
@@ -838,7 +884,7 @@ manage_tunnels_menu() {
p) manage_tunnel "$TUNNEL_ID_MANAGE" "stop";;
r) manage_tunnel "$TUNNEL_ID_MANAGE" "restart";;
d)
read -p "Вы уверены, что хотите удалить туннель $TUNNEL_ID_MANAGE? (y/N): " CONFIRM_REMOVE
CONFIRM_REMOVE=$(read_input "Вы уверены, что хотите удалить туннель $TUNNEL_ID_MANAGE? (y/N): ")
if [[ "$CONFIRM_REMOVE" =~ ^[Yy]$ ]]; then
manage_tunnel "$TUNNEL_ID_MANAGE" "remove"
return # Возврат в меню туннелей после удаления
@@ -847,7 +893,7 @@ manage_tunnels_menu() {
b) break;;
*) log_message "Неизвестная опция." "$RED";;
esac
read -p "Нажмите Enter для продолжения...";
read_input "Нажмите Enter для продолжения...";
done
else
log_message "Туннель с ID '$TUNNEL_ID_MANAGE' не найден." "$RED"
@@ -887,7 +933,7 @@ main_menu() {
echo -e "9) ${BOLD}Выход${NC}"
echo ""
read -p "Выберите опцию [1-9]: " choice
choice=$(read_input "Выберите опцию [1-9]: ")
case $choice in
1) setup_vps ;;
@@ -919,11 +965,13 @@ if [[ $# -eq 0 ]]; then
# Проверяем, установлен ли уже скрипт
if [ -f "/usr/local/bin/tunnel-manager" ]; then
echo -e "${YELLOW}Менеджер уже установлен. Запуск меню...${NC}"
sleep 2
main_menu
else
echo -e "${GREEN}Начинаем установку...${NC}"
install_manager
echo -e "${GREEN}Установка завершена. Запуск меню...${NC}"
sleep 2
main_menu
fi
else