diff options
| author | Craig Jennings <c@cjennings.net> | 2026-07-20 15:46:09 -0500 |
|---|---|---|
| committer | Craig Jennings <c@cjennings.net> | 2026-07-20 15:46:09 -0500 |
| commit | 36daf763d4007eccbb5608de0e77278c2f5a1135 (patch) | |
| tree | 6cd4d02d96ff745ff1d09a466a58a9f7cd5a5dd7 /tests | |
| parent | 948a1fc0fbc300076b6f5b605a6a555c1b50e66a (diff) | |
| download | archsetup-36daf763d4007eccbb5608de0e77278c2f5a1135.tar.gz archsetup-36daf763d4007eccbb5608de0e77278c2f5a1135.zip | |
fix(wireguard): bring the tunnel down before the rename modify
`nmcli connection import` activates a full-tunnel (0.0.0.0/0) Proton profile immediately. The import loop renamed and set autoconnect off, then brought the tunnel down. Under `set -euo pipefail`, a failed modify aborted the script before that down ran, leaving a live full-tunnel VPN routing all traffic through Proton -- the exact unasked-for VPN the script exists to prevent. The next-run guard catches the leftover profile but not the still-active tunnel.
Moved the down ahead of the modify. It targets the UUID, which is stable across the rename, so downing first is safe and no failure between import and modify can leave the tunnel up.
Diffstat (limited to 'tests')
| -rw-r--r-- | tests/import-wireguard-configs/fake-nmcli | 3 | ||||
| -rw-r--r-- | tests/import-wireguard-configs/test_import_wireguard_configs.py | 22 |
2 files changed, 25 insertions, 0 deletions
diff --git a/tests/import-wireguard-configs/fake-nmcli b/tests/import-wireguard-configs/fake-nmcli index 45b88cd..30de62f 100644 --- a/tests/import-wireguard-configs/fake-nmcli +++ b/tests/import-wireguard-configs/fake-nmcli @@ -38,6 +38,9 @@ case "$1 $2" in "connection modify") exit "${FAKE_NMCLI_MODIFY_RC:-0}" ;; +"connection down") + exit "${FAKE_NMCLI_DOWN_RC:-0}" + ;; *) echo "fake-nmcli: unexpected args: $*" >&2 exit 99 diff --git a/tests/import-wireguard-configs/test_import_wireguard_configs.py b/tests/import-wireguard-configs/test_import_wireguard_configs.py index 0307041..45afa54 100644 --- a/tests/import-wireguard-configs/test_import_wireguard_configs.py +++ b/tests/import-wireguard-configs/test_import_wireguard_configs.py @@ -162,6 +162,28 @@ class ImportWireguardConfigs(unittest.TestCase): imports = [ln for ln in self.log_lines() if ln.startswith("connection import")] self.assertEqual(len(imports), 1) + def test_tunnel_is_brought_down_before_the_modify(self): + # nmcli import auto-activates a full-tunnel (0.0.0.0/0) profile. The + # down must run before the rename/modify so a failed modify under set -e + # can never leave a live unasked-for VPN up. + self.write_conf("USNY") + r = self.run_script() + self.assertEqual(r.returncode, 0, r.stderr) + verbs = [ln.split()[1] for ln in self.log_lines() + if ln.startswith("connection ")] + self.assertEqual(verbs, ["import", "down", "modify"], verbs) + + def test_modify_failure_still_left_the_tunnel_down(self): + # Even when the modify fails and aborts the run, the down already ran, + # so no live tunnel survives. + self.write_conf("USNY") + r = self.run_script(env_extra={"FAKE_NMCLI_MODIFY_RC": "4"}) + self.assertNotEqual(r.returncode, 0) + verbs = [ln.split()[1] for ln in self.log_lines() + if ln.startswith("connection ")] + self.assertIn("down", verbs, "the tunnel must be downed before the modify aborts") + self.assertLess(verbs.index("down"), verbs.index("modify")) + if __name__ == "__main__": unittest.main() |
