接前一篇文章:PAM从入门到精通(一)
本文参考以下博文:
Oracle Solaris 10 开发者安全性指南 —— PAM 框架介绍
特此致谢!
前一篇文章中给出了PAM框架以及PAM体系结构,再来重温一下:
PAM框架由以下四部分组成:
(1)PAM应用程序,也称为消费方;
(2)PAM库;
(3)PAM配置文件;
(4)PAM服务模块,也称为提供者。
PAM体系结构如下图所示:
三、PAM框架详解
1. PAM服务模块
PAM服务模块是一个共享库(动态链接库),用于为系统登录应用程序(如 login、rlogin 和 telnet)提供验证和其它安全服务。四种类型的PAM服务是:
- 验证服务模块
用于授予用户访问帐户或服务的权限。提供此服务的模块可以验证用户并设置用户凭证。
对应函数:pam_authenticate()、pam_setcred ()。
- 帐户管理模块
用于确定当前用户的帐户是否有效。提供此服务的模块可以检查口令或帐户的失效期以及限时访问。
对应函数:pam_acc_mgmt()。
- 会话管理模块
用于设置和终止登录会话。
对应函数:pam_open_session()、pam_close_session()。
- 口令管理模块
用于强制实施口令强度规则并执行验证令牌更新。
对应函数:pam_chauthok()。
PAM 模块可以实现其中的一项或多项服务。将简单模块用于明确定义的任务可以增加配置灵活性。因此,应该在不同的模块中实现PAM服务。然后,可以按照 pam.conf 文件中定义的方式根据需要使用这些服务。
2. PAM库
PAM库libpam是PAM体系结构中的中心元素:
- libpam可以导出API pam。应用程序可以调用此API以执行验证、帐户管理、凭证建立、会话管理以及口令更改。
- libpam可以导入主配置文件pam.conf。PAM配置文件可指定每种可用服务的PAM模块要求。pam.conf由系统管理员进行管理。
- libpam可以导入SPI pam_sm,而导出则由服务模块完成。
3. PAM配置
(1)相关文件
- /usr/lib/libpam.so.*
PAM核心库。
- /etc/pam.conf、/etc/pam.d/*
PAM配置文件。
- /usr/lib/security/pam_*.so
可动态加载的PAM service module。
(2)配置管理
1)配置文件的语法
配置文件的语法如下所示:
- 该文件是由规则列表中,每个规则通常是放在同一行,但可能会延长线的转义结束: "<LF>"
- PAM规则对大小写敏感
- 注释前面加上'#'标记,并延伸到线下一个结尾
2)/etc/pam.conf文件的语法
/etc/pam.conf文件的语法如下:
3)/etc/pam.d/目录下的配置文件的语法
/etc/pam.d/目录下的配置文件的语法和/etc/pam.conf文件的语法相似,形式如下:
从Linux-PAM 5.6版开始引入了一种基于目录的配置方式,通过/etc/pam.d/目录下的文件对PAM进行配置。目录下的所有配置文件都以某个服务名命名(小写)。 两种配置方式不能同时起作用,也就是说,你只能使用其中一种对Linux-PAM进行配置,一般/etc/pam.d/优先。
这种配置方式与单一配置文件相比,具有很大的优越性:
- 减少了配置错误的几率
- 更易于维护和软件包的管理
- 可以通过使用不同配置文件的符号连接决定系统的验证策略
- 可以加快对于配置文件的解析
- 可以对单个的Linux-PAM配置文件设置不同的存取权限
(3)配置选项
语法中的各配置选项说明如下:
1)service-name(service)
应用的名字,比如telnet、login、ftp等,服务名字“OTHER”代表所有没有在该文件中明确配置的其它服务。
2)module-type(type)
PAM模块类型有四种:auth、account、session、password,即对应PAM所支持的四种管理方式。同一个服务可以调用多个PAM模块进行认证,这些模块构成一个stack。
- auth 认证管理
接受用户名和密码,进而对该用户的密码进行认证,并负责设置用户的一些秘密信息。
- account 帐户管理
检查帐户是否被允许登录系统,帐号是否已经过期,帐号的登录是否有时间段的限制等等。
- password 密码管理
主要是用来修改用户的密码。
- session 会话管理
主要是提供对会话的管理和记账(accounting)。
3)conflag-flag(control)
- required
表示本模块必须返回成功才能通过认证。但是如果该模块返回失败的话,失败结果也不会立即通知用户,而是要等到同一stack中的所有模块全部执行完毕再将失败结果返回给应用程序。可以认为是一个必要条件。
- requisite
与required类似,该模块必须返回成功才能通过认证。但是一旦该模块返回失败,将不再执行同一stack内的任何模块,而是直 接将控制权返回给应用程序。是一个必 要条件。
注:这种只有RedHat支持,Solaris不支持。
- sufficient
表明本模块返回成功已经足以通过身份认证的要求,不必再执行同一stack内的其它模块,但是如果本模块返回失败的话可以忽略。可以认为是一个充分条件。
- optional
表明本模块是可选的,它的成功与否一般不会对身份认证起关键作用,其返回值一般被忽略。
- binding
4)module-path
用来指明本模块对应的程序文件的路径名,一般采用绝对路径,如果没有给出绝对路径,默认该文件在目录/usr/lib/security下面。
5)arguments(module-arguments)
此处的参数传递给SPI,对应着SPI参数中的argc和argv,是用来传递给该模块的参数。一般来说,每个模块的参数都不相同,可以由该模块的开发者自己定义,但是也有以下几个共同 的参数:
- debug
该模块应当用syslog()将调试信息写入到系统日志文件中。
- no_warn
表明该模块不应把警告信息发送给应用程序。
- use_first_pass
表明该模块不能提示用户输入密码,而应使用前一个模块从用户那里得到的密码。
- try_first_pass
表明该模块首先应当使用前一个模块从用户那里得到的密码,如果该密码验证不通过,再提示用户输入新的密码。
- use_mapped_pass
该模块不能提示用户输入密码,而是使用映射过的密码。
- expose_account
允许该模块显示用户的帐号名等信息,一般只能在安全的环境下使用,因为泄漏用户名会对安全造成一定程度的威胁。
如果对于该服务的操作(如验证或帐户管理),/etc/pam.conf 仅包含一个模块,则该模块的结果将确定操作的结果;如果为服务操作定义了多个模块,那么这些模块就堆叠起来,即对于该服务存在一个PAM 堆栈。
下图说明如何为每种类型的控制标志记录成败信息: