linux PAM模块简介


在过去,想要对用户进行身份认证(authentication),需要用户输入账号密码, 然后自行编写程序判断账号密码是否正确。 往往需要使用不同的验证机制来判断账号密码, 导致一部主机上可能拥有多个认证系统,造成账号密码可能不同步的验证问题!
可插入认证模块PAM(Pluggable Authentication Modules)的出现正是为了解决这个问题!
PAM是一套应用程序编程接口API(Application Programming Interface),提供了一连串的验证机制, 只要用户将验证阶段的需求告知PAM, PAM就可以反馈用户验证结果。 PAM仅是一套验证的机制,可以由其他程序调用,不论使用什么程序,都可以使用PAM来进行验证,就能够让账号密码或者是其他方式的验证具有一致的结果! 方便程序设计师处理验证的问题!
PAM是一个独立的API,程序可以向PAM发出验证需求, PAM经过一连串的验证后,将验证的结果反馈给程序。
PAM分为不同的验证模块(Modules),每个PAM模块的功能都不相同。 举例来说, 在使用passwd指令时,如果随便输入字典上面的字符串, passwd就会报告错误信息! 这就是PAM的pam_cracklib.so模块的功能!pam_cracklib.so模块能够判断该密码是否在字典里! 并返回给密码修改程序,此时就能够了解你的密码强度了。
所以,当有任何需要判断是否在字典当中的密码字符串时,就可以使用pam_cracklib.so模块来验证!

PAM模块设定语法

回到顶部
PAM由一个与程序同名的配置文件来进行一连串的认证需求分析。 以passwd命令调用PAM来说明。当执行passwd命令时,passwd调用PAM的流程是:
1. 用户执行/usr/bin/passwd程序文件,并输入密码;
2. passwd进程调用PAM模块进行验证;
3. PAM模块到/etc/pam.d/目录中查找与passwd程序同名的配置文件;
4. 根据/etc/pam.d/passwd文件的设定,引用相关PAM模块逐步进行验证分析;
5. 将验证结果回传给passwd进程;
6. passwd进程根据PAM回传的结果决定下一步动作。
重点是/etc/pam.d/目录里面的配置文件,以及配置文件设置的PAM模块! 用cat查看/etc/pam.d/passwd文件:
            [root@study ~]# cat /etc/pam.d/passwd 
            #%PAM-1.0  #PAM版本说明
            auth       include	system-auth
            account    include	system-auth
            password   substack	system-auth
            -password   optional	pam_gnome_keyring.so use_authtok
            password   substack	postlogin
            
第一行为PAM版本说明,#开头的行都是注释行。 后面的每一行都是一个独立的验证流程, 每一行可以区分为三个字段,分别是验证类别(type)、控制标志(flag)、 PAM模块与该模块的参数。
include(包括)关键词代表的是调用后面的文件来作为这个类别的验证, 所以,上述的每一行都要重复调用/etc/pam.d/system-auth文件来进行验证!
我们查看/etc/pam.d/system-auth文件:
[root@study ~]# cat /etc/pam.d/system-auth
#%PAM-1.0
# This file is auto-generated.
# User changes will be destroyed the next time authconfig is run.
auth        required      pam_env.so
auth        required      pam_faildelay.so delay=2000000
auth        sufficient    pam_unix.so nullok try_first_pass
auth        requisite     pam_succeed_if.so uid >= 1000 quiet_success
auth        required      pam_deny.so

account     required      pam_unix.so
account     sufficient    pam_localuser.so
account     sufficient    pam_succeed_if.so uid < 1000 quiet
account     required      pam_permit.so

password    requisite     pam_pwquality.so try_first_pass local_users_only retry=3 authtok_type=
password    sufficient    pam_unix.so sha512 shadow nullok try_first_pass use_authtok
password    required      pam_deny.so

session     optional      pam_keyinit.so revoke
session     required      pam_limits.so
-session     optional      pam_systemd.so
session     [success=1 default=ignore] pam_succeed_if.so service in crond quiet use_uid
session     required      pam_unix.so
              
第一个字段:验证类别(Type)
验证类别主要分为四种,分别说明如下:
auth:authentication(认证)的缩写,主要用来检验用户的身份验证,这种类别通常需要密码来检验,后续接的模块用来检验用户身份。
account:account(账号)大部分是在进行authorization(授权),这种类别则主要在检验用户是否具有正确的权限, 举例来说,当你使用一个过期的密码来登录时,就无法正确的登录了。
session:session是会话的意思,session管理的就是用户在这次登录会话期间,PAM所给予的环境设定。 这个类别通常用在记录用户登录与注销时的信息!例如,如果常常使用su或者sudo命令, 应该可以在/var/log/secure里发现很多关于pam的说明, 而且记载的数据是session open, session close的信息!
password:password类别主要提供验证的修订工作,就是修改或变更密码!
这四个验证类型通常是有顺序的,不过也有例外就是了。 会有顺序的原因是,
(1)我们总是得要先验证身份 (auth) 后,
(2)系统才能够藉由用户的身份给予适当的授权与权限设定(account),而且
(3)登录与注销期间的环境才需要设定, 也才需要记录登录与注销的信息 (session)。如果在运作期间需要密码修订时,
(4)才给予password的类别。这样说起来, 自然是需要有点顺序吧!

第二个字段:验证的控制标志(control flag)
验证的控制标志简单的说就是验证通过的标准! 这个字段在管控该验证的放行方式,主要也分为四种控制方式:
required:若验证成功则带有success(成功)的标志,若失败则带有failure的标志,但不论成功或失败都会继续后续的验证流程。 由于后续的验证流程可以继续进行,因此相当有利于资料的日志记录(log) ,这也是PAM最常使用required的原因。
requisite:若验证失败则立刻返回原程序failure标志,并终止后续的验证流程。若验证成功则带有success的标志并继续后续的验证流程。 这个项目与required最大的差异,就在于失败的时候还要不要继续验证下去,由于requisite是失败就终止, 因此失败时所产生的PAM信息就无法通过后续的模块来记录了。
sufficient:若验证成功则立刻回传success给原程序,并终止后续的验证流程;若验证失败则带有failure标志并继续后续的验证流程。 与requisits刚好相反!
optional:这个模块大多用来显示讯息,并不用来验证。
如果将这些控制标志以图示的方式配合成功与否的条件绘图,会有点像底下这样:
图 13.5.2、PAM 控制标志所造成的返回流程
程序执行过程中遇到验证时才会调用PAM ,PAM验证又分很多类型与控制标志,不同的控制标志返回的讯息并不相同。 requisite失败就返回了并不会继续,而sufficient则是成功就返回了不会继续。 验证结束后返回的信息通常是succes或failure。

常用模块简介

回到顶部
我们常常需要通过各种方式登录(login)系统,了解了配置文件的语法,现在来看看登录所需要的PAM流程为何:
[root@study ~]# cat /etc/pam.d/login 
#%PAM-1.0
auth [user_unknown=ignore success=ok ignore=ignore default=bad] pam_securetty.so
auth       substack     system-auth
auth       include      postlogin
account    required     pam_nologin.so
account    include      system-auth
password   include      system-auth
# pam_selinux.so close should be the first session rule
session    required     pam_selinux.so close
session    required     pam_loginuid.so
session    optional     pam_console.so
# pam_selinux.so open should only be followed by sessions to be executed in the user context
session    required     pam_selinux.so open
session    required     pam_namespace.so
session    optional     pam_keyinit.so force revoke
session    include      system-auth
session    include      postlogin
-session   optional     pam_ck_connector.so
            
可以看到,login也多次调用system-auth:
[root@study ~]# cat /etc/pam.d/system-auth
#%PAM-1.0
# This file is auto-generated.
# User changes will be destroyed the next time authconfig is run.
auth        required      pam_env.so
auth        required      pam_faildelay.so delay=2000000
auth        sufficient    pam_unix.so nullok try_first_pass
auth        requisite     pam_succeed_if.so uid >= 1000 quiet_success
auth        required      pam_deny.so

account     required      pam_unix.so
account     sufficient    pam_localuser.so
account     sufficient    pam_succeed_if.so uid < 1000 quiet
account     required      pam_permit.so

password    requisite     pam_pwquality.so try_first_pass local_users_only retry=3 authtok_type=
password    sufficient    pam_unix.so sha512 shadow nullok try_first_pass use_authtok
password    required      pam_deny.so

session     optional      pam_keyinit.so revoke
session     required      pam_limits.so
-session     optional      pam_systemd.so
session     [success=1 default=ignore] pam_succeed_if.so service in crond quiet use_uid
session     required      pam_unix.so
              
可以看到使用了非常多的PAM模块,每个模块的功能都不太一样,详细的模块说明可以在/usr/share/doc/pam-*/目录中查看.
现在总结一下和PA相关的目录:
/etc/pam.d/*:每个程序对应的PAM配置文件;
/lib64/security/*:PAM模块文件的实际存放目录;
/etc/security/*:其他PAM环境的配置文件;
/usr/share/doc/pam-*/:详细的PAM说明文件。
例如pam_nologin的说明文件档在/usr/share/doc/pam-1.1.8/txts/README.pam_nologin。
这里仅简单介绍几个较常使用的模块,详细的信息还得要您努力查阅参考书:
pam_securetty.so :限制系统管理员root只能从安全的(secure)终端机登录; 例如tty1, tty2等就是传统的终端机设备名称。而安全的终端机设定在/etc/securetty文件中。 查阅一下该文件就知道为什么root可以从tty1~tty7登录,但却无法通过telnet登录Linux主机!
pam_nologin.so :这个模块可以限制普通用户是否能够登录主机。当/etc/nologin文件存在时, 所有普通用户均无法登录系统!若/etc/nologin存在,普通用户在登录时, 会将该文件的内容在终端机上显示出来! 正常的情况下这个文件应该是不能存在系统中的。这个模块对root以及已经登录系统中的一般账号并没有影响。 (注意喔!这与 /etc/nologin.txt 并不相同!)
pam_selinux.so :SELinux是针对程序来进行细部管理权限的功能。由于SELinux会影响到用户执行程序的权限, 因此利用PAM模块,将SELinux暂时关闭,等到验证通过后,再予以启动!
pam_console.so :当系统出现某些问题,或者是某些时刻你需要使用特殊的终端接口(例如RS232之类的终端联机设备)登入主机时, 这个模块可以帮助处理一些文件权限的问题,让用户可以通过特殊终端接口(console)顺利的登录系统。
pam_loginuid.so :我们知道系统账号与一般账号的UID是不同的!一般账号UID均大于1000才合理。 因此,为了验证用户的UID真的是我们所需要的数值,可以使用这个模块来进行规范!
pam_env.so :用来设定环境变量的一个模块,如果你有需要额外的环境变量设定,可以参考/etc/security/pam_env.conf文件的详细说明。
pam_unix.so :这是个很复杂且重要的模块,这个模块可以用在验证阶段的认证功能,可以用在授权阶段的账号许可证管理, 可以用在会话阶段的登录文件记录等,甚至也可以用在密码更新阶段的检验!非常丰富的功能! 这个模块在早期使用得相当频繁!
pam_pwquality.so :可以用来检验密码的强度!包括密码是否在字典中,密码输入几次都失败就断掉此次联机等功能,都是这模块提供的! 最早之前其实使用的是pam_cracklib.so模块,后来改成pam_pwquality.so模块, 但此模块完全兼容于pam_cracklib.so, 同时提供了/etc/security/pwquality.conf文件可以额外指定默认值!比较容易处理修改!
pam_limits.so :ulimit就是这个模块提供的能力!更多详细设定可以参考/etc/security/limits.conf文件的说明。
我们继续讨论login的PAM验证机制流程:
1. 验证阶段(auth):首先, (a)会先经过 pam_securetty.so 判断,如果用户是 root 时,则会参考 /etc/securetty 的设定; 接下来(b)经过 pam_env.so 设定额外的环境变量;再(c)通过 pam_unix.so 检验密码,若通过则返回 login 程序; 若不通过则(d)继续往下以 pam_succeed_if.so 判断 UID 是否大于 1000 ,若小于 1000 则 返回失败,否则再往下 (e)以 pam_deny.so 拒绝联机。
2. 授权阶段(account):(a)先以 pam_nologin.so 判断 /etc/nologin 是否存在,若存在则不许普通用户登录; (b)接下来以 pam_unix.so 及 pam_localuser.so 进行账号管理,再以 (c) pam_succeed_if.so 判断 UID 是否 小于 1000 ,若小于 1000 则不记录登录信息。(d)最后以 pam_permit.so 允许该账号登录。
3. 密码阶段(password): (a)先以 pam_pwquality.so 设定密码仅能尝试错误 3 次; (b)接下来以 pam_unix.so 透 过 sha512, shadow 等功能进行密码检验,若通过则返回 login 程序,若不通过则 (c)以 pam_deny.so 拒绝 登录。
4. 会话阶段(session):(a)先以 pam_selinux.so 暂时关闭 SELinux;(b)使用 pam_limits.so 设定好用户能够操 作的系统资源; (c)登录成功后开始记录相关信息在登录文件中; (d)以 pam_loginuid.so 规范不同的 UID 权限;(e)开启 pam_selinux.so 的功能。
总之,就是依据验证类别 (type) 来看,然后先由 login 的设定值去查阅,如果出现 include system-auth 就转到 system-auth 文件中的相同类别,去取得额外的验证流程就是了。然后再到下 一个验证类别,最终将所有的验证跑完! 就结束这次的 PAM 验证啦!
经过这样的验证流程,现在你知道为啥/etc/nologin存在会有问题,也会知道为何你使用一些远程联机机制时, 老是无法使用root登录的问题了吧?没错!这都是 PAM 模块提供的功能啦!
为什么root无法以telnet直接登录系统,但是却能够使用ssh直接登录?
一般来说, telnet会引用login的PAM模块,而login的验证阶段会有/etc/securetty的限制! 由于远程联机属于 pts/n (n 为数字)的动态终端机接口设备名称,并没有写入到 /etc/securetty , 因此root无法以telnet登入远程主机。至于ssh使用的是/etc/pam.d/sshd这个模块,可以查阅一下该模块, 由于该模块的验证阶段并没有加入pam_securetty ,因此就没有/etc/securetty的限制! 故可以从远程直接联机到服务器端。
关于telnet与ssh的细部说明,请参考linux运维

其他相关文件

回到顶部
除了前面谈到的/etc/securetty会影响到root可登录的安全终端机, /etc/nologin会影响到一般用户是否能够登录的功能之外, 我们也知道PAM相关的配置文件在/etc/pam.d, 说明文件在/usr/share/doc/pam-(版本) , 模块实际在/lib64/security/ 。 那么还有没有相关的PAM文件呢? 主要都在/etc/security目录内!下面介绍几个可能会用到的配置文件喔!

/etc/security/limits.conf文件

回到顶部
ulimit功能中, 除了修改用户的~/.bashrc配置文件之外,其实系统管理员可以统一藉由PAM来管理的! 那就是/etc/security/limits.conf文件的设定了。 这个文件的设定很简单,你可以自行参考一下该文件内容。
peter这个用户只能建立100MB的文件,且大于90MB会警告:
            [root@study ~]# vim /etc/security/limits.conf
            peter soft fsize 90000
            peter hard fsize 100000
            #账号 限制依据 限制项目 限制值
            
第一字段为账号,或者是群组!若为群组则前面需要加上@ ,例如@projecta
第二字段为限制的依据,是严格(hard),还是仅为警告(soft);
第三字段为相关限制,此例中限制文件容量,
第四字段为限制的值,在此例中单位为 KB。
若以peter登录后,进行如下的操作则会有相关的限制出现!
            [peter@study ~]$ ulimit -a
            ...省略...
            file size (blocks, -f) 90000
            ...省略...

            [peter@study ~]$ dd if=/dev/zero of=test bs=1M count=110
            File size limit exceeded
            [peter@study ~]$ ls -l --block-size=K test
            -rw-rw-r--. 1 peter peter 90000K Jul 22 01:33 test
            
果然有限制到了
限制pro1群组,每次仅能有一个用户登录系统(maxlogins):
            [root@study ~]# vim /etc/security/limits.conf
            @pro1 hard maxlogins 1
            
如果要使用群组功能的话,这个功能似乎对初始群组才有效喔!而如果你尝试多个pro1的登录时, 第二个以后就无法登录了。而且在/var/log/secure文件中还会出现如下的信息:
pam_limits(login:session): Too many logins (max 1) for pro1
这个文件设定完成就生效了,不用重新启动任何服务! 但是PAM有个特殊的地方,由于他是在程序调用时才予以设定的,因此你修改完成的数据, 对于已登录系统中的用户是没有效果的,要等他再次登录时才会生效喔! 另外, 上述的设定请在测试完成后立刻注释掉,否则下次这两个用户登录就会发生些许问题!

/var/log/secure, /var/log/messages

回到顶部
如果发生任何无法登录或者是产生一些你无法预期的错误时,由于PAM模块都会将数据记载在/var/log/secure中, 所以发生了问题请务必到该文件内去查询一下问题点!
举例来说, 我们在limits.conf的介绍,就有谈到多重登录的错误可以到/var/log/secure内查阅了! 这样也就知道为何第二个pro1无法登录了!

initroot编辑整理,转载请注明www.initroot.com

100次点赞 100次阅读