Трудно в изучении — легко в бо.. (нет)
Хабр, здравствуй!
Данная статья про боли, как все давалось далеко не просто, что оказалось труднее всего — от выравнивания байтов в PAC до эскалации через поддомен.
Как мы сознательно шли сложным путём, чем проверяли результат и какими инструментами собрали продукт, которому доверяют вход тысяч пользователей
Заменить контроллер домена — это не «поставить ещё один LDAP-сервер».
Это взять на себя вход пользователей в компьютеры, Kerberos, групповые политики, доверия, DNS, DHCP и сделать так, чтобы Windows- и Linux-клиенты не заметили подмены.
Active Directory — это не одна служба, а связка из десятка протоколов (LDAP, Kerberos, DNS, SMB, MS-RPC, CLDAP, NTP), и клиент Windows проверяет их все, не прощая отклонений. Это мы ощутили на себе.
Один неверный флаг в ответе Netlogon и компьютер не войдёт в домен. «Совместимость» здесь измеряется не процентами, а фактом: вошёл человек на рабочую станцию утром или нет.
HopeDC — мы смогли это на Rust.
Один принцип определил всю архитектуру: «главное — не сломать вход пользователей в компьютеры». Любая новая функция, любая проверка лицензии или целостности сначала проходит тест «а не заблокирует ли это Kerberos-вход?». Ломает — переделываем.
Rust ядро, БД и панель — один файл (запускается на большинстве Linux)
329 автотестов ядра
582 тыс. объектов — пик нагрузки на ⅓ ядра
3803 значения схемы — байт в байт как у AD
Стенды, сборки и погружения
Прежде чем перейти к этапам, расскажу о том, в каких условиях это писалось и сколько стоила каждая проверка «до байта».
Ядро, собственная БД и веб-панель — это 63 132 строки на Rust в 101 файле, 329 + 29 автотестов (ядро и движок БД) и 488 внешних крейтов в сборке.
Ресурсы на стендах
Совместимость нельзя проверить на заглушках — рядом всё время работали настоящие эталонные серверы. Стенд построен на сетевых пространствах имён Linux (netns), чтобы несколько «доменов» и клиентов жили на одной машине с разными адресами:
Стенд
Что на нём
Ресурсы
Эталон совместимости
HopeDC рядом с Samba AD DC 4.19 и 389-DS со схемой FreeIPA — сверка поведения байт в байт
netns на одной ВМ;
Windows-клиенты для проверки входа
Нагрузочный
HopeDC против Samba DC, собственный ldbench, 8 параллельных клиентов по LDAPS
2 vCPU — намеренно тесно, клиент нагрузки рядом
Масштаб каталога
Домен в 582 тыс. объектов (профиль реального метрокластера MS AD), перенос и репликация
один узел: пик на ⅓ ядра, ~2,5 ГБ ОЗУ, 0,53 ГБ на диске
Скриншоты и UI
Playwright: снимки всех экранов в светлой и тёмной теме
headless-браузер на том же стенде
Сколько длится сборка
Ядро с вкомпилированной веб-панелью собирается в один бинарник через cargo-zigbuild + Zig. Инкрементальная пересборка ядра занимает около 6 минут (релиз, оптимизированный); полная сборка с нуля тянет все 488 зависимостей и идёт заметно дольше. Релиз дополнительно подписывается ключом сборки — команда сборки при этом не меняется. Из-за длины цикла каждую гипотезу о «неправильном байте» дешевле проверить дампом и юнит-тестом, чем пересборкой всего ядра, — поэтому тесты писались вплотную к протоколам.
Как часто приходилось «нырять глубоко»
Большая часть кода — это обычная прикладная работа: каталог, политики, DNS/DHCP, панель. Но есть узлы, где отладка идёт по дампам, а не по логам, и один неверный байт означает «не входит». Таких погружений было восемь (но не 3-4), и именно они съели непропорционально много времени:
-
подсхема
CN=Aggregate— сверка 3803 значений символ в символ; -
NDR-выравнивание PAC (
KERB_VALIDATION_INFO, отложенные указатели); -
соль ключей Kerberos для пользователя / компьютера / межреалма;
-
рефералы между доменами и лесами (шесть сообщений Kerberos);
-
кто вправе ручаться за PAC — защита от эскалации «снизу вверх»;
-
вырезание секретов при отдаче на RODC;
-
подпись и шифрование SMB2/3 (AES-CMAC/GCM, сверка по RFC 4493);
-
внутренний пентест офлайн-лицензии и целостности сборки.
Сколько времени ушло на криптографию MS AD
Если мерить кодом, «криптографическая совместимость» с AD (вся подсистема Kerberos/KDC, PAC и NDR, соль и ключи, подпись и шифрование SMB, TLS к AD, импорт NT-хэшей и AES-ключей) — это около 10,6 тыс. строк, ~17 % кода и ~19 % автотестов ядра. Но время эта часть съела непропорционально: её нельзя написать «по спеке» — каждый байт выверяется по дампу эталонного сервера, а ошибка проявляется не стектрейсом, а кодом RPC_X_BAD_STUB_DATA или «неверным паролем» при верном.
По нашей оценке, на анализ и воспроизведение криптографии MS AD ушло примерно 35 % всего времени разработки — больше, чем на любой другой этап. Здесь без собаки в огне не обошлось.
Так было не раз
35%времени ~35% — анализ и воспроизведение криптографии MS ADKerberos/KDC, PAC и NDR, соль и ключи, подпись SMB, TLS, импорт хэшей~65% — каталог, политики, DNS/DHCP, кластер, панель, сборка Для сравнения: эта же криптография — лишь ~17% строк кода
Как получена оценка. Доля кода и тестов измерена по исходникам (≈17% строк и ≈19% тестов приходятся на Kerberos/PAC/ключи/SMB/TLS/импорт). Оценка в ~35% времени учитывает, что эти участки отлаживаются по байтовым дампам без промежуточного состояния, поэтому стоят в несколько раз дороже за строку, чем прикладной код. Это инженерная оценка, а не хронометраж.
Если честно, собрали пот и кровь и взвесили.
Рис. 2. «Обзор DC» — сводное состояние контроллера. За этой простотой стоит вся выверенная байт в байт совместимость из разделов ниже.
Этап 1. Схема каталога — до байта
Первая стена, в которую упирается такой проект, — схема.
Windows-инструменты (ADUC, ADSI Edit, RSAT) и SSSD не «читают схему гибко», они ждут конкретные классы и атрибуты с конкретными OID, синтаксисами и флагами. Малейшее расхождение и оснастка показывает ошибку или клиент не находит нужный контейнер.
Жестоко и без компромиссов.
Как справились. Мы не стали описывать схему «по мотивам».
Взяли выгрузку схемы настоящего AD (Windows Server 2016+, objectVersion 88) — около 1500 типов атрибутов и 270 классов — и встроили в бинарник. Подсхему CN=Aggregate, которую читают клиенты, генерируем из этих объектов по правилам NTDS и сверяем побайтно с CN=Aggregate живого контроллера: все 3803 значения совпадают символ в символ.
Отдельная сложность — детерминизм: в кластере объекты схемы на всех узлах должны получаться идентичными до байта, иначе репликация будет вечно «видеть разницу». Решили фиксированными метками времени и стабильной сериализацией.
Этап 2. Kerberos и PAC — байты, которые не прощают
Самая недобрая к ошибкам часть.
Windows не принимает билет Kerberos без PAC — подписанной структуры с SID пользователя и его групп. Внутри PAC лежит KERB_VALIDATION_INFO в формате NDR Type Serialization v1, и ловушек там хватает:
-
поля
FILETIME— это дваDWORD, и выравниваются по 4 байта, а не по 8; один лишний байт паддинга — и Windows отвечаетRPC_X_BAD_STUB_DATA; -
идентификаторы отложенных указателей (deferred pointers) не должны повторяться, а сами буферы идут строго в порядке полей структуры;
-
PAC_CLIENT_INFOобязателен: Windows сверяет имя в нём с именем клиента в билете; -
тип подписи зависит от шифра билета: HMAC-MD5 для RC4, HMAC-SHA1-96 для AES.
Рядом — соль ключей. Ключ AES в Kerberos — это PBKDF2 от пароля и соли, а соль у AD разная для разных учёток: у пользователя это REALM + имя, у компьютера — REALM + host + имя без $ + . + DNS-домен, у межреалмового ключа — REALM + krbtgt + другой REALM. Ошибка в одном символе и клиент получает «неверный пароль» при верном пароле.
И даже LDAP прощает меньше, чем кажется: приложения разбирают не код ошибки, а её текст вида data 52e (неверный пароль), 775 (учётка заблокирована), 773 (нужно сменить пароль). Воспроизводим их дословно — иначе корпоративный портал покажет пользователю не ту причину отказа.
Как справились. Единственный надёжный метод в таких местах — не «читать спеку», а поднять рядом эталонный сервер, снять дамп и повторить его поведение байт в байт. Плюс самопроверки криптографии при старте: например, SMB3 проверяет корректность AES-CMAC по тестовым векторам RFC 4493 прямо при запуске.
Именно здесь «почти работает» означает «не работает»: клиент Windows либо принимает билет, либо отвечает кодом ошибки RPC. Промежуточного состояния нет, и отлаживать приходится по дампам, а не по логам.
Этап 3. Миграция с MS AD — зеркало без DCSync
Самый быстрый способ «перетащить» домен — заговорить на языке репликации AD (DRSUAPI, GetNCChanges) и вытянуть каталог вместе с хэшами. Это ровно тот приём, что лежит в основе атаки DCSync. Мы сознательно отказались: продукт для инфраструктуры не должен вести себя как инструмент взлома (не так ли?).
Как справились — двумя честными путями.
-
Прозрачная проверка (pass-through). При первом входе по LDAP пароль проверяется в AD, и HopeDC сам выводит из него NT-хэш и ключи AES.
-
Выгрузка штатными средствами. Администратор AD заранее выгружает NT-хэши, ключи AES и историю паролей; HopeDC разбирает их в памяти, не сохраняя открытый дамп, и пользователи сразу входят по Kerberos AES.
Тонкостей оказалось больше, чем в самом переносе:
-
Идентичность.
objectGUIDиobjectSidпереносятся настоящими. На них держатся ACL файловых серверов и UID на Linux. Двоичные атрибуты (сертификаты, фотографии,ms-DS-ConsistencyGuid) отдаются клиентам теми же байтами. Первичный перенос идёт со скоростью ~1800 объектов в секунду. -
Подлинность контроллера. Раз зеркало проверяет пароли в AD, подменённый DC мог бы принять любой пароль, поэтому все подключения только LDAPS с проверкой цепочки до ЦС AD или закреплённого SHA-256 сертификата, без отката на открытый LDAP.
-
Переходный период. Пока живы оба каталога, источник истины один: правки по LDAP сначала пишутся в AD учётной записью синхронизации и лишь затем применяются в HopeDC. Групповые политики HopeDC читает и пишет прямо в SYSVOL контроллера AD по SMB с подписью, как консоль GPMC, и распознаёт конфликт, если ту же политику правили в GPMC.
-
Приём роли KDC. В конце HopeDC начинает сам выдавать билеты своим
krbtgt. Перед этим проверка готовности показывает, кто не войдёт без Windows-DC, какие DNS-записи и доверия от него зависят и в каком состоянии SYSVOL.
Samba AD DC совместима со схемой AD и идёт тем же путём; на стенде она служит эталонным партнёром. На ней проверены перенос домена в 582 тыс. объектов и работа с SYSVOL по SMB.
FreeIPA (389-DS + MIT Kerberos) устроена иначе: учётки в cn=accounts, логин — uid, SID и NT-хэш есть только с ipa-adtrust. Для неё построили слой-переводчик в модель AD; отдельно пришлось обойти лимит 389-DS в 2000 записей на выдачу (иначе импорт крупного каталога молча терял пользователей).
Это тот случай, когда «правильно» и «быстро» расходятся.
Мы выбрали правильно и потратили заметно больше времени — зато получили миграцию, которую не стыдно показать службе безопасности заказчика.
Рис. 3. Импортированный из MS AD домен в панели HopeDC: встроенные группы, контейнеры и перенесённые OU — с настоящими objectGUID и objectSid, как в исходном AD.
Этап 4. Несколько лесов на одном сервере — и полная изоляция
Один сервер HopeDC держит несколько независимых лесов (вишенка), и каждый ведёт себя как отдельный лес AD. В Windows это невозможно в принципе: контроллер обслуживает ровно один домен. Для аутсорсера с десятками клиентов это разница между двумя серверами и двумя десятками. Спорное превосходство, исходя из первого принципа админов — «разделяй и властвуй», но мы решили добавить эту фишку в продукт.
Главная сложность — изоляция.
Общий процесс и общая база не должны просвечивать нигде: ни в поиске LDAP, ни в ответе RPC, ни в билете Kerberos. Правило «учётка одного леса не видит объекты и SID другого» пришлось провести через все точки, где клиент спрашивает о чужом имени:
-
поиск LDAP «по всему каталогу» и глобальный каталог — видят только свой лес;
-
DsCrackNames— разрешение имён для окна выбора объектов Windows; -
LsarLookupSids/LsarLookupNames— их вызывает проводник, показывая владельца файла; -
KDC — билет на службу другого леса без реферала по доверию не выдаётся, даже если её ключ лежит в той же базе.
Имена ничего не значат. Администратор любого домена может создать у себя группу «Enterprise Admins», поэтому административные группы определяются только по SID: Enterprise Admins — это -519 в корневом домене, Domain Admins — -512 и только на свой домен. Чтобы региональный сервер поддомена, не хранящий корневой домен, всё же узнал Enterprise Admins, SID корня леса записывается в атрибут каждого домена-потомка и реплицируется с его разделом.
RID без RID Master. В AD уникальность RID гарантирует одна FSMO-роль. В мульти-мастер кластере HopeDC такой точки отказа нет: узлы берут блоки по 500 RID со случайным сдвигом и отслеживают пересечения. Пул у каждого домена свой — потому что свой и SID домена.
Этап 5. Доверия и поддомены — глубоко в Kerberos
Билет между доменами — это цепочка переходов, и на каждом KDC принимает решение о безопасности. Клиент из kid.hope.local просит билет на службу в corp.ru (другое дерево того же леса). Свой KDC ключа службы не знает и выдаёт реферал: TGT на krbtgt/HOPE.LOCAL, зашифрованный межреалмовым ключом. Корень леса расшифровывает его, проверяет PAC и выдаёт следующий реферал на krbtgt/CORP.RU. И только KDC corp.ru выдаёт настоящий билет — весь путь занимает шесть сообщений Kerberos.
Путь билета между доменами разных деревьев леса: шесть сообщений Kerberos. Перепутать имя krbtgt в своём TGT и во входящем реферале — значит отправить клиента в бесконечный цикл
Неочевидные детали, на которых всё ломалось:
-
Имя krbtgt. В обычном TGT имя службы —
krbtgt/, а учётка называется простоkrbtgt. Во входящем реферале то же имя означает межреалмовый ключ. Перепутать — и KDC либо не расшифрует билет, либо снова отдаст реферал, и клиент уйдёт в бесконечный цикл. -
Неизвестный хост. Региональный сервер поддомена не хранит родителя и не знает, чей хост спрашивают, — такие запросы он направляет к родителю, как это делает AD.
-
Маршрутизация по суффиксам. При лесном доверии цель ищется по именам верхнего уровня (TLN) партнёра; побеждает самое длинное совпадение суффикса.
Самое интересное решение — кто вправе ручаться за PAC. В лесу AD границей безопасности считается лес, а не домен. Поэтому злоумышленник с ключом krbtgt поддомена может вписать в ExtraSids «золотого билета» -519 и стать Enterprise Admin — известная эскалация «снизу вверх». В HopeDC этот путь закрыт:
-
домен ручается только за свои учётки и учётки своего поддерева;
-
предок принимающего домена считается доверенным, как родитель в AD;
-
от остальных принимаются только SID доменов их поддерева; привилегированные RID чужих доменов (500, 512, 518, 519, 520) и встроенные алиасы
S-1-5-32-*не принимаются никогда.
<img src="/wp-content/uploads/2026/11/habr.com/79986/img_desc_840886cccd5e8723b1b452080592fe40.png" alt="Классическая эскалация «снизу вверх» (ключ krbtgt поддомена → -519 в ExtraSids) в HopeDC закрыта: привилегированные SID чужого домена не принимаются, граница компрометации — поддомен.» title=»Классическая эскалация «снизу вверх» (ключ krbtgt поддомена → -519 в ExtraSids) в HopeDC закрыта: привилегированные SID чужого домена не принимаются, граница компрометации — поддомен.» width=»987″ height=»210″ decode=»async»>Классическая эскалация «снизу вверх» (ключ krbtgt поддомена → -519 в ExtraSids) в HopeDC закрыта: привилегированные SID чужого домена не принимаются, граница компрометации — поддомен.
Компрометация филиального контроллера поддомена остаётся в пределах этого поддомена. К тому же региональный сервер вообще не получает ключей и учёток родителя. На внешней границе действуют те же флаги trustAttributes, что и в AD: QUARANTINED_DOMAIN (SID filtering — из PAC партнёра остаются только SID его домена), FOREST_TRANSITIVE (маршрутизация по TLN) и CROSS_ORGANIZATION (выборочная аутентификация).
Модель доверия HopeDC получилась строже, чем в типовом AD: скомпрометированный поддомен не поднимается до корня леса, а чужой лес на том же сервере невидим без доверия.
Рис. 6. Доверия в панели HopeDC: направление, тип (AD / Realm MIT), транзитивность и флаги защиты (SID-фильтр, карантин, выборочная аутентификация) — те же trustAttributes, что и в AD.
Этап 6. Кластер: мультимастер и детерминизм
Отказоустойчивость — это мультимастер-репликация каталога и DNS с разрешением конфликтов «последняя запись побеждает», автотопология по сайтам и контроллеры только для чтения (RODC) для филиалов. На RODC нельзя держать хэши чужих учёток: украдут узел — не должно утечь лишнее.
Как справились. Мастер при отдаче данных на RODC сам вырезает секреты — пароли учёток вне списка разрешённых, ключи krbtgt (кроме персонального ключа RODC), ключи ЦС и PKINIT, секреты синхронизации. Чтобы репликация не «дёргалась», состояние каждого объекта приводится к детерминированному дайджесту, одинаковому на всех узлах. Новый узел во втором ЦОД получает полный снимок 583 тыс. объектов за ~60 секунд, изменение доходит до другого ЦОД за 5–15 секунд, а при остановке одного ЦОД узел второго сразу обслуживает поиск, вход и запись.
Рис. 7. «Топология» — карта репликации по сайтам: узлы, связи и состояние. Именно резервирование и геораспределение, а не нехватка мощности, определяют число контроллеров.
Рис. 7. «Топология» — карта репликации по сайтам: узлы, связи и состояние. Именно резервирование и геораспределение, а не нехватка мощности, определяют число контроллеров
Этап 7. Один бинарник на все дистрибутивы
Российский парк Linux — это Astra, РЕД ОС, ALT плюс Debian/Ubuntu и RHEL-совместимые. У всех разные версии glibc, пакетные менеджеры, механизмы защиты (у Astra — мандатный контроль целостности, ЗПС). Отдельная сборка под каждую — путь в ад.
Как справились. Собираем один бинарник через cargo-zigbuild + Zig с привязкой к glibc не выше 2.30 — он запускается на Debian 11+, Ubuntu 20.04+, RHEL/Alma/Rocky 9+ и Astra 1.8 без пересборки. Веб-панель вкомпилирована в бинарник (ядро + UI — один файл). Установщик сам проверяет версию glibc, а обновление узлов идёт встроенным механизмом с проверкой подписи пакета и автоматическим откатом.
Этап 8. Защита самого продукта — и как мы её ломали
Контроллер домена — сердце инфраструктуры, и лицензирование работает офлайн (в закрытых контурах интернета нет). Значит, вся проверка идёт на машине, которую потенциально контролирует злоумышленник, — самый неблагодарный класс задач. Конечно, наилучший вариант защиты — онлайн проверка, но в закрытом контуре это невозможно.
Мы не просто написали проверки, а провели по ним внутренний пентест:
-
Лицензия — подпись вендора. Пробовали подделать всеми ходовыми способами:
alg:none, подмена алгоритма на HS256 с публичным ключом в роли секрета, подпись своим RSA-ключом, правка полей при живой подписи, прямая подмена файла на диске — всё отклонено. -
Откат часов. Срок проверяется против наибольшего времени, которое сервер когда-либо видел. Проверили под
faketime: откат не помогает. -
Подмена бинарника. Честно воспроизвели атаку «вписать свой ключ в бинарник» — она работает, потому что это не взлом криптографии, а подмена программы. В ответ добавили самопроверку целостности: релиз подписывается отдельным ключом сборки, при старте бинарник проверяет свою подпись; порча одного байта ломает её, и продукт отключает платные функции, не трогая вход пользователей.
Под капотом — шифрование каталога, журналов и бэкапов AES-256-GCM, экспорт мастер-ключа под паролем через Argon2id, журнал безопасности с кодами событий Windows и выгрузкой в SIEM.
Принцип неизменен: даже при сработавшей защите целостности или лицензии вход пользователей в компьютеры не блокируется — ограничиваются только платные функции. Контроллер домена не имеет права «обидеться» и оставить людей без входа, а заказчика без рабочего сервиса.
Рис. 8. «Журнал безопасности» — входы, блокировки и изменения каталога с кодами событий Windows и выгрузкой в SIEM (Prometheus, Zabbix).
Этап 9. UX в масштабе: тысячи политик, два языка, тёмная тема
Мощное ядро бесполезно, если им нельзя управлять. Панель HopeDC — это 613 готовых шаблонов политик Linux (22 типа политик), 23 набора под классы защищённости и стандарты (ФСТЭК, CIS), инвентаризация, MFA, корзина объектов. И все политики Windows.
-
Два языка. Интерфейс и журналы — на русском и английском; словарь перевода — тысячи строк, включая описания всех 613 шаблонов. Собрали аудит недостающих ключей, чтобы ничего не осталось непереведённым.
-
Тёмная тема без переписывания всего. Цвета заданы прямо в классах — тысячи мест. Вместо правки каждого перевели палитру на CSS-переменные: тема переключается одним классом, а тёмная палитра генерируется скриптом. Тема и язык — личные настройки каждой учётки, хранятся на сервере и переживают вход с другого устройства.
Инструменты, которыми мы это собрали
Область
Инструменты
Зачем именно они
Ядро и БД
Rust, tokio, axum; собственный движок HopeDB (журнальное хранилище + шифрование AES-256-GCM)
Предсказуемая память без сборщика мусора, безопасность типов, один бинарник. Свой движок — чтобы хранить каталог детерминированно и зашифрованно без внешней СУБД.
Протоколы
ldap3; собственные реализации Kerberos/KDC, SMB2/3, MS-RPC (NDR), CLDAP, DNS; jsonwebtoken, openssl/aws-lc
Воспроизведение [MS-*] байт в байт с самопроверкой криптографии по RFC-векторам при старте.
Сборка под Linux
cargo-zigbuild + Zig, rust_embed
Один бинарник с привязкой к glibc 2.30 на все дистрибутивы; UI вкомпилирован в ядро.
Веб-панель
React, Vite, Tailwind, esbuild
Быстрая сборка, палитра на CSS-переменных для тем, компактный бандл.
Проверка UI
Playwright
Скриншоты всех экранов в светлой и тёмной теме, рендер схем и обложек.
Тестовый стенд
Сетевые пространства имён Linux (netns); рядом — Samba AD DC и 389-DS со схемой FreeIPA
Проверка совместимости и миграции на реальных эталонных серверах, а не на заглушках.
Нагрузка
Собственный ldbench (общий TLS-коннектор)
Замер HopeDC против Samba DC по сессиям, CPU и памяти на одном стенде.
Безопасность
PyJWT/cryptography (симуляция атак), faketime, Argon2id, machine_uid
Внутренний пентест лицензии, тесты отката часов, привязка к оборудованию, защита экспорта ключа.
Производительность: чего стоит эта совместимость
Совместимость «до байта» не бесплатна, но и не разорительна. На домене в 582 тыс. объектов (290 тыс. пользователей, 286 тыс. групп — состав реального метрокластера MS AD из 8 контроллеров) один узел HopeDC несёт реальный пик промышленной нагрузки на ⅓ одного ядра и ~2,5 ГБ ОЗУ; диск под зашифрованными данными — 0,53 ГБ.
Профиль этой нагрузки снят с реального метрокластера MS AD, который сегодня обслуживают восемь контроллеров Windows. Важно понимать, что это не значит «один HopeDC заменяет восемь Windows-DC»: восемь контроллеров в том кластере стоят не ради нехватки процессора, а ради отказоустойчивости и распределения по площадкам — чтобы вход работал при отказе узла или ЦОД и чтобы каждый филиал ходил к ближайшему DC.
Резервирование и геораспределение нужны и в HopeDC (для этого есть кластер, сайты и RODC). Цифра про ⅓ ядра говорит о другом — о том, какой запас по ресурсам на один узел остаётся: тот же пиковый объём работы, что идёт на восьми контроллерах, по процессору и памяти укладывается в небольшую долю одного сервера.
Прямое сравнение с Samba DC сделали честно — оба контроллера на одной ВМ с 2 vCPU (Samba AD DC 4.19 и HopeDC v199), 8 параллельных клиентов по LDAPS:
Замер
Samba DC 4.19
HopeDC v199
Поиск по готовому соединению
6 520–6 840 оп/с
6 140–6 440 оп/с
Сессия входа (TLS + bind + поиск + отключение)
86–94 /с
700–742 /с
Процессор сервера на одну сессию
~20 мс
~1,4 мс
Память сервера (PSS)
1,5 ГБ / 21 тыс. объектов
0,7 ГБ / 40 тыс. в 12 доменах
Загрузка 20 тыс. пользователей одним потоком
~60 /с, 5 мин
~1 100 /с, 18 с
Поиск по готовому соединению у обоих стоит одинаково (Samba чуть быстрее в среднем, HopeDC ровнее на хвосте).
Разница — в установке сессии: на том же процессоре HopeDC принимает в 8 раз больше входов и тратит на каждый в 14 раз меньше процессора. Именно так работают веб-приложения, почтовые и VPN-шлюзы, которые проверяют пароли по LDAP: подключились, вошли, спросили, отключились (на чай времени нет).
Причина — архитектура:
-
HopeDC — один процесс с общим индексированным каталогом в памяти, где TLS, bind и запись идут асинхронно без внешней СУБД;
-
Samba распределяет работу между процессами над базой LDB, где установка сессии и запись дороже.
Оба контроллера на одной ВМ с 2 vCPU, 8 клиентов по LDAPS. Поиск по готовому соединению у обоих примерно равен; разница — в установке сессии, как её и создают веб-, почтовые и VPN-шлюзы.
Как читать эти цифры. Испытание на 582 тыс. объектов шло на стенде, где MS AD эмулирован контроллером Samba AD DC. Сам MS AD под этой нагрузкой мы не замеряли, сравнение идёт по реальным пикам, которые обслуживают восемь контроллеров Windows.
Сравнение с Samba сделано на машине с 2 vCPU, где рядом работал и клиент нагрузки, поэтому важнее соотношение, чем абсолютные значения. Перед внедрением цифры обязательно стоит подтвердить на оборудовании заказчика.
Как мы понимаем, что это работает
-
326 автотестов ядра — от разбора схемы и выравнивания PAC до защиты от отката часов.
-
Эталонный стенд — Samba AD и FreeIPA рядом, чтобы сверять поведение байт в байт; на нём проверены перенос домена в 582 тыс. объектов и импорт доверий.
-
Первичные нагрузочные замеры на полном объёме каталога и прямое сравнение с Samba DC на одном стенде.
-
Внутренний пентест защитных механизмов с воспроизведением реальных атак.
Что мы вынесли
Самым трудным оказалась не одна технология, а дисциплина совместимости и безопасности на каждом шаге: схема до байта, PAC с его NDR-выравниванием, соль ключей Kerberos, рефералы между доменами, изоляция лесов — и всё это без единого шанса оставить пользователя без входа в компьютер.
Там, где был быстрый, но сомнительный путь (репликация AD с DCSync), мы выбирали длинный и честный.
Там, где защиту нельзя сделать абсолютной (офлайн-лицензия, целостность бинарника), не делали вид, что сделали, — а поднимали стоимость атаки и прямо описывали оставшиеся пределы. А модель доверия в итоге вышла строже, чем в самом AD.
Принципиальный подход в разработке.
Контроллер домена — это инфраструктура, которой доверяют, не задумываясь. Заслужить это доверие можно только одним способом: относиться к каждой мелочи так, будто от неё зависит вход тысячи человек на работу утром. Потому что так и есть.
Друзья, в обзорной статье От корпоративного монстра к своему решению вы спрашивали про дистрибутив продукта и документацию.
Обещал, что подготовят — выполняю:
-
Документация
-
Дистрибутив HopeDC. На момент выпуска статьи версия v204
Обзорные статьи про продукты Hope (Надежда)
От корпоративного монстра к своему решению
Статьи про HopeDC
HopeDC · Инженерная история
Источник: habr.com