Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save adamelliotfields/16dfac1bacf6d2eeada0582fdfbbb7b6 to your computer and use it in GitHub Desktop.
Save adamelliotfields/16dfac1bacf6d2eeada0582fdfbbb7b6 to your computer and use it in GitHub Desktop.
Windows SSH Server with Password-less Key Authentication and Default WSL2 Shell

Windows SSH Server with Password-less Key Authentication and Default WSL2 Shell

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.

Copy Your Public Key to Your User's ~/.ssh/authorized_keys File

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).

Install Windows OpenSSH Package

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

Configure OpenSSH Server

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

Restart the SSH Server

You need to restart the server every time you make changes to sshd_config.

Restart-Service sshd

Connect to Your Windows PC via SSH

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'.

ssh Adam@1.2.3.4

Debugging

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.

@eclipsedjim
Copy link

eclipsedjim commented Jan 11, 2023

Wow! Rare to see such a well written, 100% complete guide! Thanks!
I didn't see this first time through, so be sure to comment out these two lines (in sshd_config) & restart sshd:

#Match Group administrators
#  AuthorizedKeysFile __PROGRAMDATA__/ssh/administrators_authorized_keys

@adamelliotfields
Copy link
Author

Thanks Jim, appreciate the kind words. I'll add some bold text since that step is very important!

If you think of any other suggestions let me know. This is my charity work to people forced to use Windows for non-solitaire purposes.

@Asoniox
Copy link

Asoniox commented Jul 11, 2023

Finally a guide that actually works! You have no idea how long I was searching the internet to configure SSH properly 😪

@rikrdo89
Copy link

This is an excellent guide. I just wanted to point out that adding public key in C:\Users\myUser\.ssh\authorized_keys did not work for me. However, if I added the key to C:\ProgramData\ssh\administrators_authorized_keys it works without issue, as @eclipsedjim mentioned.

@dperique
Copy link

dperique commented Dec 9, 2023

I'm gonna add my .02 on this one too -- this really helped. I need to run WSL/Linux on my Windows 10 PC and this helps me avoid the whole Windows CMD thing, all those backslashes, etc.

Thanks for this super helpful doc!

@Corgi
Copy link

Corgi commented Dec 28, 2023

Super useful and clear, thank you!

@silentTeamMapReduce
Copy link

This is an excellent guide. I just wanted to point out that adding public key in C:\Users\myUser\.ssh\authorized_keys did not work for me. However, if I added the key to C:\ProgramData\ssh\administrators_authorized_keys it works without issue, as @eclipsedjim mentioned.

Many many thank's, can proof creating administrators_authorized_keys and adding there public key worked and saved many hours 🚀

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment