Я в настоящее время готовлю машину к услуге веб-хостинга, и я решил использовать MySQL для хранения всех наших пользователей (так как остальная часть наших сервисов уже использует его). Для этого я использую libnss-mysql и pam-mysql. Однако даже при том, что большая часть установки функционирует, я сталкиваюсь с проблемой при попытке изменить пароль пользователя с passwd
.
В данный момент возможно создать пользователя (INSERT INTO
) и войдите в систему как этот пользователь, использующий su
. Машина не запрашивает пароль, и доступу к оболочке пользователя непосредственно предоставляют. Однако, после того как я зарегистрирован как этот пользователь, passwd
концы с:
$ passwd myuser
passwd: Authentication token manipulation error
passwd: password unchanged
Согласно журналам MySQL, запрос сделан когда passwd
назван, поэтому соединение с MySQL не является проблемой. Кроме того, когда я пытаюсь звонить passwd
с несуществующим пользователем я получаю соответствующее passwd: user 'doesnotexist' does not exist
. passwd
действительно находит пользователя, но не может изменить его информацию. auth.log
файл журнала говорит:
pam_unix(passwd:chauthtok): user "myuser" does not exist in /etc/passwd
pam_mysql - option verbose is set to "1"
pam_mysql - pam_sm_chauthtok() called.
pam_mysql - pam_mysql_open_db() called.
pam_mysql - pam_mysql_open_db() returning 0.
pam_mysql - pam_sm_chauthtok() returning 0.
pam_mysql - pam_mysql_release_ctx() called.
pam_mysql - pam_mysql_destroy_ctx() called.
pam_mysql - pam_mysql_close_db() called.
При вызове passwd -Sa
получить состояние всех учетных записей, myuser
учетная запись действительно появляется. Кроме того, getent passwd
и getent shadow
оба возвращают действительный доступ для myuser
.
$ passwd -Sa
...
messagebus L 06/28/2014 0 99999 7 -1
mysql L 06/28/2014 0 99999 7 -1
myuser P 01/01/1970 0 99999 7 -1
$ getent passwd myuser
myuser:x:5001:5000:First Last:/home/members/myuser:/bin/bash
$ getent shadow myuser
myuser:$6$...:0:0:99999:7:::0
Однако, запрашивая стареющую информацию о myuser
:
$ chage -l myuser
chage: user 'myuser' does not exist in /etc/passwd
В целом:
su
действительно находит пользователя и выполняет вход в систему пароля меньше во всех случаях (если я - корень, иначе мне предлагают пароль и получаю маркерную ошибку).chage
не может найти пользователя; это, кажется, ищет /etc/passwd
вместо DB.passwd
действительно находит пользователя, но возвращает маркерную ошибку при попытке отредактировать его.Вот некоторые примеры конфигурации:
/etc/pam.d/common-account
account sufficient pam_unix.so
account required pam_mysql.so config_file=/etc/pam-mysql.conf
/etc/pam.d/common-auth
auth sufficient pam_unix.so nullok_secure
auth required pam_mysql.so config_file=/etc/pam-mysql.conf
/etc/pam.d/common-session
session sufficient pam_unix.so
session required pwam_mysql.so config_file=/etc/pam-mysql.conf
/etc/pam.d/common-passwd
password sufficient pam_unix.so obscure sha512
password required pam_mysql.so config_file=/etc/pam-mysql.conf
/etc/libnss-mysql.cfg
getpwnam SELECT username,'x',(5000+id),5000,CONCAT(firstname, lastname),CONCAT('/home/members/', username),'/bin/bash' \
FROM users \
WHERE username='%1$s' \
LIMIT 1
getpwuid SELECT username,'x',(5000+id),5000,CONCAT(firstname, lastname),CONCAT('/home/members/', username),'/bin/bash' \
FROM users \
WHERE (5000+id)='%1$u' \
LIMIT 1
getspnam SELECT username,password,0,'0','99999','7','-1','-1','0' \
FROM users \
WHERE username='%1$s' \
LIMIT 1
getpwent SELECT username,'x',(5000+id),5000,CONCAT(firstname, lastname),CONCAT('/home/members/', username),'/bin/bash' \
FROM users
getspent SELECT username,password,0,'0','99999','7','-1','-1','0' \
FROM users
getgrnam SELECT '%1$s','members',5000
getgrgid SELECT name,password,'%1$u'
getgrent SELECT 'members','members',5000
memsbygid SELECT username \
FROM users
gidsbymem SELECT 5000
/bin/bash
для всех.$HOME
каталог для myuser
/home/members/myuser
.members
группа, GID которой 5000./etc/pam-mysql.conf
users.host = localhost
users.database = mydatabase
users.db_user = root
users.db_passwd = root_password
users.table = users
users.user_column = username
users.password_column = password
users.password_crypt = 1
/etc/nsswitch.conf
passwd: compat mysql
group: compat
shadow: compat mysql
Что я попробовал:
$6$...
) в DB для myuser
.passwd -d
): говорит мне myuser
не может быть найден в /etc/passwd
. То же происходит, если я пытаюсь заблокировать учетную запись или вызвать ее истечение пароля.passwd
из корневой учетной записи, никаких изменений.su
): Я получаю ошибку управления аутентификационным маркером и передан обратно приглашению ко входу в систему. То же, когда я пытаюсь соединиться с SSH (плюс предупреждения истечения пароля, которые логичны).Мне это походит на часть управления пользователями (учетная запись/сессия?) правильно связан с MySQL, все же часть управления паролями, кажется, полагается частично на /etc/passwd
. Я пропустил что-то в конфигурации?
Хорошо, я нашел решение для этого. Первое: я бы настоятельно рекомендовал любому, кто занимается этим, изучить основы модулей PAM -. Это действительно помогает понять все. А теперь посмотрим на мои общие-*
файлы. Они все имеют одинаковую структуру :
facility required pam_unix.so [...]
facility sufficient pam_mysql.so [...]
Теперь, после более подробного ознакомления с модулями PAM, это выглядит для меня смешно. Вот некоторая документация о флагах управления PAM :
required : если модуль работает успешно, то выполняется оставшаяся часть цепочки, и запрос удовлетворяется, если только какой-нибудь другой модуль не выйдет из строя. Если модуль выйдет из строя, то выполняется и остальная часть цепочки, но запрос в конечном итоге отклоняется.
sufficient : если модуль выйдет из строя и ни один из предыдущих модулей в цепочке не вышел из строя, то цепочка немедленно завершается, и запрос удовлетворяется. Если модуль выйдет из строя, модуль будет проигнорирован, а остальная часть цепочки будет выполнена.
В принципе, моя конфигурация заставляет PAM вести себя следующим образом: аутентификация UNIX через /etc/passwd
и /etc/shadow
должна быть успешной во всех случаях. Также будет выполнен поиск MySQL, но если аутентификация UNIX не прошла успешно, ее результат не будет принят во внимание.
При такой настройке механизм аутентификации MySQL становится бесполезным во всех ситуациях. Правильной конфигурацией будет :
facility sufficient pam_mysql.so [...]
facility required pam_unix.so [...]
Что говорит о : Механизма аутентификации MySQL достаточно. Если он будет успешным, больше никаких механизмов тестироваться не будет. Однако, если это не удастся, аутентификация UNIX должна быть успешной. Так как у меня будет больше пользователей MySQL, чем пользователей UNIX, то логичнее сначала аутентифицироваться на MySQL.
Также важно отметить разницу в ролях PAM и NSS. В моей установке аутентификация была отлично функциональна, так как конфигурация NSS была правильной. NSS обрабатывает базовую аутентификацию UNIX, но не управление учетной записью/сессией, и не специфические для сервиса (SSH/FTP/...) соединения. Все это обрабатывается PAM. Это разделение является причиной того, что root
мог подключиться как пользователь MySQL : NSS нашёл запись, и так как root
не нужно ни с чем аутентифицироваться, чтобы взять личность пользователя, модули PAM никогда не вызывались.