THE EASY WAY how to SSH into Bash and WSL2 on Windows 10 from an external machine
This is an interesting blog post on How to SSH into WSL2 on Windows 10 from an external machine. Read it. Know how it works. Learn it. AND DO NOT DO IT BECAUSE IT'S TOO COMPLEX.
DO NOT DO THIS. It's fine. It works. But it's baroque. You're forwarding ports into a little VM'ed local subnet, you're dealing with WSL2 IP addresses changing, you'll have to keep your VM running, and you're generally trying to ice skate up hill.
Here's the thing. In that post - which you should not do - you're turning off the Windows Firewall for your port, forwarding to an internal subnet, and then letting WSL take over.
BUT! Windows 10 already knows how to accept SSH connections. In fact, it's shipped OpenSSH as a "Feature on Demand" for years. The issue is that you (Mac and Linux switchers) don't like the default shell - PowerShell.
So why not change the default Windows shell for SSH to WSL2's Bash?
Boom. Now you have no port forwarding, firewalls are only opening for one process, and your WSL2 instance starts up on entry. Literally the best of all worlds.
How do you set up SSH'ing into WSL2 on your Windows 10 machine
First, open an admin PowerShell prompt (Start menu, type PowerShell, hold ctrl+shift, and hit enter) type this:
> Get-WindowsCapability -Online | ? Name -like 'OpenSSH*'
Name : OpenSSH.Client~~~~0.0.1.0
State : Installed
Name : OpenSSH.Server~~~~0.0.1.0
State : NotPresent
See how I have the Client and not the OpenSSH Server? Add it:
Add-WindowsCapability -Online -Name OpenSSH.Server~~~~0.0.1.0
Now either start the SSHD service, or set it to start automatically:
Set-Service -Name sshd -StartupType 'Automatic'
Configuring the Default Shell for OpenSSH in Windows 10
On my server (the Windows machine I'm SSHing into) I will set a registry key to set the default shell. In this case, I'll use open source cross platform PowerShell Core. You can use whatever makes you happy and WSL2's bash makes me happy.
New-ItemProperty -Path "HKLM:\SOFTWARE\OpenSSH" -Name DefaultShell -Value "C:\WINDOWS\System32\bash.exe" -PropertyType String -Force
Note that bash.exe in this context starts up "
wsl -d YOURDEFAULTDISTRO" so you'll want to know what your Default is, and if you don't like it, change it with
wsl --set-default DISTRO.
HEADS UP: You need the FULL AND CORRECT PATH in that command above. It works for any shell. Since I'm using bash.exe, I get WSL2 starting up for free but SSH with this solution is using Windows's SSH keys and Windows auth. Note that when you're entering your password for authentication!
Even better if I wanted to add a menu item (profile) to one local Windows Terminal with an entry to ssh into my WSL on my remote Windows Machine that would automatically log me into it from elsewhere using public keys, I could do that also!
To conclude and sum up:
- This blog post - the one you are reading uses Windows' OpenSSH and authenticates with Windows and then runs WSL2. WSL2 starts up, uses bash, and Windows handles the TCP traffic.
- This other blog post - over here - has Windows only forwarding ports, and uses WSL2's Linux OpenSSH and authenticates against Linux. Windows is only involved peripherally. The WSL2 IP address changes on reboot and you'll need to maintain your portproxy rules and firewall rules with the script listened at the end of that post.
Understand what you want and use the right one for you.
Sponsor: Bug in prod? Get to the bottom of it, fast, with live production log search in Seq 2020.1.