linux pam
PAM的工作原理与流程:
以RHEL系统为例,当pam安装之后有两大部分:在/lib/security目录下的各种pam模块以及/etc/pam.d和/etc/pam.d目录下的针对各种服务和应用已经定义好的pam配置文件。当某一个有认证需求的应用程序需要验证的时候,一般在应用程序中就会定义负责对其认证的PAM配置文件。以vsftpd为例,在它的配置文件/etc/vsftpd/vsftpd.conf中就有这样一行定义:
pam_service_name=vsftpd
表示登录FTP服务器的时候进行认证是根据/etc/pam.d/vsftpd文件定义的内容进行。
那么,当程序需要认证的时候已经找到相关的pam配置文件,认证过程是如何进行的?下面我们将通过解读/etc/pam.d/system-auth文件予以说明。
首先要声明一点的是:system-auth是一个非常重要的pam配置文件,主要负责用户登录系统的认证工作。而且该文件不仅仅只是负责用户登录系统认证,其它的程序和服务通过include接口也可以调用到它,从而节省了很多重新自定义配置的工作。所以应该说该文件是系统安全的总开关和核心的pam配置文件。
下面是/etc/pam.d/system-auth文件的全部内容:
# grep -v ^# /etc/pam.d/system-auth auth required pam_env.so auth sufficient pam_unix.so nullok try_first_pass auth requisite pam_succeed_if.so uid >= 500 quiet auth required pam_deny.so account required pam_unix.so account sufficient pam_succeed_if.so uid < 500 quiet account required pam_permit.so password requisite pam_cracklib.so try_first_pass retry=3 password sufficient pam_unix.so md5 shadow nullok try_first_pass use_authtok password required pam_deny.so session optional pam_keyinit.so revoke session required pam_limits.so session [success=1 default=ignore] pam_succeed_if.so service in crond quiet use_uid session required pam_unix.so
第一部分表示,当用户登录的时候,首先会通过auth类接口对用户身份进行识别和密码认证。所以在该过程中验证会经过几个带auth的配置项。
其中的第一步是通过pam_env.so模块来定义用户登录之后的环境变量, pam_env.so允许设置和更改用户登录时候的环境变量,默认情况下,若没有特别指定配置文件,将依据/etc/security/pam_env.conf进行用户登录之后环境变量的设置。
然后通过pam_unix.so模块来提示用户输入密码,并将用户密码与/etc/shadow中记录的密码信息进行对比,如果密码比对结果正确则允许用户登录,而且该配置项的使用的是“sufficient”控制位,即表示只要该配置项的验证通过,用户即可完全通过认证而不用再去走下面的认证项。不过在特殊情况下,用户允许使用空密码登录系统,例如当将某个用户在/etc/shadow中的密码字段删除之后,该用户可以只输入用户名直接登录系统。
下面的配置项中,通过pam_succeed_if.so对用户的登录条件做一些限制,表示允许uid大于500的用户在通过密码验证的情况下登录,在Linux系统中,一般系统用户的uid都在500之内,所以该项即表示允许使用useradd命令以及默认选项建立的普通用户直接由本地控制台登录系统。
最后通过pam_deny.so模块对所有不满足上述任意条件的登录请求直接拒绝,pam_deny.so是一个特殊的模块,该模块返回值永远为否,类似于大多数安全机制的配置准则,在所有认证规则走完之后,对不匹配任何规则的请求直接拒绝。
第二部分的三个配置项主要表示通过account账户类接口来识别账户的合法性以及登录权限。
第一行仍然使用pam_unix.so模块来声明用户需要通过密码认证。第二行承认了系统中uid小于500的系统用户的合法性。之后对所有类型的用户登录请求都开放控制台。
第三部分会通过password口另类接口来确认用户使用的密码或者口令的合法性。第一行配置项表示需要的情况下将调用pam_cracklib来验证用户密码复杂度。如果用户输入密码不满足复杂度要求或者密码错,最多将在三次这种错误之后直接返回密码错误的提示,否则期间任何一次正确的密码验证都允许登录。需要指出的是,pam_cracklib.so是一个常用的控制密码复杂度的pam模块,关于其用法举例我们会在之后详细介绍。之后带pam_unix.so和pam_deny.so的两行配置项的意思与之前类似。都表示需要通过密码认证并对不符合上述任何配置项要求的登录请求直接予以拒绝。不过用户如果执行的操作是单纯的登录,则这部分配置是不起作用的。
第四部分主要将通过session会话类接口为用户初始化会话连接。其中几个比较重要的地方包括,使用pam_keyinit.so表示当用户登录的时候为其建立相应的密钥环,并在用户登出的时候予以撤销。不过该行配置的控制位使用的是optional,表示这并非必要条件。之后通过pam_limits.so限制用户登录时的会话连接资源,相关pam_limit.so配置文件是/etc/security/limits.conf,默认情况下对每个登录用户都没有限制。关于该模块的配置方法在后面也会详细介绍。
可见,不同应用程序通过配置文件在认证过程中调用不同的pam模块来定制具体的认证流程。其中我们不难看出,其实可以根据实际的需要对pam的配置文件进行修改以满足不同的认证需求,例如下面的例子:
#%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_tally.so onerr=fail deny=5 auth sufficient pam_unix.so nullok try_first_pass auth requisite pam_succeed_if.so uid >= 500 quiet auth required pam_deny.so account required pam_unix.so account sufficient pam_succeed_if.so uid < 500 quiet account required pam_permit.so password requisite pam_cracklib.so try_first_pass retry=3 minlen=10 lcredit=-1 ucredit=-1 dcredit=-1 ocredit=-1 difok=6 password requisite pam_passwdqc.so use_first_pass enforce=everyone password sufficient pam_unix.so md5 remember=6 shadow nullok try_first_pass use_authtok password required pam_deny.so session optional pam_keyinit.so revoke session required pam_limits.so session [success=1 default=ignore] pam_succeed_if.so service in crond quiet use_uid session required pam_unix.so
在其中就增加了对用户密码修改时复杂度的限制,用户多次错误输入密码之后的锁定限制以及用户使用密码历史等限制选项。
所以我们通过对上述system-auth配置文件的修改,模块的增加和选项的变化,从很大的程度上增加了用户登录验证的安全性要求。我们会在之后的文章中对该配置进行详细说明。
另外也一定需要注意,在整个的PAM配置文件当中,配置项以及模块调用的逻辑顺序非常关键。因为PAM是按照配置项的先后顺序来进行验证。错误的模块调用顺序很可能导致严重的安全问题甚至系统错误。所以对PAM配置进行修改的时候务必要考虑这一点。
http://www.infoq.com/cn/articles/linux-pam-one
浙公网安备 33010602011771号