From a11f8c4fa0e6a91504648254cb805de03257e333 Mon Sep 17 00:00:00 2001 From: Lukas Date: Thu, 21 May 2026 21:41:51 +0200 Subject: [PATCH] fix(vpn): add explicit host route for health-check target Without a /32 route in the main table, CHECK_HOST (1.1.1.1) fell through to the VPN default route where source-address selection was defeated by the priority-100 'from ETH0_IP' policy rule, causing pings to bypass wg0 and be dropped by the kill switch. Also add secondary google.com ping to distinguish IP vs DNS failures. --- Docker/entrypoint.sh | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/Docker/entrypoint.sh b/Docker/entrypoint.sh index cf1006a..df330fe 100644 --- a/Docker/entrypoint.sh +++ b/Docker/entrypoint.sh @@ -198,6 +198,14 @@ start_vpn() { echo "[vpn] DNS set to: ${VPN_DNS}" fi + # Add explicit host route for the health-check target so it is picked up by + # the 'lookup main suppress_prefixlength 0' rule (same as DNS servers above). + # Without this, CHECK_HOST falls through to the VPN table default route whose + # source-address selection can be defeated by the priority-100 'from ETH0_IP' + # policy rule, causing pings to bypass wg0 and be dropped by the kill switch. + ip -4 route add "${CHECK_HOST}" dev "$INTERFACE" 2>/dev/null || true + echo "[vpn] Health-check route: ${CHECK_HOST} → ${INTERFACE}" + echo "[vpn] WireGuard interface ${INTERFACE} is up." echo "[vpn] Main routes:" ip route show | sed 's/^/[vpn] /' @@ -249,9 +257,21 @@ health_loop() { echo "[health] VPN recovered." failures=0 fi + # Secondary DNS check + if ping -c 1 -W 5 "google.com" > /dev/null 2>&1; then + : # DNS OK — silent + else + echo "[health] WARN google.com unreachable — possible DNS issue" + fi else failures=$((failures + 1)) echo "[health] Check failed ($failures/$max_failures) — ping ${CHECK_HOST} failed" + # Secondary check: distinguish IP failure from DNS failure + if ping -c 1 -W 5 "google.com" > /dev/null 2>&1; then + echo "[health] INFO google.com reachable — DNS works, ${CHECK_HOST} may be filtered" + else + echo "[health] INFO google.com also unreachable — DNS or general routing failure" + fi # Dump WireGuard stats to show if handshake is stale and how much data flows echo "[health] wg stats:" wg show "$INTERFACE" 2>/dev/null | grep -E 'latest handshake|transfer|endpoint' | sed 's/^/[health] /' || echo "[health] wg0 not found"