Continuando con la nota anterior, en esta veremos y analizaremos las variables internas que usa la replicación de Active Directory, para detectar y replicar cambios, como así también la forma de evitar replicaciones redundantes.
El uso que hace Active Directory de que cualquier Controlador de Dominio acepte cambios, y que en teoría cualquiera pueda replicar desde cualquier otro Controlador de Dominio, implica un problema complejo de resolver, ya que los objetivos son: que los cambios se repliquen y la información de todos sea consistente lo antes posible, pero controlando el tráfico de red, y optimizando todo lo posible el tráfico de red y sobre todo en enlaces WAN
Específicamente hablaremos de: USN = Update Sequence Number, HWMV = High Watermark Vector, UTDV = Up-To-Dateness Vector, GUIDs, InvocationIDs, y todos los que sean necesarios para comprender el funcionamiento interno
Vamos al tema. Cada Controlador de Dominio es identificado unívocamente por un GUID (Global Unique IDentifier) que fue asignado durante la creación y que no cambiará durante toda su vida. Este identificador nunca es repetido, ni re-utilizado.
Los que venimos de “vieja época” estamos acostumbrados a los SIDs (Security IDentifiers) y antes decíamos que esa asignación “nunca podía cambiar”, pero actualmente eso no es correcto.
Como actualmente podemos mover cuentas entre diferentes Dominios, y el SID de una cuenta de Dominio contiene al SID del Dominio, es fácil darse cuenta que si muevo una cuenta a otro Dominio obligatoriamente debe cambiar su SID
Y por eso, actualmente el identificador único y permanente es el GUID.
Además, todos los Controladores de Dominio tienen un contador interno y propio que le sirve para identificar cuán actualizados están.
Se denomina USN = Update Sequence Number y es un número de 64 bit
Este USN, reitero, independiente en cada Controlador de Dominio, se incrementa en uno (1) por cada cambio que acepta.
En ningún caso disminuye, ni se reutiliza, salvo restaurando desde una copia de seguridad.
Un cambio en AD generalmente es la creación, actualización o eliminación de un objeto, o inclusive de un atributo de un objeto
Además debemos tener en cuenta que si una transacción fallara, el sistema la deshace por completo, pero no reutiliza el USN
Cuando un objeto es creado o modificado, el atributo usnChanged de dicho objeto incluye el USN de la transacción producida
De esta forma, uno puede saber los cambios que se han producido en Controlador de Dominio, observando el USN del mismo.
O mejor todavía. puedo hacer que el Controlador de Dominio busque todos los objetos cuyo atributo usnChanged es mayor que la última vez que pregunté. Y por lo tanto puedo saber qué cambios necesito que me transfiera.
Para desarrollar un ejemplo práctico, pero teórico, supongamos tener un Dominio con tres Controladores de Dominio. Los llamaré DC-A, DC-B y DC-C para identificarlos.
Partamos además que la información inicialmente es la misma en todos los Controladores de Dominio
Usaré además USNs totalmente ficticios pero fáciles de recordar
Comencemos por algo simple, en DC-A el administrador crea tres grupos
Operación | USN en DC-A | USN en DC-B | USN en DC-C |
USNs inciales | 1000 | 2000 | 3000 |
Creación de 3 grupos | 1003 | 2000 | 3000 |
Replicación de DC-A a DC-B | 1003 | 2003 | 3000 |
Replicación de DC-A a DC-C | 1003 | 2003 | 3003 |
Observamos que ahora los tres Controladores de Dominio tienen la misma información (convergencia)
En DC-A (donde se crearon los grupos) este cambio es considerado un “Originating Write”, en cambio desde DC-B y DC-C que recibieron el cambio, estos son considerados “Replicated Write”
Ahora supongamos que un administrador, conectado a DC-B, actualiza un atributo de uno de los grupos (cualquiera de cualquiera)
Vemos nuevamente la tabla anterior pero actualizada
Operación | USN en DC-A | USN en DC-B | USN en DC-C |
USNs inciales | 1003 | 2003 | 3003 |
Modificación de grupo en DC-B | 1003 | 2004 | 3003 |
Replicación de DC-B a DC-A | 1004 | 2004 | 3003 |
Replicación de DC-B a DC-C | 1004 | 2004 | 3004 |
En este último caso el “Originating Write” es DC-B, y estos cambios son “Replicated Write” en DC-A y DC-C
Ahora vamos a ver cómo es en realidad el tema, cómo se complica y cómo se resuelve.
Hasta ahora hemos planteado la replicación desde un Controlador de Dominio hacia los otros dos, pero debemos tener en cuenta que como cada uno crea dos conexiones entrantes para replicar (ver Parte 1), también existe replicación entre DC-B y DC-C
Por ejemplo, qué sucede cuando DC-B consulta el USN de DC-C, observa que se ha incrementado, y por lo tanto solicita la transferencia del último cambio, que en realidad ya sabemos que lo recibió desde DC-A
Sería una replicación que en realidad no actualizaría nada de datos, pero sí provocaría una actualización del USN de DC-B, que luego sería detectado por DC-A y … quedaríamos en un “loop infinito”.
Esto hay que resolverlo, así que profundicemos un poco más y veamos cómo se hace.
En realidad, el sistema utiliza dos GUIDs en cada Controlador de Dominio. Uno es el nombrado al principio de la nota, y que en realidad es conocido como “DSA GUID” (DSA = Directory Service Agent), es almacenado en el atributo “objectGUID” que podemos observar en Active Directory Sites and Services en las propiedades / Atributos de NTDS Settings del servidor
Este GUID es generado durante la promoción a Controlador de Dominio (DCPROMO), y no cambia
Pero además utiliza otro GUID que lo identifica durante el proceso de replicación, conocido como “Invocation ID”, y como ya veremos puede cambiar bajo determinadas circunstancias
Lo podemos ver en la misma pantalla que el anterior
Un ejemplo de caso de cambio del “Invocation ID”: cuando se hacer una restauración (Restore) de un Controlador de Dominio, o del System State (Estado del Sistema), el “Invocation ID” se vuelve a cero, y de esta forma se asegura que reciba todos los cambios que se han producido desde que se hizo la copia de Seguridad (Backup) y la restauración (Restore)
Al volver a cero el sistema se asegura que recibirá todos los cambios, casi como si fuera un nuevo Controlador de Dominio, y por esto mismo vemos por qué no hay que congelar estados (Snapshots), o recuperar imágenes de Controladores de Dominio
Vamos a ver ahora cómo se hace para que no se repliquen los cambios que ya ha recibido un Controlador de Dominio desde otro
Se utilizan dos vectores: HWMV = Hight-Watermark Vector y UTDV = Up-To-Dateness Vector
El HWMV es mantenido independientemente por cada Controlador de Dominio, para controlar cuál fue la última replicación (en USN) de cada uno de los otros Controladores de Dominio
El UTDV es utilizado por los Controladores de Dominio para no replicar innecesariamente datos ya recibidos
Cuando DC-A le envía a DC-B un pedido de cambios, este incluye su UTDV, entonces DC-B envía sólo los cambios que DC-A no ha recibido
La siguiente tabla muestra el HWMV de DC-A luego de los cambios producidos, en la primera tabla
HWMV en DC-A | ||
Naming Context | Domain Controller ID |
Last USN |
Domain NC | DC-B Invocation ID |
2003 |
Domain NC | DC-C Invocation ID |
3003 |
La siguente tabla muestra el HWMV en DC-B luego de la misma operación
HWMV en DC-B | ||
Naming Context | Domain Controller ID |
Last USN |
Domain NC | DC-A Invocation ID |
1003 |
Domain NC | DC-C Invocation ID |
3003 |
El vector UTDV almacena el más alto “Originating Update USN” que el Controlador de Dominio ha recibido de cada Controlador de Dominio replicando un determinado NC.
Guardando esta información, los Controladores de Dominio nunca enviarán los cambios que ellos ya han recibido por otra replicación.
Este comportamiento es conocido como “propagation dampening”
Usando el UTDV el Controlador de Dominio que envía la información puede determinar los cambios que no ha enviado al Controlador de Dominio que solicita la actualización, y además no enviar los cambios que este Controlador de Dominio ha recibido de otros Controladores de Dominio.
Esto evita el problema del “loop infinito”
Resumiendo el proceso, cada Controlador de Dominio mantiene en forma independiente un contador siempre creciente llamado USN, que es incrementado cada vez que el Controlador de Dominio ejecuta un “Originating Write”
Cuando los Controladores de Dominio replican, preguntan por todos los cambios sucedidos desde el último USN recibido desde dicho Controlador de Dominio. Este anterior USN está almacenado en el HWMV
Dentro de cada pedido de replicación está incluido su UTDV. Cada Controlador de Dominio mantiene un UTDV por cada NC replicado, y en el UTDV el Controlador de Dominio controla el más alto “Originating Update USN” del cual ha recibido cambios por cada Controlador de Dominio que replica dicho NC
Vemos un ejemplo simple, que estimo puede facilitar la comprensión. Los pasos serán:
- Crear una cuenta de usuario en DC-A
- Replicar este cambio a DC-B
- Modificar una propiedad de esta cuenta en DC-B
- Replicar este nuevo cambio a DC-A
Debemos tener en cuenta que uno de los puntos clave del modelo de replicación de Active Directory son los “metadatos” que podemos decir es la “información sobre los datos”, que es usado por Active Directory para determinar el estado relativo de los objetos entre los Controladores de Dominio
Cada objeto contiene un número de campos que almacena en cada atributo del objeto. Por ejemplo: Nombre del atributo, fecha y hora del último cambio, número de versión del atributo, Originating DC ID, y Originating DC USN
Vamos al ejemplo
Creación de un usuario en DC-A, datos en DC-A
Atributo |
USN |
Version |
Timestamp |
Originating DC |
Originating USN |
givenName |
1001 |
1 |
21/4/12 9:21 |
DC-A DSA GUID |
1001 |
sn |
1001 |
1 |
21/4/12 9:21 |
DC-A DSA GUID |
1001 |
unicodePwd |
1001 |
1 |
21/4/12 9:21 |
DC-A DSA GUID |
1001 |
El nuevo usuario replicado en DC-B
Atributo |
USN |
Version |
Timestamp |
Originating DC |
Originating USN |
givenName |
2001 |
1 |
21/4/12 9:21 |
DC-A DSA GUID |
1001 |
sn |
2001 |
1 |
21/4/12 9:21 |
DC-A DSA GUID |
1001 |
unicodePwd |
2001 |
1 |
21/4/12 9:21 |
DC-A DSA GUID |
1001 |
La cuenta de usuario actualizada en DC-B
Atributo |
USN |
Version |
Timestamp |
Originating DC |
Originating USN |
givenName |
2001 |
1 |
21/4/12 9:21 |
DC-A DSA GUID |
1001 |
sn |
2001 |
1 |
21/4/12 9:21 |
DC-A DSA GUID |
1001 |
unicodePwd |
2002 |
2 |
22/4/12 12:44 |
DC-B DSA GUID |
2002 |
El cambio hecho en DC-B se replica a DC-A
Atributo |
USN |
Version |
Timestamp |
Originating DC |
Originating USN |
givenName |
1001 |
1 |
21/4/12 9:21 |
DC-A DSA GUID |
1001 |
sn |
1001 |
1 |
21/4/12 9:21 |
DC-A DSA GUID |
1001 |
unicodePwd |
1002 |
2 |
22/4/12 12:44 |
DC-B DSA GUID |
2002 |
Bien, creo que esta parte fue la más difícil de comprender, pero nos da las bases para proseguir con otras notas e ir profundizando aún más, aunque dando esto por comprendido el resto es más sencillo.
Trackbacks
[…] Active Directory Replication – A fondo – Parte 2 By Guillermo Delprato […]