Table of Contents
LDAP e Kerberos
Introduzione
Questa breve guida illustra i concetti ed i passaggi necessari per configurare OpenStack utilizzando LDAP per la gestione degli utenti e Kerberos per l'autenticazione.
Al fine di evitare il polluting della directory1), si opterà per una directory LDAP separata da altre istanze.
In particolare, in Grizzly Keystone mantiene la struttura "non-standard" con i tenant trasformati in rami LDAP contenenti i ruoli come foglie ed i membri come attributi dei ruoli (si faccia riferimento alle slide della presentazione di Stefano Stalio presso il Workshop CCR 2013 per un'illustrazione dell'albero) e Quantum continua ad autenticarsi diverse volte al minuto contro Keystone, causando in questo modo un numero relativamente elevato di bind alla directory.
Per questi motivi, è consigliabile utilizzare una directory dedicata e quanto più "vicina" possibile a Keystone - possibilmente in esecuzione sulla stessa macchina.
Requisiti
La guida è stata sviluppata e testata nel seguente ambiente:
- Ubuntu 12.04.2 (x86_64)
- OpenStack Grizzly
- Python 2.7
- python-ldap
- setup di OpenStack eseguito utilizzando come riferimento il manuale di OpenStack e la guida d'installazione rapida presente su GitHub.
Non dovrebbe essere complesso adattarla ad ambienti RDO, ma non è stata testata con packstack.
Setup di OpenStack
Si faccia riferimento alla guida, arrestandosi alla configurazione di Keystone.
Setup di OpenLDAP
Come directory server si è scelto OpenLDAP, ma è ugualmente possibile utilizzare 389ds.
Negli esempi (LDIF e file di configurazione di Keystone) si utilizzeranno i seguenti valori:
Parametro | Valore |
---|---|
Dominio | ostack.lngs.infn.it |
Base DN | dc=ostack,dc=lngs,dc=infn,dc=it |
Admin DN | cn=admin,dc=ostack,dc=lngs,dc=infn,dc=it |
Password | admin_pass |
Preparazione della directory
Creare un file chiamato base.ldif
col seguente contenuto:
# Users dn: ou=Users,dc=ostack,dc=lngs,dc=infn,dc=it objectClass: organizationalUnit ou: Users # Tenants dn: ou=Groups,dc=ostack,dc=lngs,dc=infn,dc=it objectClass: organizationalUnit ou: Groups # Roles dn: ou=Roles,dc=ostack,dc=lngs,dc=infn,dc=it objectClass: organizationalUnit ou: Roles # Hardcoded in OpenStack!!!! dn: cn=9fe2ff9ee4384b1894a90878d3e92bab,ou=Roles,dc=ostack,dc=lngs,dc=infn,dc=it objectClass: organizationalRole ou: _member_ cn: 9fe2ff9ee4384b1894a90878d3e92bab # Enabled bit emulation for users dn: cn=enabled_users,dc=ostack,dc=lngs,dc=infn,dc=it objectClass: groupOfNames cn: enabled_users member: cn=dumb,dc=ostack,dc=lngs,dc=infn,dc=it # Enabled bit emulation for tenants dn: cn=enabled_tenants,dc=ostack,dc=lngs,dc=infn,dc=it objectClass: groupOfNames cn: enabled_tenants member: cn=dumb,dc=ostack,dc=lngs,dc=infn,dc=it
Il ruolo con id 9fe2ff9ee4384b1894a90878d3e92bab
è hardcoded in OpenStack ed utilizzato per identificare un membro di un determinato tenant nell'API Nova. Normalmente, questo ruolo viene creato da keystone-manage db_sync
durante l'installazione di Keystone.
Il membro con DN cn=dumb,dc=ostack,dc=lngs,dc=infn,dc=it
è un membro "dummy" necessario per rendere gli oggetti groupOfNames conformi allo schema. Keystone ignorerà questo membro.
Sempre facendo riferimento ad OpenLDAP, applicare le modifiche alla directory con:
ldapmodify -W -D cn=admin,dc=ostack,dc=lngs,dc=infn,dc=it -f base.ldif
Creazione degli indici
(Questa sezione è specifica per OpenLDAP)
Al fine di rendere più efficiente l'accesso alla directory2), è necessario creare degli indici sugli attributi più utilizzati da Keystone per effettuare ricerche.
Creare un file chiamato indexes.ldif
col seguente contenuto:
dn: olcDatabase={1}hdb, cn=config changetype: modify add: olcDbIndex olcDbIndex: cn pres,sub,eq - add: olcDbIndex olcDbIndex: ou pres,sub,eq - add: olcDbIndex olcDbIndex: sn pres,sub,eq - add: olcDbIndex olcDbIndex: roleOccupant pres,eq
Ed applicare le modifiche eseguendo come root:
ldapmodify -Y EXTERNAL -H ldapi:/// -f indexes.ldif
Il setup di OpenLDAP è ora completo e si può procedere con la configurazione di Keystone.
Configurazione di Keystone
Sfortunatamente, la documentazione di Keystone riguardo al supporto ad LDAP è carente o addirittura in aperta contraddizione col codice. Gran parte dei valori corretti sono stati determinati per errori successivi, analisi dei backtrace di Keystone ed in alcuni casi per analisi diretta dei sorgenti.
Prima di tutto, è necessario configurare il driver di identity management per utilizzare LDAP al posto di MySQL:
[identity] driver = keystone.identity.backends.ldap.Identity
Dopodiché è necessario configurare come segue (sempre adattando al vostro ambiente) la sezione ldap di keystone.conf:
[ldap] url = ldap://localhost user = cn=admin,dc=ostack,dc=lngs,dc=infn,dc=it password = ldap_pass suffix = dc=ostack,dc=lngs,dc=infn,dc=it use_dumb_member = True allow_subtree_delete = False dumb_member = cn=dumb,dc=ostack,dc=lngs,dc=infn,dc=it user_tree_dn = ou=Users,dc=ostack,dc=lngs,dc=infn,dc=it user_objectclass = inetOrgPerson user_domain_id_attribute = None user_id_attribute = cn user_name_attribute = sn user_mail_attribute = mail user_pass_attribute = userPassword user_enabled_default = True user_attribute_ignore = tenant_id,tenantId,tenants user_allow_create = True user_allow_update = True user_allow_delete = True user_enabled_emulation = True user_enabled_emulation_dn = cn=enabled_users,dc=ostack,dc=lngs,dc=infn,dc=it tenant_tree_dn = ou=Groups,dc=ostack,dc=lngs,dc=infn,dc=it tenant_objectclass = groupOfNames tenant_domain_id_attribute = businessCategory tenant_id_attribute = cn tenant_member_attribute = member tenant_name_attribute = ou tenant_desc_attribute = description tenant_attribute_ignore = tenantId tenant_enabled_emulation = True tenant_enabled_emulation_dn = cn=enabled_tenants,dc=ostack,dc=lngs,dc=infn,dc=it role_tree_dn = ou=Roles,dc=ostack,dc=lngs,dc=infn,dc=it role_objectclass = organizationalRole role_id_attribute = cn role_name_attribute = ou role_member_attribute = roleOccupant role_attribute_ignore =
Alcuni parametri meritano una spiegazione a sé:
use_dumb_member
contrariamente a quanto riportato nella documentazione è richiesto per poter creare tenant conformi allo schema per oggetti groupOfNamesuser_enabled_emulation
,user_enabled_emulation_dn
e i rispettivi parametri per i tenant sono necessari per emulare la presenza di un campoenabled
, assente sia da inetOrgPerson che da groupOfNames; entrambe le DN devono puntare ad un oggetto di tipo groupOfNames definito in precedenza durante l'inizializzazione della directory- i parametri
user_allow_create
eduser_allow_update
devono essere temporaneamente impostati aTrue
per permettere al setup di Keystone di procedere con successo
Prosecuzione del setup di OpenStack
A questo punto, il setup di OpenStack può proseguire con la creazione di utenti e ruoli di base, service endpoint e l'installazione/configurazione degli altri servizi.
Una volta terminata, è caldamente consigliato impostare user_allow_create
ed user_allow_update
a False
e riavviare Keystone.
Kerberos
L'integrazione con Kerberos avviene per mezzo di saslauthd e del meccanismo password {SASL}
di OpenLDAP.
Prima di procedere, è necessario creare un principal host/FQDN
per il controller node e trasferirlo in /etc/krb5.keytab
sul controller node.
Installazione di saslauthd
Installare saslauthd ed il relativo plugin per GSSAPI. Su Ubuntu:
apt-get -y install sasl2-bin libsasl2-modules-gssapi-mit
A questo punto, saslauthd deve essere configurato per utilizzare GSSAPI come backend di autenticazione. Su Ubuntu è sufficiente modificare /etc/default/saslauthd
in modo da avere i seguenti valori:
START=yes MECHANISM="kerberos5"
E successivamente avviarlo con
service saslauthd start
A questo punto, è possibile testare il funzionamento con
testsaslauthd -s slapd -u user@LNGS.INFN.IT -p 'password'
Se il vostro realm non prevede l'uso di AES, è necessario abilitare allow_weak_crypto
in /etc/krb5.conf
.
Configurazione di OpenLDAP
È ora necessario definire il meccanismo di autenticazione SASL per slapd, creando /usr/lib/sasl2/slapd.conf
col seguente contenuto:
mech_list: plain pwcheck_method: saslauthd saslauthd_path: /var/run/saslauthd/mux
Quindi aggiungere l'utente con cui è in esecuzione OpenLDAP al gruppo sasl:
gpasswd -a openldap sasl
Ed infine riavviare slapd:
service slapd restart
Da questo momento in poi, tutte le password con meccanismo {SASL}
verranno verificate su Kerberos utilizzando saslauthd come proxy.
Gestione degli utenti
Per permettere l'autenticazione degli utenti su Kerberos è necessario che ogni utente abbia come attributo userPassword {SASL}principal@REALM
. Ciò, purtroppo, non è effettuabile tramite Horizon in quanto Keystone utilizza per default il metodo {SSHA}
per salvare le password su LDAP.
Per aggiungere ed abilitare/disabilitare gli utenti, è possibile utilizzare un qualsiasi client LDAP in grado di creare oggetti inetOrgPerson. Presso i LNGS sono in uso una serie di script denominati OSGSA che effettuano le operazioni di registrazione e abilitazione/disabilitazione degli utenti.
Gli script in questione possono essere utilizzati in ambienti OpenStack/LDAP creati secondo le indicazioni di questa guida. Idealmente, dovrebbero essere installati sul controller node e richiedono python-ldap
e python-yaml
.