Releases: ryderlacin-pixel/Windows-WireGuard-KillSwitch
Release list
v15.3.2 - Server IP scope fix + emergency-reset upgrade hardening
v15.3.2 — Server IP Scope Fix + Install Hardening
Critical fix: monitor/repair empty SERVER_IP
Root cause: $serverIPs / $serverPort were set inside Invoke-InstallMainSteps0to6 (function scope) but Invoke-InstallGeneratedScripts read script-scope variables — monitor was generated with empty server IPs and KS-WARP-Server-Out was never created.
Fix:
Install-MainSteps-0-6.ps1: persist to$script:serverIPs/$script:serverPortInstall-GeneratedScripts.ps1: read script scope with WARP fallbackInstall-TasksAndWmi.ps1: registryServerIPfrom$script:serverIPs
Install hardening
Install-MainSteps-18-20.ps1: clear+S +Hattributes before overwritingemergency-reset.ps1/.bat(fixes "Access denied" on upgrade)safe-live-verify.ps1: GPO version regex acceptsv15.3.x
Unchanged (v15.3.1)
- AI Connection Invariant: pre-flight quiesce + DryRun preview-only
Test gate
1045+ assertions (version bump in constants/install header).
v15.3.1 - AI-safe DryRun preview-only + pre-flight quiesce
v15.3.1 — AI-Safe DryRun Preview
Critical fix: -DryRun no longer kills internet (and your Cursor/AI session)
AI Connection Invariant (permanent design rule)
If install or -DryRun kills internet, the user's Cursor/AI session dies too. v15.3.1 enforces:
- Pre-flight quiesce runs FIRST on every
install.ps1invocation (including-DryRun) viaInvoke-PreFlightInternetGuard. -DryRunis read-only preview only —Invoke-InstallDryRunPreview; MainSteps 0–20 never execute.- MainSteps 0–6 throws if accidentally called during DryRun (hard guard).
What pre-flight quiesce does (real mutations — restores internet)
- Ends/disables scheduled tasks (
WG-KillSwitch,WG-RepairTask,WG-InternetWatchdog,WG-RebootVerify) - Stops monitor/repair/watchdog PowerShell processes
- Deletes catch-all
KS-Block-*rules; disables DNS block rules - Sets firewall policy
blockinbound,allowoutbound - Registry:
KillSwitchArmed=0, 30min grace, clearsInstallInProgress - Clears DNS cache
What -DryRun does now
- Prints step preview list (what would happen)
- Read-only system status (WireGuard present, tunnel, block rules, armed flag)
- Zero downloads, installs, firewall mutations from install steps, monitor, tasks, or WMI
v15.3.0 behavior retained
- KillSwitchArmed gate, manual DNS lockdown, 60min post-install grace, repair fail-open — unchanged.
Test gate
1045+ assertions, 0 ERROR/WARN final line audit (99 files).
Release assets
| File | SHA256 |
|---|---|
WGKillSwitch-v15.3.1-FINAL.zip |
7D7C7F9802A5230D23BFF3AA1BFC80F77A3D6908608C53EC470E401BE4EB2490 |
v15.3.0 - Internet-safe install (KillSwitchArmed gate, DNS lock manual-only)
v15.3.0 — Internet-Safe Install
Critical fix: install and reboot no longer brick internet
Root causes eliminated
- DNS lockdown removed from auto chain —
dns-lockdown-guard.ps1no longer runs frominstall.ps1,repair.ps1, or deferred guards. Usescripts/enable-dns-lockdown.ps1manually when ready. - repair.ps1 fail-open expanded — exits early during
InstallInProgress,PostInstallGrace,BootGrace,UnbrickActive, orKillSwitchArmed=0. - KillSwitchArmed gate — catch-all firewall blocks only after tunnel+internet stable for 60s at end of install (
KillSwitchArmed=1). - DryRun zero-side-effect — steps 7-20 skipped entirely; no monitor, tasks, WMI, or guards.
- Post-install grace extended — 15 minutes to 60 minutes.
- Zombie debounce extended — 15x30s to 30x60s before block.
Install flow (STEP 19)
KillSwitchArmed=0,PostInstallGrace=60min,BootGrace=90s- Stability gate: 3x20s
SafeToOpenchecks - On success:
KillSwitchArmed=1, clear install lock, start monitor - On failure: lock cleared but armed stays 0 — internet stays open
Manual DNS lockdown
.\scripts\enable-dns-lockdown.ps1Test gate
1013+ assertions, 0 ERROR/WARN final line audit.
v15.2.9-FINAL - Final line audit gate, 1008 assertions, 0 ERROR/WARN
v15.2.9-FINAL - Consolidated production release
Merged GitHub main (95 files) + ULTIMATE lib audit + final line audit gate. Not installed on build machine - offline test gate only.
P0 - Install must not brick internet
| Fix | Detail |
|---|---|
| No catch-all during install | STEP 6 adds exemptions + allows only; KS-Block-* activated by monitor after health check |
| DNS lock gate | STEP 18f defers system DNS lock until Test-DnscryptListening (127.0.0.1:53) |
| Deferred DNS lock (v15.2.8) | Requires stable stack before guards apply |
| Install lock + fail-open | Remove-InstallBlocks during install; EnableFailsafe default true |
P1 - Security & script generation
| Fix | Detail |
|---|---|
Invoke-SafeNetsh |
cmd.exe /c instead of Invoke-Expression |
repair.ps1 firewall restore |
cmd.exe /c instead of Invoke-Expression |
wg-safety.ps1 DHCP rules |
cmd.exe /c instead of Invoke-Expression |
| UpgradePaths heredoc | Fixed WebRTC forwarder @"..."@ (was broken concatenation) |
P2 - v15.2.6 audit fixes (retained)
Mutex $acquired + Dispose(), Test-IsMainMonitor, ScriptsPath -> repo root, GPO regex, admin check before dot-source, $TUNNEL_SVC safe interpolation.
P2 - v15.2.9 install final-check (retained)
Register-RepairTaskDualTrigger, Refresh-RegistryTaskBackups, vault finalize before services, monitor wait loop, NSSM cleanup guard.
P3 - Final line audit (v15.2.9)
Every repo file scanned dot-by-dot: parse, semantic rules, version parity, SHA256 manifest. Gate requires 0 ERROR, 0 WARN.
Verification (build machine - no install)
scripts/test-suite.ps1 -> 1008 PASS (1001+ baseline; 17 gates incl. final line audit)
scripts/file-coverage-test.ps1 -> 682 PASS (49 production files, anti-hollow gate)
scripts/final-line-audit.ps1 -> 95 files dot-by-dot, 0 ERROR, 0 WARN
scripts/behavior-sim-test.ps1 -> 216 PC reaction scenarios + sim<->monitor parity
scripts/reboot-sim-test.ps1 -> 510 post-reboot internet survival scenarios
scripts/ci.ps1 -> CI QUALITY GATE: PASSED (x3 + Phase 5 audit)
scripts/pre-push-gate.ps1 -> PRE-PUSH GATE: PASSED
Each repo file: universal line scan + tier classification + SHA256 manifest (audit-results/). Production files: parse + Scriptblock::Create + role contracts (>=4 meaningful checks). Generated monitor/GPO/repair/watchdog/wg-safety: extract + compile, not grep-only.
Deploy
.\install.ps1 -DryRun # first run - no firewall changes
.\install.ps1 -NoPause # production installStuck internet: emergency-reset.bat (once, then reboot if prompted).
v15.2.6 - Code review critical fixes (mutex, GPO regex, ScriptsPath, admin order)
v15.2.6 — Code review critical fixes
Production patch addressing security/reliability audit (H-01–H-14).
Critical fixes
| ID | Fix |
|---|---|
| H-01 | Install-Constants.ps1 mojibake header → ASCII |
| H-02 | Log() mutex: track $acquired, always Dispose() — no handle leak |
| H-03 | KS-Dnscrypt-EXE netsh rule uses "" quoting for paths with spaces |
| H-04 | Legacy cleanup guarded with Test-Path $INSTALL_DIR |
| H-07 | GPO scripts.ini regex: literal \[Startup\] (single-quoted patterns) |
| H-08 | Generated scripts use Test-IsMainMonitor (matches Install-Helpers.ps1) |
| H-11 | Admin check before any lib/ dot-source |
| H-12 | Get-ShortCimSession validates stale session before reuse |
| H-14 | $TUNNEL_SVC = 'WireGuardTunnel$' + $TUNNEL_NAME (safe interpolation) |
Reliability
- ScriptsPath bug:
Install-TasksAndWmi.ps1usedlib/scripts— fixed to repo root; audit scripts deployed toC:\WireGuard\scripts\ - post-reboot-verify: finds
C:\WireGuard\scripts(no hardcoded user path) - Watchdog: 3 min interval (matches STEP 12c / README)
- emergency-reset.bat: restored proper
.batwrapper +-Waiton UAC elevation + DHCP DNS restore
Tests
scripts/test-suite.ps1: 205 PASS
v15.2.4 - Install internet protection (defer DNS lock until dnscrypt healthy)
v15.2.4 — Install internet protection (DNS defer)
Status: Production — fixes recurring "internet dies during install".
Problem
During STEP 18 (privacy stack), install could:
- Set WireGuard
DNS = 127.0.0.1before dnscrypt-proxy listened on port 53 - Run dns-lockdown / dnscrypt guards while install lock was active
- Leave the system with broken DNS → no internet every install attempt
Common on VMs when port 53 is busy or dnscrypt service is still starting.
Fix
- dnscrypt-guard (v14 + v15):
Test-DnscryptListeninggate — no WG DNS change unless127.0.0.1:53is LISTENING - Set-WireGuardDnsLocalhost: only runs when
Test-DnscryptHealthy - Privacy guards deferred during
InstallInProgress(STEP 18c–18f write scripts only) - STEP 20:
Invoke-DeferredPrivacyGuardsapplies DNS lock only after install lock cleared + dnscrypt healthy
Install
Download v15.2.4 ZIP or:
git pull
.\emergency-reset.bat # if internet currently broken
.\install.ps1 -NoPauseTests
scripts/test-suite.ps1: 202+ PASS
v15.2.3 - Critical install hotfixes (dnscrypt path, fail-soft privacy stack)
v15.2.3 — Critical install hotfixes
Status: Production — install reliability patch.
Fixes
1. dnscrypt-guard path bug (install fatal at STEP 18f)
Generated dnscrypt-guard.ps1 used single-quoted paths:
$DNSCRYPT_CONF = '$DNSCRYPT_DIR\dnscrypt-proxy.toml' # broken — literal $DNSCRYPT_DIRWhen run from C:\Windows\system32, install failed with:
Could not find a part of the path 'C:\Windows\system32\$DNSCRYPT_DIR\dnscrypt-proxy.toml'
Fix: Join-Path $DNSCRYPT_DIR 'dnscrypt-proxy.toml' in v14 and v15 guard generators.
2. Privacy stack must not abort full install
Guard script errors during STEP 18c–18f could bubble up as Install fatal and trigger fail-open.
Fix:
Invoke-GuardScriptSafe— runs guards with try/catch, logs WARN onlyEnsure-DnscryptTomlFile— always createsC:\WireGuard\dnscrypt-proxy\before writing toml- v14/v15 stack functions and MainSteps 18b–18f wrapped in fail-soft try/catch
3. Install from wrong working directory
Fix: install.ps1 now runs Set-Location -LiteralPath $PSScriptRoot so relative repo paths resolve correctly.
Includes prior patches
- v15.2.2 —
Invoke-SafeRegistrySetsplat fix (STEP 4 IPv6) - v15.2.1 —
-DryRuncompleteness (Invoke-SafeNetsh/ registry guard)
Install
Set-ExecutionPolicy Bypass -Scope Process -Force
cd "C:\path\to\Windows-WireGuard-KillSwitch"
.\install.ps1 -NoPausePartial failed install: .\emergency-reset.bat then re-run.
Tests
scripts/test-suite.ps1: 198+ assertions PASS
v15.2.2 - Invoke-SafeRegistrySet splat fix (STEP 4 install)
v15.2.2 — Invoke-SafeRegistrySet splat fix
Status: Production hotfix on v15.2.1.
Problem
Install failed at STEP 4 - IPv6 BLOCK with:
A parameter cannot be found that matches parameter name 'Value'.
Invoke-SafeRegistrySet @ipv6RegParams splatted hashtable keys (Value, Path, …) onto the wrapper function instead of Set-ItemProperty. Install aborted; fail-open ran.
Fix
Invoke-SafeRegistrySet now accepts the same parameters as Set-ItemProperty (-Path, -Name, -Value, -Type, -Force), so @ipv6RegParams splat works correctly.
Install
Re-run from extracted folder (Admin PowerShell):
.\install.ps1 -NoPauseIf a partial install left the network odd: .\emergency-reset.bat first, then .\install.ps1.
v15.2.1 - DryRun completeness fix (safe install preview)
v15.2.1 — DryRun completeness fix
Status: Production patch on top of v15.2.
Problem
-DryRun was documented as “no firewall/NIC changes,” but several install steps still executed real netsh and registry writes:
- STEP 3: bulk
KS-*rule deletion and firewall policy reset - STEP 4: IPv6 firewall rules + global
DisabledComponentsregistry lock - STEP 6: firewall policy
blockinbound,allowoutbound Remove-InstallBlocks: catch-all rule deletion
Users running .\install.ps1 -DryRun on a VM or physical PC could still get network side effects.
Fix
- New
Invoke-SafeRegistrySetinlib/Install-SafeNetwork.ps1— DryRun guard for registry writes. lib/Install-MainSteps-0-6.ps1— all firewall/registry hardening routes throughInvoke-SafeNetshorInvoke-SafeRegistrySet; no barenetshcalls remain.lib/Install-Helpers.ps1—Remove-InstallBlocksusesInvoke-SafeNetsh.- Docs updated: README, CODE_REVIEW, install banner.
What -DryRun still does
Downloads (WireGuard/wgcf), writes generated scripts to C:\WireGuard\, scheduled tasks, GPO, and registry outside network hardening may still run. Only network hardening is fully simulated.
Install
Set-ExecutionPolicy Bypass -Scope Process -Force
.\install.ps1 -DryRun # safe network-hardening preview
.\install.ps1 # real install (VM first)Network stuck? emergency-reset.bat as Administrator.
Tests
scripts/test-suite.ps1: 189/189 PASS (includes DryRun-safe MainSteps assertions)
v15.2 - Boot-safety emergency fix (90s window, DHCP exempt, emergency-reset)
v15.2 — Boot-safety emergency fix (post-mortem response)
Status: Production — replaces v15.1 after a confirmed boot deadlock on real hardware.
Incident summary (v15.1)
On a physical laptop, v15.1 worked at runtime but after reboot caused:
- Boot deadlock — catch-all
KS-Block-*rules activated before DHCP and WireGuard handshake completed. DHCP could not finish; tunnel could not start;Test-SafeToOpennever opened the lock. GPO boot script did not clear existing block rules during fail-open hold. - Physical NIC disappearance —
Disable-AllIPv6Bindingsrannetsh interface ipv6 set interface ... disabledon every connected adapter (Wi‑Fi/Ethernet), breaking NDIS bindings.ncpa.cplappeared empty.
Recovery required Reset This PC on the affected machine.
This release is a surgical defensive patch — no architectural rewrite. The lib/ modular layout is preserved.
What changed (7 defensive measures)
1. Boot-safe window (90 seconds)
- New
Test-BootSafeWindow/Get-OsUptimeSecondsinlib/Install-SafeNetwork.ps1and runtimeC:\WireGuard\wg-safety.ps1(generated). - Monitor, repair, watchdog, and GPO never apply catch-all blocks while OS uptime < 90s.
BootGracereduced from 180s to 90s (aligned with safe window).
2. DHCP + gateway exemptions (before catch-all)
- Firewall exemptions are written before
KS-Block-*rules:KS-DHCP-Out/KS-DHCP-In(UDP 67/68)KS-DHCP-Bcast-Out(255.255.255.255:67)KS-DHCP-Server-InKS-Gateway-Out/KS-Gateway-In(dynamic default-route gateway + RFC1918)
Enable-KillSwitchBlockalways refreshes exemptions first.
3. Tunnel-only IPv6 binding (physical NIC shield)
Disable-AllIPv6Bindingsremoved from physical adapters.- Replaced by
Disable-TunnelIPv6BindingsOnly— only adapters matching WireGuard / wintun / AllDebrid. Test-IsVirtualTunnelAdapterhardware whitelist; physical Intel/Realtek/MediaTek adapters cannot be mutated.
4. Emergency reset (one-click)
emergency-reset.batat repo root (also deployed toC:\WireGuard\).scripts/emergency-reset.ps1: removes allKS-*rules,netsh advfirewall reset,netsh int ip reset,netsh winsock reset, re-enables physical adapters and bindings.
5. Fail-open safeguard
install.ps1parameter:[bool]$EnableFailsafe = $true(stored in registry).- Monitor
catch→Invoke-FailOpenSafeguard(removes blocks, setsUnbrickUntil+BootGraceUntil). - Watchdog deep unbrick uses the same safeguard.
6. Dry-run mode
.\install.ps1 -DryRun- No firewall writes, no adapter binding changes.
- Logs
[DRY-RUN] Would run: ...for every destructive action.
7. Runtime safety module
wg-safety.ps1deployed toC:\WireGuard\and dot-sourced by monitor, repair, watchdog, GPO.- Centralizes
Test-BlockAllowed,Enable-KillSwitchBlock,Disable-KillSwitchBlock,Invoke-FailOpenSafeguard.
GPO boot fix (critical)
v15.1 GPO only logged fail-open during BootGrace but left stale KS-Block-* rules active.
v15.2 GPO calls Disable-KillSwitchBlock immediately on boot, then sets grace period.
New / updated files
| File | Role |
|---|---|
lib/Install-SafeNetwork.ps1 |
Installer + runtime safety primitives |
emergency-reset.bat |
Admin one-click recovery launcher |
scripts/emergency-reset.ps1 |
Recovery logic |
C:\WireGuard\wg-safety.ps1 |
Generated runtime safety (on install) |
Upgrade
# ALWAYS test in VM first:
.\install.ps1 -DryRun
# VM full install + reboot test, then physical machine:
.\install.ps1 -NoPauseFrom v15.1 on a working system (install lock keeps internet until STEP 19):
.\install.ps1 -NoPauseSafe testing procedure (mandatory)
- VM:
.\install.ps1 -DryRun— verify logs, no network changes. - VM:
.\install.ps1 -NoPause— full install. - VM: Reboot — confirm Wi‑Fi/Ethernet visible in
ncpa.cpl, internet works within 90s, tunnel comes up. - VM:
.\scripts\test-suite.ps1→ 186+ PASS. - Physical machine: only after VM reboot PASS.
Verification
.\scripts\test-suite.ps1 # 186+ offline assertions
.\scripts\ci.ps1Check log after reboot:
Get-Content C:\WireGuard\killswitch.log -Tail 30
# Expect: "BootGrace until ... (uptime Xs, no block)" and no BLOCK before 90sBreaking changes
None for normal runtime behavior after tunnel is healthy. Boot path is intentionally more permissive for the first 90 seconds.
Apology / accountability
v15.1 boot path was not safe on real hardware under slow DHCP / delayed tunnel start. v15.2 treats "never brick the user's network" as a hard invariant above kill-switch aggressiveness.