Архитектура SSSD

За работу компьютера в домене отвечает служба SSSD (System Security Services Daemon), установка которой происходит вместе с пакетом aldpro-client, а настройка выполняется при вводе компьютера в домен с помощью утилиты aldpro-client-installer. Для управления службой используется приложение systemctl, которое позволяет запускать и останавливать службу, а также просматривать ее текущее состояние:

sudo systemctl stop sssd
sudo systemctl start sssd
sudo systemctl restart sssd
sudo systemctl status sssd

Результат выполнения команды:

sssd.service - System Security Services Daemon
  Loaded: loaded (/lib/systemd/system/sssd.service; enabled; vendor preset: enabled)
  Active: active (running) since Mon 2023-07-31 22:38:35 MSK; 5s ago
Main PID: 3740 (sssd)
   Tasks: 4 (limit: 4597)
  Memory: 10.1M
  CGroup: /system.slice/sssd.service
          ├─3740 /usr/sbin/sssd -i --logger=files
          ├─3741 /usr/lib/x86_64-linux-gnu/sssd/sssd_be --domain ald.company.lan --uid 0 --gid 0 --logger=files
          ├─3742 /usr/lib/x86_64-linux-gnu/sssd/sssd_ifp --uid 0 --gid 0 --logger=files
          └─3743 /usr/lib/x86_64-linux-gnu/sssd/sssd_pac --uid 0 --gid 0 --logger=files

Основная задача службы SSSD заключается в предоставлении доступа к информации удаленной службы каталога и механизмам централизованной аутентификации. В качестве поставщика данных для SSSD может выступать FreeIPA, Active Directory, Kerberos домен и даже простой LDAP каталог. Продукт ALD Pro построен на базе службы каталога FreeIPA, поэтому в конфигурационных файлах /etc/sssd/sssd.conf на доменных компьютерах будет указан поставщик ipa, например, id_provider = ipa.

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

Идентификационные данные пользователей всегда кэшируются, так же как и информация о доменных службах. Это означает, что SSSD всегда проверяет запросы на аутентификацию. Поддержание кэша в актуальном состоянии является сложной задачей, поэтому SSSD состоит из множества компонентов, которые взаимодействуют друг с другом с помощью различных методов межпроцессного взаимодействия, архитектура службы представлена см. Архитектура службы SSSD.

../../_images/33_sssd-architechture.png

Рисунок 24 Архитектура службы SSSD

Монитор (Monitor)

Службу sssd.service называют Монитором или Наставником, так как она порождает процессы всех других компонентов и управляет ими через систему межпроцессного взаимодействия SBus (SSSD D-Bus). Чтобы понять диаграмму процесса загрузки службы см. Диаграмма загрузки службы SSSD.

  • В момент запуска службы Монитор анализирует файл конфигурации sssd.conf (1) и загружает его в кэш /var/lib/sss/db/config.ldb (2). Далее Монитор, используя системные вызовы, порождает процесс Бэкенда (3), который загружает информацию из config (4, 5) и регистрирует себя в Мониторе (6).

  • На следующем шаге Монитор порождает Ответчиков NSS и PAM (7), которые считывают информацию из config (8, 9) и регистрируются в Мониторе (10) и Бэкенде (11).

../../_images/34_sssd-loading-flow.png

Рисунок 25 Диаграмма загрузки службы SSSD

Помимо внутреннего взаимодействия через SBus, служба SSSD использует UNIX-сигналы, например, в тех случаях, когда процесс завис и не отвечает через SBus. Обработчики сигналов обычно интегрированы с главным циклом событий tevent с использованием вызова tevent_add_signal:

  • ``SIGTERM — сигнал на завершение работы процесса.

  • SIGKILL — сигнал для принудительного завершения работы процесса, который направляется монитором, если процесс не завершается после получения SIGTERM.

  • SIGUSR1 — сигнал на переключение Бэкенда в автономный режим. Если сигнал будет направлен Монитору, то он перешлет его всем дочерним процессам sssd_be.

  • SIGUSR2 — сигнал на переключение Бэкенда в режим онлайн. Если сигнал будет направлен Монитору, то он перешлет его всем дочерним процессам sssd_be.

  • SIGHUP — может быть передан Монитору, после чего тот начнет новый лог-файл и вызовет метод сброса журналов управляемым процессам. Управляемые процессы также начинают новые лог-файлы. Кроме того, процессы sssd_be перечитывают resolv.conf, а процесс sssd_nss выполнит очистку быстрого кэша.

Серверные части или Бэкенды (backends)

Бэкенд (Backend, BE) включает в себя Поставщики данных (Data Provider, DP) – это процесс приложения /usr/lib/x86_64-linux-gnu/sssd/sssd_be, который запускается Монитором для взаимодействия с доменом в соответствии с настройками секции [domain/<имя_домена>] конфигурационного файла sssd.conf.

sudo ps -aux | grep sssd_be

Результат выполнения:

root    5885 0.0 0.6 118804 26532 ?  S 21:43 0:00 /usr/lib/x86_64-linux-gnu/sssd/sssd_be --domain ald.company.lan --uid 0 --gid 0 --logger=files

Описание бэкендов в конфигурационном файле можно просмотреть командой:

sudo cat /etc/sssd/sssd.conf

Результат выполнения:

...
[domain/ald.company.lan]
id_provider = ipa
ipa_server = _srv_, dc-1.ald.company.lan
ipa_domain = ald.company.lan
ipa_hostname = pc-1.ald.company.lan
auth_provider = ipa
chpass_provider = ipa
access_provider = ipa
cache_credentials = True
ldap_tls_cacert = /etc/ipa/ca.crt
krb5_store_password_if_offline = True
...

Бэкенд не является монолитом и в зависимости от настроек подключает один и более Поставщиков данных, каждый из которых представляет из себя совместно используемую библиотеку (Shared Object, SO). Библиотеки SSSD находятся в каталоге /usr/lib/x86_64-linux-gnu/sssd/, и за работу компьютера в домене ALD Pro (FreeIPA), например, отвечает Поставщик ipa, которому соответствует библиотека libsss_ipa.so. Если же ввести Linux компьютер напрямую в домен Active Directory, то будет использоваться libsss_ad.so.

Каждый Поставщик данных может оказывать Бэкенду SSSD следующие услуги:

  • идентификация (id_provider) — предоставление информации о пользователях, служебных учетных записях, группах и т.д.;

  • аутентификация (auth_provider) — проверка аутентичности пользователей и служб;

  • авторизация (access_provider) — проверка прав доступа на запуск служб на уровне HBAC;

  • поставщик sudo (sudo_provider) — предоставление информации о правилах SUDO на повышение привилегий;

  • и другие.

Разные модули могут использовать разные настройки, например, для Поставщика ipa требуется задать параметр ipa_server, который используется для определения контроллера домена FreeIPA, с которым требуется поддерживать соединение. По умолчанию в конфигурационном файле sssd.conf для домена явно задается только несколько провайдеров (id, auth, chpass, access), а для других провайдеров подразумевается, что их имя совпадает с именем поставщика идентификационных данных (id_provider).

Для удобства, из соображений сокращения размера конфигурационного файла, служба SSSD руководствуется следующими правилами:

  • Если параметр ipa_domain не указан, то используется FQDN имя домена из секции [domain/<fqdn домена>].

  • Если параметр ipa_server не указан, то сервер определяется автоматически через DNS, как будто параметр ipa_server равен _srv_.

  • Если провайдер не указан, то используется значение id_provider (например, ipa). Исключением является access_provider, если его значение не указано, то по умолчанию параметр принимает значение permit, что означает «всем пользователям разрешен доступ». Для управления доступом параметр access_provider должен быть задан явно.

Таким образом, стандартный файл конфигурации /etc/sssd/sssd.conf может быть упрощен до следующего вида:

...
[domain/ald.company.lan]
id_provider = ipa
access_provider = ipa
cache_credentials = True
ldap_tls_cacert = /etc/ipa/ca.crt
krb5_store_password_if_offline = True
...

Ответчики (responders)

Ответчик служит посредником между пользовательским приложением, таким как id или getent, и кэшем SSSD. Когда приложение запрашивает данные, например, ищет пользователя по имени, Ответчик выполняет поиск в локальном кэше и, если данные не найдены или устарели, обращается к Бэкенду, чтобы тот совершил запрос к северу службы каталога. Клиентские библиотеки взаимодействуют с Ответчиком через Unix socket (например, /var/lib/sss/pipes/nss), а внутри ядра SSSD между Ответчиками, Бэкендами и Монитором взаимодействие осуществляется через DBus.

Каждый Ответчик работает в отдельном процессе и выполняет строго определенные задачи, например:

  • Ответчик NSS (sssd_nss) обеспечивает данными диспетчер службы имен (Name Service Switch, NSS).

  • Ответчик PAM (sssd_pam) предоставляет данные для работы подключаемых модулей аутентификации (Pluggable Authentication Modules, PAM).

  • Ответчик SUDO (sssd_sudo) обеспечивает правилами утилиту sudo.

  • И так далее.

Клиентские библиотеки и приложения

Для взаимодействия с Ответчиком приложению нужно обращаться к соответствующему unix сокету по специфичному сетевому протоколу, поэтому для упрощения разработки клиентских приложений были созданы вспомогательные совместно используемые библиотеки, такие как libnss_sss.so.2, pam_sss.so и др., которые можно найти в каталоге /usr/lib/x86_64-linux-gnu.

Например, если в конфигурационном файле nsswitch.conf для базы sudoers источником данных будет указан sss, то утилита sudo для взаимодействия с Ответчиком sssd_sudo воспользуется функциями из библиотеки libsss_sudo.so. Аналогичным образом работает autofs.

Однако, есть и такие приложения, которые могут даже не знать о существовании SSSD, если используют более универсальные функции из библиотек pam и glibc, которые взаимодействуют с клиентскими библиотеками SSSD от имени приложения. Например, утилиты id, getent, ls вызывают стандартные функции NSS, которые извлекают информацию из нескольких баз данных имен (например, passwd, group, service, netgroup и т.д.). Рассмотрим поток данных, создаваемый клиентским приложением id, выполняющим NSS запрос через службу SSSD, см. Диаграмма потока данных при вызове команды id:

  • Клиентское приложение /usr/bin/id вызывает функцию getpwnam из библиотеки glibc для получения информации о пользователе (1).

  • Библиотека glibc загружает конфигурационный файл nsswitch.conf (2, 3) и в соответствии с его настройками загружает совместно используемую библиотеку libnss_sss.so.2 и вызывает ее функцию _nss_sss_getpwnam_r (4)

  • Для получения данных от Ответчика /usr/lib/x86_64-linux-gnu/sssd/sssd_nss библиотека libnss_sss.so.2 отправляет запрос через unix сокет /var/lib/sss/pipes/nss по специализированному протоколу обмена данными (5).

  • Ответчик NSS проверяет наличие данных в кэше (6, 7), и в случае отсутствия данных или истекшего срока их действия отправляет запрос getAccountInfo к Бэкенду, запрашивая необходимые данные (8).

  • Бэкенд из-под учетной записи хоста /etc/krb5.ketyab направляет LDAP-запрос для получения данных от службы каталога (9). Если запрашиваемый пользователь принадлежит тому же домену, то это будет прямой запрос на поиск информации, в противном случае SSSD выполнит расширенную LDAP операцию.

../../_images/35_sssd-id-command-execution-flow.png

Рисунок 26 Диаграмма потока данных при вызове команды id

Библиотека PAM работает аналогичным образом с небольшими отличиями. Например, если служба SSSD находится онлайн, то при входе пользователя в систему она обязательно предпримет попытку повторной аутентификации и получения информации об участии пользователя в группах, даже если срок действия кэша еще не истек, а все команды выполняются в контексте одной транзакции PAM. В качестве примеров клиентских приложений, использующих PAM, можно привести login, su и sshd.

Несмотря на то, что клиентские приложения и библиотеки не являются синонимами, в рабочей документации и программном коде службы SSSD под словосочетанием SSSD Client (суффикс sss_cli) часто подразумеваются именно клиентские библиотеки, а не сами приложения. Например, идентификатором sss_cli обозначается сетевой протокол, с помощью которого клиентские библиотеки общаются с Ответчиками службы SSSD.

Механизм кэширования службы SSSD

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

Локальный кэш (local cache, cache)

Локальный кэш – это база данных, в которую Бэкенды записывают результаты, получаемые из службы каталога, чтобы Ответчики могли считывать их напрямую. При помещении объектов в кэш им назначается срок жизни, и до тех пор, пока он не истечет, все последующие запросы к этим данным обрабатываются без обращения к серверу. Устаревшие данные могут извлекаться из кэша только в том случае, если служба находится в автономном режиме.

Файлы локального кэша находятся на диске в каталоге /var/lib/sss/db/, для работы с этим кэшем служба sssd использует встроенную библиотеку баз данных облегченного доступа (light weight embedded database library, ldb) — ту же библиотеку, с помощью которой реализована база данных службы каталога Samba AD. Если установить пакет ldb-tools, то станет доступна утилита ldbsearch, с помощью которой можно заглянуть внутрь ldb-файлов. Структура этой базы данных подобна LDAP-каталогу, а параметры ldbsearch во многом повторяют параметры утилиты ldapseach:

sudo rm -rf /var/lib/sss/db/*; systemctl restart sssd ldbsearch -H /var/lib/sss/db/cache_ald.company.lan.ldb /
-b name=admin@ald.company.lan,cn=users,cn=ald.company.lan,cn=sysdb uidNumber
asq: Unable to register control with rootdse!
# returned 0 records
# 0 entries
# 0 referrals

Для проверки кэша запрашивается информация командой id:

sudo id admin

Результат выполнения:

uid=959800000(admin) gid=959800000(admins) группы=959800000(admins),1001(astra-admin),113(lpadmin)

Отображается, что сохранилось в локальном кэше командой:

sudo ldbsearch -H /var/lib/sss/db/cache_ald.company.lan.ldb /
-b name=admin@ald.company.lan,cn=users,cn=ald.company.lan,cn=sysdb uidNumber

Результат выполнения:

asq: Unable to register control with rootdse!
# record 1
dn: name=admin@ald.company.lan,cn=users,cn=ald.company.lan,cn=sysdb
uidNumber: 959800000
# returned 1 records
# 1 entries
# 0 referrals

Но на низком уровне ldb использует библиотеку Trivial DataBase, поэтому сырые данные в формате ключ-значение можно извлекать с помощью утилит из пакета tdb-tools:

root@dc-1:~# tdbtool /var/lib/sss/db/config.ldb keys

Результат выполнения:

key 18 bytes: DN=@INDEX:CN:SSSD
key 21 bytes: DN=CN=SSSD,CN=CONFIG
key 18 bytes: DN=@INDEX:CN:SUDO
key 17 bytes: DN=@INDEX:CN:PAC
key 13 bytes: DN=CN=CONFIG
...

В папке /var/lib/sss/db/ находятся следующие ldb-файлы локального кэша:

  • config.ldb – кэш для хранения настроек службы, загружаемых из конфигурационного файла /etc/sssd/sssd.conf

  • sssd.ldb – база данных локального домена (local provider), который позволял использовать возможности вложенных групп без централизованной службы каталога. Для администрирования использовались команды sss_useradd, sss_groupadd и др., поддержка функции прекращена с версии SSSD 2.0.0.

  • cache_ald.company.lan.ldb – кэш для хранения критически важной информации, получаемой из домена. Сохранение таких данных на диск требуется выполнять сразу при получении новых данных.

  • timestamps_ald.company.lan.ldb – кэш для хранения некритичной и часто обновляемой информации. Сохранение данных на диск выполняется в фоновом режиме по усмотрению операционной системы. Кроме файлов локального кэша в этой же папке находятся файлы кэша учетных данных Kerberos, которые можно просматривать с помощью утилиты klist с ключом -c.

  • ccache_ALD.COMPANY.LAN – кэш для хранения Kerberos-билетов службы SSSD, с помощью которых она выполняет LDAP-запросы к службе каталога.

  • fast_ccache_ALD.COMPANY.LAN – кэш для хранения TGT-билета, с помощью сессионного ключа которого которого обеспечивается дополнительное шифрование запросов по технологии FAST Armoring.

Удаление всех файлов из директории db является самым простым, но в тоже время и самым полным способом очистки локального кэша службы sssd:

sudo systemctl stop sssd
sudo rm -rf /var/lib/sss/db/*
sudo systemctl start sssd

То же самое можно сделать с помощью команды cache-remove утилиты sssctl из состава пакета sssd-tools:

sudo sssctl cache-remove

Результат выполнения:

SSSD must not be running. Stop SSSD now? (yes/no) [yes] yes
Creating backup of local data...
Removing cache files...
SSSD needs to be running. Start SSSD now? (yes/no) [yes] yes

Однако, для отладки SSSD на нагруженном сервере рекомендуют использовать специализированную утилиту sss_cache из того же пакета sssd-tools, с помощью которой можно удалять не весь кэш, а отметить недействительными только отдельные записи, например, по конкретному пользователю, чтобы они были повторно извлечены из каталога при следующем обращении:

sudo sss_cache –u admin

Быстрый кэш (in-memory cache, memcache)

Все процессы SSSD (Монитор, Бэкенд, Ответчик), являются однопоточными приложениями и обрабатывают запросы со скоростью одного ядра, поэтому Ответчик мог бы стать узким местом и ограничить возможности вертикального масштабирования. В тоже время, из соображений безопасности клиентским библиотекам нельзя давать прямой доступ к локальному кэшу, т.к. в нем содержатся в том числе конфиденциальные данные, например, хэши паролей. Для устранения противоречия был создан дополнительный быстрый кэш, который доступен клиентским библиотекам напрямую, но содержит при этом только общую информацию о пользователях и группах.

Быстрый кэш представляет из себя хэш-таблицы, которые находятся в каталоге /var/lib/sss/mc/ и отображаются на память (Memory-mapped). Ответчик NSS записывает информацию в быстрый кэш и до тех пор, пока эти данные остаются актуальными, клиентской библиотеке не требуется связываться с SSSD для их извлечения. Если же запись будет отсутствовать в кэше или ее срок жизни истечет, запрос будет перенаправлен Ответчику NSS, который извлечет данные из локального кэша или обратится к контроллеру домена через Бэкенд.

По умолчанию время хранения записей в быстром кэше составляет 300 секунд и может быть изменено с помощью параметра memcache_timeout в файле sssd.conf. Для отключения быстрого кэша нужно установить memcache_timeout=0, а для очистки, как и в случае локального кэша, просто удалить файлы и перезапустить службу:

sudo systemctl stop sssd
sudo rm -rf /var/lib/sss/mc/*
sudo systemctl start sssd

Команда cache-remove утилиты sssctl не удаляет файлы быстрого кэша, но sss_cache, как и в случае локального кэша, позволяет отметить недействительными отдельные записи, например, по конкретному пользователю, чтобы они были повторно извлечены из каталога при следующем обращении.

sudo sss_cache –u admin

Негативный или безрезультатный кэш (negative cache, ncache)

Для уменьшения нагрузки на сервер при обращении к несуществующим объектам каталога, внутри Ответчика NSS и ряда других компонентов реализован так называемый негативный или безрезультатный кэш. Этот кэш находится в оперативной памяти и обновляется каждые 15 секунд, изменить эту настройку можно с помощью параметра entry_negative_timeout в конфигурационном файле sssd.conf Для полной очистки негативного кэша достаточно просто перезапустить службу командой:

sudo systemctl restart sssd

Алгоритм использования кеша (cache lookup)

Служба SSSD кэширует пользователей, группы, правила HBAC/SUDO, SSH-ключи, карты монтирования дисков и другую информацию, но вне зависимости от типов объектов поиск в кэше выполняется очень похожим образом, см. Упрощенный алгоритм поиска.

../../_images/36_sssd-cache-lookup-flow.png

Рисунок 27 Упрощенный алгоритм поиска

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

Рассмотрим поток данных при поиске информации с использованием кэша, см. Поток данных при поиске информации о пользователе с использованием информации из кэша:

  • Клиентское приложение вызывает функцию getpwnam из библиотеки glibc, которая в соответствии настройками из sswitch.conf загружает Клиентскую библиотеку libnss_sss.so.2 и вызывает ее функции, подробнее см. в разделе «Клиентские библиотеки и приложения».

  • Клиентская библиотека проверяет, есть ли информация о запрашиваемом объекте в быстром кэше (memcache), и только после этого обращается к Ответчику sssd_nss.

  • Ответчик проверяет, есть ли информация о запрашиваемом объекте в локальном кэше, и только после этого обращается к Бэкенду sssd_be.

  • Бэкенд выполняет запрос к LDAP-каталогу, сохраняет информацию в локальный кэш и сообщает Ответчику о готовности.

  • Ответчик повторно обращается к локальному кэшу, извлекает оттуда необходимую информацию, записывает ее в быстрый кеш и передает Клиентской библиотеке в качестве ответа.

  • Клиентская библиотека возвращает ответ в функцию glibc, на чем поиск завершается.

../../_images/37_sssd-user-lookup-flow.png

Рисунок 28 Поток данных при поиске информации о пользователе с использованием информации из кэша

Инструменты администрирования

Одним из наиболее полезных приложений для диагностики работы службы SSSD является утилита sssctl из пакета sssd-tools, которая взаимодействует с компонентами SSSD напрямую через SBus. С ее помощью можно узнать, например, какой контроллер в данный момент обслуживает запросы компьютера:

sudo sssctl domain-list

Результат команды:

ald.company.lan

Узнать статус домена можно командой domain-status утилиты sssctl:

sudo sssctl domain-status ald.company.lan

Результат выполнения:

Online status: Online


Active servers:
IPA: dc-1.ald.company.lan

Discovered IPA servers:
- dc-1.ald.company.lan
- dc-2.ald.company.lan
- dc-3.ald.company.lan

С помощью команды access-report можно посмотреть HBAC правила, определенные в домене:

sudo sssctl access-report ald.company.lan

Результат выполнения:

2 rules cached

Rule name: allow_all
    User category: all
    Service category: all

Rule name: allow_systemd-user
    User category: all
    Member services: systemd-user

С помощью команды debug-level можно быстро изменить степень детализации журналирования, которая будет оставаться в силе до перезапуска службы, потому что файл /var/lib/sss/db/config.ldb пересоздается при запуске службы.

Проверить текущий уровень отладки можно командой:

sudo ldbsearch -H /var/lib/sss/db/config.ldb | grep debug | head -n 1

Результат выполнения:

debug_level: 0x1f7f0

Применить новый уровень отладки можно командой:

sudo sssctl debug-level 6

Проверить новое значение в конфигурации можно командой:

sudo ldbsearch -H /var/lib/sss/db/config.ldb | grep debug | head -n 1

Результат выполнения:

debug_level: 0x07f0