Let’s say you have a Windows machine and want to be able to SSH into the WSL2 subsystem from your network.
First we need to make sure that the sshd in the WSL2 guest system is always running:
Install sshd (duh)
apt update
apt install openssh-server
Oh, lets config things in /etc/ssh/sshd_config:
PermitRootLogin yes # root user
PasswordAuthentication no # use keysRun sshd in Windows 11
Windows 11 has implemented systemd support: https://learn.microsoft.com/en-us/windows/wsl/systemd
In the WSL2 guest:
echo -e "[boot]\nsystemd=true" > /etc/wsl.confRestart WSL:
`wsl.exe --shutdown`
Again, in the guest system:
sudo systemctl enable --now sshRun sshd in Windows 10
The systemd method doesn’t work. So, what to do? There are a few approaches but here’s the one I used.
In the WSL guest (eg Ubuntu) create a simple script /root/run.sh:
#!/bin/bash
while [ 1 ];
do
sleep 1;
done
The goal of this script is just to run forever.
Then, create a PowerShell script say at C:\run-wsl-hidden.ps1 - a PowerShell script is required to run it “hidden”:
Start-Process wsl.exe -ArgumentList "-d Ubuntu /root/run.sh" -WindowStyle Hidden
Once you’ve created this, you should open the Task Scheduler app and:
- Create Basic Task
- Trigger:
- at startup
- Action:
- Start a program
- Program:
powershell.exe
- Arguments
-WindowStyle Hidden -ExecutionPolicy Bypass -File "C:\run-wsl-hidden.ps1"
Make it accessible externally
We want to make sure we are port forwarding from Windows to the WSL
# In PowerShell as Administrator
netsh interface portproxy add v4tov4 listenport=22 listenaddress=0.0.0.0 connectport=22 connectaddress=(wsl hostname -I)
- You can get your WSL IP:
ip addr show eth0 | grep "inet\b" | awk '{print $2}' | cut -d/ -f1but using the hostname is more reliable
We need to allow connecting via SSH:
# Run in PowerShell as Administrator
New-NetFirewallRule -DisplayName "WSL2 SSH" -Direction Inbound -Action Allow -Protocol TCP -LocalPort 22
- You might have a port conflict if the Windows SSH server is also running, just shut that down
In PowerShell, you might wan to check on DNS (in theory mDNS should work):
# Run in PowerShell as Administrator
Get-Service "DNSCache" | Set-Service -StartupType Automatic
Start-Service "DNSCache"
IPv6 Debugging
If you have long hang times connecting, it could be IPv6 routing woes. Try w/ IPv4:
ssh -4 windows.local
If that fixes things you can put this in your ~/.ssh/config:
Host windows.local
AddressFamily inet
User root # you probably want this here anyway
- You could also try putting
AddressFamily inetin your WSL guest’s/etc/ssh/sshd_config