====== WM ====== #!/bin/bash # ==AUTOEXEC== # === WireGuard All-in-One Manager === # * Менеджер клиентов WireGuard с QR-кодами, безопасным удалением и Unicode-меню # === Конфигурация каталогов === WG_INTERFACE="wg0" WG_BASE="$HOME/wireguard" CLIENTS_DIR="$WG_BASE/clients" QR_DIR="$WG_BASE/qrcodes" CONFIG_DIR="$WG_BASE/config" PRIVATEKEY_FILE="$CONFIG_DIR/privatekey" PUBLICKEY_FILE="$CONFIG_DIR/publickey" EXTERNAL_IP_FILE="$CONFIG_DIR/external_ip" INTERNAL_IP_FILE="$CONFIG_DIR/internal_ip" # === Подготовка окружения === init_environment() { mkdir -p "$CLIENTS_DIR" "$QR_DIR" "$CONFIG_DIR" chmod 700 "$CLIENTS_DIR" "$QR_DIR" "$CONFIG_DIR" if [[ ! -f "$PRIVATEKEY_FILE" || ! -f "$PUBLICKEY_FILE" ]]; then echo "🔐 Серверные ключи отсутствуют. Сгенерировать новые? (yes/no):" read -r confirm if [[ "$confirm" != "yes" ]]; then echo "🚫 Без серверных ключей продолжение невозможно." exit 1 fi SERVER_PRIVATE_KEY=$(wg genkey) SERVER_PUBLIC_KEY=$(echo "$SERVER_PRIVATE_KEY" | wg pubkey) echo "$SERVER_PRIVATE_KEY" > "$PRIVATEKEY_FILE" echo "$SERVER_PUBLIC_KEY" > "$PUBLICKEY_FILE" chmod 600 "$PRIVATEKEY_FILE" "$PUBLICKEY_FILE" echo "✅ Ключи сервера сгенерированы." fi if [[ ! -f "$EXTERNAL_IP_FILE" ]]; then echo "🌐 Введите внешний IP-адрес или домен (например, your.domain.com):" read -r EXTERNAL_IP echo "$EXTERNAL_IP" > "$EXTERNAL_IP_FILE" fi if [[ ! -f "$INTERNAL_IP_FILE" ]]; then echo "💡 Введите внутреннюю подсеть (по умолчанию 10.0.0.1/24):" read -r INTERNAL_SUBNET INTERNAL_SUBNET=${INTERNAL_SUBNET:-10.0.0.1/24} echo "$INTERNAL_SUBNET" > "$INTERNAL_IP_FILE" fi } # === Чтение конфигурации сервера === read_server_config() { SERVER_PRIVATE_KEY=$(<"$PRIVATEKEY_FILE") SERVER_PUBLIC_KEY=$(<"$PUBLICKEY_FILE") EXTERNAL_IP=$(<"$EXTERNAL_IP_FILE") INTERNAL_SUBNET=$(<"$INTERNAL_IP_FILE") } # === Двойное подтверждение === confirm_twice() { read -p "❓ Вы уверены? (yes/no): " first [[ "$first" != "yes" ]] && echo "🚫 Отменено." && return 1 read -p "❗ Подтвердите действие (yes/no): " second [[ "$second" != "yes" ]] && echo "🚫 Отменено." && return 1 return 0 } # === Показать меню выбора клиента === select_client() { local clients=($(ls "$CLIENTS_DIR" 2>/dev/null | sed 's/\.conf$//')) if [[ ${#clients[@]} -eq 0 ]]; then echo "⚠️ Нет доступных клиентов."; return 1; fi echo -e "\n📋 Доступные клиенты:" for i in "${!clients[@]}"; do echo " $((i+1))) ${clients[$i]}"; done echo " 0) Отмена" read -p "Выберите клиента: " index if [[ "$index" == "0" || -z "$index" ]]; then return 1; fi CLIENT_NAME="${clients[$((index-1))]}" return 0 } # === Добавление клиента === add_client() { echo "🔧 Добавление нового клиента..." read -p "Введите имя клиента: " CLIENT_NAME CLIENT_CONF="$CLIENTS_DIR/$CLIENT_NAME.conf" CLIENT_QR="$QR_DIR/$CLIENT_NAME.png" if [[ -f "$CLIENT_CONF" ]]; then echo "⚠️ Клиент с таким именем уже существует: $CLIENT_CONF" return fi read -p "Введите IP-адрес клиента (оставьте пустым для автогенерации): " CLIENT_IP if [[ -z "$CLIENT_IP" ]]; then BASE_NET=$(echo "$INTERNAL_SUBNET" | cut -d'.' -f1-3) LAST_OCTET=$((100 + RANDOM % 100)) CLIENT_IP="$BASE_NET.$LAST_OCTET/32" fi echo "📎 IP клиента: $CLIENT_IP" confirm_twice || return 1 CLIENT_PRIVATE_KEY=$(wg genkey) CLIENT_PUBLIC_KEY=$(echo "$CLIENT_PRIVATE_KEY" | wg pubkey) sudo wg set "$WG_INTERFACE" peer "$CLIENT_PUBLIC_KEY" allowed-ips "$CLIENT_IP" cat > "$CLIENT_CONF" <> " option case $option in 1) add_client;; 2) list_clients;; 3) get_client_config;; 4) show_qr_code;; 5) regen_qr_code;; 6) remove_client;; 7) remove_all_clients;; 8) restart_wireguard;; 9) show_client_ips;; 10) show_status;; 0) echo "👋 Выход."; exit 0;; *) echo "❌ Неверный выбор.";; esac done