# VPN Fallback Pattern — WireGuard Preferred, L2TP/IPsec Fallback **Source:** `/root/.hermes/scripts/wisp-backup/wisp-backup.py` (modified Jul 2026) When a backup script needs a VPN tunnel to reach remote network devices, prefer **WireGuard over L2TP/IPsec** for reliability and reconnection speed. ## Pattern In the `main()` function, before attempting L2TP/IPsec VPN: 1. Ping the target router's IP over an existing WireGuard interface (e.g. 10.77.0.2) 2. If reachable: skip L2TP entirely 3. If not reachable: fall back to L2TP/IPsec up/down cycle 4. Track `vpn_was_connected = True/False` 5. Only teardown L2TP if it was actually connected ```python vpn_was_connected = False ping_check = subprocess.run(["ping", "-c", "1", "-W", "2", "10.77.0.2"], timeout=5) if ping_check.returncode == 0: print(" [+] Router reachable via WireGuard — skipping VPN") else: print(" [-] WireGuard unreachable, trying L2TP/IPsec ...") run_vpn_script("up", script_dir) vpn_was_connected = True ``` ## Why WireGuard wins - Always-on tunnel — no connect/disconnect per run - Faster — no IKE/L2TP/PPP negotiation - More stable through brief network interruptions - Less log noise — no CHILD_SA create/delete cycles - No config file churn in /etc/ipsec.conf or /etc/ppp/ ## Critical guard Every `run_vpn_script("down")` call must check `if vpn_was_connected:`. Otherwise the script tries to tear down L2TP even when WireGuard was used, creating log noise and IPsec errors. **Guarded teardown paths:** - Internet connectivity check failure - Tower-not-found in `--tower` filter - Dry run completion - Main completion ## Config reference The wireguard peer is configured in `/etc/wireguard/wg0.conf`: - Interface: 10.77.0.1/24, port 51820 - Peer (home router): 76.195.7.60:13231, AllowedIPs 10.77.0.2/32 10.10.10.0/24 - Handshake confirmed active (Jul 2026, 1min ago)