# WireGuard Auto-Switch — Full Implementation Complete script + systemd timer for automatic WireGuard failover. ## Auto-Switch Script Path: `~/.hermes/scripts/wg-auto-switch.sh` ```bash #!/bin/bash WG_IF="wg0" LOG="/var/log/wg-auto-switch.log" TARGETS=("8.8.8.8" "1.1.1.1" "208.67.222.222") FAIL_THRESHOLD=3 RECOVER_THRESHOLD=2 FAIL_FILE="/tmp/wg-auto-fail-count" RECOVER_FILE="/tmp/wg-auto-recover-count" log() { echo "$(date '+%Y-%m-%d %H:%M:%S') $1" >> "$LOG"; } check_network() { for target in "${TARGETS[@]}"; do if curl -s --max-time 3 --head "http://$target" > /dev/null 2>&1; then return 0; fi if ping -c 1 -W 2 "$target" > /dev/null 2>&1; then return 0; fi done return 1 } wg_is_up() { ip link show "$WG_IF" > /dev/null 2>&1; } get_count() { [ -f "$1" ] && cat "$1" || echo 0; } if check_network; then if wg_is_up; then count=$(($(get_count "$RECOVER_FILE") + 1)) echo "$count" > "$RECOVER_FILE" [ "$count" -ge "$RECOVER_THRESHOLD" ] && { log "✅ Network recovered, disconnecting WireGuard" sudo wg-quick down "$WG_IF" 2>>"$LOG" echo 0 > "$FAIL_FILE"; echo 0 > "$RECOVER_FILE" } else echo 0 > "$FAIL_FILE"; echo 0 > "$RECOVER_FILE" fi else if ! wg_is_up; then count=$(($(get_count "$FAIL_FILE") + 1)) echo "$count" > "$FAIL_FILE" [ "$count" -ge "$FAIL_THRESHOLD" ] && { log "❌ Network restricted (${count} failures), starting WireGuard" sudo wg-quick up "$WG_IF" 2>>"$LOG" echo 0 > "$FAIL_FILE"; echo 0 > "$RECOVER_FILE" } else log "⚠️ WireGuard connected but still no network" fi fi ``` ## Systemd Timer Setup ```bash # Make script executable chmod +x ~/.hermes/scripts/wg-auto-switch.sh # Create service unit sudo tee /etc/systemd/system/wg-auto-switch.service << 'EOF' [Unit] Description=WireGuard Auto Switch - Network Check After=network.target [Service] Type=oneshot ExecStart=/home/openclaw/.hermes/scripts/wg-auto-switch.sh User=openclaw EOF # Create timer unit sudo tee /etc/systemd/system/wg-auto-switch.timer << 'EOF' [Unit] Description=Run WireGuard auto switch every 30 seconds [Timer] OnBootSec=30 OnUnitActiveSec=30 AccuracySec=5 [Install] WantedBy=timers.target EOF # Enable and start sudo systemctl daemon-reload sudo systemctl enable --now wg-auto-switch.timer ``` ## Monitoring ```bash sudo systemctl status wg-auto-switch.timer tail -f /var/log/wg-auto-switch.log sudo wg show ``` ## Tuning | Parameter | Default | Effect | |-----------|---------|--------| | `FAIL_THRESHOLD` | 3 | Consecutive failures before VPN activates (higher = slower to react, less flapping) | | `RECOVER_THRESHOLD` | 2 | Consecutive successes before VPN deactivates | | Timer interval | 30s | How often to check (in `/etc/systemd/system/wg-auto-switch.timer`) | | `curl --max-time` | 3s | Per-target timeout | | `ping -W` | 2s | Ping timeout | For stricter environments (GFW deep packet inspection), add DNS-over-HTTPS check: ```bash # Add to check_network() as a third test type if curl -s --max-time 5 "https://dns.google/resolve?name=google.com&type=A" | grep -q '"Answer"'; then return 0 fi ```