Сравнение БД LDAP на контроллерах домена

Для проверки статуса репликации LDAP может проводиться сравнение БД LDAP на контроллерах одного домена или двух разных доменов с помощью подкоманды samba-tool ldapcmp.

Общие сведения

Подкоманда сравнивает состав и значения атрибутов объектов каталога в БД LDAP двух контроллеров в одном домене либо в двух различных доменах. Сравнение может проводиться как по всему каталогу, так и по отдельным его разделам.

При поиске в процессе сравнения не обрабатываются скрытые атрибуты, а также нереплицируемые атрибуты (с установленным флагом FLAG_ATTR_NOT_REPLICATED), значения которых всегда различаются у объектов на разных контроллерах домена.

Сравнение БД LDAP может использоваться, например, для проверки корректности репликации после присоединения контроллера к домену, диагностики различных проблем в работе контроллера домена, перед понижением роли сервера с помощью операции demote и т. д.

Формат вызова

Для сравнения БД LDAP на контроллерах в одном домене или двух разных доменах Эллес используется следующий формат вызова:

samba-tool ldapcmp <URL1> <URL2> (domain|configuration|schema|dnsdomain|dnsforest) [options]

При вызове подкоманды указываются:

  • URL БД LDAP первого контроллера домена в стандартном формате ldap://<имя или IP-адрес хоста>;

  • URL БД LDAP второго контроллера домена в стандартном формате ldap://<имя или IP-адрес хоста>;

  • список разделов каталога (через пробел) для сравнения:

    • domain;

    • configuration;

    • schema;

    • dnsdomain;

    • dnsforest.

По умолчанию сравниваются все разделы каталога (за исключением нереплицируемых атрибутов).

Для каждого домена может быть передан свой набор реквизитов для доступа с помощью параметров -U|--username/--password и --username2/--password2.

Для изменения области поиска могут использоваться параметры (см. более подробное описание в подразделе «Параметры»):

  • --base и --base2 для задания адреса корневого объекта в каталоге, с которого должен начинаться поиск;

  • --cmp-before=DATE и --cmp-after=DATE для задания границ временного диапазона выборки объектов для сравнения;

    При использовании данных параметров следует учитывать следующие ограничения и особенности:

    • корректная работа с временными границами сравниваемого диапазона возможна при функциональном уровне домена и леса Windows Server 2008 R2 и выше;

    • чтобы при задании временных границ для сравнения в выборку попадали объекты, удаленные на первом контроллере домена, должен использоваться параметр --search-deleted;

    • объекты для сравнения выбираются по DN-имени, а не по GUID; таким образом, в сравнение могут попасть два разных объекта с совпадающими DN.

  • --ignore-attributes=FILENAME и --force-cmp-attributes=FILENAME для загрузки файлов со списками атрибутов, которые должны быть исключены из выборки или включены в нее;

  • --scope — диапазон поиска.

Список атрибутов (через запятую), которые должны быть исключены из сравнения, может быть передан в параметре --filter.

Параметры

Общие параметры вызова:

  • -w|--two — признак того, что контроллеры находятся в разных доменах;

  • --sd — сравнение только атрибутов, содержащих дескрипторы безопасности объектов каталога (nTSecurityDescriptor);

  • --sort-aces — сортировка записей ACE в атрибутах nTSecurityDescriptor перед сравнением;

  • --view=VIEW — режим отображения результатов сравнения атрибутов nTSecurityDescriptor; возможные значения:

    • section — отображаются различия, связанные с отсутствием или несовпадением записей ACE; различия, связанные с несовпадением порядка следования записей, не отображаются, если совпадают значения записей и их количество (значение по умолчанию);

    • collision — отображаются различия, связанные с отсутствием или несовпадением записей ACE, а также с несовпадением порядка следования записей, даже если совпадают значения записей и их количество;

  • --base=BASE — адрес корневого объекта в каталоге, с которого должен начинаться поиск в БД LDAP на первом контроллере домена;

  • --base2=BASE2 — адрес корневого объекта в каталоге, с которого должен начинаться поиск в БД LDAP на втором контроллере домена;

  • --scope=SCOPE — диапазон поиска; возможные значения:

    • SUB — при указании данной опции процесс поиска опускается вниз по иерархии от указанного DN (либо, если DN не указан, базового DN домена) до самого нижнего уровня в информационном дереве каталога;

    • ONE — при указании данной опции процесс поиска опускается на один уровень от указанного DN (либо, если DN не указан, базового DN домена);

    • BASE — при указании данной опции поиск ведется только для указанного DN (либо, если DN не указан, базового DN домена);

  • --filter=FILTER — список игнорируемых атрибутов (через запятую);

  • --skip-missing-dn — пропуск отсутствующих DN-имен;

  • --cmp-before=DATE — верхняя граница временного диапазона выборки объектов для сравнения в одном из следующих форматов:

    • дата и время: "%Y-%m-%d %H:%M:%S";

      Например:

      --cmp-before="2024-08-21 12:17:45"
    • дата: "%Y-%m-%d";

      Например:

      --cmp-before="2024-08-21"
    • временной сдвиг влево относительно текущего момента времени: "%d [d|day|days|h|hrs|hour|hours|m|min|mins|minute|minutes]".

      Например:

      --cmp-before="12 hours"
      --cmp-before="1 d 6 h 10 m"
      --cmp-before="1 day 1 hour 10 minutes"

    При задании данного параметра при сравнении будут обрабатываться только объекты, которые были изменены на первом контроллере домена (URL1) до указанной временной границы.

  • --cmp-after=DATE — нижняя граница временного диапазона выборки объектов для сравнения в одном из следующих форматов:

    • дата и время: "%Y-%m-%d %H:%M:%S";

      Например:

      --cmp-after="2024-08-21 12:17:45"
    • дата: "%Y-%m-%d";

      Например:

      --cmp-after="2024-08-21"
    • временной сдвиг влево относительно текущего момента времени: "%d [d|day|days|h|hrs|hour|hours|m|min|mins|minute|minutes]".

      Например:

      --cmp-after="12 hours"
      --cmp-after="1 d 6 h 10 m"
      --cmp-after="1 day 1 hour 10 minutes"

    При задании данного параметра при сравнении будут обрабатываться только объекты, которые были изменены на первом контроллере домена (URL1) после указанной временной границы.

  • --ignore-attributes=FILENAME — имя текстового файла со списком атрибутов (по одному атрибуту на каждой строке), которые должны быть исключены из сравнения (включены в фильтруемый набор атрибутов);

  • --force-cmp-attributes=FILENAME — имя текстового файла со списком атрибутов (по одному атрибуту на каждой строке), которые должны быть включены в сравнение (исключены из фильтруемого набора атрибутов);

  • --search-deleted — включение в выборку объектов, которые были удалены на первом контроллере домена, при задании границ временного диапазона;

  • -v|--verbose — вывод детальной информации;

  • -q|--quiet — тихий режим (отключает вывод диагностических сообщений во время работы подкоманды).

Дополнительные параметры доступа:

  • --simple-bind-dn2=DN2 — DN-имя для использования при простом удаленном подключении к БД LDAP на втором контроллере домена;

  • --username2=USERNAME2 — имя пользователя для доступа к БД LDAP на втором контроллере домена;

  • --password2=PASSWORD2 — пароль пользователя для доступа к БД LDAP на втором контроллере домена;

  • --workgroup2=WORKGROUP2 — значение WORKGROUP для доступа к БД LDAP на втором контроллере домена;

  • --no-pass2 — отсутствие необходимости запрашивать пароль для доступа к БД LDAP на втором контроллере домена;

  • --use-kerberos2=desired|required|off — необходимость аутентификации с использованием Kerberos при получении доступа к БД LDAP на втором контроллере домена.

Примеры

Пример сравнения БД LDAP на двух контроллерах в одном домене:

samba-tool ldapcmp ldap://DC1 ldap://DC2 -UAdministrator

Пример сравнения отдельного раздела в БД LDAP на двух контроллерах в одном домене:

samba-tool ldapcmp ldap://DC1 ldap://DC2 configuration -UAdministrator

Пример сравнения с указанием игнорируемого атрибута:

samba-tool ldapcmp ldap://DC1 ldap://DC2 --filter=instanceType -UAdministrator

Пример сравнения атрибутов с указанием корневого DN:

samba-tool ldapcmp ldap://DC1 ldap://DC2 -UAdministrator \
    --base='CN=FirstName SecondName,OU=OrgUnit,DC=samdom,DC=example,DC=com' \
    --base2='CN=FirstName SecondName,OU=OrgUnit,DC=samdom,DC=example,DC=com'

Пример сравнения с указанием файла со списком атрибутов, которые должны быть исключены из обработки:

samba-tool ldapcmp ldap://DC1 ldap://DC2 -UAdministrator \
    --ignore-attributes=attributes-to-ignore.txt

Примеры сравнения с указанием границ временного диапазона для выборки объектов:

  • с указанием даты и времени:

    samba-tool ldapcmp ldap://DC1 ldap://DC2 -UAdministrator \
        --cmp-before="2024-08-21 12:17:45"
  • с указанием даты:

    samba-tool ldapcmp ldap://DC1 ldap://DC2 -UAdministrator \
        --cmp-before="2024-08-21"
  • с указанием временного сдвига влево относительно текущего момента:

    samba-tool ldapcmp ldap://DC1 ldap://DC2 -UAdministrator \
        --cmp-after="1 day 1 hour 10 minutes"

Пример сравнения БД LDAP на контроллерах в разных доменах:

samba-tool ldapcmp ldap://DC1.samdom1.example.com ldap://DC2.samdom2.example.com --two -UAdministrator --username2=Administrator --password2=Passw0rd

Рекомендации по настройке состава сравниваемых атрибутов объектов каталога

Для получения оптимальных результатов при использовании подкоманды samba-tool ldapcmp для сравнения конфигураций контроллеров домена рекомендуется:

  1. Предварительно сформировать файлы со списками атрибутов, которые:

    • должны игнорироваться при сравнении;

    • являются нереплицируемыми, но при этом должны быть учтены при сравнении.

  2. При вызове подкоманды указать:

    • файл с игнорируемыми атрибутами в качестве значения ключа --ignore-attributes;

    • файл с учитываемыми атрибутами в качестве значения ключа --force-cmp-attributes.

Далее приводится пример создания списков атрибутов для использования при сравнении:

  • список нереплицируемых атрибутов;

    В список включаются все атрибуты, в системных флагах (System Flags) которых установлен бит 0x01 (FLAG_ATTR_NOT_REPLICATED).

  • список атрибутов, которые не реплицируются на контроллеры RODC;

    В список включаются все атрибуты, в флагах поиска (Search Flags) которых установлен бит 0x00000200 (fRODCFilteredAttribute).

  • список атрибутов, являющихся обратными ссылками (Back Link).

    В список включаются все атрибуты с нечетным значением идентификатора ссылки (linkID).

Для выгрузки атрибутов из схемы каталога используется утилита ldapsearch (пакет ldap-utils), а для работы со списками — gawk (пакет gawk).

Чтобы сформировать списки игнорируемых атрибутов, выполните следующие действия на машине — участнике домена:

  1. Если пакеты gawk и ldap-utils отсутствуют, установите их:

    sudo apt install ldap-utils gawk
  2. Для удобства дальнейшей работы задайте DN домена, имя пользователя с правами на доступ к схеме каталога, а также имена хостов, на которых развернуты сравниваемые БД LDAP, в качестве значений переменных.

    Например:

    DOMAINDC=DC=samdom,DC=example,DC=com
    UserWithSchemaAdminRights=Administrator
    LDAPHOSTNAME1=dc1.samdom.example.com
    LDAPHOSTNAME2=dc2.samdom.example.com
  3. Получите билет Kerberos для доступа к LDAP:

    kinit ${UserWithSchemaAdminRights}
  4. Выгрузите схему каталога в файл (в примере — schema.withflags.raw) в текущем каталоге (у пользователя должны быть права на работу с файлами в каталоге):

    ldapsearch -H ldap://${LDAPHOSTNAME1} -E pr=1000/noprompt -LLL \
        -b CN=Schema,CN=Configuration,${DOMAINDC} \
        -o ldif-wrap=no \
        systemFlags searchFlags ldapDisplayName linkID > schema.withflags.raw

    В приведенном примере используются следующие параметры ldapsearch:

    • -H — URL БД LDAP участвующего в сравнении контроллера домена;

    • -E pr=1000/noprompt — ограничение размера одной страницы, возвращаемой сервером LDAP в ответ на запрос, с указанием на необходимость продолжения обработки запроса без подтверждения;

    • -LLL — вывод результатов без комментариев и версии LDIF;

    • -b — DN узла для использования в качестве точки начала поиска;

    • -o ldif-wrap=no — опция, отключающая перенос строк;

    • systemFlags searchFlags ldapDisplayName linkID — список дополнительных атрибутов для вывода в файл.

    В результате выполнения команды формируется файл schema.withflags.raw, содержащий строки следующего вида:

    ...
    dn: CN=ms-DS-User-AuthN-Policy-BL,CN=Schema,CN=Configuration,DC=samdom,DC=example,DC=com
    linkID: 2207
    searchFlags: 0
    lDAPDisplayName: msDS-UserAuthNPolicyBL
    systemFlags: 17
    
    dn: CN=MS-TS-ExpireDate,CN=Schema,CN=Configuration,DC=samdom,DC=example,DC=com
    searchFlags: 1
    lDAPDisplayName: msTSExpireDate
    systemFlags: 16
    
    dn: CN=ms-WMI-stringValidValues,CN=Schema,CN=Configuration,DC=samdom,DC=example,DC=com
    searchFlags: 0
    lDAPDisplayName: msWMI-StringValidValues
    systemFlags: 16
    ...
  5. Поскольку ldapsearch не гарантирует определенный порядок вывода запрошенных атрибутов, используйте gawk со следующими параметрами для сортировки результатов по имени атрибута в рамках одного DN:

    cat schema.withflags.raw | gawk 'BEGIN{FS=": "}/^dn/{dn=$2}{print dn "#", $0}' |sort > schema.withflags

    В результате выполнения команды формируется файл schema.withflags, содержащий строки следующего вида:

    ...
    CN=Account-Name-History,CN=Schema,CN=Configuration,DC=gmsa,DC=lan#
    CN=Account-Name-History,CN=Schema,CN=Configuration,DC=gmsa,DC=lan# dn: CN=Account-Name-History,CN=Schema,CN=Configuration,DC=gmsa,DC=lan
    CN=Account-Name-History,CN=Schema,CN=Configuration,DC=gmsa,DC=lan# lDAPDisplayName: accountNameHistory
    CN=Account-Name-History,CN=Schema,CN=Configuration,DC=gmsa,DC=lan# searchFlags: 0
    CN=Account-Name-History,CN=Schema,CN=Configuration,DC=gmsa,DC=lan# systemFlags: 16
    ...
  6. Выберите все нереплицируемые атрибуты (в System Flags установлен бит 0x01, FLAG_ATTR_NOT_REPLICATED) и сохраните их в отдельный файл в текущем каталоге:

    cat schema.withflags | gawk 'BEGIN{FS=": "}/lDAPDisplayName: /{ldapname=$2}/systemFlags:/{if(and(1,int($2))){print(ldapname)}}' \
        > attributes.nonreplicated

    В результате выполнения команды формируется файл attributes.nonreplicated, содержащий строки с именами атрибутов:

    badPasswordTime
    badPwdCount
    bridgeheadServerListBL
    dSCorePropagationData
    frsComputerReferenceBL
    ...
  7. Выберите все атрибуты, которые не реплицируются на контроллеры RODC (в Search Flags установлен бит 0x00000200, fRODCFilteredAttribute), и сохраните их в отдельный файл в текущем каталоге:

    cat schema.withflags | gawk 'BEGIN{FS=": "}/lDAPDisplayName: /{ldapname=$2}/searchFlags:/{if(and(0x200,int($2))){print(ldapname)}}' \
        > attributes.RODCFiltered

    В результате выполнения команды формируется файл attributes.RODCFiltered, содержащий строки с именами атрибутов:

    msFVE-KeyPackage
    msFVE-RecoveryPassword
    msKds-CreateTime
    msKds-DomainID
    msKds-KDFAlgorithmID
    ...
  8. Выберите все атрибуты, являющиеся обратными ссылками (linkID имеет нечетное значение), и сохраните их в отдельный файл в текущем каталоге:

    cat schema.withflags | gawk 'BEGIN{FS=": "}/lDAPDisplayName: /{ldapname=$2}/linkID:/{if(0<int($2)%2){print(ldapname)}}' \
        > attributes.BackLinks

    В результате выполнения команды формируется файл attributes.BackLinks, содержащий строки с именами атрибутов:

    bridgeheadServerListBL
    frsComputerReferenceBL
    fRSMemberReferenceBL
    memberOf
    isPrivilegeHolder
    ...
  9. Объедините файлы любым доступным способом.

    Например:

    cat attributes.* > attributes.AllIgnored
  10. Если в итоговый файл попадают атрибуты, которые не должны реплицироваться и вычисляются, но, тем не менее, должны учитываться при сравнении, отредактируйте файл вручную либо поместите такие атрибуты в отдельный файл (в примере — attributes.ForceComparison).

  11. Выполните сравнение с помощью подкоманды samba-tool ldapcmp (на машине должен быть установлен пакет inno-samba), указав полученные файлы в соответствующих ключах:

    samba-tool ldapcmp ldap://${LDAPHOSTNAME1} ldap://${LDAPHOSTNAME2} \
        -U ${UserWithSchemaAdminRights} \
        --ignore-attributes=attributes.AllIgnored \
        --force-cmp-attributes=attributes.ForceComparison