Kerberos+LDAP+NFSv4
Kerberos
Kerberos é un protocolo de autenticación que permite a ordenadores nunha rede insegura identificarse mutuamente de xeito seguro. Tanto os clientes coma o servidor verificarán a identidade un do outro. Kerberos básase en criptografía de chave simétrica e precisa dun terceiro de confianza, ainda que existen extensións que permiten o uso de criptografía de chave asimétrica. Kerberos establece tamén unha duración das autorizacións, de xeito que únicamente é necesario autenticarse unha vez ata que caduque a concesión.
O funcionamento de Kerberos emprega 2 entidades (servidores), o Servidor de Autenticación (SA) e o Servidor de Tickets de Acceso (TGS) co obxecto de asegurar o acceso a un servicio ofrecido por un Proveedor de Servizo (SS) como NFS. Estes dous servidores forman parte do servidor kerberos, que atenderá as solicitudes mediante o seguinte intercambio de mensaxes:
- O usuario introduce no cliente o seu usuario e contrasinal
- O cliente transforma o contrasinal con cifrado de un so sentido, creando a chave segreda do cliente.
- O cliente envía unha mensaxe en claro ao SA solicitando servicio para o usuario identificado.
- O SA verifica que o usuario está na súa base de datos obtendo a súa contrasinal da BBDD e xerando a chave segreda do cliente que cotexará coa recibida. Si coinciden se crearán dúas mensaxes que se envían ao cliente:
- Mensaxe A
- O SA Crea unha mensaxe cifrada coa chave segreda do cliente, chamada Client/TGS Session Key.
- Mensaxe B
- O SA obteń o contrasinal do TGS da BBDD e xenera con ela unha mensaxe cifrada que conten: ID de cliente, dirección IP do cliente, periodo de validez do ticket, e o Client/TGS Session Key. Esta mensaxe é o Ticket Granting Ticket (TGT).
- O cliente descifra a Client/TGS Session Key da Mensaxe A, que se utilizará para a comunicación co TGS.
- Cando o cliente precise un servicio, necesitará solicitarllo ao TGS mediante as seguintes mensaxes:
- Mensaxe C
- Composta polo TGT e a ID do servicio solicitado.
- Mensaxe D
- Cifrado coa Client/TGS Session Key obtida da Mensaxe A e composta polo ID de cliente e unha marca de tempo, chamada Autenticador.
- O TGS descifra o TGT da Mensaxe C obtendo a Client/TGS Session Key necesaria para descifrar a Mensaxe D (Autenticador) e obtendo así o ID de cliente e a marca de tempo
- O TGS con esta información crea unha mensaxe composta pola ID de cliente,IP do cliente,Periodo de validez e a Client/Server Session Key xenerada para a comunicación. Esta mensaxe se cifra coa Chave Segreda do Servizo e se chama Client-To-Server Ticket (Mensaxe E). Tamén se crea outra mensaxe composta pola Client/Server Session Key cifrada coa Client/TGS Session Key (Mensaxe F). Se envían estas dúas mensaxes ao cliente
- Unha vez recibidas estas mensaxes, o cliente poderá autenticarse para acceder ao servizo enviando ao Proveedor do Servizo (SS) a Mensaxe E, e unha nova mensaxe cifrada coa Client/Server Session Key obtida da Mensaxe F que terá o ID do cliente e unha Marca de Tempo.
- O proveedor de servizo (SS) descifrará a Mensaxe E coas súa chave sergreda obtendo así a Client/Server Session Key que lle permitirá descifrar a Mensaxe F e crear unha mensaxe de autorización de acceso ao servizo (Mensaxe H) composta pola marca de tempo obtida da Mensaxe F+1 e cifrada coa Client/Server Session Key.
- O cliente descifra a mensaxe de autorización e confirma a corrección da marca de tempo. Si é correcto, poderá empezar a utilizar o servizo.
Instalación de Kerberos
En Linux existen dúas versións de Kerberos: Heimdall e MIT. Utilizaremos MIT.
Os tickets kerberos teñen periodos de validez establecidos, polo que resulta importante a sincronización dos distintos ordenadores da rede. Para manter a sincronización podemos facer uso de ntp ou do paquete ntpdate, que combinado con cron nos permitirá manter o tempo en sincronía en todos os ordenadores da rede. Se recomenda a versión 5 de Kerberos, xa que a versión 4 ten diversas vulnerabilidades e debilidades no cifrado. E tamén necesario que todos os equipos que utilicen Kerberos sexan resoltos de modo axeitado, tanto de modo directo como inverso, polo que e convinte un servidor DNS, e incluso engadir ao /etc/hosts os servidores e clientes implicados para asegurar o posible fallo do DNS.
Kerberos soporta replicación a múltiples servidores, recomendándose o uso de polo menos dous, un maestro que será o servidor Primario (PDC) e outro Secundario que estará dispoñible para cubrir posibles fallos do maestro (BDC). Os clientes Kerberos utilizarán o servidor secundario automáticamente no caso de fallo do primario.
Instalaremos o servidor Kerberos:
- Instalación do software:
apt-get install krb5-kdc krb5-admin-server
Durante a instalación se solicitará:
- O nome do dominio Kerberos (Realm), que normalmente será o noso dominio en maiúsculas: IESRODEIRA.COM
- Os servidores Kerberos para o dominio, que serán en primeiro lugar o PDC, e logo o BDC: krbldap-pdc.iesrodeira.com krbldap-bdc.iesrodeira.com
- O nome do servidor administrativo (PDC): krbldap-pdc.iesrodeira.com
- Debemos modificar /etc/krb5.conf para incluir a información do noso dominio kerberos na sección [domain-realm] e un apartado para configurar os log de kerberos
mkdir /var/log/kerberos chmod 750 /var/log/kerberos
[domain-realm] .iesrodeira.com = IESRODEIRA.COM iesrodeira.com = IESRODEIRA.COM [logging] kdc=FILE:/var/log/kerberos/krb5kdc.log admin_server=FILE:/var/log/kerberos/kadmin.log default=FILE:/var/log/kerberos/krb5lib.log
- A continuación creamos a base de datos para Kerberos, para o que necesitará recolectar información aleatoria (tardará un pouco) e solicitarnos unha password que será imprescindible para o decodificado da base de datos:
krb5_newrealm service krb5-admin-server restart && service krb5-kdc restart
- Xa podemos empezar a engadir servidores e usuarios a base de datos Kerberos (principals) mediante a utilidade kadmin.local. Os principals Kerberos teñen a forma SPEC@REALMKERBEROS (no noso caso SPEC@IESRODEIRA.COM), donde SPEC normalmente ten a forma de usuario/rol ou servizo/hostname (por exemplo, root/admin, ou nfs/nfs.iesrodeira.com). Estas SPEC se poden utilizar logo no ficheiro /etc/krb5kdc/kadm5.acl para establecer ACLS especificando permisos.
- As password para os principals poden organizarse mediante políticas (policies) que forzan distintos graos de fortaleza (-minlength, -minclasses, -maxlife, -minlife, -maxfailure, -failurecountinterval, -lockoutduration), creando primeiro as políticas como por exemplo:
add_policy -minlength 8 -minclasses 1 user add_policy -minlength 8 -minclasses 3 admin
- Para posteriormente crear o principal cunha política determiñada:
addprinc -policy user root/admin
- Ou cambiar de política un principal existente:
modprinc -policy admin root/admin
- Polo tanto, creamos as políticas e un principal para poder acceder a configuración Kerberos dende calqueira equipo cliente:
add_policy -minlength 6 -minclasses 1 user add_policy -minlength 8 -minclasses 2 admin addprinc -policy admin root/admin
- E editaremos /etc/krb5kdc/kadm5.acl, especificando */admin *, indicando que todos os usuarios co rol admin teñen todos os privilexios de administración. A partir deste momento poderemos administrar o servicio Kerberos dende calqueira cliente coa utilidade kadmin, crear tickets coa utilidade kinit, examinalos (klist) e eliminalos (kdestroy).
- [domain_realm] conten o mapeo ao dominio correcto
- default_realm ten o valor correcto
- o realm está definido na sección [realms]
Podemos comprobar o correcto funcionamento creando un ticket para o principal creado, listando o ticket (TGT) e destruíndolo:
kinit -p root/admin klist kdestroy
- Creamos un principal no PDC para o servidor PDC mediante a utilidade kadmin cunha chave aleatoria, xa que unha máquina non pode introducir unha chave, e creamos o ficheiro local para as chaves.
addprinc -randkey host/krbldap-pdc.iesrodeira.com ktadd host/krbldap-pdc.iesrodeira.com
Unha boa idea sería crear o ficheiro /etc/logrotate.d/krb5-kdc cun contido similar a este:
/var/log/kerberos/krb5lib.log /var/log/kerberos/kadmin.log /var/log/kerberos/krb5lib.log { daily missingok rotate 7 compress delaycompress notifempty postrotate /etc/init.d/krb5-kdc restart > /dev/null /etc/init.d/krb5-admin-server restart > /dev/null endscript }
Tamén sería unha boa práctica alterar a vida dos tickets:
~# kadmin.local Authenticating as principal root/admin@EXAMPLE.COM with password. kadmin.local: modprinc -maxlife "1 day" -maxrenewlife "90 day" krbtgt/IESRODEIRA.COM@IESRODEIRA.COM Principal "krbtgt/IESRODEIRA.COM@IESRODEIRA.COM" modified. kadmin.local: q
e modificando o ficheiro /etc/krb5kdc/kdc.conf para reflexar os cambios cambiando as liñas:
max_life = 1d 0h 0m 0s max_renewable_life = 90d 0h 0m 0s
Servidor Slave (BDC)
- Debemos instalar o paquete krb5-user e contestar ás preguntas:
apt-get install krb5-user
- Creamos un principal no PDC para o servidor esclavo mediante a utilidade kadmin cunha chave aleatoria, xa que unha máquina non pode introducir unha chave, e creamos o ficheiro local para as chaves.
addprinc -randkey host/krbldap-bdc.iesrodeira.com ktadd host/krbldap-bdc.iesrodeira.com
- Instalamos a parte servidor. Necesitaremos xinetd para configurar o servicio de propagación kpropd.
apt-get install krb5-kdc xinetd
- Engadimos o servizo kpropd a xinetd creando o ficheiro /etc/xinetd.d/krb_prop e poñendo:
service krb_prop { disable = no socket_type = stream protocol = tcp user = root wait = no server = /usr/sbin/kpropd }
- Inciamos o servizo xinetd
service xinetd restart
- Configuramos a propagación da base de datos Kerberos do primario ao secundario
- Creamos o ficheiro cos controladores Kerberos do noso reino en /etc/krb5kdc/kpropd.acl nos dous controladores. O contido será o seguinte:
host/krbldap-pdc.iesrodeira.com@IESRODEIRA.COM host/krbldap-bdc.iesrodeira.com@IESRODEIRA.COM
- No controlador primario creamos un backup da base de datos Kerberos e a enviamos ao controlador secundario
kdb5_util dump /var/lib/krb5kdc/slave_datatrans kprop krbldap-bdc.iesrodeira.com
- De volta no controlador secundario creamos un ficheiro cunha copia da chave mestra Kerberos:
kdb5_util stash
- Xa podemos iniciar o servizo co comando service krb5-kdc start
A propagación das modificacións da base de datos Kerberos no controlador primario non se propagan ao secundario de xeito automático, polo que é aconsellable crear un script que se encarge da migración de xeito periódico mediante a utilidade cron. Crearemos o ficheiro /etc/cron.hourly/krb5-prop co seguinte contido:
#!/bin/sh
slavekdcs=krbldap-bdc.iesrodeira.com
/usr/sbin/kdb5_util dump /var/lib/krb5kdc/slave_datatrans
error=$?
if [ $error -ne 0 ]; then
echo "Kerberos database dump failed"
echo "with exit code $error. Exciting."
exit 1
fi
for kdc in $slavekdcs; do
/usr/sbin/kprop $kdc > /dev/null
error=$?
if [ $error -ne 0 ]; then
echo "Propagation of database to host $kdc"
echo "failed with exit code $error."
fi
done
exit 0
LDAP
X.500 é unha colección de protocolos, especificacións e definicións sobre o concepto de unha árbore global de información de directorio (DIT) sinxela, distribuída e replicada. Esta DIT sería capaz de almacenar todo tipo de información accesible mediante o Protocolo de Acceso ao Directorio (DAP).
da raíz de un DIT para o ies de rodeira podería ser dc=iesrodeira,dc=com, mentras que o DN de un profesor do instituto sería cn=Xavi,ou=Claustro,dc=iesrodeira,dc=com. O Relative Distinguished Name (RDN) de esta entrada sería cn=Xavi. Cada DN consiste en múltiples parellas de chave=valor. As chaves neste exemplo son abreviaturas para Common Name (cn), Organizational Unit (ou) e Domain Component (dc).
LDAP (LightWeight Directory Access Protocol) é un protocolo de acceso a bases de datos de directorio (Servicios de Directorio) que implementa un subconxunto do estándar X.500. Os servicios de directorio caracterízanse por ser sistemas con moitos accesos de lectura e moi poucas insercións e actualizacións, polo tanto están optimizadas para consultas rápidas.
Este tipo de bases de datos poden almacenar e organizar, por exemplo, a información sobre usuarios dunha rede e os recursos da mesma.LDAP xunto con Kerberos forma o núcleo do sistema de Active Directory de Microsoft Windows, e de moitas outras implementacións como Novell eDirectory ou o RedHat Directory Service.
As bases de datos LDAP teñen forma de árbore, dandolle ao administrador a posibilidade de crear as distintas ramas (DIT, Directory Information Tree), especificando en primeiro lugar a raíz da árbore, que normalmente é o dominio da organización, como pode ser dc=iesrodeira, dc=com (dc é unha abreviatura de Domain Component).
As distintas entradas na árbore LDAP se representan habitualmente en formato LDIF (LDAP Data Interchange Format) que indican o nome (dn) da nova entrada e os seus atributos.
Realizaremos unha instalación de OpenLDAP para almacenar a base de datos dos usuarios do sistema e dos servicios Kerberos, e configuraremos os clientes do modo apropiado.
Instalación de OpenLDAP
1.- Instalamos OpenLDAP
apt-get install slapd ldap-utils
2.-Configuramos de modo apropiado o ficheiro /etc/ldap/ldap.conf
BASE dc=iesrodeira,dc=com
URI ldap://krbldap-pdc.iesrodeira.com ldap://krbldap-bdc.iesrodeira.com
TLS_CACERT /etc/ssl/certs/ca-certificates.crt
3.- A configuración inicial por defecto do esquema LDAP é a seguinte:
root@krbldap-pdc:~/LDAP_configs# slapcat
dn: dc=iesrodeira,dc=com
objectClass: top
objectClass: dcObject
objectClass: organization
o: iesrodeira.com
dc: iesrodeira
structuralObjectClass: organization
entryUUID: 8cfe1ca6-cadc-1032-8ccb-2d2a52bafa1f
creatorsName: cn=admin,dc=iesrodeira,dc=com
createTimestamp: 20131016182851Z
entryCSN: 20131016182851.761222Z#000000#000#000000
modifiersName: cn=admin,dc=iesrodeira,dc=com
modifyTimestamp: 20131016182851Z
dn: cn=admin,dc=iesrodeira,dc=com
objectClass: simpleSecurityObject
objectClass: organizationalRole
cn: admin
description: LDAP administrator
userPassword:: e1NTSEF9ekxHT0c5bXpjWnAvRkFrUVRkc0IweVVHejczZFVHbU0=
structuralObjectClass: organizationalRole
entryUUID: 8d29617c-cadc-1032-8ccc-2d2a52bafa1f
creatorsName: cn=admin,dc=iesrodeira,dc=com
createTimestamp: 20131016182852Z
entryCSN: 20131016182852.044793Z#000000#000#000000
modifiersName: cn=admin,dc=iesrodeira,dc=com
modifyTimestamp: 20131016182852Z
- E os esquemas instalados:
root@krbldap-pdc:~/LDAP_configs# ldapsearch -LLL -Y EXTERNAL -H ldapi:/// -b cn=config dn
SASL/EXTERNAL authentication started
SASL username: gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth
SASL SSF: 0
dn: cn=config
dn: cn=module{0},cn=config
dn: cn=schema,cn=config
dn: cn={0}core,cn=schema,cn=config
dn: cn={1}cosine,cn=schema,cn=config
dn: cn={2}nis,cn=schema,cn=config
dn: cn={3}inetorgperson,cn=schema,cn=config
dn: olcBackend={0}hdb,cn=config
dn: olcDatabase={-1}frontend,cn=config
dn: olcDatabase={0}config,cn=config
dn: olcDatabase={1}hdb,cn=config
- Activaremos un modo que nos deixe máis información nos logs, e creamos varios índices para mellorar as velocidades de busca. Creamos o seguinte ficheiro inicializa.ldif
# 1.
dn: cn=config
changetype: modify
replace: olcLogLevel
olcLogLevel: stats
# 2.1.
dn: olcDatabase={1}hdb,cn=config
changetype: modify
add: olcDbIndex
olcDbIndex: uid eq
-
# 2.2.
add: olcDbIndex
olcDbIndex: cn eq
-
# 2.3.
add: olcDbIndex
olcDbIndex: ou eq
-
# 2.4.
add: olcDbIndex
olcDbIndex: dc eq
- e o cargamos no esquema LDAP coa orde:
ldapmodify -QY EXTERNAL -H ldapi:/// -f inicializa.ldif
- Podemos verificar os cambios executando:
ldapsearch -LLLQY EXTERNAL -H ldapi:/// -b cn=config "(|(cn=config)(olcDatabase={1}hdb))"
Replicación no BDC
- A replicación se realiza co módulo Syncrepl. Syncrepl permite que os cambios se envíen seguindo un modelo proveedor-consumidor. O proveedor enviará os cambios do directorio LDAP aos consumidores. Instalaremos o servidor secundario:
apt-get install slapd ldap-utils
- e configuramos de modo apropiado o ficheiro /etc/ldap/ldap.conf
BASE dc=iesrodeira,dc=com
URI ldap://krbldap-bdc.iesrodeira.com ldap://krbldap-pdc.iesrodeira.com
TLS_CACERT /etc/ssl/certs/ca-certificates.crt
- En primeiro lugar será necesario crear no servidor primario (productor)un obxecto de tipo organizationalRole no servidor primario (productor) para representar o secundario (consumidor). Crearemos un ficheiro consumer_role.ldif co seguinte contido:
dn: cn=krbldap-bdc,dc=iesrodeira,dc=com
objectClass: simpleSecurityObject
objectClass: organizationalRole
cn: krbldap-bdc
description: LDAP replicator
userPassword: {SSHA}2jOUxdjQthjBS5Ot3/YlAo+IHJ1nbACi
- Engadiremos consumer_role.ldif a árbore ldap (no primario):
ldapadd -cxWD cn=admin,dc=example,dc=com -f consumer_role.ldif
- Necesitaremos autorizar no servidor primario (proveedor) o acceso ao secundario, para eso creamos o ficheiro consumer_auth.ldif co seguinte contido:
# 1.1.1.
dn: olcDatabase={1}hdb,cn=config
changetype: modify
delete: olcAccess
olcAccess: {0}to attrs=userPassword,shadowLastChange
by self write
by anonymous auth
by dn="cn=admin,dc=iesrodeira,dc=com" write
by * none
-
# 1.1.2.
add: olcAccess
olcAccess: {0}to attrs=userPassword,shadowLastChange
by self write
by dn="cn=admin,dc=iesrodeira,dc=com" write
by dn="cn=krbldap-bdc,dc=iesrodeira,dc=com" read
by anonymous auth
by * none
-
# 1.2.
add: olcDbIndex
olcDbIndex: entryUUID eq
-
# 1.3.
add: olcDbIndex
olcDbIndex: entryCSN eq
# 2.
dn: cn=module{0},cn=config
changetype: modify
add: olcModuleLoad
olcModuleLoad: {1}syncprov
# 3.
dn: olcOverlay=syncprov,olcDatabase={1}hdb,cn=config
changetype: add
objectClass: olcOverlayConfig
objectClass: olcSyncProvConfig
olcOverlay: {0}syncprov
olcSpCheckpoint: 100 10
olcSpSessionlog: 100
- Instalaremos o ldif co comando:
ldapmodify -QY EXTERNAL -H ldapi:/// -f consumer_auth.ldif
- No servidor secundario (consumer) crearemos varios índices para acelerar o acceso, aumentaremos o nivel de log e indicaremos que active Syncreply para sincronizar a súa base de datos co productor. Para facer esto, creamos o arquivo consumer.ldif:
# 1.
dn: cn=config
changetype: modify
replace: olcLogLevel
olcLogLevel: stats
# 2.1.1.
dn: olcDatabase={1}hdb,cn=config
changetype: modify
delete: olcAccess
olcAccess: {0}to attrs=userPassword,shadowLastChange
by self write
by anonymous auth
by dn="cn=admin,dc=iesrodeira,dc=com" write
by * none
-
# 2.1.2.
add: olcAccess
olcAccess: {0}to attrs=userPassword,shadowLastChange
by anonymous auth
by * none
-
# 2.2.1.
delete: olcAccess
olcAccess: {2}to *
by self write
by dn="cn=admin,dc=iesrodeira,dc=com" write
by * read
-
# 2.2.2.
add: olcAccess
olcAccess: {2}to *
by * read
-
# 2.3.
replace: olcRootDN
olcRootDN: cn=manager
-
# 2.4.
delete: olcRootPW
-
# 2.5.
add: olcDbIndex
olcDbIndex: entryCSN eq
-
# 2.6.
add: olcDbIndex
olcDbIndex: entryUUID eq
-
# 2.7.
add: olcDbIndex
olcDbIndex: uid eq
-
# 2.8.
add: olcDbIndex
olcDbIndex: cn eq
-
# 2.9.
add: olcDbIndex
olcDbIndex: ou eq
-
# 2.10.
add: olcDbIndex
olcDbIndex: dc eq
-
# 2.11.
add: olcSyncrepl
olcSyncrepl: rid=123
provider="ldap://krbldap-pdc.iesrodeira.com:389/"
type=refreshAndPersist
retry="60 30 300 +"
searchbase="dc=iesrodeira,dc=com"
bindmethod=simple
binddn="cn=krbldap-bdc,dc=iesrodeira,dc=com"
credentials=xxxxxxxxxx
- Si as actualizacións da base de datos non son moi frecuentes, unha alternativa a anterior para a configuración Syncreply sería:
# 2.11. (alternative)
add: olcSyncrepl
olcSyncrepl: rid=123
provider="ldap://krbldap-pdc.iesrodeira.com:389/"
type=refreshOnly
interval=00:00:05:00
searchbase="dc=iesrodeira,dc=com"
bindmethod=simple
binddn="cn=krbldap-bdc,dc=iesrodeira,dc=com"
credentials=xxxxxxxxx
- Introducimos os cambios, paramos o servizo, eliminamos a base de datos vella, e iniciamos de novo o servizo:
ldapmodify -QY EXTERNAL -H ldapi:/// -f ~/olc-mod1.ldif
/etc/init.d/slapd stop
rm /var/lib/ldap/*
/etc/init.d/slapd start
- Podemos comprobar o funcionamento executando no servidor secundario (consumidor):
root@krbldap-bdc:~# ldapsearch -x -LLL
dn: dc=iesrodeira,dc=com
objectClass: top
objectClass: dcObject
objectClass: organization
o: iesrodeira.com
dc: iesrodeira
dn: cn=admin,dc=iesrodeira,dc=com
objectClass: simpleSecurityObject
objectClass: organizationalRole
cn: admin
description: LDAP administrator
dn: cn=krbldap-bdc,dc=iesrodeira,dc=com
objectClass: simpleSecurityObject
objectClass: organizationalRole
cn: krbldap-bdc
description: LDAP replicator