Сравнение данных LDAP между контроллерами домена

Для проверки согласованности данных службы каталогов между контроллерами домена Эллес и Windows Server путем сравнения LDAP-представления объектов и атрибутов в выбранных разделах каталога может использоваться подкоманда samba-tool ldapcmp.

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

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

В процессе работы ldapcmp устанавливает соединения с двумя источниками LDAP-данных (подключение к удаленным серверам по протоколу LDAP или прямое подключение к локальной базе данных Эллес) и формирует списки DN в стандартных разделах каталога (Domain, Configuration, Schema), а также в DNS-разделах (DomainDnsZones, ForestDnsZones). Для каждого общего DN выполняется извлечение LDAP-атрибутов соответствующего объекта и их поэлементное сравнение. Подкоманда проверяет наличие атрибутов с обеих сторон и эквивалентность их содержимого, фиксируя любые различия, включая отсутствие атрибута и несовпадение значений.

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

При сравнении данных контроллеров, принадлежащих разным доменам, дополнительно игнорируются атрибуты, которые уникальны для каждого домена. При этом в процесс обработки атрибутов выполняется нормализация значений, содержащих DN, DNS-имя домена, NetBIOS-имена и имена серверов, что позволяет сопоставлять логически эквивалентные объекты в разных средах.

Отдельно поддерживается режим сравнения только дескрипторов безопасности (атрибут nTSecurityDescriptor), в рамках которого ldapcmp сопоставляет записи управления доступом (ACE) в формате SDDL с возможностью сортировки и выбора способа представления различий.

Результаты сравнения предоставляются в виде детального отчета о различиях, включающего список объектов, которые присутствуют только на одном сервере, перечень атрибутов с различающими значениями, детализацию различий в дескрипторах безопасности и итоговую сводку по каждому разделу.

При обнаружении различия хотя бы в одном из сравниваемых разделов подкоманда возвращает в итоговой сводке ошибку "Compare failed" с кодом статуса -1.

Алгоритм формирования списка атрибутов, игнорируемых при сравнении

В процессе работы подкоманда ldapcmp формирует список атрибутов LDAP-объектов, которые должны игнорироваться при сравнении.

При формировании списка выполняется следующая последовательность шагов:

  1. Используется предопределенный список, преимущественно состоящий из атрибутов, которые не подлежат репликации согласно схеме каталога (установлен флаг FLAG_ATTR_NOT_REPLICATED):

    badPasswordTime
    badPwdCount
    dSCorePropagationData
    lastLogoff
    lastLogon
    logonCount
    modifiedCount
    msDS-Cached-Membership
    msDS-Cached-Membership-Time-Stamp
    msDS-EnabledFeatureBL
    msDS-ExecuteScriptPassword
    msDS-NcType
    msDS-ReplicationEpoch
    msDS-RetiredReplNCSignatures
    msDS-USNLastSyncSuccess
    partialAttributeDeletionList
    partialAttributeSet
    pekList
    prefixMap
    replPropertyMetaData
    replUpToDateVector
    repsFrom
    repsTo
    rIDNextRID
    rIDPreviousAllocationPool
    schemaUpdate
    serverState
    subRefs
    uSNChanged
    uSNCreated
    uSNLastObjRem
    whenChanged
  2. К списку добавляются атрибуты, переданные при вызове подкоманды с помощью параметра --filter.

  3. К списку добавляются атрибуты, перечисленные в файле, имя которого передано при вызове подкоманды с помощью параметра --ignore-attributes.

  4. Из списка удаляются атрибуты, перечисленные в файле, имя которого передано при вызове подкоманды с помощью параметра --force-cmp-attributes.

  5. Если участвующие в сравнении контроллеры находятся в разных доменах (при вызове подкоманды передан параметр -w|--two), то в список добавляются следующие атрибуты:

    objectCategory
    objectGUID
    objectSid
    whenCreated
    whenChanged
    pwdLastSet
    uSNCreated
    creationTime
    modifiedCount
    priorSetTime
    rIDManagerReference
    gPLink
    ipsecNFAReference
    fRSPrimaryMember
    fSMORoleOwner
    masteredBy
    ipsecOwnersReference
    wellKnownObjects
    otherWellKnownObjects
    badPwdCount
    ipsecISAKMPReference
    ipsecFilterReference
    msDs-masteredBy
    lastSetTime
    ipsecNegotiationPolicyReference
    subRefs
    gPCFileSysPath
    accountExpires
    invocationId
    operatingSystem
    operatingSystemVersion
    oEMInformation
    schemaInfo
    targetAddress
    msExchMailboxGuid
    siteFolderGUID

Включенные в итоговый перечень атрибуты игнорируются при формировании списков различающихся значений атрибутов и атрибутов, присутствующих только на одном из участвующих в сравнении контроллеров домена.

Атрибуты обратных ссылок (Back Link) не реплицируются, но восстанавливаются по прямым ссылкам (Forward Link) исходных объектов.

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

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

Для сравнения БД 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.

Порядок следования параметров, изменяющих список игнорируемых при сравнении атрибутов, при вызове подкоманды ldapcmp в командной строке не имеет значения и не влияет на фактический порядок их применения. Параметры применяются строго в соответствии с внутренней логикой подкоманды, описанной в подразделе «Алгоритм формирования списка атрибутов, игнорируемых при сравнении».

Параметры

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

  • -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 — тихий режим (отключает вывод диагностических сообщений во время работы подкоманды).

Порядок следования параметров, изменяющих список игнорируемых при сравнении атрибутов, при вызове подкоманды ldapcmp в командной строке не имеет значения и не влияет на фактический порядок их применения. Параметры применяются строго в соответствии с внутренней логикой подкоманды, описанной в подразделе «Алгоритм формирования списка атрибутов, игнорируемых при сравнении».

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

  • --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