Table of Contents

LDAP con slapd 2.4.23

Gli appunti LDAP sono relativi a Debian Lenny, che installa slapd 2.4.11. Con Debian Squeeze viene fornito slapd 2.4.23: la logica della configurazione rimane sostanzialmente invariata, cambia invece il metodo predefinito di salvare la configurazione.

Al posto del tradizionale file di configurazione /etc/ldap/slapd.conf adesso esiste la directory /etc/ldap/slapd.d/ che contiene la configurazione sotto forma di numerosi file in formato LDIF, secondo l'impostazione gerarchica dei nodi. La configurazione è disponibile come oggetto LDAP e corrisponde al nodo che ha come distinguished name cn=config.

slapd usa un backend speciale per memorizzare questo nodo e lo identifica con il nome config. Ne può esistere uno solo e viene istanziato automaticamente anche se non viene definito esplicitamente.

In generale il contenuto del database cn=config viene modificato a runtime tramite snippet di file LDIF caricati con il comando ldapmodify. Le modifiche effettuate a runtime vengono salvate automaticamente nella directory /etc/ldap/slapd.d/, ma bisogna fermare il servizio slapd per essere sicuri che tutte le modifiche siano state salvate. Quando il servizio è fermo è anche possibile intervenire manualmente sui file .ldif.

Ecco un esempio di come interrogare il nodo cn=config con ldapsearch:

ldapsearch -LLLQY EXTERNAL -H ldapi:/// -b cn=config "(|(olcDatabase={1}hdb)(cn=module{0}))"

Nell'esempio l'accesso avviene tramite Unix-domain socket (ldapi) e meccanismo di autenticazione SASL EXTERNAL (?).

Debug

Si imposta con l'attributo olcLogLevel del nodo cn=config (/etc/ldap/slapd.d/cn=config.ldif, da editare a servizio fermo).

Vedere loglevel in man slapd.conf. Il valore predefinito stats è fin troppo prolisso, su un sistema in produzione conviene il valore none

olcLogLevel: none

Inizializzazione o restore di un database

Nell'installazione predefinita il database #1 viene definito nel file /etc/ldap/slapd.d/cn=config/olcDatabase={1}hdb.ldif, il contenuto vero e proprio (in formato Berkeley DB) è invece in /var/lib/ldap/.

Per recuperare o inizializzare il contenuto del database (ad esempio facendo il restore di un precedente slapcat) è sufficiente eseguire questa procedura basata su slapadd (aggiustare il suffix del database in cui fare il restore):

/etc/init.d/slapd stop
slapadd -b 'dc=rigacci,dc=org' < slapcat_dump.ldif
/etc/init.d/slapd start

Dopo l'operazione controllare i permessi dei file in /var/lib/ldap/, devono essere leggibili e scrivibili da openldap. Se per esempio un indice viene creato a nome di root, nelle successive esecuzioni di ldapadd si incappa nell'errore:

ldap_add: Other (e.g., implementation specific) error (80)
        additional info: index generation failed

Notare che non è in genere possibile usare ldapadd per aggiungere oggetti in un database vuoto, ad esempio perché le informazioni per onorare le ACL (es. le password) devono risiedere nel database stesso.

In modo analogo con ldapadd non è possibile effettuare il restore di alcuni attributi, in quanto lo schema li dichiara non modificabili dall'utente. Questi alcuni esempi: structuralObjectClass, entryUUID, creatorsName. Quindi in generale il restore va effettuato con slapadd che interviene direttamente sul database senza passare per il protocollo LDAP.

Creazione di un indice

Esempio: l'esecuzione di pdbedit -L -w con Samba che si appoggia su LDAP genera il seguente messaggio di log:

slapd[28067]: <= bdb_equality_candidates: (sambaSID) not indexed

Per aggiungere l'indice opportuno si aggiunge l'attributo nel nodo relativo al database:

olcDbIndex: sambaSID eq

Si possono indicare, separati da virgola, diversi criteri per la creazione dell'indice: pres, approx, eq, sub e special.

Nel nostro esempio la configurazione del database è contenuta nel nodo olcDatabase={1}hdb, cioè nel file /etc/ldap/slapd.d/cn=config/olcDatabase={1}hdb.ldif (sempre da editare a servizio fermo).

Debug

Potrebbe capitare che l'indice risulti corrotto, in tal caso la ricerca restituisce zero risultati. Con un database Syncrepl la strada più rapida è fermare il servizio, rimuovere i file (directory predefinita /var/lib/ldap/) e quindi riavviare il servizio.

L'errore è visibile solo con olcLogLevel: stats filter trace, ed è qualcosa di simile:

slapd[2937]: #011EQUALITY
slapd[2937]: => bdb_equality_candidates (sambaSID)
slapd[2937]: => key_read
slapd[2937]: <= bdb_index_read: failed (-30988)

Inclusione di uno schema aggiuntivo

Il metodo tradizionale (versione 2.4.11) per includere uno schema LDAP era quello di utilizzare la direttiva include nel file /etc/ldap/slapd.conf, gli schemi venivano solitamente salvati in /etc/ldap/schema/.

Nella nuova configurazione gli schemi vengono caricati da file LDIF contenuti nella directory /etc/ldap/slapd.d/cn=config/cn=schema/. È comunque buona norma salvare li file sorgente dello schema in /etc/ldap/schema/.

Nell'impostazione predefinita LDAP di Debian include i seguenti schemi:

Vogliamo aggiungere a questo elenco il samba.schema, fornito dal pacchetto samba-doc.

Caricamento a freddo da file .ldif

Quello che segue è un metodo manuale per compilare i file samba.schema in un file .ldif:

zcat /usr/share/doc/samba-doc/examples/LDAP/samba.schema.gz > /etc/ldap/schema/samba.schema
mkdir tmp
cd tmp
cat << EOF > my_slapd.conf
include /etc/ldap/schema/core.schema
include /etc/ldap/schema/cosine.schema
include /etc/ldap/schema/nis.schema
include /etc/ldap/schema/inetorgperson.schema
include /etc/ldap/schema/samba.schema
EOF
mkdir my_slapd.d
slaptest -f my_slapd.conf -F my_slapd.d

Il file samba.schema verrà compilato in my_slapd.d/cn=config/cn=schema/cn={4}samba.ldif e potrà essare copiato in /etc/ldap/slapd.d/cn=config/cn=schema dopo aver fermato il servizio slapd:

/etc/init.d/slapd stop
cp 'my_slapd.d/cn=config/cn=schema/cn={4}samba.ldif' '/etc/ldap/slapd.d/cn=config/cn=schema/'
/etc/init.d/slapd start

NOTA: Eventualmente modificare il creatorsName e modifiersName per uniformarlo agli altri file .ldif.

Caricamento a caldo con ldapadd

Un vantaggio della configurazione cn=config di slapd è quella di poter modificare la configurazione senza fermare il servizio (in questo caso aggiungere uno schema). Per fare questo bisogna “ripulire” un po' il file creato con il metodo visto sopra e caricarlo a runtime con ldapadd.

La pulizia consiste nel togliere le stringhe {4} all'inizio del file (4 è il numero progressivo dello schema, mentre core.schema è il primo ed ha numero zero):

dn: cn={4}samba
objectClass: olcSchemaConfig
cn: {4}samba

In fondo al file bisogna togliere le righe:

structuralObjectClass:
entryUUID:
creatorsName:
createTimestamp:
entryCSN:
modifiersName:
modifyTimestamp:

Infine per caricare il file LDIF (in questo caso senza fermare il servizio):

ldapadd -x -D "cn=admin,cn=config" -f 'my_slapd.d/cn=config/cn=schema/cn={4}samba.ldif'

Configurazione TLS

Per utilizzare i protocolli cifrati ldaps (su porta 636 TCP) oppure ldap con StartTLS (su porta 389 TCP) bisogna anzitutto creare un certificato auto-firmato, utilizziamo per questo openssl.

Creare un file di configurazione, ad esempio /etc/ldap/ssl/ldap.rigacci.org.cnf:

#----------------------------------------------------------------
# Create an RSA key and a self-signed Certificate with the
# following command:
#
# openssl req -config /etc/ldap/ssl/ldap.rigacci.org.cnf \
#     -new -x509 -days 1461 -nodes \
#     -keyout /etc/ldap/ssl/ldap.rigacci.org.pem \
#     -out /etc/ldap/ssl/ldap.rigacci.org.pem
#
# The resulting file (unencrypted otherwise Slapd can't start
# automatically) will contains the RSA private key, so be sure
# to set its mode to 0400.
#----------------------------------------------------------------
[ req ]
prompt                          = no
default_bits                    = 2048
distinguished_name              = ldap.rigacci.org_distinguished_name

[ ldap.rigacci.org_distinguished_name ]
countryName                     = IT
stateOrProvinceName             = Italy
localityName                    = Firenze
organizationName                = Rigacci.Org
organizationalUnitName          = Information and Communications Technology
commonName                      = ldap.rigacci.org
emailAddress                    = webmaster@rigacci.org

Utilizzare il comando openssl come indicato nel commento. Il certificato .pem generato ha validtià 4 anni, deve essere protetto con mode 0400 e appartenere a openldap:openldap.

Per utilizzare il certificato si deve aggiungere al nodo cn=config le due chiavi:

olcTLSCertificateFile: /etc/ldap/ssl/ldap.rigacci.org.pem
olcTLSCertificateKeyFile: /etc/ldap/ssl/ldap.rigacci.org.pem

cioè (avendo fermato slapd) basta aggiungere le due righe in /etc/ldap/slapd.d/cn=config.ldif.

Avendo attivato ldaps si potrebbe chiudere all'esterno il protocollo ldap, mettendo in /etc/default/slapd (impedendo peró anche ldap StartTLS):

SLAPD_SERVICES="ldap://127.0.0.1:389/ ldaps:/// ldapi:///"

Questi i protocolli e i meccanismi di trasporto supportati da OpenLDAP:

URL Protocol Transport
ldap:/// LDAP TCP port 389
ldaps:/// LDAP over SSL TCP port 636
ldapi:/// LDAP IPC (Unix-domain socket)

Test

Per provare la connessione su protocollo ldaps si può usare:

ldapsearch -v -x -H ldaps://127.0.0.1/ -b "dc=rigacci,dc=org" "(objectclass=*)"

ATTENZIONE: Poiché il server slapd sta usando un certificato auto-firmato, il client (ldapsearch) non deve tentare di validarlo. Si imposta questo comportamento per tutti i client system-wide mettendo in /etc/ldap/ldap.conf:

TLS_REQCERT     never

Per verificare ldap con StartTLS (sulla porta 389 TCP) basta aggiungere l'opzione -ZZ a ldapsearch.

Catturando i pacchetti con tcpdump sull'interfaccia lo si verifica che la trasmissione dati sia cifrata.

Cambio password

Per modificare la password di un record LDAP esiste l'RFC 3062 e l'apposito tool ldappasswd. Con l'opzione -D si specifica le credenziali per il collegamento, con -S si attiva la modalità interattiva, l'utente a cui cambiare la password è indicato come ultimo parametro:

ldappasswd -x -D "cn=admin,dc=rigacci,dc=org" -W -h host.rigacci.org -S "cn=user,dc=rigacci,dc=org"