我目前正在准备一台虚拟主机服务的机器,并决定使用MySQL来存储我们所有的用户(因为我们的其他服务已经使用了它)。 为此,我使用libnss-mysql和pam-mysql 。 但是,即使大多数设置正在运行,但在尝试使用passwd更改用户密码时遇到问题。
目前,可以创build一个用户( INSERT INTO )并使用su以该用户身份login。 机器不提示input密码,直接访问用户的shell。 但是,一旦我以这个用户身份login, passwd结束于:
$ passwd myuser passwd: Authentication token manipulation error passwd: password unchanged
根据MySQL日志,在调用passwd时会进行查询,因此与MySQL的连接不成问题。 此外,当我尝试与一个未知的用户调用passwd ,我得到一个合适的passwd: user 'doesnotexist' does not exist 。 passwd确实find了一个用户,但是不能修改它的信息。 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
总而言之 :
sufind用户,并在所有情况下执行无密码login(如果我是root用户,则会提示input密码并获取令牌错误)。 chage找不到用户; 它似乎search/etc/passwd而不是数据库。 passwd确实find了用户,但在编辑它时却返回一个令牌错误。 以下是一些configuration示例:
将/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给大家。 myuser的$HOME目录是/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
我试过的:
myuser的数据库中设置密码(SHA512哈希, $6$... )。 passwd -d ):告诉我myuser在/etc/passwd找不到。 如果我尝试locking帐户或强制其密码过期,也会发生同样的情况。 passwd ,没有任何更改。 su ):我得到身份validation令牌操作错误,并返回到login提示。 当我尝试连接到SSH(加上逻辑上的密码过期警告)时也是如此。 对我来说,似乎用户pipe理部分(帐户/会话?)正确链接到MySQL,但密码pipe理部分似乎部分依赖于/etc/passwd 。 我错过了configuration中的东西吗?
好的,我find了那个解决scheme。 第一:我强烈build议任何人进入这个研究PAM模块的基本知识 。 这真的有助于理解整个事情。 现在,让我们看看我的common-*文件。 它们都具有相同的结构:
facility required pam_unix.so [...] facility sufficient pam_mysql.so [...]
现在,在阅读了关于PAM模块的更多信息之后,这对我来说很荒谬。 这里是关于PAM控制标志的一些文档:
要求 :如果模块成功,链的其余部分被执行,并且该请求被授予,除非其他模块失败。 如果模块失败,链的其余部分也被执行,但是请求最终被拒绝。
足够 :如果模块成功并且链中的较早模块没有失败,则该链立即终止并且请求被授予。 如果模块失败,模块将被忽略,链的其余部分被执行。
基本上,我的configuration使PAM的行为如下: 通过/etc/passwd和/etc/shadow进行UNIX身份validation必须在所有情况下都成功。 MySQL查找也将被执行,但是如果UNIX身份validation失败,其结果将不被考虑。
通过这种设置,MySQL身份validation机制在所有情况下都变得毫无用处。 一个适当的configuration将是:
facility sufficient pam_mysql.so [...] facility required pam_unix.so [...]
其中说明: MySQLauthentication机制是足够的。 如果成功,则不需要进一步的机制testing。 如果失败,则UNIX身份validation必须成功。 由于我将拥有比UNIX用户更多的MySQL用户,因此首先对MySQL进行身份validation更为合理。
注意PAM和NSSangular色的差异也很重要。 用我的设置,鉴于NSSconfiguration是正确的, validation是完全正常的。 NSS处理基本的UNIX身份validation,但不处理帐户/会话pipe理,也不处理服务特定的(SSH / FTP / …)连接。 所有这些都由PAM处理。 这种分离是为什么root用户可以以MySQL用户身份进行连接的原因:NSS确实find了这个条目,由于root不需要对任何用户身份进行身份validation,所以PAM模块从来没有被调用过。