Long Article Warning! You can skip all this and go directly to the script at the end.
This resolves the dilemma of managing SSH public keys on servers that are integrated with Active Directory using PBIS-Open, it allows you to do the following:
- Password-less remote SSH access of users to servers, without any setup on the client side
- Centralized Management of the users’ SSH Public Keys on Servers through Active Directory
- Prevent saving of ssh public keys locally on servers
- Prevent unauthorized access through keys if the user’s AD account is disabled/locked/expired
- The user can still login to the servers using his AD account credentials as a second means of authentication, in case he hasn’t registered a public key or lost his private key
Prerequisites
- PBIS-Open to be installed and server joined to the Active Directory
- userusedtojoinAD credentials are stored encrypted inside /etc/krb5.keytab
sudo /opt/pbis/bin/ktutil add_entry -password -p userusedtojoinAD -k 1 -e aes256-cts-hmac-sha1-96 write_kt /etc/krb5.keytab
-
Changes to SSH Server
The following additions and changes need to be done on the SSH server configuration file found in /etc/ssh/sshd_config:
Attributes to be modified
AuthorizedKeysFile /dev/null #to disable looking up the keys on the local filesystem
Attributes to be added
AuthorizedKeysCommand /ad_pki_checker.sh #The file that the SSH server looks up at first to see if there are any corresponding public keys returned
AuthorizedKeysCommandUser root #The user used by the SSH server to execute the AuthorizedKeysCommand, must be root to be able to read from the keytab file.
Note: The SSH server needs to be restarted before the new settings take effect.
Where and how to add SSH Public Keys to AD
The user’s SSH Public key is saved in the AD attribute “altSecurityIdentities” in the form of:
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCstmuV8LOtWseiMO5nlSVr8Z9RQBGtKyx80PwMFmbyIrIKOY7+CoLAdABZi+ZGds9VLtnHaDunQilbyqJAOmPj1Dt4RMLn7UXhwACiWsukG2vLaend9CDakUls4d7q4jzD0sroDwXevaRgB/wPKmOiG/dEswo/eT+e1ToJQRA96sBIuVfieeqwqVyaqMLxCsl9ufH9KDRm0+9NGQMzuY/dHUjrsTJmMXGdVSrjpnHxY/xbYdqIYtFgiJDJNJzXPFskdiaAuvFD5j+iflRNr5CBEgoaifSOiSISOLCrUbblQLSx5XcDP7HVTHZOt0Q/SnIYMQujWyoA4h+6DoMAliFD
This can be performed using the powershell or any AD management tool:
As an administrative user, run the following:
set-aduser username -Add @{ altSecurityIdentities = "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCstmuV8LOtWseiMO5nlSVr8Z9RQBGtKyx80PwMFmbyIrIKOY7+CoLAdABZi+ZGds9VLtnHaDunQilbyqJAOmPj1Dt4RMLn7UXhwACiWsukG2vLaend9CDakUls4d7q4jzD0sroDwXevaRgB/wPKmOiG/dEswo/eT+e1ToJQRA96sBIuVfieeqwqVyaqMLxCsl9ufH9KDRm0+9NGQMzuY/dHUjrsTJmMXGdVSrjpnHxY/xbYdqIYtFgiJDJNJzXPFskdiaAuvFD5j+iflRNr5CBEgoaifSOiSISOLCrUbblQLSx5XcDP7HVTHZOt0Q/SnIYMQujWyoA4h+6DoMAliFD" }
Script
The script needs to be placed on a local filesystem, we will add it as /ad_pki_checker.sh, the owner should be root, and the permissions to be 755. The purpose of the this script is to retrieve the public key – if any – of the user trying to login. It will return either the public key or an empty result, in the latter case the user will have to authenticate with his AD credentials instead. The password is saved encrypted in /etc/krb5.keytab.
#!/bin/bash # This script is used for integrating PKI with AD /opt/pbis/bin/kinit -k userusedtojoinAD #produce a ticket for userusedtojoinAD whose credentials are saved encrypted inside /etc/krb5.keytab export username=$(echo $1 | sed 's@.*\\@@') #to remove the domain name and the backslash from the username entered, i.e. mydomain\ export validornot=`/opt/pbis/bin/adtool -a search-object --filter '(&(objectClass=user)(!(userAccountControl:1.2.840.113556.1.4.803:=2))(sAMAccountName='$username'))' -t` #If AD account has any status that prevents user from logging in, e.g. disabled, expired, locked...etc #validornot will be empty if the user is disabled/expired/locked, i.e. userAccountControl:1.2.840.113556.1.4.803:=2 If not, it will contain the AD user account details if [[ ! -z "${validornot// }" ]] #if the validornot contains some data, it will remove all empty spaces as well then echo $validornot | /opt/pbis/bin/adtool -a lookup-object --dn=- --attr=altSecurityIdentities #get the corresponding public key inside the altSecurityIdentities attribute fi
Hope it helps!
Enjoy!
Sources: A LOT! Almost all of the articles from stackoverflow talking about this topic and Thanks to all who helped me
Thanks a lot!
I also leave an ability for local users to use their auth_keys through Match User construct in a sshd_config.
LikeLike
You are absolutely welcome, for security reasons at my organization, we don’t allow local users for our end users.
LikeLike
Really nice post unfortunately I can not get it to work…
in the ssh logs I do see the following:
User “” authorized keys /dev/null is not a regular file
LikeLike
you mean for the AuthorizedKeysFile in the ssh config?
LikeLike
Yes If I change this line in the sshd_config:
AuthorizedKeysFile /dev/null
I get this error in the auth.log: User “” authorized keys /dev/null is not a regular file
Sorry for the late reply
LikeLike