Fix a non-functional SSH server in Ubuntu on WSL2 by starting the sshd service, configuring Windows port forwarding with netsh, and updating the SSH client config to use the correct hostname. This resolves connection refused errors without relying on deprecated network settings or insecure root access.
Starting the SSH Daemon
The most common reason an SSH server appears broken is that the daemon process is not running. Unlike traditional Linux distributions, WSL2 does not automatically start background services likesshd every time you open a terminal window. You must explicitly start it or configure it to run on boot.
First, ensure the OpenSSH server package is installed. If you are using a fresh WSL2 instance, you may need to install it via your package manager:
sudo apt update
sudo apt install openssh-server
Once installed, verify the status of the service. You can check if it is active using:
sudo systemctl status ssh
If the service is inactive or failed, start it manually:
sudo service ssh start
To make this persistent across reboots and new terminal sessions, you should create a startup script. Create a file named ssh-start.sh in your home directory containing:
#!/bin/bash
service ssh start
Make it executable with chmod +x ssh-start.sh. Then, add a call to this script in your .bashrc or .profile file so it runs whenever you open a WSL2 shell. Alternatively, many users prefer using the Windows Task Scheduler to launch the WSL instance with a command that starts the service, ensuring it is ready before you attempt any connections.
Configuring Port Forwarding
WSL2 runs inside a lightweight utility VM, which means it has a dynamic internal IP address that changes every time the WSL2 instance restarts. Windows cannot connect directly to this changing IP. Instead, you must set up port forwarding from a static port on your Windows host to the SSH port (usually 22) inside the WSL2 VM. The previous error involved usingNew-NetNat, which is incorrect for this purpose. The correct tool is netsh. Run the following command in PowerShell as Administrator on your Windows machine:
netsh interface portproxy add v4tov4 listenport=2222 connectaddress=$(wsl hostname -I | awk '{print $1}') connectport=22
This command listens on port 2222 on your Windows host and forwards traffic to port 22 inside the WSL2 container. Note that because the WSL2 IP changes, you may need to refresh this rule occasionally. A more robust approach is to place this command in a Windows batch file or PowerShell script that runs at login, or to use a WSL2 extension that handles port management automatically.
If you encounter issues where the connection hangs or times out, refer to our guide on Troubleshooting SSH WSL Machine: Can't Connect to Localhost. That resource covers firewall blocks and other connectivity nuances that often accompany port forwarding setup.
After setting up the proxy, test the connection from Windows:
ssh username@localhost -p 2222
If this fails with "Connection Refused," check your Windows Firewall settings to ensure port 2222 is allowed for inbound connections.
Updating SSH Client Configuration
Connecting vialocalhost with a custom port can be tedious. You can simplify this by adding a configuration block to your local SSH client config file on Windows. Edit or create the file located at C:\Users\YourUsername\.ssh\config (note: this is the Windows path, not the WSL path).
Add the following lines:
Host wsl-ubuntu
HostName localhost
Port 2222
User your_username
IdentityFile ~/.ssh/id_rsa
Replace your_username with your actual WSL2 username. Now, you can simply type ssh wsl-ubuntu from your Windows terminal or Git Bash to connect.
Ensure that your SSH keys are properly generated and copied to the WSL2 environment. In WSL2, run:
cp ~/.ssh/id_rsa ~/.ssh/id_rsa.pub .
# Or copy from Windows if you share keys
cp /mnt/c/Users/YourUsername/.ssh/id_rsa ~/.ssh/id_rsa
Avoid enabling root login over SSH, as it is a significant security risk. Instead, use your standard user account and escalate privileges with sudo when necessary. For more details on handling connection refusals specific to WSL hosts, see Connection Refused to WSL(Linux) Host.
Verifying Network Settings
In older tutorials, you might see recommendations to configure static IPs using/etc/netplan. This is deprecated and unnecessary for WSL2 SSH setups. Relying on netplan for static networking in WSL2 can lead to conflicts when the virtual network adapter resets. Stick to port forwarding via netsh as described above. It is the supported and stable method for exposing WSL2 services to the Windows host.
If you experience timeouts specifically between Ubuntu and Windows components, review Unable to Connect Ubuntu 20.04 to Windows for insights into latency and handshake issues.
Finally, always ensure your WSL2 kernel and Ubuntu packages are up to date. Security patches often resolve underlying network stack bugs that manifest as SSH failures.
Frequently Asked Questions
Why does my WSL2 IP change every time I restart?
WSL2 uses a hyper-v virtual switch that assigns a new DHCP lease upon each restart. This is by design to prevent IP conflicts on your local network. Use port forwarding instead of trying to bind to a specific IP address.
Can I use PuTTY to connect to WSL2 SSH?
Yes, PuTTY works perfectly well. Configure it to connect to localhost on port 2222 (or whatever port you forwarded). Ensure you select SSH as the connection type and provide your WSL2 username.
Is it safe to enable root login in SSH?
No, enabling root login via password authentication is highly discouraged due to brute-force attack risks. Use key-based authentication with a standard user account and grant sudo privileges only when needed.
What if netsh commands fail with permission denied?
You must run PowerShell or Command Prompt as an Administrator. Right-click the Start menu and select "Windows PowerShell (Admin)" or similar, then execute the portproxy command again.
How do I disable port forwarding if I no longer need it?
To remove the port proxy rule, run netsh interface portproxy delete v4tov4 listenport=2222 in an elevated PowerShell session. This will stop forwarding traffic from port 2222 to your WSL2 instance.