简单熟悉PAM模块
一. 简单了解一下PAM
PAM可以说是一套程序编程接口(api application programming interface) ,它提供了一连串的验证,只要用户将验证阶段的需求告诉给PAM, PAM就会进行验证,将结果反馈给用户. 简而言之,PAM就是一个独立的api,任何程序有需求,可以向PAM发出验证要求通知, PAM经过验证将结果反馈给该程序.
PAM用了进行验证的数据称为模块(modules),然而每个PAM模块的功能也不相同,例如输入passwd,如果随便数据就好报如下图一样的错误.
passwd进行报错的原因是PAM的pam_cracklib.so 模块的功能, 它能够判断密码是否在字典里面,并将错误信息返回给修改程序.
二. PAM模块设置语法
PAM通过一个与程序相同文件名的配置文件来进行一连串的认证分析需求,例如passwd这个命令调用PAM,当执行passwd的时候,这个程序就会调用PAM.
具体的调用流程:
1. 用户开始执行passwd这个程序(/usr/bin/passwd),并输入密码;
2. passwd调用PAM模块进行验证;
3.PAM模块会到/etc/pam.d/中找寻与程序(passwd)同名的文件
4. 根据/etc/pam.d/passwd内的设置, 引用相关的PAM模块逐步进行验证分析.
5.将验证结果(成功,失败以及其他的信息) 回传给passwd这个程序.
6. passwd 这个程序会根据PAM返回结果决定下一步操作,例如重新输入密码,或者通过.
=====================>
1.整理一下关系, 上文提到的/etc/pam.d/ 下的配置文件名与调用的程序同名, 而配置文件会调用PAM模块进行验证 . 看一下/etc/pam.d/passwd这个配置文件的内容.
第一行是版本说明,#号开头的都是批注, 而以下每一行都是一个独立的验证流程, 每一行分三个区段, 第一列是 验证类型 (type), 第二列是 控制标准(flag), 第三列是PAM模块与该模块的参数.
注意: inlude(包括) 这个关键字 代表调用后面的文件作为这个类别的验证,所以上述第一 二行调用的是/etc/pam.d/system-auth 这个文件来进行验证.
验证类型概况(type):
1.auth 主要用于检验用户的身份凭证,这种类型通常需要密码来校验, 所以后续接的模块是用来检验用户身份的
2.account account(账号)则大部分是进行授权,这种类型则主要在检验用户是否具有正确的权限, 例如,当你使用一个过期的密码登录是,就会无法正确的登录.
3.session session是会议期间的意思,所以session 管理的就是用户在这次登录期间PAM所给予的环境设置, 在这个类型通常用于记录用户登录已注销的信息. 例如使用su或者sudo命令的话,那么应该可以在/var/log/secure里面发现很多关于PAM的说明.
4.password 这种类别主要用于提供验证的修订工作,例如 修改/更改密码
验证的控制标志(flag)
1.required 此验证如果验证成功就会带有成功的标志(success), 若是失败则带有失败的标志(failure),但是无论成功还是失败都会继续进行验证流程,因此相当有利于数据的登陆日志.
2. requisite 若验证失败则返回failure的标志,并且终止后续的验证流程,如果返回成功(success)的标志,并继续后续验证流程
3. sufficient 若验证成功立即回传success给原程序,并终止后续流程; 若验证失败带有failure标志并继续后续验证流程.
4.optional 这个模块目的大多是显示信息而已,并不是用在验证方面
简易的流程图如下:
三. 常用模块大概介绍
/etc/pam.d/* 每个程序个别的pam配置文件
/lib/security/* pam 模块文件的实际放置目录
/etc/security/* 其他pam环境的配置文件
/usr/share/doc/pam-*/ 详细的pam说明
举个修改密码验证样例:
1. 查看passwd配置文件的内容
2. 查看模块相关的内容
3.进行相关验证
3.1 验证阶段(auth), 首先会经过pam_env.so 设置额外的环境变量;再通过pam_fprintd.so进行验证成功终止进行失败继续;再通过pam_unix.so检验密码,若通过则回报给passwd程序,失败则继续往下以pam_succeed_if.so判断UID是否大于500,若小于500则回报失败,否则再往下以pam_deny.so拒绝连接.
3.2 授权验证(account); 先用pam_unix.so检验账户许可证,再用pam_localuser.so要求用户在/etc/passwd给予认可,如若通过则回报给passwd程序,失败继续往下以pam_succeed_if.so判断UID是否小于500,若小于500则不记录登记信息.最后以pam_permit.so允许该账户登陆
3.3密码阶段(password);先以pam_cracklib.so设置密码仅能尝试错误3次;接下来pam_unix.so通过sha512,shadow等功能进行密码校验,若是通过则回报passwd程序, 若不通过则以pam_deny.so拒绝登录.
有个举例:
4. 为什么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的限制, 所以可以远程直接联机到服务器.
以上信息均借鉴鸟叔的linux私房菜进行整理, 如有差错,麻烦提醒.