Outils pour utilisateurs

Outils du site


ateliers:serveurmail:ldap-ssh

SSH et LDAP

Pourquoi ?

On peut stocker les clefs SSH dans un arbre LDAP (à condition d'activer un schéma). À quoi cela sert-il ? Cela permet de n'avoir à copier la clef SSH qu'à un seul endroit pour pouvoir se connecter à toute les machines utilisant notre arbre ldap.

Cela permet aussi, lors de la suppression d'une utilisatrice, de supprimer également ses clefs de tous les serveurs. Plus besoin de s'embêter avec une maintenance te une synchronisation manuelle hasardeuse.

De même, en cas de perte de la clef, on peut supprimer celle-ci du serveur en attendant que l'utilisatrice nous fournisse une nouvelle clef. Bref, c'est le bien.

Ajout d'un schéma

On commence donc par ajouter un schéma à LDAP, vu que dans nos schémas précédemment installé, il n'y a pas de champs utilisable pour stocker une clef publique SSH.

Avant que la gestion des clefs ne soit externalisable par sshd, il y avait un patch pour openssh (openssh-ltk) qui implémentait cette fonctionnalité. Depuis openssh permet de récupérer la clef un peu comme on veut, le patch est devenu obsolète.

Mais le schéma fournit est toujours valide. Il suffit de le récupérer et de l'ajouter à la base cn=config. Si vous avez la même configuration d'ACL que nous, n'importe quel utilisateur du groupe cn=sudo peut le faire.

/usr/local/lib/ldap/schema/openssh-ltk.ldif
dn: cn=openssh-lpk,cn=schema,cn=config
objectClass: olcSchemaConfig
cn: openssh-lpk
olcAttributeTypes: ( 1.3.6.1.4.1.24552.500.1.1.1.13 NAME 'sshPublicKey'
    DESC 'MANDATORY: OpenSSH Public key'
    EQUALITY octetStringMatch
    SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 )
olcObjectClasses: ( 1.3.6.1.4.1.24552.500.1.1.2.0 NAME 'ldapPublicKey' SUP top AUXILIARY
    DESC 'MANDATORY: OpenSSH LPK objectclass'
    MAY ( sshPublicKey $ uid )
    )

Le schéma est relativement simple, il fournit une objectClass structurelle qui s'appelle ldapPublicKey et à laquelle est ajouté un champ sshPublicKey (et uid si, par exemple, on ne veut pas stocker les utilisateurs, ou associer une clef à autre chose).

$ ldapadd -xWD "uid=okhin,ou=Users,dc=anarcha,dc=pink" -f /usr/local/lib/ldap/schema/openssh-ltk.ldif

Configuration de sshd

Ensuite on modifie la configuration d'openSSHd afin de lui dire comment récupérer la clef. On en profite pour activer l'identification par clef publique.

/etc/ssh/sshd_config
[...]
PubkeyAuthentication yes
 
AuthorizedKeysCommand /usr/sbin/sshldapkey.sh
AuthorizedKeysCommandUser nobody
[...]

On dit donc à SSHD d'exécuter une commande en tant que nobody pour récupérer la clef d'un utilisateur (qui est passé en premier argument de la commande).

On mets la commande dans /usr/sbin et non dans /usr/local/sbin car openSSH veut que toute l'arborescence amenant au script soit possédée par root et interdise l'accès en écriture au reste du monde.

Le script sshldapkey.sh

Il s'agît d'un micro script qui va essentiellement effectuer une recherche en bind anonyme. Il serait parfaitement possible d'imaginer un bind différent, du moment que la commande peut lire le champ sshPublicKey tout devrait fonctionner.

Le script fait un usage de sed pour concaténer toutes les chaînes trouvées dans le retour de la commande ldapsearch. Il a été récupéré dans la réponse sur ServerFault et légèrement adapté.

/usr/sbin/sshldapkey.sh
#!/bin/bash
export LDAP_BASE="ou=Users,dc=anarcha,dc=pink"
/usr/bin/ldapsearch -xb $LDAP_BASE '(&(objectClass=posixAccount)(uid='"$1"'))' 'sshPublicKey' | sed -n '/^ /{H;d};/sshPublicKey:/x;$g;s/\n *//g;s/sshPublicKey: //gp'

On donne les droits d'exécution pour tout le monde à ce script et on relance le daemon sshd. Oui, on peut maintenant le faire à distance, sans perdre son accès à la machine.

$ sudo systemctl restart sshd
$ sudo systemctl status sshd
 ● ssh.service - OpenBSD Secure Shell server
  Loaded: loaded (/lib/systemd/system/ssh.service; enabled; vendor preset: enabled)
  Active: active (running) since Thu 2018-06-28 20:18:13 CEST; 3min 34s ago
 Process: 27037 ExecReload=/bin/kill -HUP $MAINPID (code=exited, status=0/SUCCESS)
 Process: 27035 ExecReload=/usr/sbin/sshd -t (code=exited, status=0/SUCCESS)
 Process: 27243 ExecStartPre=/usr/sbin/sshd -t (code=exited, status=0/SUCCESS)
Main PID: 27247 (sshd)
   Tasks: 1 (limit: 4915)
  CGroup: /system.slice/ssh.service
          └─27247 /usr/sbin/sshd -D

Ajout de la clef SSH à l'utilisateur

On ajoute donc maintenant la clef SSH publique de l'utilisateur à son entrée LDAP.

$ ldapmodify -xWD "uid=okhin,ou=Users,dc=anarcha,dc=pink"
cn: uid=okhin.ou=Groups,dc=anarcha,dc=pink
changetype: modify
add: ldapPublicKey
 
cn: uid=okhin,ou=Groups,dc=anarcha,dc=pink
changetype: modify
add: sshPublicKey
sshPublicKey: ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCthBqTu/AN3CwdNsjtsgJvDKTAEa/kHnnynTu403FwsS7TEafAVOJ57D50nZ+ORZ1r92rUo/Q/oX8SrUTDadyb3Edmb865+ipLaJLn+JpWEd0E8TSIoAfZli6jxULCu9DZZjatW6UjHVSaoNv2REiP7lb1cQ+CKPO0p6//A6gVcpJyo9OAHgYvlth2sgMdICYs1uk4qwpnMLg7YeYsdYIRqwokSlP6HK1e9djPzSt59UehihMNH42aPMMxdAO/LrPNjwX/582aJ/unZxCrq/AgOZwo+klFJoQ0OX3TKpT966jySMMN4hok1qsKWQ3NKEe1kXSTQkSUP8HUInqiHzeR okhin@willow

Le contenu de la clef doit être insérée sans retour à la ligne ou espaces. A partir de là, si l'utilisateur okhin se connecte sur le serveur, celui ci ira récupéré la valeur de sa clef SSH sur l'annuaire LDAP. Il est d'ailleurs possible d'avoir plusieurs sshPublicKey associée à un seul compte.

Contrôle de droits d'accès

Faites un tour dans vos ACL pour déterminer qui peut modifier et/ou lire la clef publique, après tout, il ne faudrait pas que n'importe qui puisse modifier les données. EN s'inspirant des ACL sur le userPassword, on peut ajouter une ACL de ce type là:

olcAccess: {2}to attrs=sshPublicKey
  by self write
  by * read

Nous insérons cette ACL en deuxième position, pensez à l'adapter en fonction de votre configuration.

ateliers/serveurmail/ldap-ssh.txt · Dernière modification : 2018/06/28 20:33 de okhin