Retrieve SSH public key from Active Directory for SSH authentication

How to configure SSH public key authentication for Windows Server in Active Directory (AD)?

If you want to be able to log on to your Windows Servers through Win32 OpenSSH, you can make use of SSH public key authentication through a ~/.ssh/authorized_keys file. But if you have tens (hundreds) of servers and/or users, perhaps it’s easier to retrieve SSH public keys from Active Directory (AD). In this article I’ll explain how.

First you need to extend your AD schema to allow for the storage of public keys. Just follow the great steps Ted Salmon posted at Storing SSH keys in Active Directory for easy deployment. It doesn’t really matter if you name your attribute sshPublicKey or sshPublicKeys. When adding public keys, you may leave out the IP address part (which is in the last screenshot). One of these days I’ll have to perform these steps in my third environment, I’ll recreate the screenshots for extending the AD Schema.

Now you have your AD Schema extended, and added a SSH public key, you need to reconfigure SSHD to look for a key in AD.

Note: you must have OpenSSH 8.6.0.0p1-Beta for AuthorizedKeysCommand support.

Open up the sshd_config_default file. It’s location may differ, for me it’s in the directory where I installed OpenSSH in Windows Server. Add the following to that file:

AuthorizedKeysCommand C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe -NoProfile -NonInteractive -File "c:\path\to\openssh\get-publickey.ps1" -username %u AuthorizedKeysCommandUser "system"
Code language: Nginx (nginx)

Here, AuthorizedKeysCommand is the script sshd executes to retrieve the public key. More on this file later. The AuthorizedKeysCommandUser has to be set to System. This is fixed in 8.6.0, hence why you need this version.

Save the file and restart sshd:

Get-Service sshd | Restart-Service
Code language: PowerShell (powershell)

AuthorizedKeysCommand PowerShell script to retrieve ssh public key

You need a script that runs as AuthorizedKeysCommand to retrieve the public key from the user’s Active Directory sshPublicKeys property. For this, I use PowerShell, you may use something completely different.

[CmdletBinding()] Param( [Parameter(Mandatory = $true, Position = 0)] [string]$username ) $username = $username.Split("\")[1] write-host -nonewline (([adsisearcher]"(&(objectClass=user)(sAMAccountName=${username}))").FindAll() | select -Property *).Properties.sshpublickeys
Code language: PowerShell (powershell)

I chose to use adsisearcher because not all servers have the ActiveDirectory PowerShell module available that is required for Get-ADUser. In my scenario, the username that tries to authenticate is “domain\user”, so I split the username to lookup the username part in AD. The key that is found is retrieved and printed. For this Write-Host’s -NoNewLine is important.

This set up is particularly handy if you need to access a Windows Server over ssh from outside its AD domain.

Note: I believe this only works with one public key per user, but haven’t tested this.

Sharing is caring
Show Buttons
Hide Buttons