Skip to main content

SSH Authentication via LDAP

·4 mins

So you got an OpenLDAP server running? Great! Now you want to connect it to as many systems as possible to ease the burden of managing users and authorization. However, you also want to allow SSH key authorisation managed via a central place. Can LDAP be used for this? This article will help you get started to set this up in your organisation.

LDAP Changes #

LDAP allows you to extend data you can enter using a schema. For convenience, you can use the schema listed below.

dn: cn=techwolf12,cn=schema,cn=config
objectClass: olcSchemaConfig
cn: techwolf12
olcAttributeTypes: {0}( 1.3.6.1.4.1.52389.2.1 NAME 'gpgFingerprint' DESC 'MA
 NDATORY: GnuPG Public key' EQUALITY caseExactIA5Match SYNTAX 1.3.6.1.4.1.14
 66.115.121.1.26 )
olcAttributeTypes: {1}( 1.3.6.1.4.1.52389.2.2  NAME 'sshPublicKey' DESC 'MAN
 DATORY: OpenSSH Public key' EQUALITY octetStringMatch SYNTAX 1.3.6.1.4.1.14
 66.115.121.1.40 )
olcAttributeTypes: {2}( 1.3.6.1.4.1.52389.2.5 NAME 'twoFactorPublic' DESC 'M
 ANDATORY: 2FA Public key' EQUALITY caseExactIA5Match SYNTAX 1.3.6.1.4.1.146
 6.115.121.1.26 )
olcAttributeTypes: {3}( 1.3.6.1.4.1.52389.2.6 NAME 'phoneExtNumber' DESC 'In
 ternal PBX extension' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
olcAttributeTypes: {4}( 1.3.6.1.4.1.52389.2.7 NAME 'sshHostAllow' DESC 'Opti
 onal: Allow access to specific ssh hosts' EQUALITY caseExactIA5Match SYNTAX
  1.3.6.1.4.1.1466.115.121.1.26 )
olcAttributeTypes: {5}( 1.3.6.1.4.1.52389.2.8 NAME 'sshHostDeny' DESC 'Optio
 nal: Denies access to specific ssh hosts' EQUALITY caseExactIA5Match SYNTAX
  1.3.6.1.4.1.1466.115.121.1.26 )
olcAttributeTypes: {6}( 1.3.6.1.4.1.52389.2.9 NAME 'userPinCode' DESC 'Optio
 nal: user pincode for quick identification' EQUALITY integerMatch ORDERING 
 integerOrderingMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
olcObjectClasses: {0}( 1.3.6.1.4.1.52389.1.1 NAME 'sshUser' SUP top AU
 XILIARY DESC 'MANDATORY: Cryptography objectclass' MAY ( sshPublicKey $ gpg
 Fingerprint $ twoFactorPublic $ sshHostAllow $ sshHostDeny $ phoneExtNumber $ userPinCode ) )

Creating a group #

To properly use ssh key authentication you need to assign all ssh users to a group so they can be filtered out. If you don’t do this, key authentication for users without LDAP will no longer work.

dn: cn=sshldapuser,dc=example,dc=com
objectClass: posixGroup
objectClass: top
cn: sshldapuser
gidNumber: 10000
description: SSH users from LDAP
memberUid: techwolf12

Setting up a user #

Create a user like this. Please keep in mind that the sshPublicKey value is in Hex format.

dn: uid=techwolf12,ou=example-ou,dc=example,dc=com
objectClass: inetOrgPerson
objectClass: sshUser
objectClass: organizationalPerson
objectClass: person
objectClass: posixAccount
objectClass: shadowAccount
objectClass: top
cn: Christiaan de Die le Clercq
gidNumber: 10000
homeDirectory: /home/techwolf12
sn: de Die le Clercq
uid: techwolf12
uidNumber: 10000
givenName: Christiaan
gpgFingerprint: 34B35DD172E366BF6867AB069FB800372F2546D8
loginShell: /bin/bash
mail: [email protected]
sambaNTPassword: 3BE81268C8E07E150DDF53D6AEE4E0B6
sshPublicKey:: c3NoLXJzYSBBQUFBQjNOemFDMXljMkVBQUFBREFRQUJBQUFCQVFET0VnQzJ2b
 HlBMzZ1MVNVUkZVS3hYaEdwZHA2c3ViUU10QU01MmV4bldhR0dkdURLZDNwOU9hb0x4cnB4eUtX
 bzdidGhBWHNRL045N0dETTY0bEIwZStTdkpLdCtrVGllcUZiQ3A3STB2V25zSnZJRWl3WmRjY0d
 zOU42bnRqU0xUbUl4MFdkaG4vMWF3eENId1FxTHpjYS9yM2w1cnVDRkwzR1FKU3JoeDNNMFdBT0
 Q2Yk5OdFQxT0ZDci9tcDhjVGJiYVdTbEhpajJHbjBPak1RWUpmWEpMNWs3QWJwaWJyMUdCN1V3M
 0prNXUwazUvdGRNc2twUVZZRFlkaEhRalBJZ3IrREw5ek4wUkpkaWNNLzRRQnl0aGtFYjhRNWs0
 Q0U1Vk9PM2VDWXVwYjdrYStLNkJ5dldLemVIL2REdDMvSDRIYVBTOW1JZytXamVKT3NuUTkgUHJ
 pbWFyeQ==
userPassword:: e1NTSEF9eWdsY1FYci9zR25Wem84WmtydFNjeHhDWjdEZjBMVHM4RjErWlE9P
 Q==

Server changes #

On the server which you want to have LDAP users login, you need to make a few changes to allow LDAP to be used. In this case, we assume a Debian 9 based server to be used.

The first step is to install some dependencies and packages like so:

apt install libnss-ldap libpam-ldap nscd ldap-utils

For Debian 11, use this:

apt install libnss-ldapd libpam-ldap nscd ldap-utils

After this is done, you need to create a couple of configuration files and scripts to connect to LDAP.

Create the file /etc/ldap/ldap.conf with the following content:

uri ldap://ldap.example.com/

base dc=example,dc=com

binddn uid=binduser,dc=example,dc=com
bindpw BINDPASSWORD
ssl start_tls
bind_timelimit 2
network_timeout 2
timeout 2
bind_policy soft
tls_cacertdir /etc/ssl/certs
TLS_REQCERT allow

Create the file with /etc/libnss-ldap.conf with the following content, change the values to yours:

base dc=example,dc=com

uri ldap://ldap.example.com
ldap_version 3

binddn uid=binduser,dc=example,dc=com
bindpw BINDPASSWORD

ssl start_tls

tls_checkpeer no
tls_cacertdir /etc/ssl/certs

Create a bash file (somewhere like /opt/ldap-sshkey.sh):

#!/bin/bash

/usr/bin/ldapsearch -H 'ldap://ldap.example.com' -LLL -b "ou=example-ou,dc=example,dc=com" -ZZ -D "uid=binduser,dc=example,dc=com" -w 'BINDPASSWORD' -o ldif-wrap=no uid=\$1 | /bin/grep sshPublicKey: | cut -d" " -f 2-4

Add the following to /etc/ssh/sshd_config to allow users to login with ssh-keys:

Match group sshldapuser
  AuthorizedKeysCommand /opt/ldap-sshkey.sh %u
  AuthorizedKeysCommandUser nobody

Finally, execute the following commands for the final setup, activation of LDAP in the system and auto creation of the users home directory on the first login:

rm /etc/pam_ldap.conf && ln -s /etc/ldap/ldap.conf /etc/pam_ldap.conf
chmod 755 /opt/ldap-sshkey.sh

sed -i.bak 's#compat#compat ldap#g' /etc/nsswitch.conf
service nscd restart
echo "session	 required	 pam_mkhomedir.so" >> /etc/pam.d/common-session
service ssh restart

You should now have your ssh users from LDAP and they should be able to login via SSH keys stored in LDAP. If there are any questions, feel free to contact me!