С чего начать Первые шаги трек · 15 ступеней
Linux Labs

PAM: проверка входа, политика паролей и блокировка

13 мин Ubuntu 24.04 · Linux-PAM 1.5.3 · libpwquality 1.4.5

Стек модулей в /etc/pam.d: решает, пускать ли пользователя, какой пароль принять и когда заблокировать вход.

Шпаргалка

7 команд Версия для печати
  • grep -v '^#' /etc/pam.d/common-auth | grep . стек проверки входа
  • sudo pam-auth-update --enable pwquality включить pwquality
  • echo 'Lab-Pass-2026' | pwscore оценить пароль заранее
  • sudoedit /etc/security/pwquality.conf правила паролей
  • sudo faillock --user alice неудачные входы alice
  • sudo faillock --user alice --reset снять блокировку
  • sudo journalctl -t su | grep -i fail отказы su в журнале

Обзор

PAM (Pluggable Authentication Modules) — библиотека, которой программы поручают проверку пользователя. login, su, sudo, sshd и passwd сами пароль не сверяют: они зовут PAM, а PAM читает файл с именем программы в /etc/pam.d/ и проходит по его модулям. Чтобы поменять политику — длину пароля, блокировку после неудач, — меняют стек модулей, программы трогать не нужно. Файлы читаются при каждом входе, правка действует сразу.

Файл программы обычно подключает общие файлы строкой @include:

text
student@ubuntu:~$ grep -E '^(auth|@include)' /etc/pam.d/su
auth       sufficient pam_rootok.so
@include common-auth
@include common-account
@include common-session

Так же устроены sudo и sshd: правка common-auth меняет проверку пароля у всех сразу.

Четыре стека

Каждая строка начинается с типа — к какому этапу входа она относится:

Тип Когда идёт Модули на машине
auth проверка, кто ты: пароль pam_unix, pam_faillock
account можно ли этой учётной записи войти сейчас: срок, блокировка pam_unix, pam_nologin
password смена пароля pam_pwquality, pam_unix
session что сделать при входе и выходе pam_limits, pam_umask, pam_systemd

Вход по ключу в sshd пропускает стек auth: ключ сверяет сам sshd. Стеки account и session идут и при входе по ключу.

Как читается строка

text
auth	[success=1 default=ignore]	pam_unix.so nullok

Тип, флаг управления, модуль и его параметры. Модули идут сверху вниз, и флаг говорит, что делать с их ответом:

Флаг Модуль ответил «да» Модуль ответил «нет»
required дальше отказ, но стек доходит до конца
requisite дальше отказ сразу
sufficient успех сразу, если раньше отказа не было дальше
optional важен, только если модуль в стеке один —
[success=N default=ignore] пропустить N следующих строк не учитывать, дальше

Стек auth на машине:

text
student@ubuntu:~$ grep -v '^#' /etc/pam.d/common-auth | grep .
auth	[success=1 default=ignore]	pam_unix.so nullok
auth	requisite			pam_deny.so
auth	required			pam_permit.so
auth	optional			pam_cap.so

Верный пароль: pam_unix перескакивает через одну строку — pam_deny — к pam_permit, вход разрешён. Неверный: следующая строка pam_deny и отказ. Порядок строк здесь — часть логики: строка, вставленная между pam_unix и pam_deny, меняет, куда ведёт success=1.

pam-auth-update

В Ubuntu файлы common-* собирает pam-auth-update из профилей в /usr/share/pam-configs/. На машине их пять: capability, mkhomedir, pwquality, systemd, unix. Профиль — это строки и место, куда их вставить:

text
student@ubuntu:~$ cat /usr/share/pam-configs/pwquality
Name: Pwquality password strength checking
Default: yes
Priority: 1024
Conflicts: cracklib
Password-Type: Primary
Password:
	requisite			pam_pwquality.so retry=3

На учебной машине профиль выключен. sudo pam-auth-update --enable pwquality включает его и пересобирает common-password:

Тип Флаг Модуль и параметры
password requisite pam_pwquality.so retry=3
password [success=1 default=ignore] pam_unix.so obscure use_authtok try_first_pass yescrypt
password requisite pam_deny.so
password required pam_permit.so

Первая строка — новая. use_authtok у pam_unix — взять пароль, который уже проверил pam_pwquality, и не спрашивать снова.

Если common-* правили руками, pam-auth-update сначала спрашивает Override local changes to /etc/pam.d/common-*?. Ответ yes пересоберёт файлы из профилей и сотрёт ручные строки, no оставит файлы как есть — и профиль не включится:

text
pam-auth-update: Local modifications to /etc/pam.d/common-*,
  not updating.
pam-auth-update: Run pam-auth-update --force to override.

pwquality: качество пароля

pam_pwquality проверяет новый пароль при смене. Правила — в /etc/security/pwquality.conf или в файлах /etc/security/pwquality.conf.d/*.conf (каталога на машине нет, его создают mkdir). В pwquality.conf машины всё закомментировано, и действуют значения по умолчанию:

Параметр Что значит По умолчанию
minlen минимальная длина 8
minclass сколько классов из четырёх: строчные, заглавные, цифры, прочие 0
dcredit, ucredit, lcredit, ocredit -N — нужно хотя бы N цифр, заглавных, строчных, прочих 0
maxrepeat сколько одинаковых символов подряд можно 0 — без проверки
dictcheck сверка со словарём 1
enforce_for_root отказывать и root выключен

Положительное значение *credit работает иначе: каждый такой символ, до N штук, засчитывается в длину дважды. retry=3 — параметр модуля в строке pam.d: сколько раз passwd переспросит.

Пароль заранее проверяет pwscore. Он читает тот же pwquality.conf, но в PAM не смотрит — правило видно в pwscore ещё до pam-auth-update. Ответ — оценка от 0 до 100 или причина отказа с кодом 1:

text
student@ubuntu:~$ echo 123 | pwscore
Password quality check failed:
 The password is shorter than 8 characters
student@ubuntu:~$ echo qwerty123 | pwscore
Password quality check failed:
 The password fails the dictionary check - it is based on a
 dictionary word
student@ubuntu:~$ echo 'Lab-Pass-2026' | pwscore
96

С minlen = 12, minclass = 3 и dcredit = -1 отказы такие:

Пароль Ответ
labpassword2026 The password contains less than 3 character classes
Kd8#vq2Lm9 The password is shorter than 12 characters
Labpassword-xx The password contains less than 1 digits
aaaaaaaaaaaaB1 … it does not contain enough DIFFERENT characters
Kd8#vq2Lm9Zx 36 — принят

passwd от пользователя печатает те же причины после BAD PASSWORD: и сдаётся после трёх попыток:

text
deploy@ubuntu:~$ passwd
Changing password for deploy.
Current password:
New password:
BAD PASSWORD: The password contains less than 3 character classes
New password:
BAD PASSWORD: The password is shorter than 12 characters
New password:
BAD PASSWORD: The password contains less than 1 digits
passwd: Have exhausted maximum number of retries for service
passwd: password unchanged

Root без enforce_for_root получает то же BAD PASSWORD, но пароль меняется: sudo passwd deploy печатает предупреждение и password updated successfully, chpasswd — только предупреждение и код 0. С enforce_for_root отказ получает и root — chpasswd выходит с кодом 1 и password not changed.

faillock: блокировка после неудач

pam_faillock считает неудачные входы. Профиля для него в pam-configs нет — его вписывают в common-auth руками, тремя строками вокруг pam_unix:

text
auth	requisite			pam_faillock.so preauth
auth	[success=1 default=ignore]	pam_unix.so nullok
auth	[default=die]			pam_faillock.so authfail
auth	sufficient			pam_faillock.so authsucc
auth	requisite			pam_deny.so
auth	required			pam_permit.so
auth	optional			pam_cap.so

и строкой account required pam_faillock.so в конец common-account.

Строка Что делает
preauth до пароля: учётная запись заблокирована — отказ сразу
authfail после неверного пароля: запись в счётчик и отказ
authsucc после верного: счётчик обнуляется, вход разрешён
account после входа без пароля, по ключу: тоже обнуляет счётчик

Верный пароль перескакивает authfail (success=1) и попадает на authsucc. Бывает вариант без authsucc: у pam_unix стоит success=2, и верный пароль перескакивает сразу authfail и pam_deny. Счётчик тогда обнуляет только строка account, поэтому без неё он растёт и после удачных входов. Настройки — в /etc/security/faillock.conf; на машине там всё закомментировано: deny = 3 неудачи, unlock_time = 600 секунд, fail_interval = 900 — окно, в котором считаются неудачи. Root не блокируется, пока не включён even_deny_root.

Три неверных su - deploy подряд и вход с верным паролем:

text
student@ubuntu:~$ su - deploy
Password:
su: Permission denied
student@ubuntu:~$ sudo faillock --user deploy
deploy:
When                Type  Source          Valid
2026-10-21 05:06:19 TTY   /dev/pts/0          V
2026-10-21 05:06:24 TTY   /dev/pts/0          V
2026-10-21 05:06:28 TTY   /dev/pts/0          V
student@ubuntu:~$ su - deploy
The account is locked due to 3 failed logins.
(10 minutes left to unlock)
su: Authentication failure

Пароль больше не спрашивают — preauth отказал до него. В журнале:

text
pam_faillock(su-l:auth): Consecutive login failures for user deploy
  account temporarily locked

Счётчики — файлы /var/run/faillock/<пользователь>. Каталог /run живёт в памяти, и перезагрузка их стирает. Снять блокировку раньше — sudo faillock --user deploy --reset.

Вход по ключу через sshd заблокированную учётную запись пускает: стек auth не идёт, а строка account обнуляет счётчик.

Рецепты

3

Политика паролей

bash
sudo pam-auth-update --enable pwquality
grep pwquality /etc/pam.d/common-password
sudo mkdir -p /etc/security/pwquality.conf.d
printf 'minlen = 12\nminclass = 3\n' \
  | sudo tee /etc/security/pwquality.conf.d/50-policy.conf
echo 'labpassword2026' | pwscore      # отказ: 2 класса из 3

Проверяй действием: смена пароля от имени самого пользователя (su - alice -c passwd). Смена от root без enforce_for_root пройдёт с любым паролем и ничего не докажет.

Блокировка после трёх неудач

bash
sudo cp /etc/pam.d/common-auth /root/common-auth.orig
sudo tee /etc/pam.d/common-auth <<'EOF'
auth  requisite                   pam_faillock.so preauth
auth  [success=1 default=ignore]  pam_unix.so nullok
auth  [default=die]               pam_faillock.so authfail
auth  sufficient                  pam_faillock.so authsucc
auth  requisite                   pam_deny.so
auth  required                    pam_permit.so
auth  optional                    pam_cap.so
EOF
echo 'account required pam_faillock.so' \
  | sudo tee -a /etc/pam.d/common-account
printf 'deny = 3\nunlock_time = 600\n' \
  | sudo tee -a /etc/security/faillock.conf

Файл заменяется целиком — сверь его прежний стек с этим (grep -v '^#' /etc/pam.d/common-auth | grep .): строки, которых тут нет, перенеси. Пробелы вместо табуляций PAM читает так же. Проверка — три неверных su - alice, затем sudo faillock --user alice и вход с верным паролем: он должен получить отказ. После — sudo faillock --user alice --reset.

Править PAM и не запереться

  1. Открой второй терминал с sudo -i и не закрывай до конца проверки.
  2. Сохрани копию файла: sudo cp /etc/pam.d/common-auth /root/.
  3. Проверяй новым входом: su - alice, ssh alice@localhost.
  4. Не вышло — верни копию из открытой root-сессии.

Неполадки

5

Пароль 123 принимается

grep pwquality /etc/pam.d/common-password пуст — модуля в стеке нет: sudo pam-auth-update --enable pwquality. Модуль есть, а пароль ставит root — без enforce_for_root он получает только предупреждение BAD PASSWORD, и пароль меняется.

BAD PASSWORD при смене пароля

Причина — в тексте после двоеточия: shorter than 12 characters — minlen, less than 3 character classes — minclass, less than 1 digits — dcredit, dictionary check — dictcheck. Тот же ответ даст pwscore — им удобно подобрать пароль.

The account is locked due to N failed logins

pam_faillock насчитал deny неудач за fail_interval. Кто и откуда ошибался — sudo faillock --user <имя> и journalctl -t su, journalctl -u ssh. Блокировка снимется сама через unlock_time или сразу — faillock --user <имя> --reset.

Неудач много, а блокировки нет

  • Строк pam_faillock нет в common-auth или стоят не там: authfail должен идти сразу за pam_unix, до pam_deny.
  • Ошибается root, а even_deny_root выключен.
  • Входят по ключу: стек auth с паролем не идёт вовсе.

pam-auth-update: Local modifications

common-* правили руками, и pam-auth-update отказывается их пересобирать — профиль не включается. --force пересоберёт файлы из профилей и сотрёт ручные строки, например pam_faillock: впиши их снова после --force.

Опасно

2

Правка common-auth без запасного входа

Опечатка в строке с required или requisite закрывает вход по паролю всем: su, login, sshd по паролю и sudo с паролем идут через common-auth. Держи открытую root-сессию, пока новый вход не проверен.

even_deny_root

С ним блокируется и root: несколько неверных паролей — и на сервер не войти, пока не пройдёт unlock_time. Включай, только если есть другой путь внутрь — консоль или вход по ключу.

Термины

2
pwquality (проверка качества пароля) pwquality (password quality check)
Модуль PAM pam_pwquality: при смене пароля сверяет новый с правилами из /etc/security/pwquality.conf (длина minlen, классы символов minclass, словарь) и отвечает «BAD PASSWORD». Проверить пароль заранее — pwscore.
faillock (блокировка после неудачных входов) faillock (lockout after failed logins)
Модуль PAM pam_faillock: считает неудачные входы пользователя и после deny попыток подряд не пускает его даже с верным паролем, пока не пройдёт unlock_time. Счётчик — faillock --user, сброс — faillock --reset.

См. также

  • passwd — смена пароля и /etc/shadow.
  • chage — срок действия пароля.
  • sudo — тоже проходит через PAM.
  • sshd — UsePAM, вход по паролю и по ключу.
  • fail2ban — бан адреса после неудачных входов.
  • users-groups — учётные записи.
  • journalctl — отказы su и sshd в журнале.
Загрузка…