Aspiring Craftsman

pursuing well-crafted software

SSH on WSL


I recently set up a Windows machine to allow me to ssh into its WSL network from another box. I found a couple of useful guides here and here, but still ran into a few snags along the way, so thought I’d publish my configuration in case it might be useful to someone else (or perhaps even myself) in the future. Here are my steps:

Step 1: Install OpenSSH in WSL

Our first step will be to ensure openssh-server is installed. If not, issue the following and follow the prompts:

$ sudo apt install openssh-server

Step 2: Configure SSHD

Edit the file /etc/ssh/sshd_config to allow the desired users or groups. You’ll need to edit this with root access:

$ sudo vi sshd_config

To allow specific users, you can add the following with a list of users where is replaced with the desired user:

AllowUsers <user1> <user2> <userN>

To allow all users in one or more groups, add the following:

AllowGroups <group1> <group2> <groupN>

Note that these are users and groups known to WSL, not your windows users and groups (i.e. /etc/password, /etc/group).

Step 3: Setup Startup Script

Create a new file named startup-ssh.sh in /usr/local/bin with the following contents:

#!/bin/bash

WSL_IP=$(ip addr show eth0| grep -oP '(?<=inet\s)\d+(\.\d+){3}')
NETSH_CMD=/mnt/c/Windows/System32/netsh.exe
SSL_PORT=22
FIREWALL_RULE_NAME="SSH Port ${SSL_PORT}"

echo -n "Resetting port proxy settings ... "
${NETSH_CMD} interface portproxy reset all 2>&1 1>/dev/null

[ $? == 0 ] && echo "OK" || echo "Error"

echo -n "Forwarding port ${SSL_PORT} to ${WSL_IP} ... "
${NETSH_CMD} interface portproxy add v4tov4 listenaddress=0.0.0.0 listenport=${SSL_PORT} connectaddress=${WSL_IP} connectport=${SSL_PORT} 2>&1 1>/dev/null
[ $? == 0 ] && echo "OK" || echo "Error"

echo -n "Adding firewall rule if not present ... "
if ${NETSH_CMD} advfirewall firewall show rule name="${FIREWALL_RULE_NAME}" 2>&1 1>/dev/null
then
echo "OK"
else
${NETSH_CMD} advfirewall firewall add rule name="${FIREWALL_RULE_NAME}" dir=in action=allow protocol=TCP localport=${SSL_PORT} 2>&1 1>/dev/null
[ $? == 0 ] && echo "OK" || echo "Error"
fi

echo -n "Starting WSL ssh server ... "
sudo /etc/init.d/ssh start 2>&1 1>/dev/null
[ $? == 0 ] && echo "OK" || echo "Error"

This script does the following things primarily:

  • Forwards traffic going to port 22 from your Windows system to port 22 on the WSL virtual machine
  • Adds a Windows firewall rule to allow port 22 traffic
  • Starts the ssh server

We will be configuring Windows to execute this script on startup. The reason this is necessary is that WSL obtains a new IP address each time the system starts. This results in the need to reset the port forwarding and reapply with the latest WSL IP address.

Step 4: Configure Super User Execution

As indicated in step 5 of this guide, we need to allow the ssh command to be started without prompting for a password. We do this by editing the /etc/sudoers file. This can be done with the following command:

    $ sudo visudo
Note:

The purpose of editing the /etc/sudoers file using the visudo command is to validate the syntax before saving. You could edit the file directly, but if you screw something up then you could lock yourself out of gaining root access.

When I first used this command, it launched using the nano editor with which I’m not familiar. You can configure which editor is used by executing the following command:

    
    $ sudo select-editor    

Alternately, you can set your EDITOR environment variable to the desired editor and use the following command:

    $ sudo -E visudo

Add the following as the last line of the file:

%sudo ALL=NOPASSWD: /etc/init.d/ssh

Step 5: Configure Windows Task Scheduler

Our final step will be to configure Windows Task Scheduler to launch our startup script when the system starts. Use the following steps:

  • Open the Task Scheduler app from the Windows Start Menu

  • Select Create Basic Task from the right panel

  • Create task with the following parameters:

    Name: Start SSH Server

    Description: Task to automate sshd startup

    Trigger: Select When the computer starts

    Action: Select Start a program

    Program/script :%windir%\System32\wsl.exe Add arguments (optional): -d Ubuntu -e "/usr/local/bin/startup-ssh.sh"

  • Confirm everything is correct and click Finish

Step 7: Verify Configuration

Our last step is to verify we have everything configured correctly. In Task Scheduler, locate the “Start SSH Server” task and in the right panel click “Run”. If successful, you should be able to ssh from another machine to your Windows WSL virtual machine:

$ ssh dgreer@dgreer-pc