SSH-Schlüsselauthentifizierung über LDAP


59

Zusamenfassend:

Möchte eine Möglichkeit zur SSH-Schlüsselauthentifizierung über LDAP.

Problem:

Wir verwenden LDAP (slapd) für Verzeichnisdienste und verwenden seit kurzem unser eigenes AMI zum Erstellen von Instanzen. Der Grund, warum das AMI-Bit wichtig ist, ist, dass wir uns im Idealfall mit SSH über die Schlüsselauthentifizierung anmelden möchten, sobald die Instanz ausgeführt wird, und nicht warten müssen, bis unser etwas langsames Konfigurationsverwaltungstool ein Skript zum Hinzufügen startet die richtigen Schlüssel zur Instanz.

Das ideale Szenario ist, dass beim Hinzufügen eines Benutzers zu LDAP auch dessen Schlüssel hinzugefügt wird und dieser sich sofort anmelden kann.

Die Schlüsselauthentifizierung ist ein Muss, da die kennwortbasierte Anmeldung weniger sicher und lästig ist.

Ich habe diese Frage gelesen , die darauf hindeutet, dass es für OpenSSH einen Patch namens OpenSSH-lpk gibt, der für OpenSSH-Server> = 6.2 nicht mehr benötigt wird

Die sshd_config (5) -Option AuthorizedKeysCommand wurde hinzugefügt, um das Abrufen von authorized_keys von einem Befehl zusätzlich zu (oder anstelle von) aus dem Dateisystem zu unterstützen. Der Befehl wird unter einem Konto ausgeführt, das von einer AuthorizedKeysCommandUser-Option sshd_config (5) angegeben wird

Wie kann ich OpenSSH und LDAP konfigurieren, um dies zu implementieren?

Antworten:


64

Aktualisieren Sie LDAP, um das OpenSSH-LPK-Schema einzuschließen

Wir müssen zuerst LDAP mit einem Schema aktualisieren, um das sshPublicKeyAttribut für Benutzer hinzuzufügen :

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

Erstellen Sie ein Skript, das LDAP nach dem öffentlichen Schlüssel eines Benutzers abfragt:

Das Skript sollte die öffentlichen Schlüssel für diesen Benutzer ausgeben. Beispiel:

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

Aktualisieren Sie sshd_config, um auf das Skript aus dem vorherigen Schritt zu verweisen

  • AuthorizedKeysCommand /path/to/script
  • AuthorizedKeysCommandUser nobody

Bonus : Update sshd_config, um die Kennwortauthentifizierung aus internen RFC1918-Netzwerken zuzulassen, wie in dieser Frage dargestellt:

Ermöglichen Sie nur die Kennwortauthentifizierung gegenüber dem SSH-Server über das interne Netzwerk

Nützliche Links:

BEARBEITEN: Benutzer nobodywie vorgeschlagen TRS-80 hinzugefügt


6
Das ist fantastisch, obwohl ich AuthorizedKeysCommandUser nobodyanstelle von root vorschlagen würde .
TRS-80,

Entweder bei ldapsearch oder sed muss sich etwas ändern, da das Weiterleiten der Ausgabe an den dort vorhandenen Befehl sed black magic keine Ausgabe liefert, obwohl mein einfacher Befehl ldapsearch Daten zurückgibt. Ich werde ein Skript schreiben müssen, um die Ausgabe zu bereinigen, anstatt sed zu verwenden.
Chris L

1
Ignoriere meinen vorherigen Kommentar. Mein Problem wurde dadurch verursacht, dass die sshPublicKey -Eigenschaft eine nachgestellte Newline enthält, wodurch ldapsearch veranlasst wird, das Ganze mit base64 zu codieren. Ich habe den sed Befehl vereinfacht um:ldapsearch -u -LLL -o ldif-wrap=no '(&(objectClass=posixAccount)(uid='"$1"'))' 'sshPublicKey' | sed -n 's/^[ \t]*sshPublicKey:[ \t]*\(.*\)/\1/p'
Chris L

1
@ Chris in der Tat weniger schwarze Magie, aber sed ist immer noch eine einmalige, 1-Wege-Hashing-Funktion;)
Froyke

1
Auf meiner Version von OpenSSH (5.3p1-122.el6) gibt es AuthorizedKeysCommandRunAsund nichtAuthorizedKeysCommandUser
mveroone

5

Für alle, die den Fehler beim Ausführen von ldapsearch erhalten:

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

wie ich es war (unter FreeBSD), besteht die Korrektur darin, den ersten sed-Befehl zu ändern:

/^ /{H;d;};

(Hinzufügen eines Semikolons nach dem 'd').


4

Ich wollte nur meine "Methode" teilen, meine Client-Seite ist Debian / Ubuntu-spezifisch, aber meine Server-Seite ist im Grunde die gleiche wie oben, aber mit etwas mehr "HowTo:"

Server:

Attribut für öffentlichen Schlüssel aktivieren:

Gutschrift:

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

Nun benutze dies, um ldif hinzuzufügen:

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

Hinzufügen eines Benutzers mit einem öffentlichen SSH-Schlüssel in phpLDAPadmin

Erstellen Sie zunächst einen Benutzer mit der Vorlage "Allgemein: Benutzerkonto". Wechseln Sie dann zum Attributabschnitt "objectClass", klicken Sie auf "Wert hinzufügen" und wählen Sie das Attribut "ldapPublicKey" aus. Nach dem Absenden kehren Sie zur Benutzer-Bearbeitungsseite zurück, klicken Sie auf "Neues Attribut hinzufügen" im oberen Bereich und wählen Sie "sshPublicKey", fügen Sie den öffentlichen Schlüssel in den Textbereich ein und klicken Sie schließlich auf "Objekt aktualisieren". "

sshPublicKey Attribut wird nicht angezeigt - OpenLDAP PHPLDAP SSH Key Auth

Ubuntu Client:

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

Testschlüssel erstellen:

ssh-keygen -t rsa

3

Dies ist keine vollständige Antwort, sondern nur eine Ergänzung der Antwort von c4urself . Ich hätte dies als Kommentar hinzugefügt, aber ich habe keinen ausreichenden Ruf, um einen Kommentar abzugeben. Bitte stimmen Sie nicht ab!

Dies ist das Skript, das ich für das verwende AuthorizedKeysCommand(basierend auf der Version von c4urself). Es funktioniert unabhängig davon, ob der Wert in Base64-Codierung zurückgegeben wird oder nicht. Dies kann besonders nützlich sein, wenn Sie mehrere autorisierte Schlüssel in LDAP speichern möchten - trennen Sie die Schlüssel einfach mit Zeilenumbrüchen, ähnlich wie in der Datei authorized_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
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.