Как мы ускорили ванильную FreeIPA в 20 раз!!! (почти)

Мы — это кто?

Мы — команда внедрения продуктов «Группы Астра». Каждый день имеем дело с такими решениями, как СУБД Tantor, ПК СВ «Брест», Termidesk, RuPost, WorksPad, RuBackup, VMmanager и другие.

Как инженеры внедрения (Integration Team),  мы обеспечиваем интеграцию всех продуктов компании, участвуем в составлении технической документации, проведении приёмо-сдаточных испытаний, плотно взаимодействуем с представителями заказчика по технической части, но самое важное — «наживую» внедряем собственные российские продукты в ИТ-среду наших заказчиков.
А еще мы умеем стыковать наши продукты с уже имеющимся у заказчика импортным или отечественным ПО.

Сложно? — Да.
Интересно? — Безумно!

Помимо наших продуктов (например, Astra Automation), для автоматизации и обеспечения подхода Infrastructure as Code (IaC) мы используем в своей работе:
— Ansible, Salt
— Terraform, OpenTofu
— Python, Bash
— Docker, Podman
— Git

Но в статье речь пойдет об ALD Pro (Astra Linux Domain Pro).

ALD Pro

ALD Pro — это набор сетевых служб, которыми можно управлять через единый веб-портал. В технологический стек входят следующие компоненты:

  • FreeIPA

    • Bind9

    • MIT KDC

    • 389 Directory Server

  • Reprepo

  • ISC DHCP

  • TFTP + PXE

  • Zabbix, Grafana

  • CUPS

  • Samba

  • Syslog-ng

Так что же не так с FreeIPA?

Один заказчик попросил предоставить инструмент нагрузки LDAP-запросов, да не простой, а с GUI и графиками.

Наша команда в своей работеактивно использует open source инструмент нагрузочного тестирования Locust (англ. Саранча)

Сам по себе Locust является ядром нагрузки с минимальным функционалом из коробки, но этот функционал расширяется за счет использования Locustfiles, которые пишутся на чистом Python, что позволяет не ограничиваться набором инструкций, как, например, в Dockerfile/Containerfile/Vagrantfile, а писать отдельные Python-модули.

Таким образом, «Кузнечик» состоит из двух частей: Python-модуля для Locust и изменяемой инфраструктуры служб нагрузки в docker-compose файле.
Мы добавили требуемый функционал (нагрузка LDAP, DNS и Kerberos), позволяя при этом пользоваться встроенными в Locust возможностями.

«Кузнечик»


Но за LDAP в FreeIPA отвечает компонент 389 Directory Server.

Так и есть.

Дальше по тексту все упоминания про LDAP подразумевают работу именно с 389-ds.

Инструмент нагрузки предоставлен — можно расходиться?

На создании инструмента нагрузки ничего не закончилось, а все только началось.

Мы нагрузили ALD Pro, получили графики и…
Как ранее, а точнее в 2023 году (а может, и раньше, но это не важно), было сказано на Хабре:

ALD Pro

Разработчики нашего «Кузнечика» приняли решение сравнить производительность MS AD и ALD Pro. Тем более наши предположения заказчик подтвердил на следующей встрече, изъявив желание провести подобное сравнение. Но мы уже были готовы к подобному вопросу.

Горизонтальная ось — количество пользователей (единица нагрузки, а не пользователь в LDAP):

Время ответа в ms. График сравнения продуктов ALD Pro и MS AD
График сравнения продуктов ALD Pro и MS AD. Время ответа в ms.

Да, здесь мы сделали так:

Picture background
Ошеломляюще!

Ну, и другой срез:

Число ответов в  секунду. График сравнения продуктов ALD Pro и MS AD
Число ответов в секунду. График сравнения продуктов ALD Pro и MS AD

Подождите!!! Это же катастрофа!!!
Как мы можем пойти к заказчику с такими графиками? Нужно что-то делать!

Сравнительный анализ

Мы судорожно стали делать различные сборки и сравнивать нагрузку.

Во-первых, нам предстояло исключить влияние собственных наработок ALD Pro и ОС Astra Linux:

График сравнения продуктов ALD Pro и MS AD
График сравнения продуктов ALD Pro и MS AD. Время ответа max, ms

Как видно из графика, ALD Pro на ОС Astra Linux уступает в производительности FreeIPA на Fedora в 2 раза, но все эти сборки существенно проигрывают MS AD.

График сравнения продуктов ALD Pro и MS AD. Число ответов в секунду max, rps
График сравнения продуктов ALD Pro и MS AD. Число ответов в секунду max, rps

График сравнения числа ответов в секунду подтверждает разницу. То есть разница в производительности между FreeIPA на Fedora и ALD Pro на Astra Linux есть, но незначительная по сравнению с разницей между ванильной FreeIPA и MS AD.

Если мы, как команда внедрения, не можем повлиять на ускорение запросов в операционной системе Astra Linux и продукте ALD Pro, то, быть может, стоит рассмотреть способы ускорения LDAP во FreeIPA?

— Нам это под силу?

— Пока не попробуешь, не узнаешь.

Создаем тикеты по данной проблеме в продуктовые команды и идем погружаться в 389-ds.

Нагрузка и бинарный поиск

preview url image

Какая диагностика без информации, что происходит в ОС?
Проверяем, насколько грузит процессор сервис LDAP:

нагрузка на процессор на контроллере домена
Нагрузка на процессор на контроллере домена, %

Служба Dirsrv грузит процессор по максимуму, независимо от операционной системы и версии FreeIPA.
Проверили на железе: результат такой же.

Нагрузка на процессор на контроллере домена, %
Нагрузка на процессор на контроллере домена, %

Ресурсов процессора не хватает в нескольких случаях.

Вариант с бэкдором (вспоминаем XZ backdoor) мы откинули практически сразу, но допускали возможность ошибки в исходном коде.

Под рукой была старая версия FreeIPA на Fedora 34, которая нас приятно удивила:  версия 2.0.1 389-ds работает быстрее!

Мы запустили ряд тестирований различных версий 389-ds, руководствуясь бинарным поиском.

Всего было рассмотрено 49 версий, начиная с 2.0.1 и заканчивая 3.1.1.

Здесь нужно объяснить, что 2.0.х, 2.1.х, 2.2.х, 2.3.х — это версии под разные релизы операционной системы.

2.0.х — под Fedora 34 и 35.

2.1.х — под Fedora 36.

2.2.х — под Fedora 37.

В общей сложности нами сделано несколько десятков нагрузочных тестирований на разных ОС и различными нагрузчиками.

Так мы с каждым разом оттачивали навыки владения «Кузнечиком» (плюсы есть во всем :)).

Использование контейнеров сильно облегчило нам эту задачу.

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

# пример использования freeipa в контейнере
# «медленная» freeipa
podman pull freeipa/freeipa-server: fedora-35–4.9.10
mkdir ipa35–4-data
podman run --sysctl net.ipv6.conf.all.disable_ipv6=0 -e IPA_SERVER_IP=10.191.0.159 -p 80:80 -p 443:443 -p 389:389 -p 636:636 -p 88:88 -p 464:464 -p 88:88/udp -p 464:464/udp -p 123:123/udp --name freeipa-server-container-35–4 -ti -h dc4.ipa.pro --read-only -v $(pwd)/ipa35–4-data:/data: Z freeipa/freeipa-server: fedora-35–4.9.10

# «быстрая» freeipa
podman pull freeipa/freeipa-server: fedora-35–4.9.9
mkdir ipa35–3-data
podman run --sysctl net.ipv6.conf.all.disable_ipv6=0 -e IPA_SERVER_IP=10.191.0.159 -p 80:80 -p 443:443 -p 389:389 -p 636:636 -p 88:88 -p 464:464 -p 88:88/udp -p 464:464/udp -p 123:123/udp --name freeipa-server-container-35–3 -ti -h dc4.ipa.pro --read-only -v $(pwd)/ipa35–3-data:/data: Z freeipa/freeipa-server: fedora-35–4.9.9


Результаты в студию!
(представим только наиболее значимые)

OS

FreeIPA

389 Directory Server

Результаты

Fedora 34

FreeIPA 4.9.6

389-ds 2.0.15

 высокие показатели производительности

Fedora 35

FreeIPA 4.9.7

389-ds 2.0.11

 высокие показатели производительности

Fedora 35

FreeIPA 4.9.8

389-ds 2.0.15

 высокие показатели производительности

Fedora 35

FreeIPA 4.9.10

389-ds 2.0.17

 низкие показатели производительности

Fedora 36

FreeIPA 4.9.9

389-ds 2.1.1

 высокие показатели производительности

Almalinux 8

FreeIPA 4.9.9

389-ds 2.1.1

 высокие показатели производительности

Rocky Linux 8

FreeIPA 4.9.10

389-ds 1.4.3.34

 высокие показатели производительности

Fedora 37 (rawhid)

FreeIPA 4.9.10

389-ds 2.2.1

 высокие показатели производительности

Fedora 37 (rawhid)

FreeIPA 4.9.9

389-ds 2.1.1

 высокие показатели производительности

Fedora 35

FreeIPA 4.9.11

389-ds 2.0.16 (не в контейнере)

 высокие показатели производительности

Мы специально выделили жирным результаты, которые можно сравнить с производительностью, близкой к производительности MS AD.

Вы можете проверить наши испытания и убедиться в этом самостоятельно с помощью более простых инструментов тестирования, например ldclt от разработчиков 389-ds или jmeter (сравнение в 7 главе).

Цифры могут быть другими, но сравнительный анализ покажет подобную дельту.

Так мы пришли к нашей версии, но уже с другой стороны.

Шел 2022 год…

Странный заголовок, но таковы реалии.

Давайте посмотрим на дату выхода релизов 389-ds:

Между данными релизами есть проблема
Между выделенными релизами есть проблема

Своими тестами мы исключили влияние ОС на замедление 389-ds.

Все, что связано с производительностью, прячется в самом 389-ds, и это точно шифрование.

«Чуть-чуть терпения», — говорим мы себе.

На скрине выделены релизы, между которыми большая разница в производительности. Таким образом, нас интересует разница между 2.0.16 (выпущен в июле 2022 года) и 2.0.17 (выпущен в ноябре 2022 года).

Посмотрим на сравнение между версиями.

А чтобы долго не томиться, можно сразу проваливаться в issue 5356.

С ноября 2022-го разработчики 389-ds внедрили RUST как дефолтную схему хранения паролей. А-ха!

For RUST build update the default password storage scheme

4. RUST vs C

RUST не уступает в скорости, говорили они и они, значит, и код должен быть быстрым?

Так ли это в нашем случае?

Для ответа на данный вопрос мы даже собрали свои пакеты из исходников, исключив данный коммит, чтобы получить более свежую версию 389-ds, но оставить дефолтную схему на С (хотя этих трудозатрат можно было избежать — ниже опишем).

На картинке ниже выделили новую схему на RUST.

Теперь на RUST
Теперь на RUST
PBKDF2-SHA256 и PBKDF2_SHA512
PBKDF2-SHA256 и PBKDF2_SHA512

Заметили разницу в названии между старым и вновь установленным дефолтным методом?

Запомните эту разницу: дальше по тексту это будет играть большую роль.

Погнали тесты!

Время ответа. Сравнение разных методов шифрования
Время ответа. Сравнение разных методов шифрования
Число ответов в  секунду. Разные методы шифрования
Число ответов в секунду. Разные методы шифрования
Нагрузка на процессор. Разные методы шифрования
Нагрузка на процессор. Разные методы шифрования

На графиках нас интересуют красный и фиолетовый столбцы.

WOW
WOW

Новая схема на быстром RUST грузит процессор, число ответов выдает ниже в 3 раза, а время отклика в 20 раз больше старой схемы на медленном С.

Да, с 2022 года все продукты, базирующиеся на FreeIPA, стали в 3 раза медленнее безопаснее просто потому, что в 389-ds был внесен коммит со схемой на RUST.

Но FreeIPA — это open sourse продукт, которым пользуется и Red Hat.

ну, вы поняли
ну, вы поняли

Конечно, очень интересно сравнить производительность FreeIPA на Fedora и RHEL, так как RHEL тоже использует схему на RUST.
Добавляем:

Сравнение FreeIPA на Fedora и RHEL. Время ответа max, ms
Сравнение FreeIPA на Fedora и RHEL. Время ответа max, ms
Сравнение FreeIPA на Fedora и RHEL. Число ответов в секунду max, rps
Сравнение FreeIPA на Fedora и RHEL. Число ответов в секунду max, rps
Сравнение FreeIPA на Fedora и RHEL. Нагрузка процессора DC, %
Сравнение FreeIPA на Fedora и RHEL. Нагрузка процессора DC, %

Разницы в нагрузке нет, да и число запросов не многим больше. Это обнадеживает.

Криптография

Как уже было сказано выше, на скорость повлияли коммиты, связанные с ISSUE-5356, в которых был изменен бэкенд шифрования с PBKDF2_SHA256 (написанный на языке C) на PBKDF2-SHA512 (написанный на языке Rust).

Изменение должно было ускорить алгоритм шифрования + хеширования, но, напротив, привело к снижению скорости. 

Существенная разница в скорости также сохраняется между PBKDF2_SHA256 (на C) и PBKDF2-SHA256 (на RUST):

У Rust число итераций для алгоритма RBKDF2 на языке Rust было захардкожено на 10 000, совсем недавно добавили возможность менять это значение в промежутке с 10 000 до 10 000 000 (ссылка на коммит и статью) со значением, по умолчанию равным 100 000, но все тесты проводились до появления этой функции.

У C число итераций для алгоритма PBKDF2 подбирается автоматически на основе производительности CPU (в нашем случае получилось 2 048).

Based on CPU performance
Based on CPU performance

В связи с разницей в числе итераций был проведен тест с 2 048 итерациями для алгоритма на RUST (изменено значение переменной с перекомпиляцией в новые пакеты).

 Результат: PBKDF2_SHA256 (на C) кратно быстрее,  чем PBKDF2-SHA256 (на RUST).

RUST в данном случае проявил себя далеко не с положительной стороны
RUST в данном случае проявил себя далеко не с положительной стороны

Пост автора этих двух алгоритмов,  в котором упоминаются проблемы с производительностью кода, написанного на языке C в связи с ошибкой в библиотеке NSS.
Однако результаты тестирования демонстрируют обратное поведение.
Тесты показывают, что ошибка так и не устранена.

Коммиты с ISSUE-5356:

  • https://github.com/389ds/389-ds-base/commit/7d381b9a8b000f9a9facaf45b5e09f40da6bd318

  • https://github.com/389ds/389-ds-base/commit/41c8e4101b23a0cc2a630a8040bd58d96dbb60f3

Решение

Скорость simple bind во многом определяется используемым алгоритмом шифрования, потому что при передаче пароля серверу LDAP нужно произвести шифрование переданного пароля и сравнить с паролем из базы, что может являться узким горлышком при высокой нагрузке.

Чтобы выяснить, какие схемы доступны в 389-ds, используем команду (ALD-PRO — домен) :

# Посмотреть текущие значения
grep password-storage-scheme /etc/dirsrv/slapd-ALD-PRO/dse.ldif

Доступные схемы шифрования:
CLEAR, CRYPT, CRYPT-MD5, CRYPT-SHA256, CRYPT-SHA512, GOST_YESCRYPT, MD5, PBKDF2, PBKDF2-SHA1,  PBKDF2-SHA256, PBKDF2-SHA512, PBKDF2_SHA256, SHA, SHA256, SHA384, SHA512, SMD5, SSHA, SSHA256, SSHA384, SSHA512

Мы подробно рассмотрели каждую из них. Вот наши выводы (постарались расставить по убыванию производительности):

  • CLEAR, CRYPT, CRYPT-MD5, CRYPT-SHA256, MD5, PBKDF2, PBKDF2-SHA1, SHA, SHA256, SHA384, SHA512, SMD5, SSHA, SSHA256, SSHA384 — не рекомендуются к использованию.

  • SSHA512 — менее безопасный,  чем PBKDF2-SHA512 и PBKDF2_SHA256, но очень быстрый.

  • PBKDF2_SHA256 — менее безопасный,  чем PBKDF2-SHA512, однако быстрый.

  • CRYPT-SHA512 — альтернатива PBKDF2-SHA512, точно сказать, какой из них безопаснее, нельзя, но CRYPT-SHA512 быстрее в несколько раз. Единственная информация, которую можно найти по этому вопросу.

  • PBKDF2-SHA256 — менее безопасный, чем PBKDF2-SHA512,  медленный.

  • PBKDF2-SHA512 — алгоритм по умолчанию (с ноября 2022 года),  безопасный, но медленный.

  • GOST_YESCRYPT — алгоритм ГОСТ Р 34.11–2012,  самый медленный алгоритм из всех представленных, поддерживается только в Astra Linux 1.8.

Стоит учитывать, что все алгоритмы, представленные выше,  небезопасные (кроме, возможно, GOST_YESCRYPT) согласно рекомендациям OWASP.
Для каждого из алгоритмов требуется гораздо более высокое значение итераций.

Сейчас открыт pull request на возможность параметризации числа итераций, но это будет относиться к новейшим версиям. Стоит понимать, что увеличение числа итераций очень негативно повлияет на производительность.

На данный момент для хранения паролей рекомендуются такие алгоритмы, как bcrypt, argon2i, scrypt,  однако они не реализованы в 389-ds-base.

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

Например, если домен находится в закрытом контуре, защищенном другими СЗИ (средства защиты информации), можно использовать более быстрый метод шифрования. В любом случае нужно отталкиваться от конкретной архитектуры ИТ-инфраструктуры.

 Для решения проблемы скорости simple bind нужно поменять алгоритм шифрования паролей в БД 389-ds-base на более быстрый и перезадать пароль пользователей.

Перезадать пароли важно, поскольку после смены алгоритма пароли останутся с предыдущим шифрованием.

Приводим команды:

# Посмотреть текущие значения
dsconf -D «cn=Directory Manager» ldap://$(hostname -f) config get passwordStorageScheme nsslapd-rootpwstoragescheme

# Заменить PBKDF2-SHA512 на другой алгоритм (в примере CRYPT-SHA512)
dsconf -D «cn=Directory Manager» ldap://$(hostname -f) config replace passwordStorageScheme=CRYPT-SHA512 nsslapd-rootpwstoragescheme=CRYPT-SHA512

# Поменять пароль Directory Manager
dsconf -D «cn=Directory Manager» ldap://$(hostname -f) config replace nsslapd-rootpw=»»

# Поменять пароль пользователей ALD Pro/FreeIPA
ipa user-mod admin --password

# Перезагрузить dirsrv (любой из 3 вариантов)
aldproctl restart
ipactl restart
dsctl restart

Бонус

Еще мы выяснили, что есть возможность использования различных схем шифрования для разных пользователей.

Сейчас наши коллеги работают над реализацией данной функциональности в веб-интерфейсе ALD Pro, а пока мы это делаем через cli.

Например, можно назначить администраторам пароли, используя наиболее безопасный алгоритм, а пользователям — попроще, но более быстрый:

  • для администраторов в Astra Linux 1.8 — GOST_YESCRYPT,

  • для администраторов в Astra Linux 1.7 — PBKDF2-SHA512 / CRYPT-SHA512,

  • для пользователей — менее ресурсоемкий алгоритм SSHA512 / PBKDF2_SHA256.

MS AD

Со схемами шифрования во FreeIPA разобрались, но нужно разобраться и с MS AD.

Определимся с методом шифрования в MS AD — это даст понимание, почему такая высокая скорость.

Но по MS AD мало информации, MD4 или MD5.

Нашли это и это

NTLMv1 использует MD4, v2 использует MD5
NTLMv1 использует MD4, v2 использует MD5
MD5
MD5

и это

MD5
MD5

Если обратили внимание, мы проводили сравнение FreeIPA с MS AD на базе Windows 2012R2. Но для себя провели сравнение и с MS AD на базе Windows 2019.

Таким образом, мы сравнивали разные по скорости и безопасности методы шифрования. Отсюда такая разница в производительности.

Сертификация ФСТЭК

Раз мы выявили обратную зависимость «производительность — безопасность», стоит рассказать и про безопасность.

А что может быть нагляднее, чем сертификация ФСТЭК?

ALD Pro соответствует требованиям безопасности информации, установленным в документе «Требования по безопасности информации, устанавливающие уровни доверия к средствами технической защиты информации и средствам обеспечения безопасности информационных технологий» (ФСТЭК России, 2022) (далее — Требования), по 4 уровню доверия, что удостоверяется сертификатом соответствия № 4830, выданным ФСТЭК России 26 июля 2024 г., а также соответствует декларируемым в технических условиях функциональным возможностям.

Сертификат ФСТЭК России подтверждает, что ALD Pro может применяться в ИСОП (информационные системы общего пользования) II класса, а также в информационных системах, обрабатывающих информацию ограниченного доступа, не содержащую сведения, составляющие государственную тайну, в том числе:

в ГИС (государственные информационные системы) до I класса защищенности включительно;

в ИСПДн (информационные системы персональных данных) до I уровня защищенности включительно;

в АСУ ТП (автоматизированные системы управления производственными и технологическими процессами) до I класса защищенности включительно;

в составе ЗО КИИ (значимые объекты критической информационной инфраструктуры) до I категории включительно.

MS AD

Сертификаты ФСТЭК России отсутствуют, срок действия части сертификатов закончился в 2019 году (MS Server 2008, 2012), 2021 году (MS Server 2012R2), часть сертификатов приостановили/отозвали в 2022 году (MS Server 2016, MS 10).

FreeIPA

Свободное ПО, не сертифицировано во ФСТЭК России.

У тех заказчиков, где сертификация ПО является одним из ключевых требований, выбор очевиден. А теперь еще и скорость работы ALD Pro можно получить высокую.

SambaDC

Но мы не мы, если не сравним производительность FreeIPA и SambaDC.

В SambaDC же нет 389-ds с его новой дефолтной схемой на RUST.

На удивление SambaDC не грузит процессор, но и производительностью похвастаться не может (от слова «совсем»).

Вот эти зеленые пики в космос, они же время отклика, — это SambaDC:

SambaDC. Время отклика max, ms
SambaDC. Время отклика max, ms
SambaDC. Число ответов в секунду max, rps
SambaDC. Число ответов в секунду max, rps
SambaDC. Нагрузка процессора DC, %
SambaDC. Нагрузка процессора DC, %

Заметили, у нас изменились названия на ALD Pro Patched (применение более быстрой схемы шифрования)?

В процессе тестов мы использовали различные инструменты нагрузки (ldclt, jmeter) , чтобы проверить, нет ли узкого места на стороне самого «Кузнечика».

Тесты демонстрируют чуть более низкие результаты для Astra Linux  1.7.6uu1 + ALD Pro 2.4.0 по сравнению с Fedora 41 + FreeIPA 4.12.2 (1 и 2 тест соответственно).

В тестах на MSAD 2012R2 ldclt позволил нагрузить до 7000–7500 RPS, что в 5–6 раз выше значений, полученных при помощи нашего«Кузнечика».Причина меньшей производительности «Кузнечика» была в малом числе Worker-контейнеров. С увеличением числа Worker’ов добились производительности, сравнимой с ldclt или jmeter. Однако после оптимизации LDAP на базе 389-ds и проведения нагрузки на уже высоких значениях RPS мы выявили еще одну проблему. Рассказываем.

База, но не данных

Идем в базу TCP, так как LDAP — это TCP.

Проблема

В чем проблема?  Проблема в том, что мы эмулируем клиентскую нагрузку с одного  хоста, поэтому столкнулись с нехваткой портов для TCP-соединений при нагрузке уже «затюненного» 389-ds.
Почему не сталкивались с проблемой ранее?  До «тюнинга» 389-ds не выдерживал нагрузку, которая могла бы привести к такой проблеме.

Почему этого не было в MS AD? 389ds и MS AD по-разному отрабатывают операцию unbind на транспортном уровне OSI, об этом ниже.

Вот как это выглядит на практике. Возьмем для наглядности инструмент ldclt и проведем нагрузку на уже затюненный 389-ds.

Нагрузка
Нагрузка «затюненного» 389-ds с помощью ldclt

Что получаем? Через несколько десятков секунд нагрузка полностью приостанавливается ввиду того, что нет свободных портов.
В Jmeter,  или «Кузнечике»,  без контейнеров произойдет аналогичная ситуация, так уж работает TCP.

Анализ

Начнем с того, что число соединений ограничивается 5 значениями: протокол, порт источника, порт назначения, IP-источника, IP-назначения.

В нашем случае протокол всегда TCP.

IP-назначения и порт назначения тоже постоянные.

Остаются два значения — порт источника и IP-источника. В случае использования инструментов нагрузочного тестирования специфика заключается в том, что IP-источника один и тот же, поэтому количество соединений получается сильно лимитированным.

Начнем с порта источника:

Если установить число свободных портов до максимальных 1024–65535 (в ядре linux это значение определяется параметром net.ipv4.ip_local_port_range), то получим 64511 доступных портов в одну единицу времени (порты 1–1023 служебные и требуют прав суперпользователя либо повышения прав).

Соединение TCP при переходе в статус TIME_WAIT не позволяет использовать занятый порт в течение последующих 60 секунд (время длительности TIME_WAIT) — делим 64511 портов на 60 секунд и получаем значение 1075.18 pps (Port per Second).

TCP state diagram
TCP state diagram

Округляем до целых значений и получаем 1075 — это максимальное число RPS, которое можно получить для одного хоста (не говоря о том, что некоторые порты могут быть заняты).

Принимая во внимание тот факт, что после оптимизации один экземпляр 389-ds сервер способен выдерживать нагрузку более чем в 3 000 RPS, для того чтобы нагрузить его на максимум одним клиентом нагрузочного тестирования, у этого клиента должно быть не менее трех IP-адресов сразу.

Мы помним, что один хост может использовать несколько разных IP-адресов (IP-alias/network namespaces/bridge). Для понимания принципа работы TCP-соединений прикладываем:

389 Directory Server

В системе Linux время задержки захардкожено, и изменить его в меньшую сторону не представляется возможным.

tcp_fin_timeout
tcp_fin_timeout

Вот что нам показывает Wireshark:

# TCP handshake
SYN -->
<-- SYN/ACK
ACK -->

LDAP (bindRequest) -->
<-- ACK
<-- LDAP(bindResponse(2) success)
ACK -->
LDAP (unbindRequest) -->
FIN/ACK -->
<-- FIN/ACK
ACK -->

# Соединение со стороны клиента попадает в статус TIME_WAIT и ожидает своего завершения 60 секунд (значение захардкожено и равно 2 * MSL)
# На диаграмме соединение идет по длинному пути — от TIME WAIT к CLOSED
# Соединение со стороны сервера попадает в статус CLOSE_WAIT и закрывается практически моментально

FIN, ACK
FIN, ACK

MS AD

В это время у MS AD:

# TCP handshake
SYN -->
<-- SYN/ACK
ACK -->

LDAP (bindRequest) -->
<-- LDAP(bindResponse(2) success)
ACK -->
LDAP (unbindRequest) -->
FIN/ACK -->
<-- ACK
<-- RST/ACK
# Соединение обрывается незамедлительно из-за флага RST (Reset)

MS AD намеренно отправляет флаг RST при закрытии соединения, аналогичный механизм использует HAProxy при отправке Healthcheck’ов для экономии времени и ресурсов:

RST, ACK
RST, ACK

Получается:

FIN, ACK - ACK - RST, ACK
FIN, ACK — ACK — RST, ACK

Решение

Повлиять на количество портов со стороны нагрузчика мы не можем, уменьшить время ожидания TIME_WAIT мы тоже не способны.

Так почему бы нам не создать бОльшее количество нагрузчиков (в терминологии Locust — workers)?

Мы так и сделали — все наши воркеры крутятся в docker-контейнерах с использованием типа сети ipvlan, что позволяет каждому воркеру иметь свою пару IP: Порт.

Но есть нюанс!  Использование простого bridge в Docker не поможет, и для решения мы использовали ipvlan, который позволяет каждому контейнеру иметь IP-адрес из подсети хоста (аналог bridge в qemu/kvm). Ниже вывод DST NAT таблицы на хосте при использовании простого docker bridge, и мы видим, что в итоге все контейнеры будут использовать адрес хоста, и, как следствие, число соединений мы не увеличим.

вывод таблицы DST NAT с хоста и в итоге все контейнеры будут использовать адрес хоста
вывод таблицы DST NAT с хоста, и в итоге все контейнеры будут использовать адрес хоста

Подведем итоги

Picture background
Вывод

Здесь можно написать что-то подобное:
Никогда не сдавайся!
Не доверяй open-source решениям
Тестирование продуктов — один из важных процессов. При заимствовании разработок необходимо тестировать и эти разработки.
Безопасность MS AD под вопросом.

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

Как лучше действовать: накинуть контроллерам домена вычислительных ресурсов или упросить алгоритм шифрования, будет зависеть, конечно же, от потребностей конкретного проекта. Но смеем заметить, что до тех пор, пока в ИТ-инфраструктуре будет оставаться MS AD с ее NTLM-хешами, вариант с упрощением алгоритма шифрования видится вполне оправданным решением. Будем рады, если материалы нашего исследования окажутся вам полезны, тогда с вас лайки, комментарии, подписка.

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

© Habrahabr.ru