====== 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: * **core** * **cosine** * **nis** * **inetorgperson** 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"