OGOwnGate

Почему прямой LDAP Bind в каждом сервисе — это мина замедленного действия

Раздавать пароль сервисной учётки AD каждому сервису и гонять LDAP Bind по локалке кажется простым решением, пока логи не утекут или контроллер домена не ляжет от сотен одновременных поисков. Разбираем, почему прямой LDAP пора отправить на свалку истории.

Прямой LDAP bind против централизованного шлюза

В девяти из десяти компаний со штатом до 200 человек архитектура авторизации выглядит одинаково: сисадмин Вася десять лет назад создал в Active Directory сервисную учётку svc_ldap_reader, накинул ей пароль P@ssw0rd2016! и галочку «Срок действия пароля не ограничен».

С тех пор эту учётку заботливо скопипастили во все конфиги: в Jenkins, Zabbix, старый Redmine, корпоративную вики, Grafana, внутреннюю CRM и десяток скриптов бэкапа.

Работает? Работает. Трогать страшно? Безумно.

Но если копнуть чуть глубже удобной иллюзии «у нас же всё завязано на единый домен», оказывается, что прямой LDAP Bind из каждого утюга — это архивная мина, на которой ваш контур безопасности подорвётся при первом же серьёзном аудите или инциденте.

---

1. Пароль от сервисной учётки знают даже стены

Что нужно приложению, чтобы авторизовать пользователя через LDAP?

Ему нужно:

1. Подключиться к контроллеру домена (DC).

2. Забиндиться под сервисной учёткой (Bind DN и пароль).

3. Найти DN пользователя по его логину ((sAMAccountName=username)).

4. Попробовать забиндиться от имени пользователя с введённым им паролем.

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

Где лежат эти креды?

  • В открытых конфигурационных файлах /etc/... на веб-серверах;
  • В переменных окружения docker-compose.yml, забытых в публичном пайплайне;
  • В репозиториях Git, которые клонируют джуны на свои домашние ноутбуки;
  • В бэкапах баз данных приложений.

Стоит скомпрометировать хотя бы один тестовый стенд или забытый WordPress во внутренней сети — и злоумышленник получает валидную доменную учётку для разведки структуры всей компании.

---

2. Порт 389 и передача паролей в открытом виде

«Мы же внутри закрытого сетевого периметра, зачем нам LDAPS?» — любимая отговорка перед катастрофой.

Если вы используете обычный LDAP на порту 389 без StartTLS, пароли сотрудников летают по корпоративной локальной сети открытым текстом при каждой аутентификации. Любой скомпрометированный хост в том же VLAN или сетевой интерфейс в режиме promiscuous (зеркалирование трафика, ARP-спуфинг) аккуратно собирает базу паролей прямо из сырых пакетов Simple Bind.

Настройка LDAPS (порт 636) решает вопрос шифрования трафика, но приносит с собой персональный ад:

  • Протухающие сертификаты внутренних CA;
  • Проблемы с валидацией цепочек доверия в разных языках и рантаймах (Java TrustStore, Python certifi, OpenSSL в PHP);
  • Внезапные падения сервисов в 3 часа ночи из-за того, что на DC обновился сертификат контроллера, а контейнер с Grafana об этом не узнал.

---

3. Невозможность прикрутить второй фактор (MFA)

Вот здесь наступает тупик. Бизнес приходит к ИТ-руководителю и требует: «Срочно внедрить второй фактор на все внутренние системы!».

И тут выясняется неприятная правда: протокол LDAP был спроектирован в 1993 году. В нём фундаментально нет концепции интерактивного второго фактора, пуш-уведомлений или TOTP-кодов. Протокол знает только операцию Bind: «вот DN, вот пароль — скажи, верный или нет».

Как сисадмины пытаются выкручиваться?

Костылями вроде конкатенации: заставляют сотрудников вводить в поле пароля Пароль+123456 (где последние 6 цифр — код из приложения).

Результат:

  • Пользователи путаются, ошибаются, блокируют себе учётки в AD;
  • Мобильные клиенты и плагины ломаются, потому что сохраняют склеенный пароль и спамят им до полной блокировки аккаунта;
  • Саппорт тонет в тикетах «почему меня заблокировало».

---

4. DDoS контроллера домена на каждый чих

Когда у вас 3 сервиса — контроллер домена справляется. Когда у вас 25 внутренних сервисов и 150 активных сотрудников, контроллер домена превращается в бутылочное горлышко.

Каждый клик в веб-интерфейсе, каждый опрос API, каждый фоновый воркер генерирует серию LDAP-запросов:

1. bind

2. search

3. bind пользователя

4. search по группам (memberOf)

5. unbind

Если приложение не умеет в Connection Pooling (а большинство легковесных веб-приложений открывает новое сокет-соединение на каждый HTTP-запрос), контроллер домена захлёбывается в TCP-хэндшейках и шифровании TLS. При утреннем наплыве сотрудников или запуске тяжёлого CI/CD пайплайна задержки авторизации подскакивают до десятков секунд.

---

Как перестать страдать: архитектура SSO-шлюза

Решение этой проблемы придумано давно и называется федерацией удостоверений (Modern Identity Federation).

Сервисы компании вообще не должны знать адрес контроллера домена и тем более хранить пароли сервисных учёток.

Вместо сотен прямых труб в AD ставится единый шлюз доступа (OwnGate):


[Пользователь] ──► [Веб-сервис (GitLab / Grafana / Wiki)]

                          │ (Перенаправление OIDC)

                          ▼

                  [Шлюз OwnGate]

                          │ 

               (Проверка AD / MFA / Сессии)

                          │

                          ▼

            [Active Directory / OpenLDAP]

Что меняется кардинально:

1. Сервисы не знают паролей. Приложение общается со шлюзом по современному протоколу OpenID Connect (OIDC). Пользователь вводит пароль только в окне шлюза.

2. Второй фактор из коробки. Шлюз сам запрашивает TOTP, пуш или аппаратный ключ FIDO2. Приложению вообще не нужно знать, как устроен ваш второй фактор.

3. Контроллер домена защищён. Шлюз кэширует сессии, держит пул соединений и не долбит Active Directory на каждый переход по страницам.

4. Мгновенный отзыв. Заблокировали сотрудника в AD — шлюз мгновенно сбрасывает все активные токены во всех подключённых системах.

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

← Все статьи