一、PAM的结构
PAM提供了像插槽一样的管理机制,所有的认证服务都像“插销”一样,可以直接插在PAM“插线板”上。
PAM基本思想
1 PAM配置文档(pam.conf和pam.d/*);
2 需要身份认证的服务程序(login、ftp、telnet、ssh);
3 系统身份认证(传统UNIX认证方法、NIS认证方法、NIS+认证方法、Kerberos认证方法)。
二、PAM的文件组成
PAM核心库文件 /usr/lib/libpam.so.*
PAM配置文件 /etc/pam.conf或/ect/pam.d/*
PAM服务模块 /usr/lib/security/pam_*.so
三、它们之间的关系
1系统管理员通过PAM配置文件来制定认证策略,即指定什么服务该采用什么样的认证方法;
2应用程序开发者通过在服务程序中使用PAM API而实现对认证方法的调用;
3而PAM服务模块的开发者则利用PAM SPI来编写认证模块(主要是引出一些函数pam_sm_xxxx( )供libpam调用),将不同的认证机制加入到系统中;
4 PAM核心库(libpam)则读取配置文件,以此为根据将服务程序和相应的认证方法联系起来。
具体关系,如下所示:
四、PAM支持的四种管理界面:
1、认证管理(authentication management)
主要是接受用户名和密码,进而对该用户的密码进行认证,并负责设置用户的一些秘密信息。
2、帐户管理(account management)
主要是检查帐户是否被允许登录系统,帐号是否已经过期,帐号的登录是否有时间段的限制等等。
3、密码管理(password management)
主要是用来修改用户的密码。
4、会话管理(session management)
主要是提供对会话的管理和记账(accounting)。
五、PAM的配置
1 pam.conf;
这种配置方式的语法如下所示:
service-name module-type control-flag module-path arguments
pam.conf文件中每一行的格式如上所示,一条这样的行规定的是某一个或一类的认证方式。pam.conf正是由此种格式的行所组成的认证方式的集合。
1)service-name(服务名称)指的是所要设定的认证方式所对应的服务名称,例如telnet、ftp、login等。其中服务名称“OTHER”代表所有没有在该配置文件中明确设置的其它服务。
2)module-type(模块类型)所提供的模块类型有四种:auth、account、session和password,即对应PAM所支持的四种管理方式,认证管理、账户管理、会话管理和密码管理。同一个服务(service-name)可以调用多个PAM模块进行认证,这些模块构成一个堆栈。
3)control-flag(控制标记)可以支持四种控制标记,分别为:requisite、required、sufficient和optional。控制标记用来告诉PAM库该如何处理与该服务相关的认证成功或失败情况。
required 表示本模块必须返回成功才能通过认证,但是如果该模块返回失败的话,失败结果也不会立即通知用户,而是要等到同一堆栈中的所有模块全部执行完毕再将失败结果返回给应用程序。可以认为是一个必要条件。
requisite 与required类似,该模块必须返回成功才能通过认证。二者不同之处在于,一旦该模块返回失败,将不再执行同一stack内的任何模块,而是直接将控制权返回给应用程序。是一个必要条件。
sufficient 表明本模块返回成功已经足以通过身份认证的要求,不必再执行同一堆栈内的其它模块,但是如果本模块返回失败的话可以忽略。可以认为是一个充分条件。
optional表明本模块是可选的,它的成功与否一般不会对身份认证起关键作用。它的执行结果不影响其他命令的执行,也不影响PAM报告的结果,其返回值一般被忽略。
4)module-path(模块路径)代表PAM验证模块的路径。如果以“/”开头,就表示是完整的路径;如果不是以“/”打头,就表示是相对于“/usr/lib/security”的相对路径。
5)arguments(参数)表示传递给模块的参数,此部分为可选项,如果不需要传递任何参数则可以忽略此项。
2 pam.d/*;
此种配置方法与上一中基本类似,其语法为:
module-type control-flag module-path arguments
与上一中配置方法的语法相比,此种配置方法语法缺少了“service-name”部分,那么如何为某种服务指定其配置方法呢?从图2-2中可以看出,此种配置方法的服务名称即为每个文件的名称,加入需要为“login”服务设置认证方式,那么只需要在此目录下创建“login”文件,并对其进行设置即可。词语法中的各个字段配置方法与“pam.conf”完全相同。需要注意的是,此种配置方法的优先级要比上一中配置方法的优先级要高。比如,在“pam.d”目录下配置了“login”服务,那么它将覆盖掉“pam.conf”中对“login”服务的设置。
3 配置的例子;
例一:用/etc/pam.conf配置默认的认证方式。
下面的例子将拒绝所有没有在/etc/pam.conf中明确配置的服务。OTHER代表没有明确配置的其它所有服务,pam_deny模块的作用只是简 单地拒绝通过认证。
OTHER auth required /usr/lib/security/pam_deny.so
OTHER account required /usr/lib/security/pam_deny.so
OTHER password required /usr/lib/security/pam_deny.so
OTHER session required /usr/lib/security/pam_deny.so
例二:通过/etc/pam.d/rsh文件配置rsh服务的认证方式。
rsh服务认证用户时,先使用/etc/hosts.equiv和.rhosts文件的认证方式,然后再根据/etc/nologin文件的存在与否来判断是否允许该用户使用 rsh,最后使用password database来认证用户。
auth required /lib/security/pam_rhosts_auth.so
auth required /lib/security/pam_nologin.so
account required /lib/security/pam_pwdb.so
session required /lib/security/pam_pwdb.so
例三:通过/etc/pam.conf配置ftpd的认证方式。
下面是ftpd服务利用PAM模块进行用户认证的三个步骤。首先用pam_ftp模块检查当前用户是否为匿名用户,如果是匿名用户,则 sufficient控制标志表明无需再进行后面的认证步骤,直接通过认证;否则继续使用pam_unix_auth模块来进行标准的unix认证,即用/etc/ passwd和/etc/shadow进行认证;通过了pam_unix_auth模块的认证之后,还要继续用pam_listfile模块来检查该用户是否出现在文件/etc/ ftpusers中,如果是则该用户被deny掉。
ftpd auth sufficient /usr/lib/security/pam_ftp.so
ftpd auth required /usr/lib/security/pam_unix_auth.so use_first_pass
ftpd auth required /usr/lib/security/pam_listfile.so /onerr=succeed item=user sense=deny file=/etc/ftpusers
六、密码映射(password-mapping)
密码映射允许用户在不同的认证机制下使用不同的密码,其中有一个主密码(primary password),其它密码为次密码(secondary passwords,可能有多个)。主密码用来对次密码进行加密。在主密码认证通过后,认证模块利用主密码将加密过的次密码(也称为 mapped password)解密,并对次密码进行认证。
注:如果使用了一次性密码的机制,就不使用密码映射。
所有服务模块必须支持如下4个映射选项(在第四部分已经简单解释过):
1、use_first_pass
这个选项指示本模块不能提示用户输入密码,而是使用已有的密码,即从第一个向用户提示输入密码的模块那里取得密码,并对该密码进 行认证。
2、try_first_pass
这个选项指示本模块首先尝试使用已有的密码,即从第一个向用户提示输入密码的模块那里取得密码,并对该密码进行认证。如果密码认 证失败,则再提示用户输入密码。
3、use_mapped_pass
这个选项指示本模块不能向用户提示输入密码,而应使用映射过的密码,即利用主密码将加密过的次密码解密出来并进行认证。
4、try_mapped_pass
这个选项指示本模块首先尝试使用映射过的密码,即利用主密码将加密过的次密码解密出来并进行认证。如果密码认证失败,则再提示用 户输入密码。
密码映射的例子:
下面是/etc/pam.conf中关于login服务的配置。
这里login共有3种认证机制:Kerberos、UNIX和RSA认证,两个required控制标志表明用户必须通过Kerberos认证和UNIX认证才能使用login服务,optional选项则说明RSA认证是可选的。
首先用户输入主密码进行Kerberos认证;use_mapped_pass选项指示UNIX认证模块利用主密码将用于UNIX认证的次密码解密出来并对该次密码进行认证;try_first_pass选项 指示RSA认证模块先使用第一个模块(即Kerberos模块)的密码作为进行认证的密码,当对该密码认证失败时才提示用户输入用于RSA认 证的次密码。
login auth required pam_kerb_auth.so debug
login auth required pam_unix_auth.so use_mapped_pass
login auth optional pam_rsa_auth.so try_first_pass
七、PAM API
1、框架API:
任何一个支持PAM的服务程序在进行认证时必须以pam_start( )开始进行初始化,最后以pam_end( )结束以便进行清理工作。
2、认证管理API:
pam_authenticate( )对用户名/密码进行认证。
pam_setcred( )用来修改用户的秘密信息。
3、帐户管理API:
pam_acct_mgmt( )检查帐户本身是否有权限登录系统、帐户是否过期、帐户是否有登录时间限制等。
4、密码管理API:
pam_chauthtok( )修改用户的密码。
5、会话管理API:
一个会话以pam_open_session( )开始,最后以pam_close_session( )结束。
6、其它:
pam_get_item( )、pam_set_item( )用来读写PAM事务(transaction)的状态信息。
pam_get_data( )、pam_set_data( )用来取得和设置PAM模块及会话的相关信息。
pam_putenv( )、pam_getenv( )、pam_getenvlist( )用来读写环境变量。
pam_strerror( )返回相关的错误信息。
例子程序(摘自Sun的白皮书):
下面的例子使用PAM API写了一个简单的login服务程序(注:这不是个完整的程序,所以省略了对pam_close_session的调用)。
见pam_api_sample文件
八、PAM SPI
当服务程序(ftpd、telnetd等)调用PAM API函数pam_xxx( )时,由PAM 框架(libpam)根据该服务在/etc/pam.conf文件中的配置调用指 定的PAM模块中对应的SPI函数pam_sm_xxx()。如下:API函数的名字为pam_xxx( ),对应的SPI函数的名字为pam_sm_xxx( ),即每个服务模块需要引出相应的函数以供libpam调用。为方便对 照,再列一下。
API 对应的 SPI
帐号管理 pam_acct_mgmt( ) pam_sm_acct_mgmt( )
认证管理 pam_authenticate( ) pam_ sm_authenticate( )
密码管理 pam_chauthtok( ) pam_ sm_chauthtok( )
会话管理 pam_open_session( ) pam_ sm_open_session( )
会话管理 pam_close_session( ) pam_ sm_close_session( )
认证管理 pam_setcred( ) pam_ sm_setcred( )
九、常用的PAM服务模块
下面是Linux提供的PAM模块列表(只是其中一部分):
模块名称 | 所属类型 | 模块功能描述 | 相关配置文件 |
pam_access | account | 提供logdaemon风格的登录控制 | /etc/security/access.conf |
pam_chroot | account,session,auth | 提供类似chroot命令的功能 | |
pam_cracklib | password | 对密码的强度进行一定的检查 | 库文件libcrack和字典文件/usr/lib/cracklib_dict |
pam_deny | account,session,auth | 总是无条件地使认证失败 | |
pam_env | auth | 设置或取消环境变量 | /etc/security/pam_env.conf |
pam_filter | account,session,auth,password | 对输入输出流进行过滤filters | |
pam_ftp | Auth | 对匿名ftp用户进行认证 | |
pam_group | auth | 当用户在指定的终端上请求指定的服务时赋予该用户相应的组权限 | /etc/security/group.conf |
pam_issue | Auth | 在提示用户输入用户名之前显示/etc/issue | /etc/issue文件的内容 |
pam_krb4 | auth | 对用户密码进行Kerberos认证 | 相应的Kerberos库文件 |
pam_lastlog | auth | 在用户登录成功后显示关于用户上次登录的信息,并维护/var/log/lastlog文件。 | /var/log/lastlog |
pam_limits | session | 限制用户会话所能使用的系统资源 | /etc/security/limits.conf |
pam_listfile | Auth | 根据指定的某个文件决定是否允许或禁止提供服务 | 例如/etc/ftpusers |
pam_mail | Auth,session | 检查用户的邮箱中是否有新邮件 | /var/spool/mail/xxxx |
pam_mkhomedir | session | 为用户建立主目录 | /etc/skel/ |
pam_moud | session | 显示/etc/motd文件的内容 | /etc/motd |
pam_nologin | auth | 根据/etc/nologin文件的存在与否来决定用户认证是否成功 | /etc/nologin |
pam_permit | Account,auth,password,session | 总是无条件地使认证成功 | |
pam_pwdb | Account,auth,password,session | 作为pam_unix_xxxx模块的一个替代使用Password Database通用接口进行认证。 | /etc/pwdb.conf |
pam_rhosts_auth | auth | 利用文件~/.rhosts和 /etc/hosts.equiv和~/.rhosts/etc/hosts.equiv对用户进行认证。 | |
pam_rootok | auth | 检查用户是否为超级用户,如果是超级用户则无条件地通过认证。 | |
pam_securetty | auth | 提供标准的Unix securetty检查 /etc/securetty | |
pam_time | account | 提供基于时间的控制,比如限制用户只能在某个时间段内才能登录 | /etc/security/time.conf |
pam_unix | auth | 提供标准的Unix认证 | /etc/passwd和 /etc/shadow |
pam_userdb | auth | 利用Berkeley DB数据库来检查Berkeley DB用户/密码 | |
pam_warn | Auth,password | 利用syslog( )记录一条告警信息 | |
pam_wheel | auth | 只允许wheel组的用户有超级用户的存取权限 |
参考资料:
1、《Linux服务器安全策略详解》
2、The Linux-PAM System Administrators’ Guide
3、http://doc.linuxpk.com/5209.html
4、《信息安全系统概论》 石文昌等 电子工业出版社