From 99c96677920841efcbe5140147a4335241cf30ae Mon Sep 17 00:00:00 2001 From: pstruebi Date: Wed, 17 Dec 2025 18:29:10 +0100 Subject: [PATCH] feat: fix WireGuard AllowedIPs to preserve local network access - Added rewrite_allowed_ips() to replace 0.0.0.0/0 with VPN CIDR in WireGuard configs - Modified step_wireguard_provision() to rewrite AllowedIPs before deploying config - Removed TODO comment about VPN blocking local network access --- src/provision.py | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/src/provision.py b/src/provision.py index 1982bc4..3529d10 100644 --- a/src/provision.py +++ b/src/provision.py @@ -23,6 +23,25 @@ SSH_KEY = os.getenv("SSH_KEY") or None # path or None PROVISION_LOG = os.getenv("PROVISION_LOG") or str((Path(__file__).resolve().parent / "provision.log")) +def rewrite_allowed_ips(config_text: str, allowed_cidr: str = None) -> str: + """Rewrite AllowedIPs in a WireGuard config to only route VPN traffic. + + By default, wg-easy generates configs with AllowedIPs = 0.0.0.0/0 which routes + ALL traffic through the VPN, making the device unreachable on the local network. + This rewrites it to only route traffic destined for the VPN network. + """ + if allowed_cidr is None: + allowed_cidr = POOL_CIDR + # Replace AllowedIPs = 0.0.0.0/0 (and optional ::/0 for IPv6) with just the VPN CIDR + # Handles various formats: "0.0.0.0/0", "0.0.0.0/0, ::/0", "0.0.0.0/0,::/0" + config_text = re.sub( + r"(AllowedIPs\s*=\s*)0\.0\.0\.0/0[^\n]*", + rf"\g<1>{allowed_cidr}", + config_text + ) + return config_text + + def scp_and_enable(ssh_host, config_text): tmp = Path(tempfile.gettempdir()) / f"{WG_IFACE}.conf" tmp.write_text(config_text) @@ -99,6 +118,8 @@ def step_wireguard_provision(iot_host: str, client_name: str): name = client_name base, auth = get_env_auth() cid, iface, cfg = ensure_client_and_config(base, auth, name) + # Rewrite AllowedIPs to only route VPN traffic, preserving local network access + cfg = rewrite_allowed_ips(cfg, POOL_CIDR) scp_and_enable(iot_host, cfg) return {"wg_name": name, "wg_iface": iface} @@ -393,7 +414,7 @@ def main(): "pull", "hostname", "mac", - "wg", # TODO: after wiregurd setup a device was only reachable via vpn not in local network - fix this + "wg", "update_app", "start_app", "finish"