WSL 2 SSH server setup - chhwang/devel-note GitHub Wiki
Preliminaries
-
Install WSL 2 (available since Windows 10 version 2004) and enable Hyper-V.
-
Install any Linux distro (e.g. Ubuntu) from Microsoft Store. Run the distro to create your account and complete the installation.
Linux-side Setup
-
Run the Linux distro.
-
Re-install OpenSSH server as follows.
sudo apt remove --purge openssh-server sudo apt install openssh-server
-
Edit
/etc/ssh/sshd_config
.- Open
/etc/ssh/sshd_config
(e.g.sudo vi /etc/ssh/sshd_config
). - Write
PasswordAuthentication yes
- Write
AllowUsers YOUR_ACCOUNT_NAME
(whereYOUR_ACCOUNT_NAME
should be replaced by your Linux account name). - Save the file and exit.
- Open
-
(Optional) For security, allow only specific IP addresses to login. E.g. to allow
192.30.118.x
and194.57.240.32
only, do as follows. edit as follows.- Open
/etc/hosts.deny
(e.g.sudo vi /etc/hosts.deny
). - Write
ALL EXCEPT sshd: 192.30.118.0/24 194.57.240.32
. - Save the file and exit.
- Open
-
Full restart the SSH server.
sudo service ssh --full-restart
-
Allow SSH server to start without password.
- Run
sudo visudo
. - Add
%sudo ALL=NOPASSWD: /etc/init.d/ssh
after%sudo ALL=(ALL:ALL) ALL
.
- Run
Windows-side Setup
-
Copy and save the following PowerShell script under a permanent directory. (File is uploaded here.) Note that this script is needed because the IP address of WSL 2 changes whenever we reboot the system, so this script automatically change the port forwarding rule at every startup. Suggested here: link.
$remoteport = bash.exe -c "ifconfig eth0 | grep 'inet '" $found = $remoteport -match '\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}'; if( $found ){ $remoteport = $matches[0]; } else{ echo "The Script Exited, the ip address of WSL 2 cannot be found"; exit; } #[Ports] #All the ports you want to forward separated by coma $ports=@(22); #[Static ip] #You can change the addr to your ip config to listen to a specific address $addr='0.0.0.0'; $ports_a = $ports -join ","; #Remove Firewall Exception Rules iex "Remove-NetFireWallRule -DisplayName 'WSL 2 Firewall Unlock' "; #adding Exception Rules for inbound and outbound Rules iex "New-NetFireWallRule -DisplayName 'WSL 2 Firewall Unlock' -Direction Outbound -LocalPort $ports_a -Action Allow -Protocol TCP"; iex "New-NetFireWallRule -DisplayName 'WSL 2 Firewall Unlock' -Direction Inbound -LocalPort $ports_a -Action Allow -Protocol TCP"; for( $i = 0; $i -lt $ports.length; $i++ ){ $port = $ports[$i]; iex "netsh interface portproxy delete v4tov4 listenport=$port listenaddress=$addr"; iex "netsh interface portproxy add v4tov4 listenport=$port listenaddress=$addr connectport=$port connectaddress=$remoteport"; }
-
Open Windows Task Scheduler (search for 'task' from the search bar).
-
Select "Create Task..." at the right-side pane and configure the task as follows.
- In General tab,
- Name: WSL 2 SSH Server
- Select "Run with highest privileges"
- In Triggers tab, click the "New" button and create a trigger:
- Begin the task: At startup
- Delay task for up to: 10 seconds
- In Actions tab, click the "New" button and create an action that starts the SSH server:
- Action: Start a program
- Program/script:
%windir%\System32\bash.exe
- Add arguments:
-c "sudo /etc/init.d/ssh start"
- In Actions tab, click the "New" button and create an action that runs the aforementioned PowerShell script:
- Action: Start a program
- Program/script:
powershell.exe
- Add arguments: the path you stored the script in 1.
- Click "OK" to save the task.
- In General tab,
-
Select the task created in 3. (the name is "WSL 2 SSH Server"), and click "Run" at the right-side pane.
Verification
-
To check whether the port forwarding script ran correctly, open up PowerShell and run the following.
netsh interface portproxy dump
It should print
add v4tov4 listenport=22 connectaddress=WSL_IP_ADDRESS connectport=22
where
WSL_IP_ADDRESS
is the IP address you see at the Linux-side.