Подключаемые Модули Аутентификации (PAM)

Подключаемые Модули Аутентификации (PAM)

FreeBSD это зарегистрированная торговая марка FreeBSD Foundation.

This article was written for the FreeBSD Project by ThinkSec AS and Network Associates Laboratories, the Security Research Division of Network Associates, Inc. under DARPA/SPAWAR contract N66001-01-C-8035 (“CBOSS”), as part of the DARPA CHATS research program.

Linux это зарегистрированная торговая марка Linus Torvalds.

Motif, OSF/1 и UNIX это зарегистрированные торговые марки, а IT DialTone и The Open Group это торговые марки Open Group в Соединенных Штатах и других странах.

Sun, Sun Microsystems, Java, Java Virtual Machine, JDK, JRE, JSP, JVM, Netra, Solaris, StarOffice, SunOS это торговые марки или зарегистрированные торговые марки Sun Microsystems, Inc. в Соединенных Штатах и других странах.

Многие из обозначений, используемые производителями и продавцами для обозначения своих продуктов, заявляются в качестве торговых марок. Когда такие обозначения появляются в этом документе, и Проекту FreeBSD известно о торговой марке, к обозначению добавляется знак “™” или “®”.

Table of Contents

В этой статье описываются принципы и механизмы, лежащие в основе библиотеки Подключаемых Модулей Аутентификации (PAM - Pluggable Authentication Modules), и рассказывается, как настроить PAM, как интегрировать PAM в приложения и как создавать модули PAM.

1. Введение

Библиотека Pluggable Authentication Modules (PAM) является обобщённым API для служб, связанных с аутентификацией, которые позволяют системному администратору добавлять новые методы аутентификации простой установкой новых модулей PAM, и изменять политику аутентификации посредством редактирования конфигурационных файлов.

PAM описали и разработали Vipin Samar и Charlie Lai из Sun Microsystems в 1995 году, с тех он сильно не менялся. В 1997 году Open Group опубликовала предварительные спецификации на X/Open Single Sign-on (XSSO), что стандартизовало API для PAM и добавило расширения для одноразовой (или достаточно интегрированной) подписи. На момент написания этого документа эта спецификация ещё не была принята за стандарт.

Хотя эта статья посвящена в основном FreeBSD 5.x, в которой используется OpenPAM, она подойдёт для FreeBSD 4.x, использующей Linux-PAM, и других операционных систем, таких, как Linux и Solaris™.

2. Термины и соглашения

3. Определения

Терминология, используемая в PAM, достаточно запутана. Ни оригинальная работа Samar и Lai, ни спецификация XSSO не делают никаких попыток формально определить термины для различных объектов и участвующих в PAM сторон, а термины, которые они используют (но не определяют) иногда неверны и неоднозначны. Первой попыткой создать недвусмысленную и согласованную терминологию была работа, которую написал Andrew G. Morgan (автор Linux-PAM) в 1999 году. Хотя выбор терминологии, которую сделал Морган, был гигантским скачком вперед, это, по мнению автора данной статьи, не означает ее правильность. Далее делается попытка, в значительной степени на основе работы Моргана, дать точные и недвусмысленные определения терминов для всех участников и объектов PAM.

Набор полномочий, которые аппликант запрашивает от арбитратора.

Пользователь или объект, запрашивающие аутентификацию.

Пользователь или объект, имеющий привилегии, достаточные для проверки полномочий аппликанта и права подтвердить или отклонить запрос.

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

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

Одна из четырех основных групп функциональности, которые дает PAM: аутентификация, управление учетными записями, управление сеансом и обновление ключом аутентификации.

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

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

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

Класс серверов, предоставляющих похожую или связанную функциональность, и требующую подобную аутентификацию. Политики PAM задаются на основе сервисов, так что ко всем серверам, объявляющим одно и тоже имя сервиса, будет применяться одна и та же политика.

Контекст, в котором сервис оказывается аппликанту сервером. Одна из четырех подсистем PAM, управление сеансом, касается исключительно настройке и очистке этого контекста.

Блок информации, связанный с учётной записью, например, пароль или ключевая фраза, которую аппликант должен предоставить для своей идентификации.

Последовательность запросов от одного и того же аппликанта к одному и тому же экземпляру того же самого сервера, начиная с аутентификации и установления сеанса и заканчивая закрытием сеанса.

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

Этот раздел предназначен для иллюстрации значений некоторых терминов, определенных выше, при помощи простых примеров.

5. Объединенные клиент и сервер

В этом простом примере показывается пользователь alice , выполняющий команду su(1) для того, чтобы стать пользователем root .

Аппликантом является alice .

Учетной записью является root .

Процесс su(1) является как клиентом, так и сервером.

Аутентификационным ключом является xi3kiune .

Арбитратором выступает root , и именно поэтому у команды su(1) выставлен бит выполнения с правами root .

6. Клиент и сервер разделены

В примере ниже рассматривается пользователь eve , пытающийся установить ssh(1)-соединение с login.example.com , и успешно входя как пользователь bob . Боб должен был выбрать пароль получше!

Аппликантом является eve .

Клиентом является процесс ssh(1) пользователя Eve.

Сервером является процесс sshd(8) на машине login.example.com

Учетной записью является bob .

Ключом аутентификации является god .

Хотя этого не видно в примере, но арбитратором является root .

7. Пример политики

Следующее является политикой, используемой во FreeBSD по умолчанию для sshd :

Эта политика применяется к службе sshd (что не обязательно ограничено сервером sshd(8)).

auth , account , session и password являются подсистемами.

pam_nologin.so , pam_unix.so , pam_login_access.so , pam_lastlog.so и pam_permit.so являются модулями. Из этого примера видно, что pam_unix.so реализует по крайней мере две подсистемы (аутентификацию и управление учётными записями).

8. Основы PAM

9. Подсистемы и примитивы

API для PAM предоставляет шесть различных примитивов для аутентификации, сгруппированных в четыре подсистемы, каждая из которых описывается ниже.

Аутентификация. Эта подсистема, собственно говоря, реализует аутентификацию аппликанта и выяснение полномочий учётной записи. Она предоставляет два примитива:

Функция pam_authenticate(3) аутентифицирует аппликанта, обычно запрашивая аутентификационный ключ и сравнивая его со значением, хранящимся в базе данных или получаемым от сервера аутентификации.

Функция pam_setcred(3) устанавливает полномочия учётной записи, такие, как идентификатор пользователя, членство в группах и ограничения на использование ресурсов.

Управление учётной записью. Эта подсистема обрабатывает вопросы доступности учетной записи, не связанные с аутентификацией, такие, как ограничения в доступе на основе времени суток или загрузки сервера. Он предоставляет единственный примитив:

Функция pam_acct_mgmt(3) проверяет, доступна ли запрашиваемая учётная запись.

Управление сеансом. Эта подсистема отрабатывает задачи, связанные с установлением и закрытием сеанса, такие, как учет входов пользователей. Она предоставляет два примитива:

Функция pam_open_session(3) выполняет действия, связанные с установлением сеанса: добавление записей в базы данных utmp и wtmp , запуск агента SSH и так далее.

Функция pam_close_session(3) выполняет действия, связанные с закрытием сеанса: добавление записей в базы данных utmp и wtmp , завершение работы агента SSH и так далее.

Управление паролем. Эта подсистема используется для изменения ключа аутентификации, связанного с учетной записью, по причине истечения его срока действия или желания пользователя изменить его. Она предоставляет единственный примитив:

Функция pam_chauthtok(3) изменяет ключ аутентификации, опционально проверяя, что он труден для подбора, не использовался ранее и так далее.

10. Модули

Модули являются центральной концепцией в PAM; в конце концов, им соответствует буква "M" в сокращении "PAM". Модуль PAM представляет собой самодостаточный кусок программного кода, который реализует примитивы одной или большего количества подсистем одного конкретного механизма; к возможным механизмам для подсистемы аутентификации, к примеру, относятся базы данных паролей UNIX®, системы NIS, LDAP или Radius.

11. Именование модулей

Во FreeBSD каждый механизм реализуется в отдельном модуле с именем pam_mechanism.so (например, pam_unix.so для механизма UNIX®.) В других реализациях иногда отдельные модули используются для разных подсистем, и в их имя включается, кроме названия механизма, и имя подсистемы. К примеру, в Solaris™ имеется модуль pam_dial_auth.so.1 , который часто используется для аутентификации пользователей, работающих по коммутируемым каналам связи.

12. Версии модулей

Изначальная реализация PAM во FreeBSD, которая была основана на Linux-PAM, не использовала номера версий для модулей PAM. Это будет приводить к проблемам при работе унаследованных приложений, которые могут быть скомпонованы со старыми версиями системных библиотек, так как способа подгрузить соответствующую версию требуемых модулей нет.

OpenPAM, с другой стороны, ищет модули, которые имеют тот же самый номер версии, что и библиотека PAM (на данный момент 2), и использует модуль без версии, только если модуль с известной версией не был загружен. Поэтому для старых приложений могут предоставляться старые модули, при этом новые (или заново построенные) приложения будут использовать все возможности последних версий модулей.

Хотя модули PAM в Solaris™ имеют номер версии, по-настоящему номер версии в них не отслеживается, потому что номер является частью имени и должен включаться в конфигурацию.

13. Цепочки и политики

Когда сервер инициирует PAM-транзакцию, библиотека PAM пытается загрузить политику для службы, указанной при вызове функции pam_start(3). Политика определяет, как должны обрабатываться запросы на аутентификацию, и задаётся в конфигурационном файле. Это составляет другую основополагающую концепцию PAM: возможность администратору настраивать политику безопасности системы (в самом широком её понимании) простым редактированием текстового файла.

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

Понимание смысла управляющего флага необходимо для понимания конфигурационных файлов PAM. Существуют четыре различных управляющих флага:

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

Этот управляющий флаг был добавлен компанией Sun в Solaris™ 9 (SunOS™ 5.9), и поддерживается в OpenPAM.

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

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

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

Так как семантика этого флага может оказаться запутанной, особенно при его использовании с последним модулем в цепочке, рекомендуется вместо него использовать управляющий флаг binding , если реализация его поддерживает.

Модуль отрабатывается, но результат выполнения игнорируется. Если все модули в цепочке помечены как optional , то удовлетворяться будут все запросы. Когда сервер вызывает один из шести PAM-примитивов, PAM запрашивает цепочку подсистемы, к которой принадлежит примитив, и запускает каждый модуль, перечисленный в цепочке в порядке их перечисления, пока список не будет исчерпан либо не будет определено, что дальнейшей обработки не нужно (по причине достижение модуля, вернувшего положительный ответ при условии binding или sufficient , либо отрицательный с условием requisite ). Запрос подтверждается, если только был вызван по крайней мере один модуль, и все неопциональные модули вернули положительный ответ.

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

14. Транзакции

Жизненный цикл типичной PAM-транзакции описан ниже. Заметьте, что в случае, если любой из перечисленных шагов оканчивается неудачно, сервер должен выдать клиенту соответствующее сообщение об ошибке и прервать транзакцию.

Если это необходимо, сервер получает полномочия арбитратора через независимый от PAM механизм-чаще всего по факту запуска пользователем root или с установленным setuid-битом root .

Сервер вызывает функцию pam_start(3) для инициализации библиотеки PAM и задания имени сервиса и целевой учётной записи, а также регистрации подходящего способа общения.

Сервер получает различную информацию, относящуюся к транзакции (такую, как имя пользователя аппликанта и имя хоста, на котором запущен клиент), и отправляет её в PAM при помощи функции pam_set_item(3).

Сервер вызывает функцию pam_authenticate(3) для аутентификации аппликанта.

Сервер вызывает функцию pam_acct_mgmt(3) для проверки того, что запрошенная учётная запись доступна и корректна. Если пароль верен, но его срок истёк, pam_acct_mgmt(3) возвратит результат PAM_NEW_AUTHTOK_REQD , а не PAM_SUCCESS .

Если на предыдущем шаге был получен результат PAM_NEW_AUTHTOK_REQD , то сервер вызывает функцию pam_chauthtok(3) для того, чтобы вынудить клиента изменить ключ аутентификации для запрошенной учётной записи.

Теперь, когда аппликант полностью аутентифицирован, сервер вызывает функцию pam_setcred(3) для получения полномочий запрошенной учётной записи. Сделать это возможно, потому что он работает как арбитратор, и оставляет за собой полномочия арбитратора.

После получения необходимых полномочий, сервер вызывает функцию pam_open_session(3) для установления сеанса.

Теперь сервер выполняет тот сервис, который затребовал клиент-например, предоставляет аппликанту оболочку.

После того, как сервер закончил обслуживание клиента, он вызывает функцию pam_close_session(3) для закрытия сеанса.

Наконец, сервер вызывает функцию pam_end(3) для оповещения библиотеки PAM о том, что работа с ней завершена и какие-либо выделенные в течение сеанса ресурсы можно освободить.

📎📎📎📎📎📎📎📎📎📎