linuxlab.io
Учебники▾
  • Линукс и сети
    Файловая система, процессы, TCP/IP, BGP и OSPF
    →
  • Terraform и IaC
    HCL, state, plan/apply на sandbox LocalStack
    →
  • Git и GitHub
    Объектная модель, plumbing, ветвление, GitHub Actions
    →
Все учебники →
ЦеныО платформеВойтиСоздать аккаунт
/
  • Введение
  • Уроки
  • How it works
  • Симулятор
  • База знаний
  • Собеседование
Index
Categories
All entries
Footer
linuxlab-УчебникиЦеныО платформеКонфиденциальность и куки
Copyright © 2026 LinuxLab. Все права защищены.
home/linux/kb/Протоколы/ldap-basics

kb/protocols ── Протоколы ── intermediate

LDAP - directory services основы

LDAP - запрос к иерархическому справочнику. DN = координата объекта (cn=user,ou=People,dc=example,dc=com), bind = аутентификация, schema задаёт классы объектов и атрибуты. OpenLDAP/389-DS на Linux.

view as markdownaka: ldap, openldap, ds-389, ldap-search, active-directory-ldap

Зачем LDAP

Lightweight Directory Access Protocol (RFC 4511), стандарт доступа к иерархическому справочнику: пользователи, группы, hosts, сертификаты, конфиги приложений. Появился в 90-х как упрощение X.500. Сегодня используется для:

  • Centralized auth: Active Directory (Microsoft), FreeIPA (Red Hat), OpenLDAP / 389-DS (linux-only)
  • Адресная книга email-серверов (ou=People для autocomplete в Outlook/Thunderbird)
  • Конфиги приложений и DNS-данных в одном дереве
  • Хранение SSH-ключей пользователей (с patches/openssh-ldap)

Не БД общего назначения. Чтение быстрое, запись редкая оптимизирован под "много read, мало write".

Иерархическая структура

Дерево объектов (DIT, Directory Information Tree):

dc=example,dc=com                      ← корень = domain
├─ ou=People
│   ├─ uid=alice         (objectClass: posixAccount, inetOrgPerson)
│   ├─ uid=bob
│   └─ uid=carol
├─ ou=Groups
│   ├─ cn=admins
│   └─ cn=developers
└─ ou=Services
    └─ cn=ldap-replica
  • DN (Distinguished Name), полная "координата": uid=alice,ou=People,dc=example,dc=com
  • RDN (Relative DN), последний компонент: uid=alice
  • dc (domainComponent), ou (organizationalUnit), uid, cn (commonName), атрибуты, формирующие DN

Чтение справа-налево: dc=com → dc=example → ou=People → uid=alice.

Bind, аутентификация

Перед запросами клиент bind'ится:

  • Anonymous bind, без credentials, доступ только к public-данным
  • Simple bind, DN + пароль в plaintext (требует TLS!)
  • SASL bind, через Kerberos/EXTERNAL/DIGEST-MD5/PLAIN
bash
# Anonymous (для тестов)
ldapsearch -x -H ldap://ldap.example.com -b "dc=example,dc=com" "(uid=alice)"
# Simple bind
ldapsearch -x -D "uid=alice,ou=People,dc=example,dc=com" -W \
           -H ldaps://ldap.example.com -b "dc=example,dc=com" "(objectClass=*)"
# SASL Kerberos (когда есть TGT)
ldapsearch -Y GSSAPI -H ldap://ldap.example.com -b "dc=example,dc=com" "(uid=alice)"
  • -x, simple bind
  • -D, bind DN
  • -W, спросить пароль интерактивно
  • -H, URL (ldap://, ldaps://)
  • -Y, SASL mechanism

Объекты и атрибуты

Каждый объект имеет один или несколько objectClass (определяет schema), которые задают обязательные и опциональные атрибуты:

ldif
dn: uid=alice,ou=People,dc=example,dc=com
objectClass: top
objectClass: posixAccount             # uidNumber, gidNumber, homeDirectory
objectClass: inetOrgPerson            # mail, sn, givenName, telephoneNumber
objectClass: shadowAccount            # shadowLastChange и подобное
uid: alice
cn: Alice Wonderland
sn: Wonderland
givenName: Alice
uidNumber: 1001
gidNumber: 1001
homeDirectory: /home/alice
loginShell: /bin/bash
mail: alice@example.com
userPassword: {SSHA}xxxx              # hashed

Главные классы для пользователя в Linux:

  • posixAccount, uid/gid, чтобы NSS+PAM могли использовать
  • inetOrgPerson, почта, имя
  • shadowAccount, password expiry

LDAP-фильтры

Поиск через LDAP Filter (RFC 4515):

(uid=alice)                          # точное совпадение
(cn=Alice*)                          # wildcard
(mail=*@example.com)                 # суффикс
(&(uid=alice)(memberOf=cn=admins,ou=Groups,dc=example,dc=com))   # AND
(|(uid=alice)(uid=bob))              # OR
(!(loginShell=/bin/false))           # NOT
(uidNumber>=1000)                    # >= (только для int)
(objectClass=posixAccount)

Все спецсимволы в значении надо экранировать (\28 для ().

ldapsearch, основная утилита

bash
# Все posixAccount'ы с uidNumber >= 1000
ldapsearch -x -H ldaps://ldap -b "dc=example,dc=com" \
           "(&(objectClass=posixAccount)(uidNumber>=1000))" uid uidNumber cn
# Только конкретные атрибуты
ldapsearch ... "(uid=alice)" mail telephoneNumber
# ВСЁ что есть на объекте
ldapsearch ... "(uid=alice)" "+"                # operational attributes
# Размер дерева
ldapsearch -x -H ldap://srv -b "" -s base "(objectclass=*)"  # rootDSE

LDIF, формат экспорта/импорта

LDIF (LDAP Data Interchange Format), текстовый формат:

ldif
dn: ou=Test,dc=example,dc=com
changetype: add
objectClass: organizationalUnit
ou: Test
dn: uid=alice,ou=Test,dc=example,dc=com
changetype: add
objectClass: posixAccount
objectClass: inetOrgPerson
uid: alice
cn: Alice
sn: Wonderland
uidNumber: 1001
gidNumber: 1001
homeDirectory: /home/alice
bash
ldapadd -D "cn=admin,dc=example,dc=com" -W -f users.ldif
ldapmodify -f changes.ldif
ldapdelete "uid=alice,ou=People,dc=example,dc=com"

OpenLDAP vs 389-DS vs FreeIPA vs AD

ПризнакOpenLDAP (slapd)389-DSFreeIPAActive Directory
Default гдеDebian/UbuntuRHELRHEL/FedoraWindows Server
Конфигcn=config (LDIF)dse.ldif + consoleвеб-UI + CLIWindows GUI
Replicationmirror/N-way multimastermulti-suppliersuppliers + RO replicasDC + RODC
Kerberosотдельно (MIT)можновстроен + DNS + Kerberos + CAвстроен
Сложность setupсредняясредняянизкая (всё-в-одном)низкая (на Windows)
Linux-клиентыsssd / nss-ldapsssdsssd (родная интеграция)sssd через realmd

Для нового self-hosted на Linux, FreeIPA (если RHEL/Fedora) или 389-DS standalone. OpenLDAP, legacy, но всё ещё распространён.

TLS, обязательно

Без TLS пароли при simple-bind идут в plaintext, tcpdump их достанет. Варианты:

  • ldaps:// на 636, implicit TLS
  • STARTTLS на 389, opportunistic, но клиент может не запросить

Современный сервер должен принимать только ldaps:// или запрещать simple-bind без STARTTLS:

ldif
# OpenLDAP
olcSecurity: ssf=128

Когда что-то пошло не так

  • Invalid credentials (49), неверный DN или пароль. Бывает также если запись не имеет userPassword вообще.
  • Insufficient access rights (50), bind ок, но ACL-rule запрещает чтение/запись. Смотри olcAccess.
  • Server is unwilling to perform (53), operation запрещена конфигом (например write на read-only replica).
  • Constraint violation (19), пароль не прошёл pwd-policy (длина, история).
  • Object class violation (65), добавляешь атрибут которого нет в objectClass'ах или удаляешь обязательный.
  • Чудовищно медленный поиск, нет индекса по атрибуту. slapindex после olcDbIndex: cn,uid eq.
  • TLS handshake падает, старые шифры на одной стороне или самоподписанный CA не в trust store клиента.

Альтернативы и связанные

  • sssd, Linux-клиент, кэширует LDAP/AD/Kerberos для NSS+PAM
  • nslcd / nss-ldap, старый клиент, deprecated в пользу sssd
  • Apache Directory Studio, GUI для просмотра/правки дерева
  • OpenID Connect / OAuth2, современный пользовательский SSO (приложения уходят с LDAP-аутентификации в OIDC, но LDAP остаётся как backing user-store)

§ команды

bash
ldapsearch -x -H ldaps://ldap -b 'dc=example,dc=com' '(uid=alice)' mail uidNumber

Поиск конкретного юзера, ограниченный набор атрибутов

bash
ldapsearch -x -H ldap://srv -b '' -s base '+'

rootDSE - метаинформация о сервере (поддержка SASL, TLS, naming contexts)

bash
ldapadd -x -D 'cn=admin,dc=example,dc=com' -W -f users.ldif

Импортировать LDIF - типичный bulk-add

bash
ldapmodify -x -D 'cn=admin,dc=example,dc=com' -W <<EOF\ndn: uid=alice,ou=People,dc=example,dc=com\nchangetype: modify\nreplace: mail\nmail: alice@new.com\nEOF

Модификация атрибута через heredoc - быстрее чем редактировать LDIF-файл

bash
slapcat -n 1 > backup.ldif

Бэкап OpenLDAP базы данных N1 в LDIF - оффлайн-метод

bash
getent passwd alice

NSS-проверка - LDAP-юзер виден операционке (если sssd/nss-ldap настроены)

bash
openssl s_client -connect ldap.example.com:636 -showcerts

Проверить TLS-сертификат LDAPS-сервера - дебаг handshake-проблем

§ см. также

  • pamPAM - Pluggable Authentication ModulesPAM - фреймворк аутентификации в Linux. Программы (sudo, login, sshd) не проверяют пароли сами, а вызывают PAM, который через стек модулей в `/etc/pam.d/<service>` решает: пускать или нет.
  • kerberosKerberos - сетевой single sign-onKerberos - SSO-система с тикетами на временной криптографии. Один раз вводишь пароль (`kinit`), получаешь TGT, дальше KDC выдаёт service tickets в обмен. Основа AD и FreeIPA.
  • smtp-mtaSMTP и MTA - доставка emailSMTP - текстовый протокол доставки почты. 25/tcp - server-to-server, 587 - submission (клиент с auth), 465 - implicit-TLS legacy. MX-запись в DNS, STARTTLS+SPF+DKIM+DMARC - стандартный набор.
  • tls-handshakeTLS handshakeTLS - слой шифрования поверх TCP. Перед передачей данных стороны делают handshake: обмениваются ключами, проверяют сертификат, выбирают cipher.
  • sshSSH - secure shellSSH - зашифрованный канал к удалённому хосту: shell, копирование файлов, port-forwarding. Стандартный порт 22, аутентификация по ключам или паролю.
  • radiusRADIUS - аутентификация для сети, VPN, Wi-FiRADIUS - старый AAA-протокол UDP/1812+1813 (auth+accounting). Использование - аутентификация на сетевом железе: Wi-Fi WPA2-Ent через EAP, VPN-клиенты, доступ к роутерам и switch'ам. FreeRADIUS - реализация по умолчанию.
Footer
linuxlab-
Copyright © 2026 LinuxLab. Все права защищены.
Учебники
Цены
О платформе
Конфиденциальность и куки