Disclaimer: I am not a Windows Admin and I'm not even that good with PowerShell.
I wanted to be able to SSH into my Windows laptop directly into Linux. I also wanted to disable password authentication and only allow public key (RSA in my case) authentication.
Scott Hanselman wrote a blog post on how to make your default WSL2 distro your default shell for SSH. Windows OS Hub published an article on using public key authentication. These were both helpful resources.
I'll assume you're already familiar with using SSH keys. If not, this article at DigitalOcean is very informative.
First thing you want to do is create the file ~/.ssh/authorized_keys
. Note that in my case I'm the
only user on my PC, so the file owner will be me by default. If you run into issues, it could be due
to incorrect file ownership. Also worth mentioning that Windows doesn't have the concept of numeric
permissions like on Linux/Mac, so you don't need to chmod 600
this file like you may be used to
doing.
Paste your public key into this file. If you've done this on a Linux server it's literally the
same thing (the SSH server checks the user's authorized_keys
file to see if the private key being
used by the SSH client matches one of the public keys in the file).
I would not recommend installing OpenSSH via Optional Features (either the GUI or from PowerShell). It will install an old version and it will not uninstall cleanly. I'd recommend using a package manager like Scoop or Chocolatey. I personally use Scoop for everything.
Run PowerShell as Administrator as you'll need elevated privileges.
# Install the package.
scoop install win32-openssh
# Allow inbound connections on port 22.
netsh advfirewall firewall add rule name=sshd dir=in action=allow protocol=TCP localport=22
# Create the SSH Server service and set it to start automatically.
cd "$Env:USERPROFILE\scoop\apps\win32-openssh\current"
.\install-sshd.ps1
Set-Service -Name sshd -StartupType 'Automatic'
# You need to start the server once to generate the configuration files.
Start-Service sshd
# Set WSL2 as the default shell for SSH sessions.
New-ItemProperty -Path "HKLM:\SOFTWARE\OpenSSH" -Name DefaultShell -Value "C:\WINDOWS\System32\bash.exe" -PropertyType String -Force
In the same Administrator PowerShell session, open the SSH Server config file in VS Code.
cd C:\ProgramData\ssh
code .
VS Code should have [Administrator]
in the title bar and you'll need it to edit this file. You
want to edit the sshd_config
file, specifically changing the below settings. The default settings
are all commented-out, so you can leave them. All of the settings are documented here.
Comment out AuthorizedKeysFile
below
# The default is "yes", but it's worth mentioning that this MUST be yes!
PubkeyAuthentication yes
# The default is ".ssh/authorized_keys .ssh/authorized_keys2", but we only want/need the first one.
AuthorizedKeysFile .ssh/authorized_keys
# The default is "yes", but we obviously want this to be "no".
PasswordAuthentication no
# IMPORTANT: You must comment out the following lines or delete them if your user is in the
# "administrators" group, which it most likely is if this is your personal computer.
#Match Group administrators
# AuthorizedKeysFile __PROGRAMDATA__/ssh/administrators_authorized_keys
I also like to set the SSH Server to IPv4 only, disable root login, and allow only 1 authentication attempt per connection. This isn't required, though.
AddressFamily inet
ListenAddress 0.0.0.0
PermitRootLogin no
MaxAuthTries 1
You need to restart the server every time you make changes to sshd_config
.
Restart-Service sshd
First get the network IP address for your Windows PC.
Get-NetIPAddress -AddressFamily ipv4 -PrefixOrigin dhcp
Now go to another PC that has the matching private key (should be in ~/.ssh/id_rsa
) to the public
key you pasted into the authorized_keys
file.
Replace my name with your Windows username (whatever $Env:USERNAME
is in PowerShell). If your
username has spaces in it, wrap your entire name in 'single quotes'.
On the server-side, you'll want to stop the sshd
service if it's running and then run sshd -d
manually to see debug output.
On the client-side, you'll want to try connecting to the server with the -v
flag to see verbose
output.
Many many thank's, can proof creating administrators_authorized_keys and adding there public key worked and saved many hours 🚀