Что такое SSSD и зачем он нужен для LDAP-аутентификации
SSSD (System Security Services Daemon) держит локальный кэш учётных записей и хэшей паролей, поэтому вход в систему продолжает работать, когда LDAP-каталог временно недоступен. Цепочка запросов выглядит так: утилита (login, sshd, ls, sudo) обращается к NSS или PAM, те передают запрос демону sssd, а он отвечает из локальной базы или идёт в каталог по LDAP. Каталог не ответил, но запись пользователя уже лежит в кэше, и вход проходит по сохранённому хэшу пароля.
Для эксплуатации это ключевая возможность. Когда сервер каталога лёг или до него пропал маршрут, администратор всё ещё заходит по SSH под доменной учётной записью и чинит инфраструктуру. Без прослойки вроде SSSD каждый вход требует живого соединения с LDAP, и отказ каталога превращается в отказ доступа ко всему парку машин, включая те, через которые этот каталог чинят.
Пакеты SSSD лежат в стандартных репозиториях RHEL 8/9, CentOS Stream, Rocky, AlmaLinux, Ubuntu 22.04 и 24.04, Debian, SUSE. Собирать из исходников ничего не нужно: dnf install sssd sssd-ldap sssd-tools в семействе RHEL или apt install sssd sssd-ldap sssd-tools ldap-utils в Debian/Ubuntu.
SSSD vs nss-pam-ldapd: почему выбор в пользу SSSD
nss-pam-ldapd (связка nslcd и pam_ldap) ходит в каталог при каждом обращении NSS. Пока каталог жив, разницы почти нет. Как только он ушёл в недоступность, вход блокируется целиком, потому что кэша учётных данных у связки нет.
| Критерий | SSSD | nss-pam-ldapd |
|---|---|---|
| Вход при недоступном каталоге | Работает по кэшу, если пользователь уже входил онлайн | Не работает, нужен живой LDAP |
| Кэш пользователей и групп | Локальная база с настраиваемым TTL | Только вспомогательный nscd, часто отключён |
| Правила sudo из каталога | sudo_provider = ldap, правила кэшируются | Не поддерживается |
| Переключение между серверами | Список ldap_uri, переход к резервному автоматически | Ограниченный failover |
| Нагрузка на каталог | Один демон, ответы из кэша, меньше запросов | Запрос в LDAP на каждое обращение NSS |
| Конфигурация | Один файл sssd.conf на все сервисы | ldap.conf плюс nsswitch.conf плюс скрипты PAM |
| Статус в дистрибутивах | Штатный компонент RHEL, Ubuntu, Debian, SUSE | Вытеснен, в новых версиях не развивается |
Компоненты SSSD: identity provider, auth provider, access provider
Домен SSSD описывается набором провайдеров, каждый закрывает свою часть работы.
- id_provider отвечает, откуда брать пользователей, группы и их атрибуты (uid, gid, домашний каталог, shell). Для каталога это id_provider = ldap.
- auth_provider определяет способ проверки пароля. При auth_provider = ldap SSSD делает bind в каталог от имени самого пользователя.
- access_provider решает, кому разрешён вход на конкретный хост: ldap проверяет фильтр по атрибутам, simple сверяется со списком групп или имён.
- sudo_provider указывает, откуда брать правила sudo. При значении ldap правила читаются из каталога и кэшируются для офлайн-работы.
Порядок при входе по SSH такой: PAM просит auth_provider проверить пароль, затем access_provider разрешает или запрещает вход на этот хост, и только после этого NSS отдаёт uid, gid и путь к домашнему каталогу. Отказ на шаге проверки доступа выглядит как «Permission denied» при верном пароле, поэтому фильтр доступа проверяют отдельно от аутентификации.
Установка и базовая настройка SSSD для LDAP
Файл /etc/sssd/sssd.conf пакеты не создают, его пишут руками. Права обязательны строгие: файл читает только root, иначе демон откажется стартовать.
Минимальный рабочий sssd.conf: разбор параметров
[sssd] config_file_version = 2 services = nss, pam, sudo domains = example.com [domain/example.com] id_provider = ldap auth_provider = ldap access_provider = ldap sudo_provider = ldap ldap_uri = ldaps://ldap1.example.com,ldaps://ldap2.example.com ldap_search_base = dc=example,dc=com ldap_user_search_base = ou=people,dc=example,dc=com ldap_group_search_base = ou=groups,dc=example,dc=com ldap_sudo_search_base = ou=sudoers,dc=example,dc=com ldap_default_bind_dn = cn=sssd-reader,ou=services,dc=example,dc=com ldap_default_authtok = ПарольСлужебнойУчётнойЗаписи ldap_tls_cacert = /etc/sssd/certs/ca.crt ldap_tls_reqcert = demand cache_credentials = True entry_cache_timeout = 5400 entry_cache_user_timeout = 86400 offline_credentials_expiration = 7 enumerate = False
Разбор по строкам. Секция [sssd] перечисляет сервисы, которые демон обслуживает: nss для резолвинга имён, pam для аутентификации, sudo для правил. В [domain/example.com] имя домена после слэша должно совпадать с тем, что указано в domains, иначе конфиг не применится. ldap_uri принимает список серверов через запятую, порядок задаёт приоритет, переход к резервному происходит автоматически. ldap_search_base задаёт корень поиска по умолчанию, а ldap_user_search_base и ldap_group_search_base сужают область и заметно ускоряют ответы. ldap_default_bind_dn и ldap_default_authtok описывают служебную учётную запись, которой SSSD ищет записи в каталоге: ей достаточно прав на чтение нужных OU.
Пароль в открытом виде в конфиге допустим только при правах 600. Безопаснее хранить обфусцированное значение: sss_obfuscate --domain example.com, тогда вместо пароля в файл попадёт строка вида {...} с ключом. Параметр enumerate = False отключает выгрузку всего каталога на клиент: при больших деревьях он превращает вход в многоминутное ожидание.
В конце настройки файла: chown root:root /etc/sssd/sssd.conf и chmod 600 /etc/sssd/sssd.conf.
Настройка nsswitch.conf и PAM для работы с SSSD
В /etc/nsswitch.conf строки должны выглядеть так: passwd: files sss, group: files sss, shadow: files sss, sudoers: files sss. Порядок важен: files стоит первым, поэтому root и локальные сервисные записи резолвятся без обращения к демону. Это спасает, когда SSSD упал или не стартовал.
В RHEL 8/9 и производных стек PAM собирают командой authselect: authselect select sssd --with-mkhomedir --with-sudo. В Debian и Ubuntu настройку включают через pam-auth-update: pam-auth-update --enable mkhomedir, затем --enable sssd. Параметр mkhomedir создаёт домашний каталог при первом входе пользователя, без него вход проходит, а сессия ломается на отсутствующей папке. Подробности про связку PAM и NSS разобраны в материале о подключении Linux к LDAP через SSSD.
После правок: systemctl enable --now sssd и systemctl restart sssd.
Проверка результата: getent, id, su
Три команды показывают, что связка работает.
- getent passwd testuser@example.com - должен вернуть строку с uid, gid, домашним каталогом и shell.
- id testuser@example.com - покажет uid, gid и список групп, включая дополнительные из каталога.
- su - testuser@example.com или ssh testuser@example.com@localhost - проверяет полный цикл: PAM, access rules, создание домашнего каталога.
Пустой вывод getent означает, что запрос не доходит до SSSD: проверяют nsswitch.conf, статус службы systemctl status sssd и лог /var/log/sssd/sssd_example.com.log. Пользователь виден в getent, но не входит, значит проблема на слое PAM или в фильтре доступа.
Настройка TLS для безопасного подключения SSSD к LDAP
Открытый LDAP на порту 389 передаёт пароль bind в виде, доступном для перехвата. В продакшене соединение либо шифруют сразу (ldaps), либо поднимают шифрование поверх существующего канала (StartTLS).
ldaps vs StartTLS: что выбрать
| Параметр | ldaps:// | StartTLS |
|---|---|---|
| Порт | 636 | 389 |
| Запись в sssd.conf | ldap_uri = ldaps://ldap1.example.com | ldap_uri = ldap://ldap1.example.com плюс ldap_id_use_start_tls = True |
| Момент шифрования | TLS с первого байта соединения | Канал открывается в открытом виде, затем апгрейд до TLS |
| Риск понижения защиты | Отсутствует | Есть, если не задан ldap_id_use_start_tls = True: клиент молча работает без шифрования |
| Совместимость с прокси и балансировщиками | Часть решений не пропускает 636 | Проходит там, где 636 закрыт |
| Быстрая проверка снаружи | openssl s_client -connect ldap1.example.com:636 | ldapsearch -H ldap://ldap1.example.com -ZZ |
Практическое правило: если инфраструктура позволяет держать 636 открытым, выбирают ldaps, это меньше поводов для ошибки в конфиге. StartTLS берут при жёстких сетевых ограничениях, обязательно с явным флагом в sssd.conf.
Установка CA-сертификата и проверка цепочки
SSSD проверяет сертификат сервера по доверенному корню. Два способа сделать это: положить CA в системное хранилище или указать файл напрямую в конфиге. Первый вариант удобнее для всего парка: в RHEL копируют сертификат в /etc/pki/ca-trust/source/anchors/ и выполняют update-ca-trust, в Debian и Ubuntu кладут в /usr/local/share/ca-certificates/ и выполняют update-ca-certificates. Второй вариант точнее контролируется: сертификат лежит, например, в /etc/sssd/certs/ca.crt, а в домене задан ldap_tls_cacert = /etc/sssd/certs/ca.crt.
Параметр ldap_tls_reqcert = demand означает обязательную проверку сертификата сервера и совпадения имени. Значение never допустимо только на время отладки: с ним шифрование работает, но подмена сервера не обнаруживается.
Проверка цепочки и прав учётной записи выполняется двумя командами:
openssl s_client -connect ldap1.example.com:636 -CAfile /etc/sssd/certs/ca.crt -verify_return_error ldapsearch -H ldaps://ldap1.example.com -D "cn=sssd-reader,ou=services,dc=example,dc=com" -W -b "dc=example,dc=com" "(uid=testuser)"
В выводе openssl ищут строку «Verify return code: 0 (ok)». Если ldapsearch находит пользователя, а SSSD сообщает «TLS handshake failed», значит сертификат читает не тот файл: проверяют ldap_tls_cacert и логи домена. Итоговое состояние домена показывает sssctl domain-status example.com.
Offline cache: вход пользователей при недоступности LDAP
Механизм прост: при успешной онлайн-аутентификации SSSD сохраняет запись пользователя и хэш пароля в локальную базу. Когда каталог перестаёт отвечать, демон помечает домен как offline и дальше проверяет пароль по кэшу. Срок жизни кэша и сама возможность офлайн-входа управляются параметрами в домене.
Параметры кэширования в sssd.conf: полный разбор
| Параметр | Рекомендуемое значение | Что даёт |
|---|---|---|
| cache_credentials | True | Сохраняет хэш пароля и разрешает офлайн-аутентификацию. Без него кэш учётных данных не заполняется |
| entry_cache_user_timeout | 86400 | Сутки хранения записи пользователя в кэше, в секундах |
| entry_cache_group_timeout | 86400 | Срок жизни кэша групп и членства |
| entry_cache_timeout | 5400 | Общий TTL по умолчанию для тех типов записей, для которых не задан свой |
| offline_credentials_expiration | 7 | Сколько дней разрешён офлайн-вход после последнего успешного онлайн-входа. Ноль означает отсутствие ограничения |
| ldap_connection_expire_timeout | 60 | Через сколько секунд неудачных попыток домен переводится в offline |
Значение offline_credentials_expiration = 7 даёт неделю автономной работы. Больше ставить рискованно: уволенный сотрудник сохраняет доступ к серверу, пока кэш не истёк, а смена пароля в каталоге на клиенте не видна. Меньше суток тоже неудобно: короткий сбой сети или плановые работы на каталоге выводят людей из системы.
Каталог с двумя серверами описывают списком в ldap_uri: клиент перебирает адреса и уходит в offline только когда недоступны все. Как это сочетается с кэшем, подробно разобрано в руководстве по настройке SSSD с failover и кэшированием.
Практический сценарий: проверка входа при отключённом LDAP
- Убедиться, что пользователь хоть раз вошёл при живом каталоге: ssh testuser@example.com@server, затем exit. Кэш заполняется именно в момент успешной аутентификации, а не при простом getent.
- Имитировать отказ каталога на клиенте: iptables -I OUTPUT -p tcp -d 10.20.0.10 --dport 636 -j REJECT. Блокировка на клиенте безопаснее остановки боевого сервера каталога.
- Посмотреть статус домена: sssctl domain-status example.com. Ожидаемый вывод содержит строку «Online status: offline» и перечень активных серверов.
- Проверить вход: su - testuser@example.com. При включённом cache_credentials пароль принимается, несмотря на недоступный LDAP.
- Проверить, что именно отвечает демон: sssctl user-checks testuser@example.com. Команда показывает данные пользователя, список групп и результат проверки правил доступа.
- Снять блокировку: iptables -D OUTPUT 1, затем sssctl domain-status example.com -o для принудительного перехода в онлайн.
Если на шаге 4 вход не проходит, смотрят лог домена: строки «Backend is offline» подтверждают офлайн-режим, а «User not found in cache» означают, что кэш для этого пользователя не заполнен.
Ограничения offline cache: что не работает без LDAP
- Новый сотрудник войти не сможет: его записи и хэша пароля в кэше нет, а получить их негде.
- Смена пароля недоступна, операция требует живой каталог.
- Пароль, изменённый в каталоге другим администратором, офлайн не действует: принимается старый хэш из кэша.
- Членство в группах и записи групп показываются в состоянии на момент последнего обновления кэша, поэтому новые права не появятся.
- После истечения offline_credentials_expiration вход блокируется до первого успешного онлайн-сеанса.
- Первая настройка и первое подключение сервера всегда требуют доступного каталога, кэш заполнить нечем.
Офлайн-режим не заменяет локального аварийного доступа. На каждом сервере стоит держать локальную учётную запись администратора с ключом SSH и помнить, что при недоступном каталоге вход доменного пользователя без кэша невозможен.
Access rules и sudoers через SSSD
По умолчанию домен пускает на хост любого пользователя, найденного в каталоге. Ограничение задаёт access_provider, и для каталога это делается фильтром LDAP.
Фильтрация доступа по группам LDAP
Рабочая конфигурация для сценария «только администраторы Linux» выглядит так: access_provider = ldap и ldap_access_filter = (memberOf=cn=linux-admins,ou=groups,dc=example,dc=com). Фильтр должен находить саму запись пользователя: если атрибут memberOf в вашей схеме не поддержан, фильтр не совпадёт ни с кем и вход запретят всем подряд. Проверяют фильтр тем же bind DN, которым пользуется SSSD:
ldapsearch -H ldaps://ldap1.example.com -D "cn=sssd-reader,ou=services,dc=example,dc=com" -W -b "ou=people,dc=example,dc=com" "(&(uid=testuser)(memberOf=cn=linux-admins,ou=groups,dc=example,dc=com))"
Альтернатива с меньшей нагрузкой: access_provider = simple и simple_allow_groups = linux-admins, ops-team. Список групп хранится в конфиге, каждый вход не требует дополнительного поиска в каталоге. Минус один: изменения в каталоге не влияют на доступ, правку конфига нужно раскатывать по серверам. Как строить роли на основе членства в группах, включая делегирование sudo и права на файловые шары, разбирает статья про RBAC через группы LDAP.
Интеграция sudo с SSSD: пошаговая настройка
Правила sudo в каталоге описываются объектами sudoRole. Минимальный набор: sudoUser (кому), sudoHost (где), sudoCommand (что), sudoRunAs (от чьего имени), sudoOption (например, !authenticate). Для чтения этих правил в домене добавляют sudo_provider = ldap и ldap_sudo_search_base = ou=sudoers,dc=example,dc=com, а в секции [sssd] в services указывают sudo.
Периодичность обновления настраивается: ldap_sudo_full_refresh_interval = 21600 перечитывает весь набор правил раз в шесть часов, ldap_sudo_smart_refresh_interval = 900 обновляет только изменившиеся записи каждые 15 минут. Кэшированные правила продолжают работать при недоступном каталоге, что делает sudo доступным в офлайне.
Проверка: sudo -l -U testuser@example.com в списке правил, журнал /var/log/sssd/sssd_sudo.log при разборе проблем. Если правила не появляются, проверяют наличие строки sudoers: files sss в nsswitch.conf и права служебной учётной записи на OU с объектами sudoRole.
Очистка кэша SSSD и диагностика через sssctl
Кэш изменяется в двух случаях: после правки конфигурации и после изменений в каталоге, которые клиент не увидел из-за TTL. Различать эти ситуации важно, чтобы не стирать рабочий кэш на пустом месте.
Команды sssctl и sss_cache: шпаргалка
| Команда | Действие | Когда применять |
|---|---|---|
| sss_cache -E | Полная очистка кэша всех доменов | Массовые изменения в каталоге, подозрение на повреждённый кэш |
| sss_cache -u testuser@example.com | Сброс кэша конкретного пользователя | Пользователя переименовали, сменили uid или состав групп |
| sss_cache -G | Сброс кэша групп | Поменялось членство в группах, права не применились |
| sssctl user-checks testuser@example.com | Показывает, что демон отвечает про пользователя: данные, группы, результат проверки доступа | Пользователь виден в каталоге, но не входит |
| sssctl domain-status example.com | Статус домена: онлайн или офлайн, активные серверы, число записей в кэше | Проверка failover и офлайн-режима |
| sssctl config-check | Проверка синтаксиса и обязательных параметров sssd.conf | Перед перезапуском демона |
| sssctl cache-remove | Удаление файлов кэша с диска, требует подтверждения | Кэш повреждён или занимает аномальный объём |
Порядок действий при изменениях в каталоге: сначала sss_cache по нужному пользователю или группе, при массовых правках sss_cache -E, затем проверка через getent и id. Полный сброс кэша лишает сервер офлайн-входа до следующего успешного сеанса каждого пользователя, поэтому на удалённых площадках его делают осознанно.
Чтение логов SSSD: на что обращать внимание
Логи лежат в /var/log/sssd/. Для домена это /var/log/sssd/sssd_example.com.log, отдельные файлы создаются для сервисов: sssd_pam.log, sssd_nss.log, sssd_sudo.log. Системные сообщения дублируются в journalctl -u sssd -f, что удобно при воспроизведении проблемы в реальном времени.
Ключевые строки для разбора: «Backend is offline» подтверждает офлайн-режим, «TLS handshake failed» указывает на проблему с сертификатами, «User not found» и «returned 0 results» говорят о неверном search base или фильтре, «Invalid credentials» означает отказ bind в каталоге. Уровень детализации задаётся параметром debug_level = 9 в секции домена: этого хватает, чтобы увидеть реальные LDAP-фильтры и запросы. После отладки уровень возвращают к нулю, иначе journal на сервере растёт на гигабайты в сутки. Общий алгоритм поиска причин сбоев, включая проверку сетевых запросов, собран в шпаргалке по диагностике LDAP-аутентификации.
Типовые ошибки при настройке SSSD+LDAP и их решения
| Симптом | Причина | Решение |
|---|---|---|
| getent passwd возвращает пусто для доменного пользователя | В nsswitch.conf нет sss | Добавить sss в строки passwd, group, shadow, перезапустить sssd |
| Демон не стартует, в journalctl жалоба на права файла | Права на /etc/sssd/sssd.conf шире 600 | chmod 600 /etc/sssd/sssd.conf и chown root:root /etc/sssd/sssd.conf |
| В логе домена TLS handshake failed | CA-сертификат не указан или в цепочке нет корня | Задать ldap_tls_cacert, проверить цепочку через openssl s_client |
| Пользователь не найден при верном пароле | Неверный ldap_search_base или у bind DN нет прав на нужный OU | Повторить поиск ldapsearch с тем же bind DN и базой |
| Доступ запрещён после успешной проверки пароля | ldap_access_filter не совпадает с атрибутами пользователя | Сверить фильтр через ldapsearch, проверить регистр значений в memberOf |
| Офлайн-вход не работает | cache_credentials = False либо пользователь ни разу не входил онлайн | Включить кэш, выполнить один успешный вход при живом каталоге |
| Пароль офлайн не принимается | Истёк offline_credentials_expiration | Увеличить срок, обновить кэш онлайн-сеансом |
| sudo не видит правила из каталога | Не задан sudo_provider или нет строки sudoers в nsswitch.conf | Добавить sudo_provider = ldap и sudoers: files sss |
| Вход длится десятки секунд | Включён enumerate = True или мал TTL кэша | Отключить enumerate, поднять entry_cache_user_timeout |
| Пользователь входит, но домашний каталог не создаётся | Не включён модуль mkhomedir | authselect select sssd --with-mkhomedir или pam-auth-update --enable mkhomedir |
Диагностика через sssctl config-check
sssctl config-check читает sssd.conf и сообщает о синтаксических ошибках и пропущенных обязательных параметрах до перезапуска демона. Команда ловит опечатки в именах параметров, незакрытые секции и отсутствие ключа domains, из-за которого демон стартует без единого настроенного домена. Проверку запускают сразу после правки файла: найти опечатку в выводе быстрее, чем искать её в логах после падения службы.
Когда перезапускать SSSD, а когда очищать кэш
systemctl restart sssd нужен после изменения sssd.conf: демон перечитывает конфигурацию только при старте. sss_cache применяют, когда менялись данные в каталоге, а сам конфиг не трогали: новые группы, изменённые атрибуты, переименованный пользователь. Перезапуск без причины ухудшает ситуацию: сброс кэша означает, что офлайн-вход не сработает, пока каждый пользователь не войдёт при доступном каталоге.
Чек-лист: настройка SSSD+LDAP с offline cache за 10 шагов
- Установить пакеты sssd, sssd-ldap, sssd-tools и клиентские утилиты ldap-utils.
- Создать /etc/sssd/sssd.conf с id_provider = ldap, auth_provider = ldap, ldap_uri и ldap_search_base.
- Прописать служебную учётную запись ldap_default_bind_dn с правами только на чтение нужных OU.
- Включить cache_credentials = True и задать offline_credentials_expiration = 7.
- Настроить TLS: ldaps либо StartTLS с ldap_id_use_start_tls = True, плюс ldap_tls_cacert и ldap_tls_reqcert = demand.
- Привести nsswitch.conf к виду files sss для passwd, group, shadow, при необходимости sudoers.
- Собрать стек PAM через authselect select sssd --with-mkhomedir --with-sudo или pam-auth-update.
- Выставить права 600 на sssd.conf, запустить sssd и проверить sssctl config-check.
- Проверить getent passwd, id и вход через su либо ssh, затем оценить статус через sssctl domain-status.
- Смоделировать недоступность каталога блокировкой порта, убедиться в офлайн-входе, после чего настроить access_provider и sudo_provider.
Для проверки сценариев отказа удобно держать отдельный стенд: клиент с SSSD и второй сервер с OpenLDAP, который можно останавливать без риска для продакшена. Такой стенд быстро поднимается на облачных VDS, например в Timeweb Cloud, где ресурсы меняются под нагрузку теста и не требуют железа в офисе. Разбор длинных логов SSSD ускоряется, если передать их модели через AiTunnel: единый API к популярным нейросетям помогает вытащить из сотен строк нужный фильтр и код ошибки.