Pam

Материал из noname.com.ua
Перейти к навигацииПерейти к поиску


Linix PAM

Это статья про полную хуйню ерунду - от руководства поставлена задача: заводить пользователя вида user@domain.tld на линукс-боксах. Из ограничений - такой пользователь нужен только один в системе.
В линуксе нельзя завести пользователя с символом "@" в имени стандартными средствами (--force варианты я не расматриваю). Потому для хранения пользователей нужно использовать какое-то внешнее хранилище.
Все написаное относится к CentOS 6.5 - меня интересовала именно эта система и со всякими вашими убунтами я не тестировал :)

С авторизацией по ключам в ssh РАБОТАТЬ НЕ БУДЕТ так как ssh не использует PAM для ключей

Решение


Первое что пришло в голову - использовать PAM и не заморачиваться с хранением пользователя вообще. Сделать что то вроде такого в /etc/pam.d.sshd

auth       sufficient   pam_exec.so debug  expose_authtok  log=/root/pam_exec_debug.log /root/pam_exec.sh

Естественно /root/pam_exec.sh для моего пользователя (или для теста - всегда) возвращает "успех".
Это не сработало
Т.е. на уровне PAM это конечно же работает- но ssh слишком умный как утка и имеет дополнительную проверку - вызывая системную ф-ю getpwnam которая ничего не знает про PAM (а использует дедовские методы - /etc/passwd ... ) и не пускает с ошибкой:

Mar  5 17:52:55 test-vm-mm sshd[3378]: fatal: Internal error: PAM auth succeeded when it should have failed
Mar  5 17:52:55 test-vm-mm sshd[3379]: fatal: mm_request_send: write: Broken pipe

После чтения кода sshd перевести на человеческий я зык это сообщение можно так "PAM сказал что пускать можно но т.к. поверка на наличие такого пользователя в системе дала отрицательный результат то мы все равно пускаем."
Отличный результат.

Для того что бы пользователь был доступен при проверке getpwnam это должен быть системный пользователь. Другого варианта нет.


Однако системные пользователи могут храниться не только в /etc/passwd но и в других местах
Тут возможно несколько вариантов

  • LDAP
  • NIS
  • DB

Я остановлюсь на последнем - достаточно простое решение и не требует установки сторонних сервисов.

  • Установить пакет nss_db-2.2.3-0.5.pre1.el6_5.1.x86_64 (версия может отличаться
  • В файле /etc/nsswitch.conf включить использование bd
passwd:     files db
shadow:     files db
group:      files db
  • Отредактировать файл /var/db/Makefile что бы использовать не /etc/paswd, shadow и прочие, а свои файлы
  • Сгенерировать базу (/usr/bin/make -f ./Makefile). Важно не забывать удалять старые базы перед перегенерацией.

Для проверки я сделал следующее:

  • создал пользователя (useradd ...)
  • сбекапил passwd shadow groups
  • в копиях - оставил только этого нового пользователя
  • из основной базы - его удалил (userdel ..), домашний каталог оставил.


После этого я смог успешно залогиниться в ssh с пользователем которого нет в /etc/passwd
Но и это не решает проблему - пользователь с "@" в имени остается не валидным.

PAM

Для того что бы пользователь маппился на другого (валидного) я применил простейшее решение - pam_regex.


Для примера я возьму вот такую регулярку:
auth       required   pam_regex.so debug extended transform=s/.*@.*/user1/g

Т.е. любой пользователь с @ будет мапиться на одного и того же пользователя.
в реальности это конечно же не нужно - маппить надо только того пользователя которого надо.


После чего у меня все заработало .

Сам модуль для PAM я брал здесь: http://puszcza.gnu.org.ua/software/pam-modules/manual/html_chapter/regex.html

Links