OpenSSH Public Key Authentication on Windows —Not working? The secret tricks come out!
I figured out the trick to get OpenSSH public key authentication working on Windows.
Usually it’s not that complicated. But OpenSSH was not playing nice today.
This article assumes you have already installed OpenSSH through the installer, in the default directories, and have created a key pair using ssh-keygen
with id_rsa
and id_rsa.pub
files in your .ssh
user directory.
Example .ssh
path: C:\Users\User\.ssh
Example sshd_config
path: C:\ProgramData\ssh\sshd_config
If you perform these steps in order, you should have some success! 😊
Make sure you don’t have ANY instances of sshd
or ssh-agent
running (important):
- Run PowerShell as Administrator:
Stop-Service sshd
Stop-Service ssh-agent
taskkill /f /im sshd.exe
taskkill /f /im ssh-agent.exe
- Make sure you have these in your config and do not have duplicate lines
PubkeyAuthentication yes
PasswordAuthentication no
- Starting with Win 10 build 1809 and later, apparently you need to comment out these lines (matching administrators and its
authorized_keys
file):
Match Group administrators
AuthorizedKeysFile __PROGRAMDATA__/ssh/administrators_authorized_keys
- administrators_authorized_keys
needs to include the lines from your user’s id_rsa.pub
file (your public key file that contains the ssh-rsa
command)
id_rsa
andid_rsa.pub
andadministrators_authorized_keys
need to be in UTF-8 (without BOM) character encoding. You can use this script to ensure all of them are.
function UTF8NoBom($filter) {
$Utf8NoBomEncoding = New-Object System.Text.UTF8Encoding($False)
foreach($i in ls -Recurse -Filter $filter) {
$MyFile = Get-Content $i.fullname
[System.IO.File]::WriteAllLines($i.fullname, $MyFile, $Utf8NoBomEncoding)
}
}Set-Location “~/.ssh”
UTF8NoBom(“id_rsa*”)Set-Location “$ENV:ProgramData\ssh”
UTF8NoBom(“*authorized_keys*”)
administrators_authorized_keys
needs to have ONLY TWO permissions: SYSTEM and Administrators (important). Run this script in PowerShell as Administrator to fix the permissions on the file.
$ak = “$ENV:ProgramData\ssh\administrators_authorized_keys”
$acl = Get-Acl $ak
$acl.SetAccessRuleProtection($true, $false)
$administratorsRule = New-Object system.security.accesscontrol.filesystemaccessrule(“Administrators”,”FullControl”,”Allow”)
$systemRule = New-Object system.security.accesscontrol.filesystemaccessrule(“SYSTEM”,”FullControl”,”Allow”)
$acl.SetAccessRule($administratorsRule)
$acl.SetAccessRule($systemRule)
$acl | Set-Acl
- Ensure those are the only two users:
Get-Acl “$ENV:ProgramData\ssh\administrators_authorized_keys” | Format-List
If you have more than SYSTEM and Administrators, go to the file and remove other users/groups.
id_rsa
andid_rsa.pub
need to have ONLY TWO permissions: SYSTEM and your username (important). Run this script in PowerShell as the user but running as Administrator to fix the permissions on the file.
$userRule = New-Object system.security.accesscontrol.filesystemaccessrule(“$(whoami)”,”FullControl”,”Allow”)
$systemRule = New-Object system.security.accesscontrol.filesystemaccessrule(“SYSTEM”,”FullControl”,”Allow”)$idrsa = “~/.ssh/id_rsa”
$acl1 = Get-Acl $idrsa
$acl1.SetAccessRuleProtection($true, $false)
$acl1.SetAccessRule($userRule)
$acl1.SetAccessRule($systemRule)
$acl1 | Set-Acl$idrsapub = “~/.ssh/id_rsa.pub”
$acl2 = Get-Acl $idrsapub
$acl2.SetAccessRuleProtection($true, $false)
$acl2.SetAccessRule($userRule)
$acl2.SetAccessRule($systemRule)
$acl2 | Set-Acl
- Ensure those are the only two users:
Get-Acl “~/.ssh/id_rsa” | Format-ListGet-Acl “~/.ssh/id_rsa.pub” | Format-List
If you have more than SYSTEM and your username, go to the file and remove other users/groups.
- Remaining in PowerShell as the user but running as Administrator, start the authentication agent:
Start-Service ssh-agent
- Add the user account to the authentication agent:
ssh-add
- Start the
sshd
service:
Start-Service sshd
It should be working now. 👍
If you are still having issues, run:
FixHostFilePermissions.ps1
FixUserFilePermissions.ps1
Both of these scripts should be located in the OpenSSH installation folder, although you should be able to execute them from anywhere if it’s installed correctly. For me, that path is C:\Program Files\OpenSSH-Win64
.
After completing the above steps using this sshd_config file, I am able to log in using public key authentication.