Laboratorio

Modulo 9 - Amministrazione, gestione e autenticazione in rete

Esperienza su Kerberos V5

Per la realizzazione di questo modulo useremo Netkit4TIC con la connettività con la rete reale (leggere il file README).

A quasi un anno della prima versione di questa esperienza, la lettura dell'e-book di Giuseppe Paternò dal titolo "Single Sign-On con Kerberos e LDAP" mi ha indotto a riscriverla pesantemente con credo un ottimo risultato. Ringrazio pubblicamente.

Nella mappa (pdf, xml) della rete in esame ci sono tre nodi collegati allo stesso dominio di collisione 192.168.10.0/24. Nel nodo kdc (192.168.10.4) sono configurati i seguenti servizi:

Nel nodo srv (192.168.10.10) saranno configurati i servizi ftp, telnet e http. Il nodo client (192.168.10.200) rappresenta la classica stazione di lavoro, ossia il posto destinato al login dell'utenza.

Vogliamo configurare kerberos e ldap in modo tale da sperimentare che un utente già autenticato nel realm ISTITUTO.IT possa ottenere servizio (ftp/telnet/http) senza doversi di nuovo autenticare.

L'elenco dei pacchetti da installare per kerberos è: krb5-admin-server, krb5-kdc, libkrb53 a cui si aggiunge krb5-clients, krb5-ftpd, krb5-rsh-server, krb5-telnetd per kerberizzare alcuni servizi.

Per l'elenco dei pacchetti da installare per LDAP rimandiamo all'esperienza su LDAP. È importante notare che anche se il supporto SASL viene garantito dal pacchetto libsasl2 occorre installare il supporto GSSAPI realizzato da libsasl2-gssapi-mit.

Il file con l'esperienza deve essere decompresso su una sottodirectory della HOME. In seguito, dopo aver seguito le istruzioni presenti nel file README occorre lanciare lo script:

user@realHost$ ./lab start

(screenshot) che costruisce i tre nodi con i servizi già configurati e attivati.

In seguito gli argomenti vengono esposti suddivisi nelle seguenti sezioni:

Configurazione KDC

Procediamo con i comandi sul nodo krc per l'inizializzazione del database:

root@kdc# kdb5_util create -s
Loading random data
Initializing database '/var/lib/krb5kdc/principal' for realm 'ISTITUTO.IT',
master key name 'K/M@ISTITUTO.IT'
You will be prompted for the database Master Password.
It is important that you NOT FORGET this password.
Enter KDC database master key: not24get
Re-enter KDC database master key to verify: not24get

Il tratto evidenziato in colore indica l'attività di generare numeri casuali. Nei mondo virtuale tutte le funzioni che utilizzano generazioni casuali basandosi sull'attività dell'hardware subiscono rallentamenti e a volte dei blocchi perchè l'entropia è molto bassa rispetto alla realtà. In genere quindi dopo lo start dell'esperienza aspetto qualche minuto e nel frattempo genero dell'entropia battendo alcuni comandi alla console della macchina virtuale. Nel caso di blocco dovuto a un comando che usa /dev/random, lo sgancio dalla shell con CTRL-Z, poi lo faccio proseguire in background con il comando bg e nel frattempo genero entropia con comandi dalla tastiera.

Costruiamo le utenze amministrative:

root@kdc# kadmin.local
kadmin.local: ktadd -k /etc/krb5kdc/kadm5.keytab kadmin/admin
kadmin.local: ktadd -k /etc/krb5kdc/kadm5.keytab kadmin/changepw
kadmin.local: addprinc -pw secret krbadm@ISTITUTO.IT
kadmin.local: q

Ora facciamo partire il servizio:

root@kdc# /etc/init.d/krb5-kdc start

Per attivare la possibilità di amministrare il kdc da remoto dovremmo anche lanciare:

root@kdc# /etc/init.d/krb5-admin-server start

Configurazione LDAP

Iniziamo costruendo i principals necessari per LDAP:

Occorre far notare che siccome il nome kdc per il DNS è un alias a ns, il principals deve essere ldap/ns.istituto.it@ISTITUTO.IT.

root@kdc# host kdc
kdc.istituto.it is an alias for ns.istituto.it.
ns.istituto.it has address 192.168.10.4

root@kdc# kadmin.local
Authenticating as principal root/admin@ISTITUTO.IT with password.

kadmin: addprinc -pw secret ldap/ns.istituto.it@ISTITUTO.IT
kadmin: ktadd -k /etc/krb5.keytab ldap/ns.istituto.it@ISTITUTO.IT

kadmin: addprinc -pw secret ldapadm@ISTITUTO.IT

Per una dettagliata configurazione di un server OpenLDAP rimandiamo all'esperienza virtuale LDAP. La configurazione che andremo invece a fare riguarda la capacità di utilizzare kerberos come sistema di autenticazione e di utilizzare kerberos come sistema di back-end per le password. Nel file di configurazione il primo settaggio consiste in:

# /etc/ldap/slapd.conf
[...]
sasl-realm      ISTITUTO.IT
sasl-host       ldap.istituto.it
[...]

mentre la seconda feature viene ottenuta da un modulo che occorre compilare a partire dai sorgenti e che si chiama pw-kerberos.so.

Le istruzioni sono le seguenti:

# apt-get --download-only source slapd; \
  dpkg-source -x openldap2.3_2.2.23-8.dsc; \
  cd openldap2.3-2.2.23/; \
  cd contrib/slapd-modules/passwd; \
  gcc -shared -I../../../include -Wall -g -DHAVE_KRB5 \
      -o pw-kerberos.so kerberos.c

Ora dopo aver spostato il modulo in /usr/lib possiamo richiamarlo dall'interno del file di configurazione di slapd:

# /etc/ldap/slapd.conf
[...]
modulepath      /usr/lib
moduleload      pw-kerberos.so
[...]

e visto che le password stanno su kerberos, possiamo specificare il root DN come:

# /etc/ldap/slapd.conf
[...]
rootdn          "cn=ldapadm,ou=People,dc=istituto,dc=it"
rootpw          {KERBEROS}ldapadm@ISTITUTO.IT
[...]

Inoltre occorre includere krb5-kdc.schema che si può reperire ad esempio da:

wget http://www.bayour.com/openldap/schemas/krb5-kdc.schema

Una cura particolare vanno alle ACL che vengono modificate dal sistema GSSAPI. Ad esempio il principal mrossi@ISTITUTO.IT viene visto come:

dn="uid=mrossi,cn=istituto.it,cn=gssapi,cn=auth"

Da questo segue che le ACL devono prevedere questa modalità di accesso. Infatti in "Administrator's Guide" c'è una sezione da leggere e applicare dal titolo "Using SASL".
Le direttive che abbiamo applicato inserendole nella configurazione di slapd sono:

# Mapping Authentication Identities (SASL + GSSAPI case)
sasl-regexp
       uid=(.*),cn=istituto.it,cn=gssapi,cn=auth
       cn=$1,ou=People,dc=istituto,dc=it

Sempre a proposito di ACL occorre proteggere il sistema da cambi di password che vanno fatti esclusivamente con kerberos:

# /etc/ldap/slapd.access
[...]
# 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 ldapadm can change (if need be).
# Please see krb5 userPassword attribute
access to attr=userPassword
        by dn="cn=ldapadm,ou=People,dc=istituto,dc=it" write
        by anonymous auth
        by * none
[...]

Ora siamo quasi pronti: carichiamo il database e attiviamo slapd:

root@srv# slapadd -l ldapentries.diff
root@srv# /etc/init.d/slapd start

Configurazione server ftp e telnet

Definiamo dal nodo srv i "principal":

root@srv# kadmin -p krbadm
Authenticating as principal krbadm with password.
Password for krbadm@ISTITUTO.IT:secret

kadmin: addprinc -pw secret host/srv.istituto.it@ISTITUTO.IT
kadmin: ktadd -k /etc/krb5.keytab host/srv.istituto.it@ISTITUTO.IT

kadmin: addprinc -pw secret ftp/srv.istituto.it@ISTITUTO.IT
kadmin: ktadd -k /etc/krb5.keytab ftp/srv.istituto.it@ISTITUTO.IT

Per lo startup dei server ci basiamo su xinetd il quale ha bisogno di un file di definizione per ogni servizio. Per ftp:

# /etc/xinet.d/ftp
service ftp
{
        socket_type         = stream
        wait                = no
        nice                = 10
        user                = root
        server              = /usr/sbin/ftpd
}

per telnet:

# /etc/xinet.d/telnet
service telnet
{
        socket_type         = stream
        wait                = no
        nice                = 10
        user                = root
        server              = /usr/sbin/telnetd
        server_args         = -h
}

Terminato il lavoro di configurazione, attiviamo il servizio:

root@srv# /etc/init.d/xinetd start

Configurazione server apache

Definiamo per prima cosa, dal nodo srv, il principal relativo al servizio http:

root@srv# kadmin -p krbadm
Authenticating as principal krbadm with password.
Password for krbadm@ISTITUTO.IT:secret

kadmin: addprinc -pw secret HTTP/srv.istituto.it@ISTITUTO.IT
kadmin: ktadd -k /etc/krb5-srv.keytab HTTP/srv.istituto.it@ISTITUTO.IT

kadmin: q

Per provare il servizio web occorre usare un browser come firefox che non è installato nelle vm ma solo sulla macchina reale. Occorre quindi configurare un utente della macchina reale, knoppix ad esempio, come principal del realm ISTITUTO.IT. Occorre inoltre settare il server web per accettare connessioni con kerberos almeno su una particolare directory.
Dividiamo la configurazione in due sezioni:

Configurazione server http virtuale

Abilitiamo il modulo apache per il dialogo con kerberos:

# /etc/apache/modules.conf
[...]
LoadModule auth_kerb_module /usr/lib/apache/1.3/mod_auth_kerb.so
[...]

Costruiamo una pagina minimale:

<php
/* /protected/index.php */
phpinfo()
?>

Configuriamo la directory /protected/ per attivare kerberos:

# /etc/apache/http.conf
[...]
<Directory /var/www/protected>
   Options Indexes SymLinksIfOwnerMatch

   AuthType Kerberos
   AuthName "ISTITUTO.IT Login"
   Krb5Keytab /etc/krb5.keytab
   KrbAuthRealms ISTITUTO.IT
   require valid-user
<Directory>
[...]

Aggiustiamo il gruppo e i permessi del file /etc/krb5.keytab:

root@srv# chmod g+r,o= /etc/krb5.keytab
root@srv# chgrp www-data /etc/krb5.keytab

Attiviamo il server apache:

root@srv# /etc/init.d/apache start

Configurazione client http reale

Definire dal nodo srv i "principal":

root@srv# kadmin -p krbadm
Authenticating as principal krbadm with password.
Password for krbadm@ISTITUTO.IT:secret

kadmin: addprinc -pw secret knoppix@ISTITUTO.IT

kadmin: q

Per configurare l'utenza knoppix della macchina reale sul realm ISTITUTO.IT occorre per prima cosa far riferimento al DNS della rete virtuale:

# /etc/resolv.conf
domain istituto.it
nameserver 192.168.10.4

dopo di ciò occorre installare, grazie a UNION filesystem, il software kerberos mancante:

root@realHost# dpkg -i knoppix/krb5-config_1.6_all.deb \
                       knoppix/krb5-user_1.3.6-2sarge2_i386.deb \
                       knoppix/libkrb53_1.3.6-2sarge2_i386.deb \
                       knoppix/libkadm55_1.3.6-2sarge2_i386.deb

poi copiamo il file di configurazione:

root@realHost# cp krb5.conf /etc/krb5.conf

Configurazione client

Per prima cosa definiamo il principal associato al nostro utente di prova mrossi@ISTITUTO.IT (con password bianchi) e il principal associato al nodo client stesso:

root@client# kadmin -p krbadm
Authenticating as principal krbadm with password.
Password for krbadm@ISTITUTO.IT:secret

kadmin: addprinc -pw bianchi mrossi@ISTITUTO.IT

kadmin: addprinc -pw secret host/client.istituto.it@ISTITUTO.IT
kadmin: ktadd -k /etc/krb5.keytab host/client.istituto.it@ISTITUTO.IT
kadmin: q

Per la configurazione del nodo client ricorreremo alla configurazione di PAM per l'autenticazione e poi a NSS in combinazione con LDAP per la risoluzione dei nomi dei servizi. Tale configurazione và replicata in ogni nodo in cui si vuole permettere il login: infatti tale configurazione viene riportata anche per il nodo srv.

Come sperimentato nell'esperienza legata al PAM occorre modificare i files common-* all'interno della directory /etc/pam.d inserendo con clausola sufficient il modulo kerberos:

# /etc/pam.d/common-account
account   sufficient pam_krb5.so
account   required   pam_unix.so

# /etc/pam.d/common-auth
auth      sufficient pam_krb5.so nullok_secure forwardable
auth      required   pam_unix.so nullok_secure use_first_pass

# /etc/pam.d/common-password
password  sufficient pam_krb5.so nullok obscure
password  required   pam_unix.so nullok obscure min=4 max=8 md5 use_first_pass

# /etc/pam.d/common-session
session   sufficient pam_krb5.so forwardable
session   required   pam_unix.so

In seguito configuriamo come il Name Service Switch (NSS) deve accedere a LDAP:

# /etc/libnss-ldap.conf
host ldap.istituto.it
base dc=istituto,dc=it
nss_base_passwd ou=People,dc=istituto,dc=it
nss_base_shadow ou=People,dc=istituto,dc=it
nss_base_group  ou=Group,dc=istituto,dc=it

e ora l'ultimo passo è quello di attivare il NSS a consultare LDAP:

# /etc/nsswitch.conf
passwd:         compat ldap
group:          compat ldap
shadow:         compat ldap

Configurazione client "reali"

Per la configurazione dei client reali rimandiamo al già citato documento di Paternò. Ricordiamo solo che occorre configurare opportunamente le tabelle di routing.

Sperimentazione interattiva

Da questo punto in poi iniziano le attività interattive che si possono sperimentare alla conclusione dello script lab.

Login

Per sperimentare il login ci posizioniamo sul nodo client e ci loggiamo come utente mrossi (password: bianchi):

client login: mrossi
Password for mrossi@ISTITUTO.IT:bianchi 

mrossi@client$ klist -5
Ticket cache: FILE:/tmp/krb5cc_500_p6FFBQ
Default principal: mrossi@ISTITUTO.IT

Valid starting     Expires            Service principal
08/20/05 21:12:33  08/21/05 07:12:32  host/client.istituto.it@ISTITUTO.IT
08/20/05 21:12:33  08/21/05 07:12:32  krbtgt/ISTITUTO.IT@ISTITUTO.IT

possiamo verificare che il login è avvenuto correttamente e ha prodotto un token relativo alla "workstation" client e un Ticket Granting Ticket (TGT) (screenshot).

Accesso ftp kerberizzato

Per sperimentare il servizio ftp, sempre dal nodo client diamo il comando:

mrossi@srv$ ftp srv
Connected to srv.istituto.it.
220 srv FTP server (Version 5.60) ready.
334 Using authentication type GSSAPI; ADAT must follow
GSSAPI accepted as authentication type
GSSAPI authentication succeeded
Name (srv:mrossi):INVIO
232 GSSAPI user mrossi@ISTITUTO.IT is authorized as mrossi
Remote system type is UNIX.
Using binary mode to transfer files.
ftp> quit
221 Goodbye.

verifichiamo che l'utente ha acquisito automaticamente anche il token per il servizio ftp (screenshot):

mrossi@srv$ klist -5
Ticket cache: FILE:/tmp/krb5cc_500_p6FFBQ
Default principal: mrossi@ISTITUTO.IT

Valid starting     Expires            Service principal
08/20/05 21:12:33  08/21/05 07:12:32  host/client.istituto.it@ISTITUTO.IT
08/20/05 21:12:33  08/21/05 07:12:32  krbtgt/ISTITUTO.IT@ISTITUTO.IT
08/20/05 21:15:12  08/21/05 07:12:32  ftp/srv.istituto.it@ISTITUTO.IT

Accesso telnet kerberizzato

Per sperimentare il servizio telnet, sempre dal nodo client diamo il comando:

mrossi@srv$ telnet -l mrossi srv
telnet -l mrossi srv
Trying 192.168.10.10...
Connected to srv.istituto.it (192.168.10.10).
Escape character is '^]'.
[ Kerberos V5 accepts you as ``mrossi@ISTITUTO.IT'' ]
Last login: Thu Aug 18 18:32:30 from client
Linux x 2.4.26-bs1 #2 Sun Jul 31 10:36:46 CEST 2005 i686 GNU/Linux
mrossi@srv$ exit
logout
Connection closed by foreign host.

verifichiamo che l'utente ha acquisito automaticamente anche il token per il servizio telnet (screenshot):

mrossi@srv$ klist -5
Ticket cache: FILE:/tmp/krb5cc_500_p6FFBQ
Default principal: mrossi@ISTITUTO.IT

Valid starting     Expires            Service principal
08/20/05 21:12:33  08/21/05 07:12:32  host/client.istituto.it@ISTITUTO.IT
08/20/05 21:12:33  08/21/05 07:12:32  krbtgt/ISTITUTO.IT@ISTITUTO.IT
08/20/05 21:15:12  08/21/05 07:12:32  ftp/srv.istituto.it@ISTITUTO.IT
08/20/05 21:17:04  08/21/05 07:12:32  host/srv.istituto.it@ISTITUTO.IT

Accesso http kerberizzato

Ora possiamo chiedere un token e verificare il risultato:

knoppix@realHost$ kinit
Password for knoppix@ISTITUTO.IT:secret

knoppix@realHost$  klist -5
Ticket cache: FILE:/tmp/krb5cc_1000
Default principal: knoppix@ISTITUTO.IT

Valid starting     Expires            Service principal
08/20/05 15:28:32  08/21/05 01:28:29  krbtgt/ISTITUTO.IT@ISTITUTO.IT

(screenshot).
Prima di provare l'accesso http configuriamo firefox affinchè utilizzi kerberos non solo per le sessioni https.
Ora proviamo l'accesso http:

knoppix@realHost$ mozilla http://srv/protected/index.php

Dallo (screenshot) possiamo verificare che REMOTE_USER è valorizzato a knoppix@ISTITUTO.IT riportando quindi anche il Kerberos Principal.
Controlliamo i token a disposizione:

knoppix@realHost$ klist -5
Ticket cache: FILE:/tmp/krb5cc_1000
Default principal: knoppix@ISTITUTO.IT

Valid starting     Expires            Service principal
08/20/05 15:28:32  08/21/05 01:28:29  krbtgt/ISTITUTO.IT@ISTITUTO.IT
08/20/05 15:37:15  08/21/05 01:28:29  HTTP/srv.istituto.it@ISTITUTO.IT

Accesso ldap kerberizzato

Verifichiamo i SASL supportati dal lato server:

root@srv# ldapsearch -h ldap -x -b "" -s base \
  -LLL supportedSASLMechanisms
supportedSASLMechanisms: GSSAPI
supportedSASLMechanisms: NTLM
supportedSASLMechanisms: OTP
supportedSASLMechanisms: DIGEST-MD5
supportedSASLMechanisms: CRAM-MD5

e ora controlliamo il database:

root@srv# ldapsearch -h ldap -x -b "dc=istituto,dc=it" -W \
  -D "cn=ldapadm,ou=People,dc=istituto,dc=it"  "objectClass=*"
Enter LDAP Password:secret
[...]

Facciamo la controprova: cambiamo la password del principal ldapadm in kerberos e vediamo se tutto continua a tornare:

root@srv# kadmin -p krbadm
Authenticating as principal krbadm with password.
Password for krbadm@ISTITUTO.IT: secret
kadmin: cpw ldapadm
Enter password for principal "ldapadm": qwerty
Re-enter password for principal "ldapadm": qwerty
Password for "ldapadm@ISTITUTO.IT" changed.
kadmin: q
root@srv# ldapsearch -h ldap -x -b "dc=istituto,dc=it" -W \
  -D "cn=ldapadm,ou=People,dc=istituto,dc=it"  "objectClass=*"
Enter LDAP Password:qwerty
[...]

Funziona: effettivamente va a pescare la password su kerberos!

Lo schema di autorizzazioni (ACL) abilita la modifica al solo utente amministrativo. Abbiamo voluto verificare questo vincolo utilizzando il browser grafico gq che purtroppo ha le funzionalità GSSAPI disabilitate perchè con troppi bachi. In modalità "simple" abbiamo ottenuto questo risultato nel caso di BIND con cn=ldapadm,ou=People,dc=istituto,dc=it e quest'altro risultato nel caso di BIND con cn=Mario Rossi,ou=People,dc=istituto,dc=it.

Lasciamo al lettore l'esercizio di verificare la "visibilità" del campo userPassword utilizzando GSSAPI.

Per controllare l'autenticazione con kerberos:

client login: mrossi
Password for mrossi@ISTITUTO.IT:bianchi
mrossi@client$ klist -5
Ticket cache: FILE:/tmp/krb5cc_500_CcEKZG
Default principal: mrossi@ISTITUTO.IT

Valid starting     Expires            Service principal
08/20/05 21:44:25  08/21/05 07:44:25  host/client.istituto.it@ISTITUTO.IT
08/20/05 21:44:25  08/21/05 07:44:25  krbtgt/ISTITUTO.IT@ISTITUTO.IT

mrossi@client$ ldapsearch -h ldap -b "dc=istituto,dc=it" "objectClass=*"
SASL/GSSAPI authentication started
SASL username: mrossi@ISTITUTO.IT
SASL SSF: 56
SASL installing layers
[...]

mrossi@client$ klist -5
Ticket cache: FILE:/tmp/krb5cc_500_CcEKZG
Default principal: mrossi@ISTITUTO.IT

Valid starting     Expires            Service principal
08/20/05 21:44:25  08/21/05 07:44:25  host/client.istituto.it@ISTITUTO.IT
08/20/05 21:44:25  08/21/05 07:44:25  krbtgt/ISTITUTO.IT@ISTITUTO.IT
08/20/05 21:45:55  08/21/05 07:44:25  ldap/ns.istituto.it@ISTITUTO.IT

(screenshot)

Creative Commons License FREE THE MOUSE Valid HTML! Sandro Doro (email me)
Ultima modifica: $Date: 2006-08-30 12:25:22 $