Connect to your WSL SSH server by ensuring the service is running, configuring port forwarding in Windows Terminal or PowerShell, and verifying firewall rules. This guide resolves common localhost connection failures for developers using Windows Subsystem for Linux.
Verify the SSH Service Status
The most frequent cause of connection refusal is that the OpenSSH server process is not active within the Linux distribution. Unlike Windows services, WSL does not automatically start background daemons on boot unless explicitly configured. You must manually check if the ssh daemon is listening on port 22. Open your WSL terminal and run the command sudo service ssh status. If the output indicates the service is inactive or dead, you need to start it immediately with sudo service ssh start.
To ensure this happens every time you launch your WSL instance, add the start command to your shell profile. Append sudo service ssh start to the end of your ~/.bashrc or ~/.zshrc file. This prevents the "Connection refused" error from recurring after a system restart. Note that some newer versions of Ubuntu may use sshd instead of ssh, so verify the correct service name if the initial command fails.
Configure Port Forwarding Correctly
WSL runs in a virtualized network environment that is isolated from the Windows host loopback interface by default. You cannot simply connect to localhost:22 without explicit port forwarding rules. The modern and recommended approach uses Windows Terminal. Navigate to your settings.json file for Windows Terminal and locate the profile corresponding to your Linux distribution. Add the property "forwardPorts": [ 22 ] inside the JSON object for that specific profile.
If you are not using Windows Terminal, you can configure port forwarding via PowerShell. Run the command netsh interface portproxy add v4tov4 listenaddress=127.0.0.1 listenport=22 connectaddress=. To find your WSL IP address, execute hostname -I inside your WSL terminal. Remember that the IP address assigned to WSL instances changes dynamically upon reboot. Therefore, relying on a static IP in netsh commands often leads to broken connections after a short period. Using the Windows Terminal configuration is more robust because it handles dynamic IP resolution automatically.
Check Windows Firewall Rules
Even with correct port forwarding, the Windows Firewall may block incoming connections on port 22. This is particularly common on fresh Windows installations or after major updates. Open the Windows Defender Firewall with Advanced Security console. Look for inbound rules related to OpenSSH Server. If no rule exists, create a new inbound rule that allows TCP traffic on port 22 for all profiles (Domain, Private, Public).
You should also verify that the Windows Firewall is not set to block private network connections. Go to Settings > Network & Internet > Ethernet (or Wi-Fi) and ensure your current network profile is set to Private rather than Public. Public networks have stricter firewall defaults that often block SSH access. After adjusting these settings, attempt to connect again using ssh user@localhost from your Windows command prompt or PowerShell.
Validate User Permissions and Keys
Authentication failures can sometimes manifest as connection issues if the SSH key permissions are too restrictive. Linux requires that private keys have permissions set to 600. Run chmod 600 ~/.ssh/id_rsa to fix this. Additionally, ensure that the authorized_keys file in your home directory has the correct ownership and permissions. It should be owned by your user and have permissions set to 600 or 644.
If you are still experiencing issues, check the SSH logs for detailed error messages. In your WSL terminal, run sudo journalctl -u ssh -f while attempting to connect from Windows. This real-time log view will reveal whether the connection is being dropped due to authentication failure, protocol mismatch, or network timeout. For further assistance with permission-related SSH issues, see our guide on Passing Passwords for Remote Users in Bash and review strategies for Setting Up a Development Environment with Low Permissions.
Frequently Asked Questions
Why does my WSL IP change every time I restart?
WSL uses a virtual switch that assigns IPs dynamically via DHCP. Each time the WSL instance stops and starts, the virtual network adapter may receive a different address. This is why hardcoding the IP in port proxy rules is unreliable. Always use dynamic resolution methods like Windows Terminal's built-in forwarding or scripts that query the current IP before connecting.
Can I use PuTTY to connect to WSL?
Yes, but you must point PuTTY to 127.0.0.1 and ensure port forwarding is correctly configured in Windows. PuTTY does not natively understand WSL's internal networking, so it relies entirely on the host machine's forwarded ports. Ensure that the Windows Firewall allows PuTTY to bind to the local port if it prompts for permission.
How do I stop the SSH service in WSL?
You can stop the service by running sudo service ssh stop in your WSL terminal. This is useful if you need to troubleshoot configuration files without the service interfering. Stopping the service frees up port 22 on the WSL side, allowing you to test other configurations or debug startup scripts.
Is it safe to expose WSL SSH to the internet?
No, exposing WSL directly to the internet is highly discouraged due to security risks. WSL shares the Windows kernel and file system, which could lead to privilege escalation vulnerabilities if exploited. Always use a VPN or tunneling solution if remote access is required. For secure remote setups, consider reviewing best practices in Troubleshooting Connection Reset Issues to maintain secure channels.
What if I get a "Permission Denied" error?
This usually means your public key is not in the ~/.ssh/authorized_keys file on the WSL side, or the password authentication is disabled. Check the /etc/ssh/sshd_config file to ensure PasswordAuthentication yes is set if you intend to use passwords. For key-based auth, verify that the key pair matches and permissions are strict.