Skip to content

Releases: ryderlacin-pixel/Windows-WireGuard-KillSwitch

v15.3.2 - Server IP scope fix + emergency-reset upgrade hardening

Choose a tag to compare

@ryderlacin-pixel ryderlacin-pixel released this 08 Jun 22:21

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:serverPort
  • Install-GeneratedScripts.ps1: read script scope with WARP fallback
  • Install-TasksAndWmi.ps1: registry ServerIP from $script:serverIPs

Install hardening

  • Install-MainSteps-18-20.ps1: clear +S +H attributes before overwriting emergency-reset.ps1/.bat (fixes "Access denied" on upgrade)
  • safe-live-verify.ps1: GPO version regex accepts v15.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

Choose a tag to compare

@ryderlacin-pixel ryderlacin-pixel released this 08 Jun 22:04

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:

  1. Pre-flight quiesce runs FIRST on every install.ps1 invocation (including -DryRun) via Invoke-PreFlightInternetGuard.
  2. -DryRun is read-only preview onlyInvoke-InstallDryRunPreview; MainSteps 0–20 never execute.
  3. 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, clears InstallInProgress
  • 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)

Choose a tag to compare

@ryderlacin-pixel ryderlacin-pixel released this 08 Jun 21:58

v15.3.0 — Internet-Safe Install

Critical fix: install and reboot no longer brick internet

Root causes eliminated

  1. DNS lockdown removed from auto chaindns-lockdown-guard.ps1 no longer runs from install.ps1, repair.ps1, or deferred guards. Use scripts/enable-dns-lockdown.ps1 manually when ready.
  2. repair.ps1 fail-open expanded — exits early during InstallInProgress, PostInstallGrace, BootGrace, UnbrickActive, or KillSwitchArmed=0.
  3. KillSwitchArmed gate — catch-all firewall blocks only after tunnel+internet stable for 60s at end of install (KillSwitchArmed=1).
  4. DryRun zero-side-effect — steps 7-20 skipped entirely; no monitor, tasks, WMI, or guards.
  5. Post-install grace extended — 15 minutes to 60 minutes.
  6. Zombie debounce extended — 15x30s to 30x60s before block.

Install flow (STEP 19)

  1. KillSwitchArmed=0, PostInstallGrace=60min, BootGrace=90s
  2. Stability gate: 3x20s SafeToOpen checks
  3. On success: KillSwitchArmed=1, clear install lock, start monitor
  4. On failure: lock cleared but armed stays 0 — internet stays open

Manual DNS lockdown

.\scripts\enable-dns-lockdown.ps1

Test gate

1013+ assertions, 0 ERROR/WARN final line audit.

v15.2.9-FINAL - Final line audit gate, 1008 assertions, 0 ERROR/WARN

Choose a tag to compare

@ryderlacin-pixel ryderlacin-pixel released this 08 Jun 21:45

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 install

Stuck internet: emergency-reset.bat (once, then reboot if prompted).

v15.2.6 - Code review critical fixes (mutex, GPO regex, ScriptsPath, admin order)

Choose a tag to compare

@ryderlacin-pixel ryderlacin-pixel released this 08 Jun 18:19

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.ps1 used lib/scripts — fixed to repo root; audit scripts deployed to C:\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 .bat wrapper + -Wait on UAC elevation + DHCP DNS restore

Tests

scripts/test-suite.ps1: 205 PASS

v15.2.4 - Install internet protection (defer DNS lock until dnscrypt healthy)

Choose a tag to compare

@ryderlacin-pixel ryderlacin-pixel released this 08 Jun 18:07

v15.2.4 — Install internet protection (DNS defer)

Status: Production — fixes recurring "internet dies during install".

Problem

During STEP 18 (privacy stack), install could:

  1. Set WireGuard DNS = 127.0.0.1 before dnscrypt-proxy listened on port 53
  2. Run dns-lockdown / dnscrypt guards while install lock was active
  3. 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-DnscryptListening gate — no WG DNS change unless 127.0.0.1:53 is LISTENING
  • Set-WireGuardDnsLocalhost: only runs when Test-DnscryptHealthy
  • Privacy guards deferred during InstallInProgress (STEP 18c–18f write scripts only)
  • STEP 20: Invoke-DeferredPrivacyGuards applies 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 -NoPause

Tests

scripts/test-suite.ps1: 202+ PASS

v15.2.3 - Critical install hotfixes (dnscrypt path, fail-soft privacy stack)

Choose a tag to compare

@ryderlacin-pixel ryderlacin-pixel released this 08 Jun 18:05

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_DIR

When 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 only
  • Ensure-DnscryptTomlFile — always creates C:\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.2Invoke-SafeRegistrySet splat fix (STEP 4 IPv6)
  • v15.2.1-DryRun completeness (Invoke-SafeNetsh / registry guard)

Install

Set-ExecutionPolicy Bypass -Scope Process -Force
cd "C:\path\to\Windows-WireGuard-KillSwitch"
.\install.ps1 -NoPause

Partial 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)

Choose a tag to compare

@ryderlacin-pixel ryderlacin-pixel released this 08 Jun 17:57

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 -NoPause

If a partial install left the network odd: .\emergency-reset.bat first, then .\install.ps1.

v15.2.1 - DryRun completeness fix (safe install preview)

Choose a tag to compare

@ryderlacin-pixel ryderlacin-pixel released this 08 Jun 17:32

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 DisabledComponents registry 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-SafeRegistrySet in lib/Install-SafeNetwork.ps1 — DryRun guard for registry writes.
  • lib/Install-MainSteps-0-6.ps1 — all firewall/registry hardening routes through Invoke-SafeNetsh or Invoke-SafeRegistrySet; no bare netsh calls remain.
  • lib/Install-Helpers.ps1Remove-InstallBlocks uses Invoke-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)

Choose a tag to compare

@ryderlacin-pixel ryderlacin-pixel released this 08 Jun 17:25

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:

  1. Boot deadlock — catch-all KS-Block-* rules activated before DHCP and WireGuard handshake completed. DHCP could not finish; tunnel could not start; Test-SafeToOpen never opened the lock. GPO boot script did not clear existing block rules during fail-open hold.
  2. Physical NIC disappearanceDisable-AllIPv6Bindings ran netsh interface ipv6 set interface ... disabled on every connected adapter (Wi‑Fi/Ethernet), breaking NDIS bindings. ncpa.cpl appeared 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-OsUptimeSeconds in lib/Install-SafeNetwork.ps1 and runtime C:\WireGuard\wg-safety.ps1 (generated).
  • Monitor, repair, watchdog, and GPO never apply catch-all blocks while OS uptime < 90s.
  • BootGrace reduced 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-In
    • KS-Gateway-Out / KS-Gateway-In (dynamic default-route gateway + RFC1918)
  • Enable-KillSwitchBlock always refreshes exemptions first.

3. Tunnel-only IPv6 binding (physical NIC shield)

  • Disable-AllIPv6Bindings removed from physical adapters.
  • Replaced by Disable-TunnelIPv6BindingsOnly — only adapters matching WireGuard / wintun / AllDebrid.
  • Test-IsVirtualTunnelAdapter hardware whitelist; physical Intel/Realtek/MediaTek adapters cannot be mutated.

4. Emergency reset (one-click)

  • emergency-reset.bat at repo root (also deployed to C:\WireGuard\).
  • scripts/emergency-reset.ps1: removes all KS-* rules, netsh advfirewall reset, netsh int ip reset, netsh winsock reset, re-enables physical adapters and bindings.

5. Fail-open safeguard

  • install.ps1 parameter: [bool]$EnableFailsafe = $true (stored in registry).
  • Monitor catchInvoke-FailOpenSafeguard (removes blocks, sets UnbrickUntil + 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.ps1 deployed to C:\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 -NoPause

From v15.1 on a working system (install lock keeps internet until STEP 19):

.\install.ps1 -NoPause

Safe testing procedure (mandatory)

  1. VM: .\install.ps1 -DryRun — verify logs, no network changes.
  2. VM: .\install.ps1 -NoPause — full install.
  3. VM: Reboot — confirm Wi‑Fi/Ethernet visible in ncpa.cpl, internet works within 90s, tunnel comes up.
  4. VM: .\scripts\test-suite.ps1 → 186+ PASS.
  5. Physical machine: only after VM reboot PASS.

Verification

.\scripts\test-suite.ps1          # 186+ offline assertions
.\scripts\ci.ps1

Check log after reboot:

Get-Content C:\WireGuard\killswitch.log -Tail 30
# Expect: "BootGrace until ... (uptime Xs, no block)" and no BLOCK before 90s

Breaking 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.