Мониторинг OpenLDAP с помощью Proto Observability

Сбор метрик и логов сервера каталогов OpenLDAP (slapd) — соединения, операции, потоки, статистика передачи данных.

На этой странице:

Сбор метрик OpenLDAP

Интеграция openldap собирает рантайм-статистику сервера каталогов OpenLDAP (slapd): читает поддерево cn=Monitor по протоколу LDAP (не JMX, не Prometheus). Из него извлекаются метрики соединений, операций (bind / search / add / modify / delete / …), потоков, ожидающих воркеров, объёма переданных данных и аптайма. Дополнительно можно описать произвольные LDAP-поиски в custom_queries — для них собираются длительность и число найденных записей.

Конфигурация OpenLDAP

Включите бэкенд cn=Monitor и выдайте доступ на чтение поддерева cn=Monitor тому DN, под которым будет биндиться агент (здесь — cn=admin,dc=example,dc=org). В современном slapd (формат конфигурации cn=config, она же slapd.d) это делается LDIF-файлом:

# enable-monitor.ldif
dn: olcDatabase=monitor,cn=config
objectClass: olcDatabaseConfig
olcDatabase: monitor
olcAccess: to dn.subtree="cn=Monitor" by dn.base="cn=admin,dc=example,dc=org" read by * none

Примените его от имени root-DN сервера через ldapi:///:

ldapadd -Y EXTERNAL -H ldapi:/// -f enable-monitor.ldif

slapd сам присвоит индекс базе данных (например, olcDatabase={2}monitor,cn=config, после {0}config и {1}mdb/{1}hdb).

В Docker-образах с механизмом «bootstrap LDIF» (например, osixia/openldap) те же LDIF-файлы достаточно положить в каталог, который образ применяет на первом старте — для osixia/openldap это /container/service/slapd/assets/config/bootstrap/ldif/custom:

services:
  openldap:
    image: osixia/openldap:1.5.0
    environment:
      LDAP_DOMAIN: "example.org"          # → base DN dc=example,dc=org
      LDAP_ADMIN_PASSWORD: "adminpassword"
      LDAP_LOG_LEVEL: "256"               # loglevel "stats" — нужен для сбора логов
    volumes:
      - ./bootstrap/ldif/custom:/container/service/slapd/assets/config/bootstrap/ldif/custom
    ports:
      - "389:389"

В таком образе back_monitor обычно не статический, поэтому набор LDIF состоит из двух файлов: сначала moduleload back_monitor (см. предыдущий alert), затем создание olcDatabase=monitor,cn=config с ACL на cn=Monitor. Учтите, что стартовый скрипт osixia выбирает ldapadd vs ldapmodify по наличию слова changetype в файле — не пишите его в комментариях к LDIF, который должен примениться через ldapadd.

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

ldapsearch -x -H ldap://localhost:389 -D "cn=admin,dc=example,dc=org" -w adminpassword \
  -b "cn=Monitor" -s base "+"

Команда должна вернуть запись cn=Monitor (а с -s sub — всё поддерево со счётчиками monitorCounter / monitorOpInitiated / monitoredInfo и т.п.).

Конфигурация ProtoOBP агента

Если агент запускается в виде службы на хосте

  1. Создайте файл /etc/protoobp-agent/conf.d/openldap.d/conf.yaml:

    init_config:
    
    instances:
      - url: ldap://localhost:389          # ldaps://localhost:636 для TLS, ldapi:/// для unix-сокета
        username: cn=admin,dc=example,dc=org
        password: adminpassword
        # ssl_verify: true                 # проверять сертификат сервера (для ldaps://)
        # ssl_ca_certs: /path/to/ca.pem    # CA-сертификат
        # ssl_cert: /path/to/client.pem    # клиентский сертификат (mTLS)
        # ssl_key: /path/to/client.key     # ключ клиентского сертификата
        # tags:
        #   - ldap_instance:primary
        # custom_queries:
        #   - name: active_users
        #     search_base: ou=people,dc=example,dc=org
        #     search_filter: "(objectClass=inetOrgPerson)"
        #     search_scope: subtree        # base | level | subtree
        #     attributes: []               # [] = только посчитать записи; иначе список атрибутов
        #     # username / password можно переопределить per-query
    
  2. Перезапустите агента: systemctl restart protoobp-agent.

url поддерживает схемы ldap:// (открытое соединение), ldaps:// (TLS) и ldapi:// (unix-сокет). Если на cn=Monitor выдан анонимный доступ на чтение — username / password можно не указывать; в примере выше доступ ограничен admin-DN, поэтому они обязательны.

Если агент запускается в виде Docker контейнера

Добавьте autodiscovery-лейблы к контейнеру slapd. В docker-compose.yaml:

labels:
  com.protoobp.ad.check_names: '["openldap"]'
  com.protoobp.ad.init_configs: '[{}]'
  com.protoobp.ad.instances: '[{"url": "ldap://%%host%%:389", "username": "cn=admin,dc=example,dc=org", "password": "adminpassword"}]'

%%host%% агент подставит автоматически — это адрес контейнера в docker network. Для TLS используйте "url": "ldaps://%%host%%:636" и при необходимости "ssl_verify": false / "ssl_ca_certs": "<путь>" в том же объекте instance.

Проверка

Убедитесь, что проверка запустилась и собирает метрики:

docker exec protoobp-agent agent status | grep -A 8 "^    openldap"

Ожидаемый вывод — Instance ID: … [OK] и ненулевые Metric Samples:

openldap (1.10.0)
  Instance ID: openldap:bdbe18c6f6daf828 [OK]
  Configuration Source: container:docker://…
  Total Runs: 8
  Metric Samples: Last Run: 40, Total: 320
  Service Checks: Last Run: 1, Total: 8
  Average Execution Time : 84ms

Полный список собираемых метрик с тегами — agent check openldap--check-rate собираются и кумулятивные count-метрики openldap_operations_*, openldap_connections_total, openldap_statistics_* — на одном прогоне дельты ещё нет):

docker exec protoobp-agent agent check openldap --check-rate

За один прогон проверка отдаёт около 40 семплов (18 различных метрик плюс разбивка по лейблам operation / status).

Собираемые метрики

Метрики приходят из поддерева cn=Monitor. Тип метрики:

  • gauge — мгновенное значение на момент сбора;
  • count — кумулятивный счётчик slapd; интеграция отправляет его как monotonic count (агент считает дельту между сборами).

В ProtoOBP backend имена метрик хранятся в Prometheus-стиле — точки заменены на подчёркивания (openldap_connections_current, openldap_operations_initiated и т.д.). Именно в таком виде они приведены ниже и под ними их видно на дашбордах и в алертах.

Лейблы

Добавляются агентом и ProtoOBP backend’ом:

ЛейблЗначение
hostХост, на котором работает агент
urlURL LDAP-сервера из instances: (например, ldap://openldap:389)
operationТип LDAP-операции — только на openldap_operations_initiated / openldap_operations_completed (bind, unbind, search, compare, modify, modrdn, add, delete, abandon, extended)
statusСостояние пула потоков — только на openldap_threads (open, starting, active, pending, backload, max, max_pending)
queryИмя запроса из custom_queriesтолько на openldap_query_*
serviceТег service (через com.protoobp.tags.service или POBP_TAGS)
envТег env
docker_imageПолный ref образа контейнера (например, osixia/openldap:1.5.0)
image_nameИмя образа без тега
image_tagТег образа
short_imageКороткое имя образа

Соединения

Имя метрикиТипЕдиницаОписание
openldap_connections_currentgaugeconnectionТекущее число активных клиентских соединений
openldap_connections_totalcountconnectionСуммарное число соединений с момента старта сервера
openldap_connections_max_file_descriptorsgaugefileМаксимальное число файловых дескрипторов, доступное процессу

Операции

Метрики операций несут лейбл operation:<тип>; есть также агрегаты *_total без этого лейбла.

Имя метрикиТипЕдиницаОписание
openldap_operations_initiatedcountoperationЧисло инициированных операций, по типам (лейбл operation)
openldap_operations_completedcountoperationЧисло завершённых операций, по типам (лейбл operation)
openldap_operations_initiated_totalcountoperationСуммарное число инициированных операций по серверу
openldap_operations_completed_totalcountoperationСуммарное число завершённых операций по серверу

Статистика передачи данных

Имя метрикиТипЕдиницаОписание
openldap_statistics_bytescountbyteКоличество байт, отправленных сервером
openldap_statistics_entriescountentryКоличество записей (entries), отправленных сервером
openldap_statistics_pducountpacketКоличество PDU-пакетов, отправленных сервером
openldap_statistics_referralscountmessageКоличество referral’ов, отправленных сервером

Потоки и ожидающие

Метрика openldap_threads несёт лейбл status:<состояние>.

Имя метрикиТипЕдиницаОписание
openldap_threadsgaugethreadЧисло потоков пула, по состояниям (лейбл status)
openldap_threads_maxgaugethreadСконфигурированный максимум потоков пула
openldap_threads_max_pendinggaugethreadМаксимальное число потоков в очереди ожидания
openldap_waiter_readgaugeworkerТекущее число воркеров, ожидающих чтения из сокета
openldap_waiter_writegaugeworkerТекущее число воркеров, ожидающих записи в сокет

Время и доступность

Имя метрикиТипЕдиницаОписание
openldap_uptimegaugesecondАптайм сервера slapd (по cn=Start,cn=Time,cn=Monitor)
openldap_bind_timegaugesecondВремя, которое заняла у проверки операция bind к серверу

Пользовательские запросы (custom_queries)

Собираются для каждого элемента custom_queries (лейбл query:<name>):

Имя метрикиТипЕдиницаОписание
openldap_query_durationgaugesecondВремя выполнения LDAP-поиска
openldap_query_entriesgaugeentryКоличество записей, вернувшихся по запросу

Ключевые метрики для дашбордов и алертов

Доступность сервера

  • Отсутствие свежих серий по url — алерт: slapd недоступен или агент не может забиндиться к cn=Monitor.
  • Резкий сброс openldap_uptime (или значение близкое к нулю при работающем трафике) — slapd перезапустился.
  • openldap_bind_time — рост = сервер отвечает медленно (нагрузка, проблемы с диском/сетью).

Соединения и дескрипторы

  • openldap_connections_current близко к openldap_connections_max_file_descriptors — сервер скоро упрётся в лимит fd и начнёт отбрасывать соединения; алерт по отношению (например, > 80 %).
  • Резкий рост openldap_connections_total (производная) — всплеск подключений (клиенты не переиспользуют соединения / DDoS / неисправный клиент).

Операции

  • openldap_operations_initiated{operation:search} — основной показатель нагрузки на чтение; рост search без роста числа клиентов = неэффективные запросы (нет индекса → full scan).
  • openldap_operations_initiated_totalopenldap_operations_completed_total стабильно растёт — операции зависают (блокировки, перегрузка пула потоков).
  • Ненулевой openldap_operations_initiated{operation:bind} при росте ошибок аутентификации (видно в логах) — перебор паролей.

Пул потоков и backpressure

  • openldap_threads{status:active}openldap_threads_max и openldap_threads{status:pending} > 0 — пул потоков исчерпан, запросы ждут в очереди; алерт.
  • openldap_waiter_read / openldap_waiter_write стабильно высокие — много соединений в ожидании ввода-вывода (медленные клиенты или сеть).

Объём отдаваемых данных

  • Резкий рост openldap_statistics_entries / openldap_statistics_bytes (производная) — кто-то делает массовые/нефильтрованные выгрузки ((objectClass=*) по всему дереву).
  • Ненулевой openldap_statistics_referrals там, где referral’ов быть не должно — неверно сконфигурированы chaining/глобальные referral’ы.

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

  • openldap_query_entries для контрольного custom_query упал до нуля — ожидаемые данные исчезли из каталога (сломалась репликация, кто-то удалил OU).
  • openldap_query_duration растёт — деградация конкретного поиска (потеря индекса по атрибуту фильтра).

Сбор логов OpenLDAP

Логи slapd собираются ProtoOBP агентом и отправляются в бэкенд ProtoOBP. Здесь — только специфичные для OpenLDAP настройки. Включение логов на стороне агента (logs_enabled, logs_pobp_url) описано в Получение данных логов.

Конфигурация ProtoOBP агента

Если агент запускается в виде службы на хосте

Куда slapd пишет лог, зависит от роутинга syslog: с olcLogLevel процесс шлёт записи в syslog facility local4, дальше rsyslog/journald раскладывают их по файлу (часто /var/log/slapd.log, или /var/log/syslog). Настройте этот файл в rsyslog (local4.* /var/log/slapd.log), затем дополните существующий /etc/protoobp-agent/conf.d/openldap.d/conf.yaml (тот же файл, где лежит instances: для метрик) блоком logs::

logs:
  - type: file
    path: /var/log/slapd.log
    source: openldap
    service: openldap

Записи slapd однострочные (syslog-формат <дата> <host> slapd[pid]: conn=… op=… SEARCH …) — правило multi_line не требуется.

Перезапустите агента: systemctl restart protoobp-agent.

Если агент запускается в виде Docker контейнера

Шаг 1 — включите сбор логов в самом агенте через переменные окружения и смонтируйте директорию JSON-логов docker-демона:

services:
  protoobp-agent:
    environment:
      POBP_LOGS_ENABLED: "true"
      POBP_LOGS_CONFIG_USE_HTTP: "true"
      POBP_LOGS_CONFIG_LOGS_POBP_URL: <protoobp-backend>:<port>
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock:ro
      # Прямое чтение JSON-лог файлов docker-демона быстрее,
      # чем тянуть их через Docker socket API.
      - /var/lib/docker/containers:/var/lib/docker/containers:ro

Шаг 2 — добавьте лейбл com.protoobp.ad.logs к контейнеру slapd. Агент подхватит stdout/stderr контейнера и пометит записи указанными source и service:

services:
  openldap:
    image: osixia/openldap:1.5.0
    environment:
      LDAP_LOG_LEVEL: "256"             # без этого slapd почти ничего не пишет
    labels:
      com.protoobp.ad.logs: '[{"source": "openldap", "service": "openldap"}]'

Проверка

В выводе agent status должен быть раздел Logs Agent со статусом running и источник openldap с ненулевым BytesRead:

docker exec protoobp-agent agent status \
  | sed -n '/^==== Logs Agent ====/,/^====/p'