Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save shakahl/49c4a4b60946adf3b24795d6fa97992d to your computer and use it in GitHub Desktop.
Save shakahl/49c4a4b60946adf3b24795d6fa97992d 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.

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