Autenticazione con chiave SSH tramite LDAP


59

In breve:

Vorrebbe un modo per eseguire l'autenticazione con chiave SSH tramite LDAP.

Problema:

Utilizziamo LDAP (slapd) per i servizi di directory e recentemente ci siamo spostati sull'utilizzo del nostro AMI per la creazione di istanze. Il motivo per cui il bit AMI è importante è che, idealmente , vorremmo essere in grado di accedere con SSH tramite l'autenticazione con chiave non appena l'istanza è in esecuzione e non dobbiamo aspettare che il nostro strumento di gestione della configurazione un po 'lento inizi uno script da aggiungere le chiavi corrette per l'istanza.

Lo scenario ideale è che, quando si aggiunge un utente a LDAP, aggiungiamo anche la loro chiave e sarebbero immediatamente in grado di accedere.

L'autenticazione con chiave è un must perché l'accesso basato su password è sia meno sicuro che fastidioso.

Ho letto questa domanda che suggerisce che esiste una patch per OpenSSH chiamata OpenSSH-lpk per farlo, ma questo non è più necessario con il server OpenSSH> = 6.2

Aggiunta un'opzione sshd_config (5) AuthorizedKeysCommand per supportare il recupero di authorized_keys da un comando in aggiunta a (o invece di) dal filesystem. Il comando viene eseguito con un account specificato da un'opzione AuthorizedKeysCommandUser sshd_config (5)

Come posso configurare OpenSSH e LDAP per implementarlo?

Risposte:


64

Aggiorna LDAP per includere lo schema OpenSSH-LPK

Per prima cosa dobbiamo aggiornare LDAP con uno schema per aggiungere l' sshPublicKeyattributo per gli utenti:

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

Crea uno script che richiede LDAP per la chiave pubblica di un utente:

Lo script dovrebbe generare le chiavi pubbliche per quell'utente, ad esempio:

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

Aggiorna sshd_configper puntare allo script dal passaggio precedente

  • AuthorizedKeysCommand /path/to/script
  • AuthorizedKeysCommandUser nobody

Bonus : aggiornamento sshd_configper consentire l'autenticazione della password dalle reti RFC1918 interne come mostrato in questa domanda:

Consentire l'autenticazione della password solo al server SSH dalla rete interna

Link utili:

EDIT: Aggiunto l'utente nobodycome suggerito TRS-80


6
Questo è fantastico, anche se suggerirei AuthorizedKeysCommandUser nobodyinvece di root.
TRS-80,

Deve esserci qualcosa di diverso nel mio ldapsearch o nel sed perché il piping dell'output al comando sed black magic che hai lì non mi dà alcun output, anche se il mio semplice comando ldapsearch sta restituendo dati. Dovrò scrivere uno script per pulire l'output invece di usare sed.
Chris L,

1
Ignora il mio commento precedente. Il mio problema era causato dall'avere una nuova riga finale nella proprietà sshPublicKey, che a sua volta fa sì che ldapsearch a base64 codifichi l'intera cosa. Ho semplificato il comando sed anche se: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 effetti meno magia nera, ma sed è ancora una funzione di hashing a una via di scrittura una volta;)
Froyke

1
Sulla mia versione di OpenSSH (5.3p1-122.el6) c'è AuthorizedKeysCommandRunAse nonAuthorizedKeysCommandUser
mveroone il

5

Per chiunque riceva l'errore durante l'esecuzione di ldapsearch:

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

come ero (su FreeBSD), la soluzione è cambiare il primo comando sed in:

/^ /{H;d;};

(aggiungendo un punto e virgola dopo la 'd').


4

Volevo solo condividere il mio "metodo", il mio lato client è specifico di Debian / Ubuntu, ma il mio lato server è sostanzialmente lo stesso di sopra, ma con un po 'più di "HowTo:"

Server :

Abilita attributo chiave pubblica:

Credito:

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

Ora usa questo per aggiungere ldif:

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

Aggiunta di un utente con chiave pubblica SSH in phpLDAPadmin

Innanzitutto, crea un utente con il modello "Generico: account utente". Quindi, vai alla sezione dell'attributo "objectClass", fai clic su "aggiungi valore" e scegli l'attributo "ldapPublicKey". Dopo l'invio, torna alla pagina di modifica dell'utente, fai clic su "Aggiungi nuovo attributo" nella parte superiore e scegli "sshPublicKey", incolla la chiave pubblica nell'area di testo e infine fai clic su "Aggiorna oggetto". "

Attributo sshPublicKey non visualizzato - Chiave SSH PHPLDAP OpenLDAP 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

Crea chiavi di prova:

ssh-keygen -t rsa

3

Questa non è una risposta completa, ma solo un'aggiunta alla risposta di c4urself . Avrei aggiunto questo come commento, ma non ho una reputazione sufficiente per commentare, quindi per favore non sottovalutare!

Questo è lo script che sto usando per AuthorizedKeysCommand(basato sulla versione di c4urself). Funziona indipendentemente dal fatto che il valore sia restituito o meno nella codifica base64. Ciò può essere particolarmente utile se si desidera memorizzare più chiavi autorizzate in LDAP: separare semplicemente le chiavi con caratteri di nuova riga, in modo simile al file 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
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.