Alternative Approaches & Community Comparison¶
How our setup compares to what others have done, and what we could steal.
Our Stack vs The Field¶
| Aspect | Our approach | Most common alternative |
|---|---|---|
| VPN/tunnel | Tailscale on Windows host | Tailscale inside WSL2, or WireGuard direct |
| Networking | Mirrored mode (.wslconfig) | netsh portproxy (NAT mode) |
| SSH server | openssh-server inside WSL2 | Windows OpenSSH with bash.exe as default shell |
| Persistence | Task Scheduler + sleep infinity |
NSSM Windows service, or [boot] command= |
| Keep-alive | instanceIdleTimeout=-1 + sleep |
dbus-launch true, or rely on systemd (unreliable) |
| Key mgmt | ed25519 keypair, manual transport | Tailscale SSH (no keys at all) |
| Firewall | Windows FW + Hyper-V FW, CGNAT only | Often omitted entirely |
| DNS | Static resolv.conf + chattr +i |
dnsTunneling=true (newer WSL), or re-generate each boot |
Notable Projects¶
dhermes/tailscale-wsl2¶
URL: https://github.com/dhermes/tailscale-wsl2
Go reverse-proxy pair that bridges the Windows Tailscale daemon's HTTP API
into WSL2 via a Unix socket. Lets you run tailscale status etc. from bash.
Verdict: Obsoleted by mirrored networking. Before mirrored mode, WSL2 couldn't see the host's Tailscale IP. Now it can. We don't need this.
peppy0510/wsl-service¶
URL: https://github.com/peppy0510/wsl-service
Python-based WSL startup manager. Supports both NSSM (Windows service) and NirCmd (Task Scheduler). JSON config for declaring services + firewall rules.
What they have that we don't: NSSM registration runs at boot without user login. Eliminates the auto-login hack.
Gotcha: NSSM on Win11 causes file permission issues in Explorer.
nullpo-head/winsomnia-ssh¶
URL: https://github.com/nullpo-head/winsomnia-ssh
Prevents Windows from sleeping during active SSH sessions. Detects SSH via
process tree, blocks sleep with SetThreadExecutionState.
We should steal this idea -- our remote PC could sleep and become
unreachable. A powercfg command in the setup scripts would be simpler:
CzBiX/WSLHostPatcher¶
URL: https://github.com/CzBiX/WSLHostPatcher
Injects into wslhost.exe to make WSL2 listen on all interfaces in NAT
mode, without netsh portproxy. Obsoleted by mirrored networking.
Alternative Architectures We Considered¶
A. Windows OpenSSH as Jump Host (ProxyJump)¶
SSH config:
Host win-jump
HostName 100.125.78.30
User Admin
Host wsl-dev
HostName localhost
Port 2222
User simon
ProxyJump win-jump
Pros: Works without mirrored networking. No special firewall rules for WSL2. Cons: Need Windows OpenSSH + WSL2 sshd running. Double encryption overhead. Two credential sets. Windows OpenSSH has its own quirks.
When to use: Fallback if mirrored networking doesn't work on this Win11 build.
B. Tailscale SSH (no OpenSSH at all)¶
Run Tailscale inside WSL2 with tailscale up --ssh. Tailscale owns port 22,
authenticates via WireGuard node keys. Zero SSH key management.
Pros: No keys to manage. No authorized_keys. No private key transport problem.
Cons: Must disable Windows Tailscale (double encapsulation). MTU issues.
Officially discouraged by Tailscale.
C. Windows OpenSSH + bash.exe as Default Shell¶
Set HKLM\SOFTWARE\OpenSSH\DefaultShell = C:\WINDOWS\System32\bash.exe.
SSH into Windows and you land in a WSL2 bash shell directly.
Status: Broken since Microsoft moved WSL to the Store. bash.exe from
Store WSL fails with "The file cannot be accessed by the system" when invoked
by the OpenSSH service. Was Hanselman's recommended approach until it broke.
D. Task Scheduler AtStartup (vs our AtLogOn)¶
Change the trigger from AtLogOn to AtStartup with "Run whether user is
logged on or not". Would eliminate the auto-login requirement entirely.
Gotcha: WSL2 started before user login creates a separate session context.
File Explorer and \\wsl.localhost break when the user later logs in
(WSL#7365). Only safe for
purely headless/SSH-only use. If anyone ever sits at the Windows desktop, this
causes problems.
Our auto-login + AtLogOn approach avoids this at the cost of storing a password in the registry.
What Others Do That We Should Add¶
-
WSL_INTEROP fix in .bashrc -- so
notepad.exe,clip.exe, etc. work over SSH. See wslg-architecture.md. -
Disable Windows sleep --
powercfg /change standby-timeout-ac 0. Our remote PC could go to sleep and become unreachable. -
Boot delay -- jmmv.dev's guide adds a 30-second delay in Task Scheduler to ensure WSL2 networking is ready. Could help on slow-booting systems.
-
Tailscale auth keys -- for fully unattended Tailscale setup. The rmrazeen/remote-access-tailscale project uses
tailscale up --authkey=...for zero-browser-interaction deployment.
What We Do Better Than Most¶
-
Mirrored networking -- most guides still use
netsh portproxywhich breaks on every WSL restart (IP changes). We avoid this entirely. -
Hyper-V firewall -- almost nobody handles this. It silently blocks inbound traffic in mirrored mode. We have the rule.
-
Tailscale CGNAT restriction -- our firewall rules scope to
100.64.0.0/10. Most guides use0.0.0.0/0or skip firewalls entirely. -
sleep infinitykeepalive -- we don't rely solely on systemd or timeouts, which have known regressions. Our Task Scheduler entry chainsservice ssh start; exec sleep infinity. -
DNS hardening --
chattr +i /etc/resolv.confprevents Tailscale and WSL from overwriting DNS. Others use boot commands to regenerate resolv.conf each restart, which is fragile. -
Comprehensive diagnostics -- our
01-tryout.ps1prints full status of every component. Most scripts just hope for the best.
Created: 2026-03-16
Sources: - dhermes/tailscale-wsl2 - peppy0510/wsl-service - nullpo-head/winsomnia-ssh - CzBiX/WSLHostPatcher - rmrazeen/remote-access-tailscale - Hanselman: SSH into WSL2 (easy way) - Hanselman: Tailscale + WSL2 - jmmv.dev: SSH access into WSL - microsoft/WSL#7365 (pre-login session isolation) - microsoft/WSL#13416 (systemd keep-alive regression)