In questa sezione si dà la definizione degli oggetti e dei termini la cui conoscenza è essenziale alla successiva trattazione del protocollo Kerberos. Poiché molte definizioni dipendono da altre, si è cercato, per quanto possibile, di ordinarle in modo da non dover anticipare il significato di un termine prima di definirlo. Tuttavia, per la completa comprensione di tutti i termini può essere necessaria una seconda rilettura di questa sezione.
1.3.1 Realm
Con il termine realm si indica un dominio amministrativo di autenticazione. Si intende cioè fissare i confini entro cui un server di autenticazione è autoritario nell’autenticare un utente, un host o un servizio. Ciò non vuol dire che affinché ci possa essere autenticazione tra un utente e un servizio questi debbano necessariamente appartenere allo stesso realm: se due oggetti fanno parte di realm diversi e tra questi ultimi intercorre una relazione di fiducia, allora l’autenticazione potrà aver luogo. Questa caratteristica detta Cross-Authentication sarà descritta in seguito.
Praticamente un utente/servizio appartiene ad un realm se e soltanto se condivide un segreto (password/chiave) con il server di autenticazione di quel realm.
Il nome di un realm è case sensitive, cioè fa differenza tra maiuscole e minuscole; tuttavia, per consuetudine, i realm sono sempre in maiuscolo. È inoltre buona abitudine, in un’organizzazione, far coincidere il nome del realm con il dominio DNS (in maiuscolo però). Seguire questi consigli al momento della scelta del nome del proprio realm semplifica significativamente la configurazione dei client Kerberos, soprattutto qualora si vogliano stabilire relazioni di fiducia con sottodomini. A titolo di esempio, se ad un’organizzazione appartiene il dominio DNS example.com, è opportuno che il relativo realm Kerberos sia EXAMPLE.COM.
1.3.2 Principal
Un principal è il nome con cui si fa riferimento alle entry nel database del server di autenticazione. Ad ogni utente, host o servizio di un dato realm viene associato un principal. In Kerberos 5 un principal è del tipo:componente1/componente2/…/componenteN@REALM
In pratica però si usano al massimo due componenti. Nel caso di un entry riferita ad un utente il principal è del tipo:Nome[/Istanza]@REALM
L’istanza è opzionale e la si usa di solito per qualificare meglio il tipo di utente. Per esempio gli utenti amministratori hanno di solito l’istanza admin. Sono esempi di principal riferiti a utenti i seguenti:pippo@EXAMPLE.COM admin/admin@EXAMPLE.COM pluto/admin@EXAMPLE.COM
Se invece le entry sono riferite a servizi, i pricipal assumono la forma:Servizio/Hostname@REALM
La prima componente è il nome del servizio, per esempio imap, afs, ftp. Spesso è la parola host con cui si indica accesso generico alla macchina (telnet, rsh, ssh). La seconda componente è l’hostname completo (FQDN) della macchina che fornisce il servizio richiesto. È importante che questa componente coincida esattamente (in minuscolo) alla reverse DNS dell’IP del server applicativo. Sono esempi validi di principal riferiti a servizi i seguenti:imap/mbox.example.com@EXAMPLE.COM
host/server.example.com@EXAMPLE.COM
afs/example.com@EXAMPLE.COM
Si noti che l’ultimo caso è un’eccezione perché la seconda componente non è un hostname ma il nome della cella AFS a cui il pricipal è riferito. Infine ci sono principal che non fanno riferimento nè a utenti nè a servizi ma hanno un ruolo nel funzionamento del sistema di autenticazione. Un esempio per tutti è krbtgt/REALM@REALM con la cui chiave associata viene criptato il Ticket Granting Ticket (vediamo dopo di che si tratta).
In Kerberos 4 le componenti non possono mai essere più di due e vengono separate dal carattere “.” invece che da “/”, mentre l’hostname nei principal riferiti a servizi è quello breve cioè non il FQDN. Sono esempi validi i seguenti:pippo@EXAMPLE.COM pluto.admin@EXAMPLE.COM imap.mbox@EXAMPLE.COM
1.3.3 Ticket
Un ticket è un “biglietto” che un client presenta ad un server applicativo per dimostrargli l’autenticità della sua identità. I ticket vengono emessi dal server di autenticazione e vengono criptati con la chiave segreta del servizio a cui sono destinati. Poiché tale chiave è un segreto condiviso soltanto tra il server di autenticazione e il server che fornisce il servizio, neanche il client stesso che ha richiesto il ticket potrà conoscerne o modificarne il contenuto. Le principali informazioni contenute in un ticket sono:
- Il principal del richiedente (in genere è lo username);
- Il principal del servizio a cui è destinato;
- L’indirizzo IP della macchina client da cui il ticket può essere usato. In Kerberos 5 questo campo è opzionale e può essere anche multiplo allo scopo di far funzionare anche client sotto NAT o multihomed.
- La data e l’ora (in formato di timestamp) in cui ha inizio la validità del ticket;
- Il tempo massimo di vita (lifetime) del ticket
- La chiave di sessione (ha un ruolo fondamentale che viene descritto più avanti);
Ogni ticket ha una scadenza (in genere 10 ore). Ciò è essenziale in quanto su un ticket già emesso, il server di autenticazione non ha più nessun controllo. L’amministratore del realm, cioè, benchè possa in qualsiasi momento impedire l’emissione di nuovi ticket per un certo utente, non potrà impedire a quest’ultimo di utilizzare quelli che già possiede. Da qui la necessità di limitare il tempo di vita dei ticket in modo da limitare nel tempo eventuali abusi.
I ticket contengono molte altre informazioni e flag che ne caratterizzano il comportamento, ma non è opportuno parlarne ora. Di ticket e flag riparleremo ancora dopo aver affrontato il funzionamento del sistema di autenticazione.
1.3.4 Encryption
Come si vedrà Kerberos ha spesso la necessità di criptare e decriptare i messaggi (ticket e autenticatori) che intercorrono tra i diversi partecipanti all’autenticazione. Si tenga presente che Kerberos usa solo la crittografia a chiave simmetrica (in altre parole in cui la stessa chiave viene usata sia per criptare che per decriptare). Sono attivi alcuni progetti (es. pkinit) per introdurre un sistema a chiave pubblica allo scopo di ottenere l’autenticazione iniziale dell’utente mediante la presentazione di una chiave privata a cui ne corrisponde una pubblica certificata, ma non essendovi uno standard di fatto ne rimandiamo la trattazione.
1.3.4.1 Encryption type
Kerberos 4 implementa un unico tipo di cifratura che è il DES a 56 bit. La fragilità di questa encryption unitamente ad altre vulnerabilità del protocollo, hanno di fatto reso obsoleto Kerberos 4. La versione 5 di Kerberos, invece, non fissa a priori il numero e il tipo di encryption supportate. Sarà compito della specifica implementazione supportare e negoziare al meglio vari tipi di encryption. Tuttavia, questa flessibilità ed estensibilità del protocollo ha accentuato problemi di interoperabilità tra le varie implementazioni di Kerberos 5. Affinché client, server applicativi e di autenticazione che utilizzano implementazioni diverse, possano interoperare tra loro, è necessario che abbiano in comune almeno un tipo di encryption. Emblematica a tal proposito è stata la difficoltà di interoperabilità tra le implementazioni Unix di Kerberos 5 e quella presente in Active Directory di Windows. Quest’ultima, infatti, supportando un numero limitato di encryption aveva in comune con Unix solo il DES a 56 bit. Ciò costringeva a tenere abilitata quest’ultima, benchè fossero noti i rischi che si correvano, se si voleva garantire interoperabilità. Il problema si è risolto successivamente con la versione 1.3 di MIT Kerberos 5, che ha introdotto il supporto a RC4-HMAC presente anche in Windows e più sicura del DES. Tra le encryption supportate (ma non da windows) sono sicuramente degne di nota il triplo DES (3DES) e le più nuove AES128 e AES256.
1.3.4.2 Encryption key
Come si è detto, uno degli obiettivi del protocollo Kerberos è evitare che la password dell’utente sia registrata in chiaro persino nel database del server di autenticazione. Tenendo poi conto che ogni algoritmo di encryption usa la sua lunghezza di chiave, risulta allora scontato che, se non si vuole costringere l’utente ad usare una password differente e di dimensione fissata per ogni encryption da supportare, le encryption key non possono essere le password. Si introduce per le suddette ragioni, la funzione string2key, che trasforma una password in chiaro in una encryption key adeguata al tipo di crittografia da utilizzare. Tale funzione viene richiamata ognivolta che un utente cambia la sua password o la immette per autenticarsi. Si dice che la string2key è una funzione hash, intendendo con ciò che è irreversibile: data un’encryption key non si può determinare la password che l’ha generata (se non per brute force). Famosi algoritmi di hashing sono MD5 e CRC32.
1.3.4.3 Salt
In Kerberos 5, a differenza che nella versione 4, si è introdotto il concetto di salt della password. Si tratta di una stringa da concatenare alla password in chiaro prima di applicare la funzione string2key per ottenere la chiave. Per default, Kerberos 5 usa come salt il principal stesso dell’utente:Kpippo = string2key ( Ppippo + “pippo@EXAMPLE.COM” )
Kpippo è l’encryption key dell’utente pippo e Ppippo la password in chiaro dello stesso.
Utilizzando questo tipo di salt si hanno i seguenti vantaggi:
- Due principal appartenenti allo stesso realm ed aventi la stessa password in chiaro, hanno comunque le chiavi differenti. Si pensi, per esempio, ad un amministratore che ha un principal per il lavoro quotidiano (pippo@EXAMPLE.COM) e uno per il lavoro amministrativo (pippo/admin@EXAMPLE.COM). È molto probabile che tale utente abbia per comodità impostato la stessa password per entrambi i principal. La presenza del salt garantirà che le relative chiavi siano diverse.
- Se un utente ha due account in realm diversi, è abbastanza frequente che la password in chiaro coincida in entrambi i realm: grazie alla presenza del salt, un’eventuale compromissione di un account in un realm, non determinerà automaticamente la compromissione dell’altro.
Per compatibilità con Kerberos 4 si può configurare un salt nullo. Viceversa, per compatibilità con AFS, si può configurare un salt che non sia il nome completo del principal, ma semplicemente il nome della cella.
Avendo trattato i concetti di encryption type, string2key e salt si può verificare la veridicità della seguente osservazione: affinché ci sia interoperabilità tra diverse implementazioni di Kerberos, non basta negoziare un encryption type comune, ma si deve usare anche i medesimi tipi di string2key e di salt.
Si noti infine che, nell’esprimere i concetti di string2key e di salt, si è fatto riferimento solo ai principal degli utenti e mai a quelli dei servizi. Il motivo è evidente: un servizio, benchè condivida con il server di autenticazione un segreto, non è una password in chiaro (chi la dovrebbe digitare?), ma una chiave che, una volta generata dall’amministratore sul server Kerberos, viene memorizzata così come è sul server che fornisce il servizio.
1.3.4.4 Key Version Number (kvno)
Quando un utente effettua un cambio di password o un amministratore aggiorna la chiave segreta di un server applicativo, viene tenuta traccia di tale cambiamento incrementano un contatore. Il valore attuale di tale contatore che identifica appunto la versione della chiave, prende il nome di Key Version Number o piu brevemente kvno.
1.3.5 Key Distribution Center (KDC)
Abbiamo parlato genericamente di server di autenticazione. Trattandosi dell’oggetto fondamentale che partecipa all’autenticazione di utenti e servizi vediamolo più approfonditamente senza scendere nei dettagli del funzionamento che invece sono argomento della sezione dedicata alla descrizione operativa del protocollo.
Si parla di server di autenticazione al singolare anche se è possibile ridondare il server all’interno del realm in una struttura Master/Slave o Multimaster (Windows Active Directory). Come ottenere la ridondanza non è descritto dal protocollo, ma dipende dall’implementazione che si sta utilizzando e non sarà argomento di discussione.
Il server di autenticazione in un ambiente Kerberos, in virtù della sua funzione di distributore di ticket per l’accesso ai servizi, prende il nome di Key Distribution Center o più brevemente KDC. Benchè risieda interamente su un unico server fisico (spesso coincide con un unico processo) lo si può pensare logicamente diviso in tre parti: il Database, l’Authentication Server (AS) e il Ticket Granting Server (TGS). Vediamoli brevemente.
1.3.5.1 Database
Il database è il contenitore delle entry associate a utenti e servizi. Ci si riferisce ad una entry utilizzando il principal (cioè appunto il nome della entry) anche se spesso il termine principal è utilizzato quale sinonimo di entry. Ogni entry contiene le seguenti informazioni:
- Il principal a cui la entry è associata;
- Le encryption key ed il relativo kvno;
- La durata massima di validità per un ticket associato al principal;
- Il tempo massimo in cui un ticket associato al principal può essere rinnovato (solo Kerberos 5);
- Gli attributi o flags che caratterizzano il comportamento dei ticket;
- La data di scadenza della password;
- La data di scadenza del principal dopo la quale non verranno più emessi ticket.
Allo scopo di rendere più arduo il furto delle chiavi presenti nel database le implementazioni criptano il database con la master key, il cui principal associato è di solito K/M@REALM. Anche eventuali dump del database, usati come backup o per la propagazione dal KDC master verso gli slave, sono criptati con tale chiave che è necessario conoscere per poterli ricaricare.
1.3.5.2 Authentication Server (AS)
L’Authetication Server è la parte del KDC che risponde a richieste di autenticazione iniziale da parte dei client, quando l’utente, non essendo ancora autenticato, deve digitare la password. L’AS, in risposta ad una richiesta di autenticazione, emette uno speciale ticket chiamato Ticket Granting Ticket o piu brevemente TGT il cui principal associato è krbtgt/REALM@REALM. Se l’utente è veramente chi dice di essere (e capiremo in seguito come fa a dimostrarlo) potrà usare il TGT per ottenere altri ticket di servizio, senza dover ridigitare la password.
1.3.5.3 Ticket Granting Server (TGS)
Il Ticket Granting Server è la componente del KDC che distribuisce ai client con un TGT valido, i ticket di servizio che garantiscono l’autenticità dell’identità per ottenere la risorsa richiesta sui server applicativi. Si potrebbe pensare al TGS come ad un server applicativo (visto che per accedervi è necessario presentare il TGT) che fornisce come servizio l’emissione di ticket di servizio. Si faccia poi attenzione a non confondere le sigle TGT e TGS: la prima indica un ticket mentre la seconda un servizio.
1.3.6 Session Key
Come abbiamo visto, gli utenti e i servizi condividono un segreto con il KDC. Tale segreto è, per gli utenti, la chiave derivata dalla loro password, mentre per i servizi, la loro chiave segreta (impostata dall’amministratore). Queste chiavi sono dette a lungo termine poiché non cambiano al variare della sessione di lavoro.
È necessario però, almeno per il tempo in cui un client ha una sessione di lavoro aperta su di un server, che anche l’utente condivida con il servizio un segreto: questa chiave, generata dal KDC al momento dell’emissione di un ticket, prende il nome di Session Key (o chiave di sessione). La copia destinata al servizio viene imbustata dal KDC nel ticket (tanto il server applicativo conoscendo la chiave a lungo termine del servizio potrà decifrarlo ed estrarre la session key), mentre la copia destinata all’utente viene incapsulata in un pacchetto cifrato con la chiave a lungo termine dell’utente. La session key ha un ruolo fondamentale nel dimostrare l’autenticità dell’utente che vediamo nel paragrafo successivo.
1.3.7 Authenticator
Benchè in un ticket sia presente il principal dell’utente e soltanto il server applicativo possa estrarre ed eventualmente manipolare tale informazione (essendo il ticket criptato con la chiave segreta del servizio), ciò non basta a garantire l’autenticità del client. Un impostore, infatti, potrebbe catturare (si ricordi l’ipotesi di rete aperta e insicura) il ticket quando questo viene inviato dal client legittimo al server applicativo e, al momento opportuno, inviarlo per ottenere illegittimamente il servizio. D’altra parte, mettere nel ticket anche gli indirizzi IP delle macchine da cui è possibile utilizzarlo non serve a molto: si sa che in una rete aperta e insicura gli indirizzi sono facilmente falsificabili. Per risolvere il problema, si deve sfruttare il fatto che client e server, almeno durante la sessione hanno in comune la session key che solo loro conoscono (anche il KDC la conosce visto che l’ha generata, ma tanto lui è fidato per definizione!!!). Si applica allora la seguente strategia: insieme alla richiesta contenente il ticket, il client affianca un altro pacchetto (l’autheticator) in cui ci mette il principal dell’utente e il timestamp (il suo in quel momento) e lo cripta con la session key; il server che deve offrire il servizio, ricevendo la richiesta, spacchetta prima il ticket, estrae la session key e se l’utente è veramente chi dice di essere riesce a decriptare l’authenticator estraendo il timestamp. Se quest’ultimo differisce dall’orario del server per meno di 2 minuti (ma la tolleranza è configurabile) l’autenticazione va a buon fine. Da tutto questo si evince la criticità della sincronizzazione tra le macchine appartenenti ad un realm.
1.3.8 Replay Cache
Esiste la possibilità, per un impostore, di rubare contemporaneamente sia il ticket che l’authenticator e di utilizzarli nell’arco dei 2 minuti in cui l’autenticatore è valido. Ciò è molto difficile ma non impossibile. A soluzione di questo problema con Kerberos 5 viene introdotta la Replay Cache. Nei server applicativi (ma anche nel TGS), si implementa la capacità di ricordare gli autenticatori già pervenuti negli ultimi 2 minuti e di scartarli se si tratta di una replica. Con ciò il problema è risolto a patto che l’impostore non sia tanto bravo da copiare ticket e autenticatore e farli arrivare al server applicativo prima ancora che pervenga la richiesta legittima. Sarebbe proprio una beffa visto che l’utente autentico sarebbe rifiutato mentre l’impostore avrebbe accesso al servizio.
1.3.9 Cache delle Credenziali
Il client non conserva mai la password dell’utente così come non ne memorizza la chiave segreta ottenuta applicando la string2key: esse vengono utilizzate per decriptare le risposte del KDC ed immediatamente scartate. D’altra parte però, per implementare la caratteristica del single sign-on (SSO), in cui all’utente è richiesto di digitare la password una sola volta per sessione di lavoro, è necessario memorizzare i ticket e le relative session key. Il luogo dove vengono conservati questi dati è detto “Cache delle Credenziali”. Dove tale cache debba essere collocata non riguarda il protocollo, ma varia da implementazione a implementazione. Spesso per questioni di portabilità si sceglie di collocarla nel filesystem (MIT e Heimdal). In altre implementazioni (AFS ed Active Directory), allo scopo di aumentare la sicurezza in caso di client vulnerabili, la cache delle credenziali è posta in una zona della memoria accessibile solo al kernel e non paginabile su disco.