Skip to content

feat: Windows + WSL support for SSH-over-TLS#61

Open
shaunymca wants to merge 2 commits intohdresearch:mainfrom
shaunymca:feat/windows-ssh-support
Open

feat: Windows + WSL support for SSH-over-TLS#61
shaunymca wants to merge 2 commits intohdresearch:mainfrom
shaunymca:feat/windows-ssh-support

Conversation

@shaunymca
Copy link
Copy Markdown

Summary

Adds Windows and WSL support to all Vers SSH extensions. Zero changes to Linux/macOS behavior.

Problem

On Windows:

  1. ProxyCommand has TLS compatibility issues with the Vers proxy
  2. SSH ControlMaster requires Unix domain sockets, which fail on NTFS

On WSL:
3. returns a Windows filesystem path (e.g. ) where POSIX permission bits are ignored — every file is 0777. SSH refuses world-readable private keys.

Solution

**Commit 1: **

New file:

  • — detection
  • — local TCP→TLS proxy per VM using / (cached, ephemeral port on 127.0.0.1)
  • — returns platform-appropriate SSH connection args

Modified: , , ,

  • Import shared utils, replace hardcoded ProxyCommand with
  • Guard ControlMaster/ControlPath behind checks
  • Make async where needed for the async proxy setup

**Commit 2: **

  • Detect WSL (Linux + tmpdir starts with ) and write keys to instead

Design decisions

  • No new npm dependencies — uses Node built-ins (, )
  • Proxy-per-VM caching — avoids spinning up redundant servers
  • **** is intentional — TLS is only a transport wrapper to reach the Vers proxy. SSH key authentication inside the tunnel provides the actual security. This matches the Linux behavior where also skips certificate verification.
  • All Windows paths are behind guards — Linux/macOS codepaths are untouched

Testing

Tested on Windows 11 (native) and WSL2 with pi-v VM operations (create, SSH, copy, lieutenant, swarm).

shaun added 2 commits March 13, 2026 11:32
Add platform detection with a Node.js-native fallback for Windows, where
openssl s_client ProxyCommand and SSH ControlMaster (Unix sockets) fail.

New file: extensions/vers-ssh-utils.ts
- IS_WINDOWS constant (platform() === 'win32')
- ensureWinProxy(vmId): local TCP->TLS proxy per VM using node:tls/node:net
- platformSSHArgs(vmId): returns platform-appropriate SSH connection args

Modified: vers-vm.ts, vers-lieutenant.ts, vers-swarm.ts, vers-vm-copy.ts
- Import shared utils, replace hardcoded ProxyCommand with platformSSHArgs()
- Guard ControlMaster/ControlPath behind !IS_WINDOWS checks
- Make sshArgs() async where needed to support the async proxy setup

Design:
- Zero changes to Linux/macOS behavior (all behind IS_WINDOWS guards)
- No new dependencies (uses Node built-in tls and net modules)
- rejectUnauthorized:false matches openssl s_client -quiet behavior
  (TLS is transport only; SSH key auth provides actual security)
On WSL, os.tmpdir() returns a Windows filesystem path (e.g.
/mnt/c/Users/.../Temp) where POSIX permission bits are ignored —
every file appears as 0777. SSH refuses to use a private key that is
world-readable, causing authentication failures.

Detect WSL (Linux + tmpdir starts with /mnt/) and write SSH keys to
/tmp instead, where chmod 0600 works correctly.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants