Вы вошли как Гость | Группа "Гости" Приветствую Вас Гость | RSS
mdErrDX5341.lab:...I'm a fool studying schizophrenia as a source of life...=)

Не забудь поспать: Понедельник, 13.05.2024, 21:55
Главная » Статьи » Unix/Linux » Прочее

Linux# PAM

Учимся использовать и создавать свои модули PAM

Ты, конечно же, знаешь, что учетные данные и пароли в большинстве *nix хранятся в таких файлах, как /etc/passwd, /etc/shadow, /etc/master.passwd. Но знаешь ли ты, что эти файлы относятся лишь к стандартной аутентификации, которая легко может быть изменена? В свою систему ты можешь внедрить более сложные системы аутентификации, вплоть до использования смарт-карт, электронных ключей и сканера сетчатки глаза. Причем для этого совсем не надо патчить ОС, перекомпилировать ядро и выполнять множество громоздких операций.

[что такое PAM]

Во всех современных unix-like системах механизм аутентификации отделен от программ, с помощью которых она осуществляется. Это стало возможным благодаря использованию PAM (Pluggable Authentication Modules) - Подключаемых Аутентификационных Модулей. Такие программы, как login, su, passwd, в современных системах сами не работают с паролями, а делают запрос к PAM, которая осуществляет всю процедуру аутентификации и возвращает ответ: УСПЕХ (PAM_SUCCESS) или НЕУДАЧА (PAM_AUTH_ERR), а прикладная программа лишь выводит сообщение пользователю в зависимости от ответа PAM. Таким образом, прикладным программам совершенно неважно, каким образом PAM осуществляет аутентификацию, поэтому администратор может внедрить иные механизмы аутентификации, не перекомпилируя никаких прикладных программ. А как это сделать, сейчас мы узнаем.

[три ветви PAM]

Впервые PAM появился в операционной системе Solaris 2.3, после чего был адаптирован для Linux, BSD и прочих *nix. Сейчас существует три основных ветви развития PAM: Solaris PAM, Linux-PAM и OpenPAM. Linux-PAM используется почти всеми современными Linux. OpenPAM впервые стал применяться во FreeBSD 5.x и NetBSD 3.x, до этого BSD-системы использовали Linux-PAM. В целом все три ветви имеют лишь незначительные отличия. Дальше пойдет разговор применительно к Linux-PAM, но иногда я буду указывать расхождения с другими ветвями.

[архитектура PAM]

Как следует из самого названия, PAM состоит из модулей. Именно модули отвечают за то, как будет осуществляться аутентификация. Модули представляют собой обычные динамические библиотеки с расширением «.so», стандартно распложенные в каталоге /usr/lib/security (хотя это не обязательно).

Настройка модулей для работы с конкретным приложением осуществляется с помощью конфигурационных файлов, расположенных в /etc/pam.d (в некоторых системах используется только один файл /etc/pam.conf). Каждому приложению, которое использует аутентификацию, соответствует свой файл конфигурации с одноименным названием. В конфигурационных файлах указывается последовательность вызовов PAM-модулей с дополнительными параметрами. Изменяя конфигурационный файл (например, добавляя новый PAM-модуль), можно изменить процедуру аутентификации.

Файл конфигурации состоит из четырех столбцов. В первом столбце указывается тип модуля (всего существует четыре типа модулей: auth, account, password и sessions). Во втором столбце находится флаг контроля, который указывает, как система будет реагировать при удачном или неудачном прохождении соответствующего модуля. Флагов также существует всего четыре: required, requisite, sufficient и optional. В третьем поле указывается имя модуля и его расположение в системе. Некоторые модули имеют необязательные параметры, которые указываются в четвертом столбце. Символ решетки (#) используется для комментариев.


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

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

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

[типы модулей]

Как уже отмечалось, всего существует четыре типа модулей:

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

pam_sm_authenticate() выполняет задачу аутентификации пользователя, то есть сравнивает введенный ключ со значением в базе данных; pam_sm_setcred() открывает доступ прикладной программе к такой информации о пользователе, как его ID, членство в группах и лимит ресурсов. Для корректной инициализации в модуле должна быть включена строка «#define PAM_SM_AUTH» после включения «#include <security/pam_modules.h>».

  1. account. Модули такого типа проверяют доступность аккаунта на основе ресурсов системы (время суток или загрузка сервера). Account-модуль должен обязательно предоставлять функцию pam_sm_acct_mgmt(), которая проверяет, доступен ли запрашиваемый аккаунт. Для корректной инициализации в модуле должна быть включена строка «#define PAM_SM_ACCOUNT».
  2. password. Модули этого типа предназначены для смены пароля по запросу пользователя или по истечению срока действия. Password-модуль должен обязательно предоставлять функцию pam_sm_chauthtok(), которая изменяет ключ аутентификации, проверяет, не использовался ли он ранее, а заодно и его стойкость. Для корректной инициализации в модуле должна быть включена строка «#define PAM_SM_PASSWORD».
  3. session. Данные модули используются для выполнения определенных действий перед началом сеанса и перед его окончанием. Такими действиями могут быть, например, добавление записей в log-файлы, подготовка пользовательского окружения, запуск каких-нибудь служб и т.д. Session-модуль должен предоставлять следующие две функции: pam_sm_open_session() выполняет задачи, связанные с установкой сеанса; pam_sm_close_session() отвечает за завершение сеанса. Для корректной инициализации в модуле должна быть включена строка «#define PAM_SM_SESSION».

В Linux-PAM существует всего четыре флага контроля:

  1. required. Если модуль выдал ошибку, то цепочка продолжит выполняться, но запрос будет отклонен.
  2. requisite. Если произошла ошибка модуля, то цепочка немедленно заканчивается, и запрос отклоняется.
  3. sufficient. Если модуль выполнился нормально, и никакой предыдущий модуль в цепочке не потерпел неудачу, то цепочка заканчивается, и принимается положительное решение о предоставлении доступа. В случае ошибки модуль игнорируется, и выполняется остальная часть цепочки.
  4. optional. Модуль с этим флагом не критичен для аутентификации и используется как дополнительный, то есть модуль будет выполнен, но его результат игнорируется.

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

[стандартные модули]

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

% find / -name pam_*.so

Рассмотрим некоторые модули и заодно укажем тип, который они могут принимать:

pam_access.so. Тип account. Предоставляет или запрещает доступ на основании файла /etc/security/access.conf. Строки этого файла имеют следующий формат:

«права:пользователи:откуда»,

где:

Права - знак «+» (разрешить) или знак «-» (запретить).

Пользователи - ALL, имя пользователя или пользователь@узел, где узел соответствует имени локальной машины, иначе запись игнорируется.

Откуда - одно или несколько имен файлов терминалов (без префикса /dev/), имена узлов, доменные имена (начинающиеся с точки), IP-адреса (с точкой на конце, например, 172.85.10.10.), ALL или LOCAL.

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

  • pam_cracklib.so. Тип password. Проверяет пароли на стойкость. Имеет необязательные параметры: debug - заносит отладочную информацию в файл журнала; retry=N - число попыток ввода пароля, по исчерпанию которых возвращается ошибка (по умолчанию дается одна попытка); diffok=N - должно быть изменено минимум N символов при смене пароля; minlen=N - минимальный размер пароля; dcredit=N, ucredit=N, lcredit=N, ocredit=N - в пароле должно присутствовать минимум N цифр, строчных, прописных букв и других символов.
  • pam_deny.so. Тип любой. Данный модуль на любой запрос отвечает PAM_AUTH_ERR. Бывает полезен для быстрого отключения сервиса (если добавить в начало цепочки) или для завершения цепочки sufficient модулей.
  • pam_lastlog.so. Тип auth. Заносит в файлы utmp, utmpx, wtmp, wtmpx, lastlog и lastlogx сведения о том, когда и откуда пользователь вошел в систему. Имеет параметры: debug - записывать подробную информацию в syslog; nodate, noterm, nohost, silent - отбрасывать дату, имя терминала, имя хоста или все вместе; never - если пользователь первый раз входит в систему, то его приветствуют таким сообщением: «Добро пожаловать...».
  • pam_limits.so. Тип session. Позволяет накладывать ограничения на пользователей, вошедших в систему. Требует файл /etc/security/limits.conf и поддержку ядра для ограничений.
  • pam_nologin.so. Тип auth. Проверяет наличие файла /etc/nologin. Если он существует, то в систему может войти только root, а остальным будет выдано на экран содержимое этого файла.
  • pam_permit.so. Простейший модуль, который на каждый запрос просто возвращает PAM_SUCCESS. Этот модуль бывает полезен в качестве метки или для предотвращения появления пустой цепочки.
  • pam_pwdb.so. Тип любой. Обычно является альтернативой модулю pam_unix.so. Предоставляет интерфейс к файлам passwd и shadow. Полезные параметры: nullok - можно использовать пустые пароли; md5, shadow, bigcrypt - различные способы шифрования пароля.
  • pam_rootok.so. Тип auth. Допускает пользователя к сервису, только если его uid=0.
  • pam_time.so. Тип account. Позволяет ограничить доступ к службе в зависимости от времени. Настраивается с помощью конфигурационного файла /etc/securitty/time.conf.
  • pam_warn.so. Тип auth и password. Просто заносит сообщение о своем вызове в syslog. Параметров не имеет.
  • pam_wheel.so. Тип auth. Позволяет получать права суперпользователя только пользователям группы wheel. Один из полезных параметров: group=XXX - использовать указанную группу вместо wheel.

Существует еще особый модуль pam_stack.so, который может быть любого типа и всегда используется с параметром service=XXX, где XXX - название конфигурационного файла другого сервиса. Этот модуль предназначен для включения цепочки модулей из другого конфигурационного файла. Например, запись «/lib/security/pam_stack.so service=system-auth» означает, что нужно выполнить цепочку модулей из конфигурационного файла system-auth.

В разных *nix существуют свои стандартные модули, хотя рассмотренные модули присутствуют почти в каждой системе.

[пример использования стандартных модулей]

В качестве примера изменим поведение команды su. Напомню, su предоставляет возможность регистрироваться в системе под другим именем, в том числе root. Сделаем так, чтобы только пользователи одной группы ( «ivan») могли получать права («root») при помощи su. Для этого нужно добавить следующие две строки в начало конфигурационного файла su в каталоге /etc/pam.d:

auth sufficient /lib/security/pam_rootok.so

auth required /lib/security/pam_wheel.so group=ivan

[программирование PAM-приложений]

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

Компиляция выполняется следующим образом:

% gcc -o appl_pam appl_pam.c -lpam -lpam_misc

Программа appl_pam просто запрашивает у пользователя его пароль, и если пароль введен верно, то выводит Authentication OK, иначе - Not Authenticated.

Вызывать функции PAM API в программе можно только после вызова функции pam_start(), которая инициализирует библиотеку PAM, а заканчиваться работа должна функцией pam_end(). Первый аргумент в pam_start() - это имя сервиса. В appl_pam я задействовал сервис passwd. Хочу обратить внимание на второй параметр: getenv(«LOGNAME»), который определяет имя пользователя из стандартной переменной окружения LOGNAME. Если второй параметр сделать нулевым значением, то функция будет запрашивать не только пароль, но и логин пользователя. Третьим аргументом является ссылка на объект диалога. В четвертую переменную pam_start() запишет дескриптор сеанса, который будет использоваться всеми последующими функциями PAM API в программе.

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

В pam_test() используется стандартная функция диалога misc_conv(), выполняющая терминальный ввод-вывод, адрес которой вначале программы мы указали в структуре pam_conv. Можно написать свою функцию, использующую другие способы общения с пользователем, например, всплывающее окно, голосовой ввод-вывод и т.д.

В программе вызывается функция pam_authenticate(). Во втором ее аргументе указываются различные флаги. Значение 0 означает стандартные установки.

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

[программирование PAM-модулей]

Программировать свои модули в целом несложно. Все зависит от того, какой алгоритм ты будешь в нем реализовывать, а именно: будет ли твой модуль обращаться к оборудованию, например, к USB-ключу, или использовать криптографический протокол. На диске к журналу ты можешь найти исходник аутентификационного модуля pam_test. Он хорошо прокомментирован, поэтому здесь я только дам общие сведения. Модуль получает от пользователя пароль, сравнивает его со статическим паролем и выдает результат. Так как модуль является типа AUTH, то он обязательно должен реализовывать две функции: pam_sm_authenticate() и pam_sm_setcred(). Дескриптор pamh позволяет связываться модулю с приложением и получать от него данные с помощью специальных PAM-функций. Имя пользователя определяется с помощью PAM-функции pam_get_user(), а пароль принимается с помощью функции pam_get_item().

Модуль и приложение, которое его вызывает, могут обмениваться сообщениями. Структура сообщения, передаваемого от модуля к приложению, определена в security/pam_appl.h как:

struct pam_message {

int msg_style;

const char *msg;

};

Допустимые опции для msg_style:

  • PAM_PROMPT_ECHO_OFF - получить строку без повторения любого текста;
  • PAM_PROMPT_ECHO_ON - получить строку пока текст отображается эхом;
  • PAM_ERROR_MSG - отображать ошибку;
  • PAM_TEXT_INFO - отображать текст.

Структура ответа от приложения к модулю имеет следующий вид:

struct pam_response {

char *resp;

int resp_retcode;

};

Компиляция PAM-модуля осуществляется точно так же, как и компиляция обычной динамической библиотеки:

% gcc -с -fPIC pam_test.c

% gcc -shared -fPIC -o pam_test.so pam_test.o

Чтобы проверить работу модуля, добавь в конфигурационный файл login (/etc/pam.d/login) - в конец списка модулей типа auth - следующую строку:

auth required /lib/security/pam_test.so

[PAM для хакера]

И напоследок скажу о безопасности PAM. Если хакер сумеет подменить один из модулей PAM на троянскую версию, то скомпрометированными окажутся все программы, которые используют этот модуль. Например, такой модуль, как pam_unix.so или pam_pwdb.so, используются практически всеми программами аутентификации (login, passwd, sshd, su и т. д.). Поэтому если ты админ и заметил, что один из модулей PAM в твоей системе был изменен, то знай - у тебя серьезные неприятности.



Источник: http://www.xakep.ru/magazine/xa/086/112/1.asp
Категория: Прочее | Добавил: mdErrDX5341 (06.12.2011)
Просмотров: 5214 | Комментарии: 2 | Рейтинг: 5.0/1
Всего комментариев: 2
1 AbnorneUndepe  
0
почерпнул много нового

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

Добавлять комментарии могут только зарегистрированные пользователи.
[ Регистрация | Вход ]