Cuando tenés una configuración master -> slaves, los slaves son read-only, por lo que no guardarán ningún atributo por si mismos, sino que replican lo que tiene el master. Esto es, si por ejemplo están utilizando un slave como ldap server, varios intentos fallidos de login nunca bloquearán la cuenta, porque el tipo no guardará el atributo pwdAccountLockedTime en ningún lado. Esto es lo mismo que sucede cuando intentan hacer un change password y están usando un slave, el pass no se puede cambiar.
Para solucionar este problema, OpenLDAP provee la alternativa de que los slave redirijan los updates al master. Esto es, si alguien quiere actualizar un valor en el slave, el slave redirigirá el update al ldap master, y lo obtendrá por replicación. La solución comprende utilizar updateref, enconjunto con el overlay chain y la opción ppolicy_forward_updates, donde:
- updateref "<master ldap server>" indica a qué servidor LDAP enviar los updates (se utiliza sólo en slaves). Esta opción por sí sola retorna al cliente la URL del master ldap, y es el cliente quien se debe encargar de tomar esa URL y hacer el update allí.
- El overlay chain facilita lo anterior, haciendo que el update lo haga el mismo slave, en lugar de retornar la URL del master al cliente. Con chain podemos configurar que si alguna acción dispara un update, el slave se conecte al master y lo aplique. Para ello, hay que configurar un usuario de binding que en el master tenga permisos de escritura para los atributos que deberá actualizar. Este overlay también se usa para resolver DNs que no están replicados en el slave, ya que sin él, OpenLDAP retornará un redirect que el cliente final deberá seguir.
- ppolicy_forward_updates es la opción del overlay ppolicy que le indica que debe forwardear los password failures, ya que sino asume que es un master y no dispara el hook de redirect.
Veamos todo junto en un ejemplo, donde el ldap master se llama masterserver.dvpem.org. Esta config es para el slave y va en slapd.conf. Incluí sólo las líneas relevantes de la configuración, no es una configuración slapd.conf completa.
IMPORTANTE:
- La configuración del overlay chain debe ir lo más arriba posible, antes de la configuración de cualquier base de datos y de la configuración de replicación.
- updateref debe ir luego de la configuración de replicación (syncrelp).
- El usuario que utilicen para el overlay chain debe tener permiso manage sobre los atributos de password. Por ejemplo, este es el permiso necesario para un user SlaveUpdater:
{0}to dn.subtree="ou=people,dc=dvpem,dc=org" attrs=pwdChangedTime,pwdAccountLockedTime,pwdFailureTime,pwdHistory,pwdGraceUseTime,pwdReset by dn.base="cn=SlaveUpdater,dc=dvpem,dc=org" manage by * +0 break
... #importamos el módulo que contiene el overlay chain moduleload back_ldap.la #cargamos el overlay overlay chain #definimos cuál es la URL del master y con qué usuario bindear. Recuerden que el user debe tener permiso manage. chain-uri "ldap://masterserver.dvpem.org" chain-idassert-bind bindmethod="simple" binddn="cn=SlaveUpdater,dc=dvpem,dc=org" credentials="elpassdeSlaveUpdater" mode="self" #starttls=yes #necesario si usamos ldaps como protocolo #tls_reqcert=allow #necesario si usamos ldaps como protocolo chain-return-error TRUE ... ... #cargamos el overlay ppolicy moduleload ppolicy.la overlay ppolicy #indicamos dónde está la pólicy default de password (largo, cantidad de intentos, etc). Misma config que en el master. ppolicy_default "cn=default,ou=Policies,dc=dvpem,dc=org" #indicamos que se deben forwardear los updates al master ppolicy_forward_updates ... ... #configuración estándar syncrelp syncrelp rid=001 provider=ldap://masterserver.dvpem.org type=refreshAndPersist interval=00:00:02:00 retry="30 10 120 +" searchbase="dc=dvpem,dc=org" attrs="*,+" bindmethod=simple binddn="cn=replicator,dc=dvpem,dc=org" credentials=elpassdelreplicator tls_reqcert=allow #especificamos a dónde redirigir los updates updateref "ldap://masterserver.dvpem.org"Si tienen configurado el slave para utilizar la base cn=config, deberán ejecutar el diguiente ldif (aquí lo llamo enable-ppolicy-forward.ldif):
dn: cn=module{0},cn=config
changetype: modify
add: olcModuleLoad
olcModuleLoad: back_ldap
dn: olcOverlay={0}chain,olcDatabase={-1}frontend,cn=config
changetype: add
objectClass: olcOverlayConfig
objectClass: olcChainConfig
olcOverlay: {0}chain
olcChainCacheURI: FALSE
olcChainMaxReferralDepth: 1
olcChainReturnError: TRUE
dn: olcDatabase=ldap,olcOverlay={0}chain,olcDatabase={-1}frontend,cn=config
changetype: add
objectClass: olcLDAPConfig
objectClass: olcChainDatabase
olcDatabase: ldap
olcDbURI: "ldaps://masterserver.dvpem.org"
olcDbStartTLS: none starttls=no
olcDbIDAssertBind: mode=self
flags=prescriptive,proxy-authz-non-critical
bindmethod=simple
timeout=0
network-timeout=0
binddn="cn=SlaveUpdater,dc=dvpem,dc=org"
credentials="elpassdeSlaveUpdater"
keepalive=0:0:0
starttls=yes
tls_cert="/etc/ldap/ssl/certificado.pem"
tls_key="/etc/ldap/ssl/certificado.pem"
tls_cacert="/etc/ldap/ssl/certificado.pem"
tls_reqcert=allow
tls_cipher_suite=NORMAL
olcDbRebindAsUser: FALSE
olcDbChaseReferrals: TRUE
olcDbTFSupport: no
olcDbProxyWhoAmI: FALSE
olcDbProtocolVersion: 3
olcDbSingleConn: FALSE
olcDbCancel: abandon
olcDbUseTemporaryConn: FALSE
olcDbConnectionPoolMax: 16
olcDbSessionTrackingRequest: FALSE
olcDbNoRefs: FALSE
olcDbNoUndefFilter: FALSE
dn: olcDatabase={1}hdb,cn=config
changetype: modify
add: olcUpdateRef
olcUpdateRef: ldaps://masterserver.dvpem.org
dn: olcOverlay={0}ppolicy,olcDatabase={1}hdb,cn=config
changetype: modify
replace: olcPPolicyForwardUpdates
olcPPolicyForwardUpdates: TRUE
Ejecutamos el ldif con ldapmodify (cambien el usuario admin por el que corresponda a ustedes):
ldapmodify -D "cn=admin,cn=config" -W -f enable-ppolicy-forward.ldif
Como siempre, espero que les haya resultado útil. Yo perdí un buen rato hasta entender cómo funciona esta lógica.

1 comentarios:
Interesting post! This is really helpful for me. I like it! Thanks for sharing.
Publicar un comentario