Authentification par clé SSH avec LDAP

59

En bref:

Voudrait un moyen de faire l'authentification de clé SSH via LDAP.

Problème:

Nous utilisons LDAP (slapd) pour les services d'annuaire et nous sommes récemment passés à utiliser notre propre AMI pour la création d'instances. La raison pour laquelle le bit AMI est important est que, dans l' idéal , nous aimerions pouvoir nous connecter avec SSH via l'authentification de clé dès que l'instance est en cours d'exécution et ne pas avoir à attendre que notre outil de gestion de la configuration, un peu lent, lance un script à ajouter. les clés correctes à l'instance.

Le scénario idéal est que, lors de l'ajout d'un utilisateur à LDAP, nous ajoutions également sa clé et qu'il puisse immédiatement se connecter.

L'authentification par clé est indispensable car la connexion par mot de passe est à la fois moins sécurisée et gênante.

J'ai lu cette question qui suggère qu'il existe un correctif pour OpenSSH appelé OpenSSH-lpk pour le faire, mais que ce n'est plus nécessaire avec le serveur OpenSSH> = 6.2

Ajout d'une option sshd_config (5) AuthorizedKeysCommand pour prendre en charge la récupération de allowed_keys à partir d'une commande en plus (ou au lieu de) du système de fichiers. La commande est exécutée sous un compte spécifié par une option AuthorizedKeysCommandUser sshd_config (5).

Comment configurer OpenSSH et LDAP pour implémenter cela?

nous-même
la source

Réponses:

64

Mettre à jour LDAP pour inclure le schéma OpenSSH-LPK

Nous devons d’abord mettre à jour LDAP avec un schéma pour ajouter l’ sshPublicKeyattribut aux utilisateurs:

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 )
    )

Créez un script qui interroge LDAP sur la clé publique d'un utilisateur:

Le script doit générer les clés publiques de cet utilisateur, par exemple:

ldapsearch '(&(objectClass=posixAccount)(uid='"$1"'))' 'sshPublicKey' | sed -n '/^ /{H;d};/sshPublicKey:/x;$g;s/\n *//g;s/sshPublicKey: //gp'

Mettre sshd_configà jour pour pointer vers le script de l'étape précédente

  • AuthorizedKeysCommand /path/to/script
  • AuthorizedKeysCommandUser nobody

Bonus : mise sshd_configà jour pour permettre l'authentification par mot de passe à partir des réseaux internes RFC1918, comme indiqué dans cette question:

Autoriser l'authentification par mot de passe sur le serveur SSH à partir du réseau interne

Liens utiles:

EDIT: Utilisateur ajouté nobodycomme suggéré TRS-80

nous-même
la source
6
C'est fantastique, bien que je suggère AuthorizedKeysCommandUser nobodyau lieu de root.
TRS-80
Il doit y avoir quelque chose de différent dans ldapsearch ou dans sed, car transférer la sortie vers la commande sed noire que vous avez ne me donne aucune sortie, même si ma commande ldapsearch simple renvoie des données. Je vais devoir écrire un script pour nettoyer la sortie au lieu d'utiliser sed.
Chris L
1
Ignorer mon commentaire précédent. Mon problème était dû à la présence d'un retour à la ligne dans la propriété sshPublicKey, ce qui a pour conséquence que ldapsearch est codé en base64. J'ai simplifié la commande sed mais:ldapsearch -u -LLL -o ldif-wrap=no '(&(objectClass=posixAccount)(uid='"$1"'))' 'sshPublicKey' | sed -n 's/^[ \t]*sshPublicKey:[ \t]*\(.*\)/\1/p'
Chris L
1
@Chris est certes moins une magie noire, mais sed est toujours une fonction de hachage à écriture unique, à sens unique;)
Froyke
1
Sur ma version d'OpenSSH (5.3p1-122.el6) il y a AuthorizedKeysCommandRunAset pasAuthorizedKeysCommandUser
mveroone le
5

Pour toute personne rencontrant l'erreur lors de l'exécution de ldapsearch:

sed: 1: "/^ /{H;d};": extra characters at the end of d command

comme j'étais (sur FreeBSD), la solution consiste à changer la première commande sed en:

/^ /{H;d;};

(ajout d'un point-virgule après le «d»).

Scott
la source
4

Je voulais juste partager ma "méthode", mon côté client est spécifique à Debian / Ubuntu, mais mon côté serveur est fondamentalement le même que ci-dessus, mais avec un peu plus de "HowTo:"

Serveur:

Activer l'attribut de clé publique:

Crédit :

https://blog.shichao.io/2015/04/17/setup_openldap_server_with_openssh_lpk_on_ubuntu.html

cat << EOL >~/openssh-lpk.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 )
  )
EOL

Maintenant, utilisez ceci pour ajouter ldif:

ldapadd -Y EXTERNAL -H ldapi:/// -f ~/openssh-lpk.ldif

Ajouter un utilisateur avec une clé publique SSH dans phpLDAPadmin

Tout d’abord, créez un utilisateur avec le modèle «Generic: User Account». Ensuite, allez à la section attribut «objectClass», cliquez sur «ajouter une valeur», puis choisissez l’attribut «ldapPublicKey». Une fois que vous avez envoyé, retournez à la page de modification de l'utilisateur, cliquez sur «Ajouter un nouvel attribut» dans la partie supérieure, choisissez «sshPublicKey», collez la clé publique dans la zone de texte, puis cliquez sur «Mettre à jour un objet». "

sshPublicKey Attribut non affiché - OpenLDAP PHPLDAP SSH Key Auth

Client Ubuntu:

apt-get -y install python-pip python-ldap
pip install ssh-ldap-pubkey
sh -c 'echo "AuthorizedKeysCommand /usr/local/bin/ssh-ldap-pubkey-wrapper\nAuthorizedKeysCommandUser nobody" >> /etc/ssh/sshd_config' && service ssh restart

Créer des clés de test:

ssh-keygen -t rsa
FreeSoftwareServers
la source
3

Ce n'est pas une réponse complète, juste un ajout à la réponse de c4urself . J'aurais ajouté ceci comme commentaire, mais je n'ai pas assez de réputation pour commenter, alors s'il vous plaît, ne votez pas!

C'est le script que j'utilise pour le AuthorizedKeysCommand(basé sur la version de c4urself). Cela fonctionne que la valeur soit renvoyée en encodage base64 ou non. Cela peut être particulièrement utile si vous souhaitez stocker plusieurs clés autorisées dans LDAP. Il suffit simplement de séparer les clés avec des caractères de nouvelle ligne, similaires au fichier allowed_keys.

#!/bin/bash
set -eou pipefail
IFS=$'\n\t'

result=$(ldapsearch '(&(objectClass=posixAccount)(uid='"$1"'))' 'sshPublicKey')
attrLine=$(echo "$result" | sed -n '/^ /{H;d};/sshPublicKey:/x;$g;s/\n *//g;/sshPublicKey:/p')

if [[ "$attrLine" == sshPublicKey::* ]]; then
  echo "$attrLine" | sed 's/sshPublicKey:: //' | base64 -d
elif [[ "$attrLine" == sshPublicKey:* ]]; then
  echo "$attrLine" | sed 's/sshPublicKey: //'
else
  exit 1
fi
mbrgm
la source