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

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

To configure SSH public key-based authentication in OpenSSH for Windows Server, you 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.

For the sake of this post, and to have all steps complete, I've redone the steps here.

Extend the Active Directory Schema

First, as an administrator - I'm sure you are - start your PowerShell prompt, and execute the following command to create a new DWORD key Schema Update Allowed with value 1:

# on one line:# New-Itemproperty "HKLM:\SYSTEM\CurrentControlSet\Services\NTDS\Parameters"  -Name "Schema Update Allowed"  -Value "1"  -PropertyType DWORD  -Force

When in doubt you can always use the regedit.exe GUI, even on Windows Server Core. Or create a .reg file and silently import .reg file in your Windows registry. Otherwise the schema cannot be updated. Do this on the domain controller having the Schema master FSMO role (see netdom query fsmo).

Secondly, run regsvr32.exe C:\windows\system32\schmmgmt.dll to enable the Schema Editor snap-in for mmc.

regsvr32 schmmgmt.dll to enable the Schema Editor Snap-in. Schema Management DLL.
regsvr32 schmmgmt.dll to enable the Schema Editor Snap-in. Schema Management DLL.

Now if you run mmc from the (PowerShell) prompt you get the option to load the Active Directory Schema Snap-In in the Microsoft Management Console (MMC):

Load the Active Directory Schema Snap-In in Microsoft Management Console (MMC).
Load the Active Directory Schema Snap-In in Microsoft Management Console (MMC).
Active Directory Schema Snap-In is loaded and active in Microsoft Management Console (MMC).
Active Directory Schema Snap-In is loaded and active in Microsoft Management Console (MMC).

This is what you need to extend the Active Directory Schema.

The following steps might feel a bit tensive. Just keep calm. If you're not already, make sure you are an Schema Admin.

Add a new Attribute

You first need to create a new Attribute in your AD Schema. Follow these steps:

  1. Right click Attributes and click Create New Attribute
    • Click Continue if a warning titled "Schema Object Creation" appears.
  2. Create a New Attribute Object values:
    • Common Name: sshPublicKey
    • LDAP Display Name: sshPublicKey
    • Unique X500 Object ID: 1.3.6.1.4.1.24552.1.1.1.13
    • Syntax: select IA5-String
    • Minimum: can be left blank
    • Maximum: can be left blank
    • select Multi-Valued check box
Active Directory Schema new attribute object window and data
Active Directory Schema new attribute object window and data

Now you can create a class for the attribute.

Add a new Class

As with the schema attribute, follow the steps to create a new class.

  1. Right click Classes and select Create Class
    • Click Continue if a warning titled "Schema Object Creation" appears.
  2. Create New Schema Class values:
    • Common Name: ldapPublicKey
    • LDAP Display Name: ldapPublicKey
    • Unique X500 Object ID: 1.3.6.1.4.1.24552.500.1.1.2.0
    • Parent Class: top
    • Class Type: select Auxiliary
Create a new ldapPublicKey Schema Class in Active Directory
Create a new ldapPublicKey Schema Class in Active Directory
  1. Click Next
  2. Under Optional Add and Select sshPublicKey
Add sshPublicKey -attribute created earlier- as Optional to your Class
Add sshPublicKey -attribute created earlier- as Optional to your Class
  1. Click Finish

Associate class to user objects

The class ldapPublicKey you created and which has the attribute sshPublicKey you created, need to be associated with (a) user object(s). Follow these steps:

  1. Expand Classes, right click user and select Properties
  2. Click on the Relationship tab
    • click Add Class under Auxiliary Classes
    • select ldapPublicKey, click OK
    • click Apply
Add ldapPublicKey to AD Schema class user Properties
Add ldapPublicKey to AD Schema class user Properties
  1. click OK to close the window
  2. close MMC and other windows you may have open

Now you have your AD Schema extended. Let's added a SSH public key! Later on you'll need to reconfigure SSHD to look for a key in your Active Directory Schema.

Add SSH Public Key to Active Directory User properties

To manually add an SSH public key to a user's properties, start Active Directory Users and Computers. Make sure Advanced Features are enabled under View > Advanced Features.

Advanced Features enabled in Active Directory Users and Computers management GUI program
Advanced Features enabled in Active Directory Users and Computers management GUI program

Browse to the user for whom you want to add a public SSH key, and follow these steps:

  1. Right click the user
  2. select Properties
  3. select the tab Attribute Editor
  4. scroll down to the sshPublicKey attribute and click Edit
  5. paste the public key into Value to add field and click Add
  6. repeat for a second or third public key if necessary
ed25519 SSH public key added to user properties and sshPublicKey attribute
ed25519 SSH public key added to user properties and sshPublicKey attribute
  1. Close the windows.

Configure OpenSSH AuthorizedKeysCommand

You must have at least 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 %uAuthorizedKeysCommandUser "system"

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 at least this version.

Save the file and restart sshd:

Get-Service sshd | Restart-Service

AuthorizedKeysCommand PowerShell script to retrieve SSH public key

You need a script that runs an 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]$(([adsisearcher]"(&(objectClass=user)(sAMAccountName=${username}))").FindAll() | select -Property *).Properties.sshpublickey

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 Active Directory. The key that is found is retrieved and printed.

Test logging in using SSH keys

OK, you have:

  • extended your Active Directory Schema to add support for SSH public keys.
  • reconfigured sshd_config to support AuthorizedKeysCommandUser,
  • restarted sshd, and
  • created a tiny script to pull the public key from the User properties (sshPublicKey attribute)

Now it's time to test logging in. Ssh to your server and it should automatically log you in.

PS C:\Users\janreilink> ssh host.example.orgMicrosoft Windows [Version 10.0.17763.3650](c) 2018 Microsoft Corporation. All rights reserved.domain\janreilink@host E:\Users\janreilink>

This setup is particularly handy if you need to access a Windows Server over ssh from outside its AD domain, but still having a domain user.

Donate a cup of coffee
Donate a cup of coffee

Thank you very much! <3 ❤️

4 Comments

  1. ferrosenfeld

    `server refused our key.`
    Your script works if I run it from powershell console. I added respective lines to the sshd_config file in C:\Program Data\ssh\ directory. SSH service is running but whatever I do I get the `server refused our key.` Do you have any clue where I make the mistake ?

    • Thank you for your comment ferrosenfeld.

      99 out of 100 times it’s file permission issue, perhaps the service SSHD runs as doesn’t have the appropriate permissions on the PowerShell script. You can find out by stopping OpenSSHd and running it in debug mode on the command-line, see https://github.com/PowerShell/Win32-OpenSSH/wiki/Logging-Facilities#file-based-logging. This should give more details as to why authorization fails with “server refused our key.“. Keep me posted!

      PS: I noticed line breaks are missing in the scripts / code, I’ll try to fix that asap (or it’s a WP plugin issue).

  2. Zulgrib

    In this scenario, is “authorized_keys” file still evaluated if no keys are found in AD?

    If not, is it possible to evaluate it?

    • Hi Zulgrib,
      Thank you for your comment. You can always add an `AuthorizedKeysFile` directive to your `sshd_config` file.

Comments are closed