Infrastruttura Single-Signon Unix
Una volta definito l’ambiente in cui verrà sviluppato il modello, si è proceduto alla scelta dei programmi da integrare: la scelta è ricaduta su programmi OpenSource, in quanto più facilmente reperibili ed eventualmente modificabili. È possibile realizzare la stessa infrastruttura con programmi supportati, ma bisogna verificare con il produttore se le funzionalità siano disponibili, ad esempio se l’LDAP server supporta Kerberos come password back-end.
Preparazione del DNS
Kerberos richiede che vi siano alcune entry nel DNS che puntino ai servizi erogati, anche se pochi programmi sembrano cercare queste entry. È bene verificare che il reverse look-up di ciascun server sia garantito: alcuni problemi legati al kerberos sono relativi al fatto di non riuscire a risolvere in modo corretto i nomi. Per quanto riguarda il laboratorio, questo è il DNS relativo alla parte kerberos:
$TTL 604800 $ORIGIN azienda.it. @ IN SOA azienda.it. postmaster.azienda.it. ( 26010400 ; Serial 604800 ; Refresh 86400 ; Retry 2419200 ; Expire 604800 ) ; Negative Cache TTL ; @ IN NS ns.azienda.it. ; Kerberos principals (DA AGGIUNGERE!!!!) _kerberos IN TXT "AZIENDA.IT" _kerberos-master._udp IN SRV 0 0 88 kdc _kerberos-adm._tcp IN SRV 0 0 749 kdc _kpasswd._udp IN SRV 0 0 565 kdc _kerberos._udp IN SRV 0 0 88 kdc _ldap._tcp IN SRV 0 0 389 ldap ; Aliases kdc IN CNAME zeus.azienda.it. ldap IN CNAME zeus.azienda.it. ns IN CNAME zeus.azienda.it. www IN CNAME venere.azienda.it. mail IN CNAME venere.azienda.it. time IN CNAME zeus.azienda.it. ; Real IP Addresses zeus IN A 192.168.0.10 venere IN A 192.168.0.20 cerbero-server IN A 192.168.0.1 cerbero-client IN A 192.168.1.1 kirk IN A 192.168.1.20 picard IN A 192.168.1.40 spok IN A 192.168.1.60
Come si può notare nell’esempio precedente, le entry importati sono quelle che si riferiscono ai Service Locator (SRV) e al _kerberos che specifica, attraverso il record TXT, il realm della rete locale (nel nostro caso AZIENDA.IT). I numeri successivi alla definizione dei record sono nell’ordine: la priorità (simile alla priorità del record MX), il peso da usare in caso di load-balancing e la porta TCP o UDP su cui è in attesa il servizio. Come accennato precedentemente, non tutti i programmi sfruttano la risoluzione del realm e/o dei servizi tramite DNS, ma è bene provvedere alla loro definizione per una corretta configurazione.
Il server NTP
Un altro prerequisito al funzionamento di Kerberos è la sincronizzazione degli orologi di sistema. A tale scopo è stato creato un NTP server sul sistema zeus.azienda.it a cui viene fatto riferimento con time.azienda.it. Vediamo un esempio di configurazione di un NTP server (file /etc/ntp.conf):
driftfile /var/lib/ntp/ntp.drift statsdir /var/log/ntpstats/ statistics loopstats peerstats clockstats filegen loopstats file loopstats type day enable filegen peerstats file peerstats type day enable filegen clockstats file clockstats type day enable authenticate no ## Mettere il proprio server di riferimento, esempio quello ## del vostro provider. Il server time.ien.it si riferisce ## all'orologio ufficiale italiano, cioè l'Istituto Galileo ## Ferraris di Torino. Prima di usare un NTP server è bene ## avvisare il relativo l'amministratore di sistema. server time.ien.it prefer
Per maggiori informazioni su come configurare un server NTP e i relativi client si faccia riferimento alla manualistica del sistema operativo. Nei capitoli successivi si darà per assunto che la sincronizzazione degli orologi sia stata effettuata correttamente.
Il server Kerberos
Il server Kerberos installato è il MIT Kerberos V. Molti sistemi operativi Unix includono ormai un server Kerberos, quindi non mi soffermerò sui dettagli della compilazione del server: si faccia riferimento alla documentazione relativa al proprio vendor, oppure si verifichi per Linux l’elenco dei pacchetti installabili, solitamente libkrb5-dev, krb5-admin-server e krb5-kdc. È possibile scaricarne i sorgenti nella home page del progetto del MIT, ovvero http://web.mit.edu/kerberos/www/. Durante l’installazione del server è bene installare anche i pacchetti relativi allo sviluppo del kerberos, solitamente le librerie e gli include file: tali pacchetti serviranno successivamente per compilare le applicazioni aggiungendo il supporto Kerberos.
Dopo aver installato i pacchetti, è necessario personalizzare il file di configuazione /etc/krb5.conf presente sul KDC: tale file verrà usato sia dal KDC che dal client kerberos della macchina. Nell’esempio seguente si noti il tipo di crittografia specificata: di defaut il MIT Kerberos 5 usa des3-hmac-sha1, ma l’implementazione Kerberos di Windows è in grado solamente di comprendere la crittografia des-cbc-crc o des-cbc-md5. Per assicurare la compatibilità con Windows, si è scelto pertanto di adottare questa crittografia: essendo DES una crittografia debole, è consigliabile usare, quando possibile, comunicazioni protette.
[libdefaults] default_realm = AZIENDA.IT ## For Windows 2000 compatibility default_tgs_enctypes = des-cbc-crc des-cbc-md5 default_tkt_enctypes = des-cbc-crc des-cbc-md5 permitted_enctypes = des-cbc-crc des-cbc-md5 krb4_config = /etc/krb.conf krb4_realms = /etc/krb.realms kdc_timesync = 1 ccache_type = 4 forwardable = true proxiable = true # The following libdefaults parameters are only # for Heimdal Kerberos. v4_instance_resolve = false v4_name_convert = { host = { rcmd = host ftp = ftp } plain = { something = something-else } } [realms] AZIENDA.IT = { kdc = kdc.azienda.it admin_server = kdc.azienda.it } [domain_realm] .azienda.it = AZIENDA.IT [login] krb4_convert = true krb4_get_tickets = true
Una volta configurato /etc/krb5.conf si è pronti a creare il Realm Kerberos. Da utenza di root è necessario eseguire i seguenti comandi:
# kdb5_util create -s # kadmin.local -q “ktadd -l /etc/krb5kdc/kadm5.keytab kadmin/admin” # kadmin.local -q “ktadd -l /etc/krb5kdc/kadm5.keytab kadmin/changepw” # kadmin.local -q “addprinc -pw miapassword1 krbadm@AZIENDA.IT” # kadmin.local -q “addprinc -pw miapassword2 ldapadm@AZIENDA.IT”
Le ultime due righe si riferiscono all’aggiunta di due utenze: la prima servirà come amministratore di Kerberos, la seconda invece sarà associata all’amministratore di LDAP. A questo punto siamo pronti per avviare il server:
# krb5kdc & # kadmind &
Il metodo migliore per avviare i due servizi kerberos (KDC il primo e Admin server il secondo) è attraverso gli script di avvio: riferirsi al manuale del proprio vendor per ulteriori dettagli.
L’ultimo passo per l’installazione di Kerberos è quello relativo alle access lists, in quanto dobbiamo abilitare l’utenza (o il principal) krbadm@AZIENDA.IT ad amministrare il server Kerberos. Il file in oggetto è /etc/krb5kdc/kadm5.acl, vediamone un esempio:
kadmin/admin@AZIENDA.IT * krbadm@AZIENDA.IT * */*@AZIENDA.IT i
L’asterisco dopo l’account significa che può eseguire qualsiasi operazione, mentre la lettera “i” significa che può leggere le informazioni nel database.
La libreria SASL
Precedentemente è stato accennato come la libreria SASL sia in grado di offrire un livello di astrazione per l’autenticazione di protocolli di rete, come definito nell’RFC 2222. Molti sistemi Unix hanno le librerie SASL, ma non tutti supportano GSSAPI come meccanismo: ad esempio Debian è in grado di supportare le GSSAPI attraverso il pacchetto libsasl-gssapi-mit e RedHat attraverso cyrus-sasl-gssapi, ma è necessario contattare il proprio vendor per sapere se implementa o distribuisce SASL e se GSSAPI è un meccanismo valido.
Qualora non si disponesse delle GSSAPI come meccanismo di autenticazione, è possibile scaricare il sorgente di Cyrus SASL dal sito http://asg.web.cmu.edu/sasl/sasl-library.html. Per compilarlo, occorre specificare i seguenti parametri:
# ./configure --prefix=/usr/local --enable-static \ --enable-login--enable-gssapi=/usr/kerberos/ \ --disable-krb4 # make # make install
È necessario sostituire /usr/kerberos con la directory contenente gli include file del MIT Kerberos V. Anche per la libreria SASL è importante installare i file di include, pertanto quando si installa attraverso i pacchetti della propria distribuzione è necessario installare anche i file di development.
Il server LDAP
Come server LDAP è stato scelto OpenLDAP, disponibile su http://www.openldap.org. Questo server, oltre ad essere gratuito, ha la possibilità di sfruttare Kerberos come back-end delle password utente, pertanto fa al caso nostro. Molte distribuzioni dispongono di openldap server tra i pacchetti disponibili, raramente però viene compilato con le opzioni necessarie, pertanto è necessario ricompilarlo. Come prerequisito dobbiamo avere gli header file e le librerie dei seguenti pacchetti: Kerberos, SASL, OpenSSL e Berkley DB (o equivalente). Le opzioni che ci serviranno in particolare sono:
--disable-cleartext --disable-rlookups --with-tls --enable-kpasswd
Queste sono le opzioni che sono state usate per compilare il server OpenLDAP:
$ ./configure --prefix=/usr/local/ldap --enable-debug \ --enable-syslog --enable-proctitle --enable-cache \ --enable-referrals --enable-ipv6 --enable-local \ --with-readline --with-threads --disable-cleartext \ --enable-multimaster --enable-phonetic --disable-rlookups \ --enable-wrappers --enable-dynamic --enable-dnssrv \ --enable-ldap --enable-ldbm --enable-passwd --enable-shell \ --enable-sql --enable-slurpd --enable-shared $ make depend $ make # make install (da root!)
Prima di configurare il server LDAP è necessario preparare un principal Kerberos e un certificato digitale per usare SSL. Per creare un principal per LDAP, sul sistema zeus.azienda.it si esegue il seguente comando:
# kadmin.local -q "addprinc -randkey ldap/ldap.azienda.it@AZIENDA.IT" # kadmin.local -q "ktadd ldap/ldap.azienda.it@AZIENDA.IT"
Il primo comando crea il principal, mentre il secondo inserisce la chiave nel file di default /etc/krb5.keytab che verrà usato dal server. Successivamente è necessario ottenere un certificato SSL (X.509) per abilitare SSL con LDAP. Qualora non si disponga già di una Certification Authority (CA), con OpenSSL viene distribuito uno script perl (CA.pl) capace di generare e mantenere una piccola CA. Grazie a questo script è possibile generare una CA ed un certificato di test con i seguenti comandi:
CA.pl -newca CA.pl -newreq CA.pl -signreq
Come creare e mantenere una CA è al di fuori dello scopo di questo documento, per maggiori informazioni sull’uso di CA.pl come script, si faccia riferimento al sito http://www.openssl.org/docs/apps/CA.pl.html. Si ottengono due file, newreq.pem e newcert.pem, che andranno rinominati rispettivamente in ldap-priv.pem (la chiave privata) e ldap-pub.pem(la chiave pubblica). Vediamo la configurazione adottata nei nostro esempio in /etc/ldap/slapd.conf:
# LDAP SEVER # Configuration for: ldap.azienda.it 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/krb5-kdc.schema include /etc/ldap/schema/samba.schema # Schema check allows for forcing entries to # match schemas for their objectClasses's schemacheck on pidfile /var/run/slapd.pid # Where to store the replica logs replogfile /var/lib/ldap/replog # Read slapd.conf(5) for possible values loglevel 0 ## Kerberos support sasl-realm AZIENDA.IT sasl-host ldap.azienda.it ## TLS support TLSCACertificateFile /etc/ldap/cacert.pem TLSCertificateFile /etc/ldap/ldap-pub.pem TLSCertificateKeyFile /etc/ldap/ldap-priv.pem TLSRandFile /dev/random # The backend type, ldbm, is the default standard database ldbm # The base of your directory suffix "dc=azienda,dc=it" # Where the database file are physically stored directory "/var/lib/ldap" ## RootDN rootdn "cn=Directory Manager,ou=People,dc=azienda,dc=it" rootpw {KERBEROS}ldapadm@AZIENDA.IT # Indexing options index objectClass eq index cn,mail,surname,givenname eq,subinitial # Save the time that the entry gets modified lastmod on # Include the access lists include /etc/ldap/slapd.access
Rivediamo brevemente le parti salienti di questa configurazione. La prima parte del file riguarda la definizione degli schema file da includere, ovvero la sintassi degli attributi di LDAP. In particolare sottolineiamo l’inclusione degli schemi relativi al nis (nis.schema), che serviranno ai sistemi Unix per l’assegnazione dei profili agli utenti (contengono gid/uid, home directory, shell, ecc.), e kerberos (krb5-kdc.schema), che permetterà di definire gli attributi per l’interfacciamento con il KDC. Successivamente i parametri sasl realm e sasl host, come si intuisce dal nome, si riferiscono al metodo di interfacciamento con le librerie SASL e definiscono il Kerberos realm il primo (AZIENDA.IT) e il principal relativo al server LDAP il secondo (che coincide con l’hostname, ovvero ldap.azienda.it). A seguire i parametri relativi al TLS per permettere di usare SSL con LDAP (protocollo LDAPS): TLSCACertificateFile specifica il file contenente la chiave pubblica della Certification Autority, TLSCertificateFile contiene la chiave pubblica del server LDAP in formato PEM, TLSCertificateKeyFile punta alla chiave privata del server ed infine TLSRandFile contiene il device /dev/random per la generazione casuale dei file.
Proseguendo con la configurazione si specifica il base dn del nostro LDAP server, ovvero la radice del nostro albero LDAP, con il parametro suffix nel nostro caso impostato a dc=azienda,dc=it. Si identifica poi l’amministratore della directory, solitamente chiamato anche Directory Manager, che viene specificato con il parametro rootdn: da notare che è stato collocato sotto la Organizational Unit (OU) di People, anche se non abbiamo ancora popolato i dati relativi alla struttura. A Directory Manager è stata associata, tramite il parametro rootpw, la relativa password: in questo caso è molto particolare in quanto si riferisce a {KERBEROS}ldapadm@AZIENDA.IT. Come si può intuire, la keyword KERBEROS espressa tra parentesi graffe permette, in congiunzione all’opzione -kpasswd espressa durante la compilazione del server LDAP, di usare Kerberos come password server. Così facendo, quando ci si collegherà all’LDAP server come Directory Manager, andrà specificata la password di ldapadm@AZIENDA.IT (ovvero miapassword2, come specificato precedentemente). Durante l’inserimento dei dati vedremo che questa opzione vale anche per le password utente espresse nel parametro userPassword, ma è da notare che in successive query al database LDAP il contenuto verrà offuscato tramite base64.
L’ultima opzione, ma non ultima come importanza, è l’inclusione di un file esterno per la definizione delle Access List: in LDAP è possibile definire delle ACL con lo scopo di limitare gli utenti, specificando a quali attributi possono accedere e/o modificare. Vediamo una access list di esempio caricata nel file /etc/ldap/slapd.access:
# Attributes visibile to everyone, but can be changed only # by the owner access to attr=cn,givenName,sn,krbName,krb5PrincipalName,gecos by dn="cn=Directory Manager,ou=People,dc=azienda,dc=it" write by dn="uid=ldapadm.+\+realm=AZIENDA.IT" write by self write by * read access to attr=loginShell,gecos by dn="cn=Directory Manager,ou=People,dc=azienda,dc=it" write by dn="uid=ldapadm.+\+realm=AZIENDA.IT" write by self write by * read # Since we’re using {KERBEROS}<PRINCIPAL>, we can't allow # the user to change the password. They have to use the # Kerberos 'kpasswd' to do this. But the admin can change # (if need be). Please see krb5 userPassword attribute access to attr=userPassword by dn="cn=Directory Manager,ou=People,dc=azienda,dc=it" write by dn="uid=ldapadm.+\+realm=AZIENDA.IT" write by anonymous auth by * none # Directory Manager can do anything access to * by dn="cn=Directory Manager,ou=People,dc=azienda,dc=it" write by dn="uid=ldapadm.+\+realm=AZIENDA.IT" write by * read
A questo punto è possibile avviare il server con:
# /usr/local/ldap/sbin/slapd -u ldap -g ldap -h “ldaps://0.0.0.0/”
Con l’opzione -h si è specificato quali protocolli e quali IP address il server LDAP deve ascoltare, in questo caso solo ed esclusivamente LDAPS. Inoltre è consigliabile avviare il server LDAP con un utente e gruppo diverso da root, in questo caso è stato avviato con l’utente ldap e gruppo ldap, creando appositamente un utente ldap con home directory /var/lib/ldap (la directory del database). Proviamo quindi se LDAP funziona e se supporta i meccanismi di autenticazione preposti:
- ldapsearch -H “ldaps://localhost/” -x -b “” -s base -LLL supportedSASLMechanisms
Il risultato dovrebbe essere come segue, facendo attenzione che ci sia GSSAPI:
supportedSASLMechanisms: PLAIN supportedSASLMechanisms: LOGIN supportedSASLMechanisms: ANONYMOUS supportedSASLMechanisms: GSSAPI
A questo punto siamo pronti per popolare il database LDAP con i dati fittizi, a questo scopo useremo l’utility slapadd e un file temporaneo in cui scrivere i dati, ad esempio /tmp/ldapentries.diff, come segue:
dn: cn=Mario Rossi, ou=People, dc=azienda,dc=it objectClass: top objectClass: person objectClass: inetOrgPerson objectClass: krb5Principal objectClass: posixAccount sn: Rossi cn: Mario Rossi givenName: Mario mail: mrossi@azienda.it krb5PrincipalName: mrossi@AZIENDA.IT userPassword:: {KERBEROS}mrossi@AZIENDA.IT uid: mrossi uidNumber: 500 homeDirectory: /home/mrossi gidNumber: 100 dn: ou=People,dc=azienda,dc=it objectClass: top objectClass: organizationalUnit ou: People dn: cn=Directory Manager,ou=People,dc=azienda,dc=it objectClass: organizationalRole cn: Directory Manager description: Directory Manager dn: dc=azienda,dc=it objectClass: dcObject objectClass: organization dc: azienda o: azienda.it description: Root LDAP dn: ou=Group,dc=azienda,dc=it objectClass: top objectClass: organizationalUnit ou: Group dn: cn=users,ou=Group,dc=azienda,dc=it objectClass: posixGroup objectClass: top cn: users gidNumber: 100 memberUid: mrossi dn: ou=Computers,dc=azienda,dc=it objectClass: top objectClass: organizationalUnit ou: Computers
Importiamo il file eseguendo il comando:
# slapadd -l /tmp/ldapentries.diff
A questo punto possiamo provare ad effettuare la prima chiamata a LDAP con l’utente Directory Manager, ad esempio con il seguente comando
# ldapsearch -H “ldaps://localhost/” -b “dc=azienda,dc=it” -x -W -D “cn=Directory Manager,ou=People,dc=azienda,dc=it” “objectclass=*”
Il comando dovrebbe restituire l’intero database LDAP. È possibile aggiungere anche una replica a LDAP per avere una maggiore alta affidabilità e disponibilità; si consiglia la lettura dell’ottimo How-To di Turbo Fredriksson LDAPv3 per un approfondimento.
Il Firewall
Come accennato in precedenza, uno degli obiettivi prioritari di questo laboratorio è di riflettere quanto possibile una realtà di produzione. A questo scopo è stato inserito nell’architettura un firewall, in modo da capire le problematiche relative all’aggiunta di un filtro IP. Nella tabella sottostante si riassumono le necessità di cominicazione dai client verso il KDC e i servizi Kerberos all’interno del firewall.
Tipo di macchina | Porta di destinazione | Descrizione |
---|---|---|
KDC | 88/udp 88/tcp | Kerberos 5 erogazione ticket |
KDC | 749/tcp | Kerberos 5, servizio kpasswd per cambio password e servizio di amministrazione remota |
LDAP | 636/tcp | LDAP con SSL per l’accesso ai dati utente |
Nel nostro caso, queste necessità si tradurranno in policy da applicare al firewall cerbero. Vediamo nella tabella sottostante queste policy:
Nome della macchina | Porta di destinazione | Descrizione |
---|---|---|
zeus.azienda.it | 88/udp 88/tcp 749/tcp | Accesso alle funzionalità di Kerberos (autenticazione e cambio password) |
zeus.azienda.it | 636/tcp | LDAPS per lookup utenti |
venere.azienda.it | 80/tcp | Accesso al Web server |
venere.azienda.it | 25/tcp 143/tcp | Accesso alla posta elettronica (SMTP ed IMAP) |