#!/bin/bash ################################################################################ # WireGuard Chain Manager # Gestisce connessioni random/intelligenti a catena di server WireGuard ################################################################################ CONFIG_DIR="/etc/wireguard/chains" CLIENT_KEY="/etc/wireguard/client_privatekey" STATE_FILE="/var/run/wg-chain-current" # Colori RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' BLUE='\033[0;34m' NC='\033[0m' # No Color ################################################################################ # Configurazione server disponibili ################################################################################ # Array associativo: Nome => Endpoint:Porta,PublicKey,ChainPosition declare -A SERVERS=( # Entry servers (primo hop) ["DE-Entry"]="de1.example.com:51820,,entry" ["NL-Entry"]="nl1.example.com:51820,,entry" ["SE-Entry"]="se1.example.com:51820,,entry" # Middle servers (hop intermedi) ["CH-Middle"]="ch1.example.com:51820,,middle" ["AT-Middle"]="at1.example.com:51820,,middle" # Exit servers (ultimo hop) ["FR-Exit"]="fr1.example.com:51820,,exit" ["ES-Exit"]="es1.example.com:51820,,exit" ) ################################################################################ # Funzioni helper ################################################################################ log_info() { echo -e "${BLUE}[INFO]${NC} $1" } log_success() { echo -e "${GREEN}[OK]${NC} $1" } log_warning() { echo -e "${YELLOW}[WARN]${NC} $1" } log_error() { echo -e "${RED}[ERROR]${NC} $1" } check_root() { if [ "$EUID" -ne 0 ]; then log_error "Questo script richiede privilegi root" exit 1 fi } get_server_by_position() { local position=$1 local servers=() for name in "${!SERVERS[@]}"; do IFS=',' read -r endpoint pubkey pos <<< "${SERVERS[$name]}" if [ "$pos" = "$position" ]; then servers+=("$name") fi done echo "${servers[@]}" } get_random_server() { local position=$1 local available=($(get_server_by_position "$position")) if [ ${#available[@]} -eq 0 ]; then log_error "Nessun server disponibile per posizione: $position" return 1 fi echo "${available[$RANDOM % ${#available[@]}]}" } parse_server_info() { local name=$1 IFS=',' read -r endpoint pubkey position <<< "${SERVERS[$name]}" echo "$endpoint|$pubkey|$position" } test_server_latency() { local name=$1 local info=$(parse_server_info "$name") local endpoint=$(echo "$info" | cut -d'|' -f1) local host=$(echo "$endpoint" | cut -d':' -f1) local latency=$(ping -c 3 -W 2 "$host" 2>/dev/null | tail -1 | awk -F '/' '{print $5}') if [ -z "$latency" ]; then echo "9999" else echo "$latency" fi } generate_wg_config() { local name=$1 local client_ip=$2 local info=$(parse_server_info "$name") local endpoint=$(echo "$info" | cut -d'|' -f1) local pubkey=$(echo "$info" | cut -d'|' -f2) cat </dev/null || echo 0) )); then best_latency=$latency best_server=$name fi done server_name=$best_server log_success "Server più veloce: $server_name (${best_latency}ms)" ;; *) # Nome specifico if [ -n "${SERVERS[$mode]}" ]; then server_name=$mode else log_error "Server non trovato: $mode" log_info "Usa 'list' per vedere server disponibili" return 1 fi ;; esac if [ -z "$server_name" ]; then log_error "Nessun server selezionato" return 1 fi log_info "Connessione a: $server_name" # Disconnetti connessione esistente wg-quick down wg0 2>/dev/null # Genera config temporanea local temp_config="/tmp/wg-temp-$$.conf" generate_wg_config "$server_name" "10.100.0.2" > "$temp_config" # Connetti if wg-quick up "$temp_config"; then log_success "Connesso a $server_name" echo "$server_name" > "$STATE_FILE" rm -f "$temp_config" # Mostra info echo "" wg show wg0 echo "" log_info "IP pubblico: $(curl -s --max-time 5 https://api.ipify.org || echo 'N/A')" else log_error "Connessione fallita" rm -f "$temp_config" return 1 fi } connect_chain() { local chain_length=${1:-2} # Default 2 hop log_info "Creazione catena di $chain_length server..." local positions=() case $chain_length in 2) positions=("entry" "exit") ;; 3) positions=("entry" "middle" "exit") ;; *) log_error "Lunghezza catena supportata: 2 o 3" return 1 ;; esac local selected_servers=() for pos in "${positions[@]}"; do local server=$(get_random_server "$pos") if [ -z "$server" ]; then log_error "Nessun server disponibile per posizione: $pos" return 1 fi selected_servers+=("$server") log_info "Hop ${#selected_servers[@]}: $server ($pos)" done log_warning "NOTA: Implementazione catena multi-hop richiede configurazione avanzata" log_info "Connessione a primo hop: ${selected_servers[0]}" # Per ora connette solo al primo hop # Implementazione completa richiede configurazione server-side connect_single "${selected_servers[0]}" } disconnect() { log_info "Disconnessione..." if wg-quick down wg0 2>/dev/null; then log_success "Disconnesso" rm -f "$STATE_FILE" else log_warning "Nessuna connessione attiva" fi } status() { echo "" echo "=== STATUS WIREGUARD ===" echo "" if [ -f "$STATE_FILE" ]; then local current=$(cat "$STATE_FILE") log_info "Server corrente: $current" else log_warning "Nessuna connessione attiva" fi echo "" if wg show wg0 >/dev/null 2>&1; then wg show wg0 echo "" log_info "IP pubblico: $(curl -s --max-time 5 https://api.ipify.org || echo 'N/A')" else log_warning "Interfaccia wg0 non attiva" fi echo "" } rotate() { log_info "Rotazione server..." if [ -f "$STATE_FILE" ]; then local current=$(cat "$STATE_FILE") log_info "Server corrente: $current" fi disconnect sleep 2 connect_single random } ################################################################################ # Menu principale ################################################################################ show_usage() { cat < Connetti a server singolo mode: random, fastest, NOME_SERVER chain Connetti a catena (2 o 3 hop) disconnect Disconnetti status Mostra stato connessione rotate Cambia server random ESEMPI: $(basename $0) list $(basename $0) connect random $(basename $0) connect fastest $(basename $0) connect DE-Entry $(basename $0) chain 2 $(basename $0) chain 3 $(basename $0) rotate $(basename $0) disconnect EOF } ################################################################################ # Main ################################################################################ check_root case "${1:-}" in list) list_servers ;; connect) connect_single "${2:-random}" ;; chain) connect_chain "${2:-2}" ;; disconnect) disconnect ;; status) status ;; rotate) rotate ;; *) show_usage exit 1 ;; esac exit 0