Стек и контрольные флаги

PAM - Pluggable Authentication Modules

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

Из чего состоит строка

тип   флаг-контроля   модуль            аргументы
auth  required        pam_unix.so       nullok
Поле Что означает
тип auth, account, session, password — одна из четырёх задач
флаг-контроля Как повлияет результат модуля на всю цепочку
модуль Какой модуль вызвать: pam_unix.so, pam_sss.so, …
аргументы Настройки конкретного модуля: nullok, retry=3, delay=3000000

Строка, начинающаяся с @include имя, модуль не вызывает: она вставляет сюда содержимое другого файла. Так на Debian и Ubuntu собраны все программы входа: у каждой в файле своя мелочь, а общая проверка пароля вынесена в common-auth.

Флаги контроля

Флаг Если модуль отказал Если модуль успешен
required Отказ, но проверка продолжается; в конце вход будет отклонён Идём дальше
requisite Отказ немедленно, остальные модули не вызываются Идём дальше
sufficient Игнорируется (важно лишь то, что раньше не было отказа по required) Успех без проверки остальных — если раньше не было отказа
optional Игнорируется Успех, но остальные всё равно проверяются

Разница между required и requisite не косметическая. requisite отвечает сразу и этим сообщает, что именно сломалось. required продолжает вызывать остальные модули, чтобы по времени ответа и по журналу нельзя было понять, какой именно фактор подвёл. Это осознанная осторожность против перебора.

Гибкая форма: [значение=действие …]

Вместо одного слова можно задать таблицу: что делать при разных результатах модуля. В живом файле /etc/pam.d/common-auth (Ubuntu 26.04) это выглядит так:

auth  [success=2 default=ignore]  pam_unix.so nullok
auth  [success=1 default=ignore]  pam_sss.so use_first_pass
auth  requisite                   pam_deny.so
auth  required                    pam_permit.so
auth  optional                    pam_cap.so

Читается по шагам:

  1. pam_unix.so проверяет пароль по /etc/shadow. Если успех — success=2 означает «перепрыгнуть две следующие строки»: пропускаем pam_sss и pam_deny и попадаем на pam_permit.
  2. Если pam_unix не смог (пароль не местный), default=ignore говорит «не отказ, просто идём дальше» — к pam_sss.so, то есть к домену.
  3. Если и домен не подтвердил, pam_sss со success=1 пропустит только pam_deny — и мы упрёмся в pam_permit… но нет: при неудаче pam_sss управление уходит на pam_deny.so, который стоит requisite и отказывает сразу.

Действия в квадратных скобках:

Действие Смысл
ok Успех, продолжаем
done Успех и конец цепочки: считаем вход успешным
bad Отказ (обычный)
die Отказ немедленно, как requisite
ignore Результат не важен
N (число) Перепрыгнуть N следующих строк: положительное число — вниз, отрицательное — вверх
reset Сбросить состояние счётчиков и продолжить

Числа в N — именно то, из-за чего common-* читают внимательно: опечатка в числе меняет не «оформление», а кто кого пускает.

Что ещё надо знать про порядок

  • Флаги важнее порядка, но порядок важен. Ранее случившийся отказ по required или requisite отменяет любой последующий sufficient: «успех» ниже по стеку уже ничего не решает.
  • pam_permit.so и pam_deny.so — кирпичики, а не проверка. pam_permit всегда говорит «да», pam_deny всегда «нет». Их ставят в конце цепочки, чтобы результат был определён явно. Случайно оставленный pam_permit в auth — это вход без пароля.
  • account проверяется после auth. Поэтому бывает так: пароль верный, а вход запрещён — сработал account (pam_deny, pam_faillock или pam_sss с отказом).
  • session — это не проверка, а действие. Если отказал модуль session, вход уже состоялся, а вот сессия может не открыться.

Где почитать свою цепочку целиком

# все действующие (не закомментированные) правила конкретной программы
$ grep -vE '^\s*#|^\s*$' /etc/pam.d/login

# что подключается из общих файлов
$ grep -vE '^\s*#|^\s*$' /etc/pam.d/common-auth

Читать удобно с блокнотом: сначала файл программы, потом то, что подключается через @include, и только затем — конкретные модули.

Источники

  • man 5 pam.conf — формат правил, флаги контроля и действия в скобках, @include.
  • man 3 pam — четыре типа модулей и порядок их вызова.
  • Содержимое /etc/pam.d/common-auth, /etc/pam.d/common-account, /etc/pam.d/common-session, /etc/pam.d/common-password — приведено с рабочей системы (Ubuntu 26.04).

Что ещё не проверено

  • Синтаксис N (переход на N строк) проверен по документации и по чтению живых файлов common-*, но отдельный эксперимент «что если поменять число» мы не ставили — на рабочей машине это как раз тот случай, когда эксперимент дороже чтения.
  • В разных версиях PAM набор действий одинаков, но поведение reset описано в документации кратко; на практике его лучше не использовать без нужды.
Оценка статьи 0

Комментарии

Пока комментариев нет.