PAM(Pluggable Authentication Modules)即可插拔式认证模块,它是一种高效而且灵活便利的用户级别的认证方式,它也是当前Linux服务器普遍使用的认证方式。当然,在不同版本的Linux统中部署PAM认证是有所不同的,本文将以RHEL4版本为例进行解析。
1.部署PAM认证的必要性
我们知道一台Linux服务器会开许多不同的服务,这些服务中很多服务本身并没有认证功能,只是把认证交给用户名及密码。如果这样的话,那么所有服务都用Linux系统的用户名及密码来认证,对于服务器来说是很危险的。比如一台服务器开着FTP、SMTP、SSH等服务,那么新建一个用户默认就享有对以上的服务的操作权限,那么如果一个用户的帐号密码泄露会涉及到多个服务。因此,不管是PC还是服务器在类Linux系统中部署PAM认证是非常必要的。通过新型的认证模块——PAM就能解决认证方面的不足,加强Linux系统安全。
2.PAM认证的方式
PAM认证一般遵循这样的顺序:Service(服务)→PAM(配置文件)→PAM_*.so。PAM认证首先要确定那一项服务,然后加载相应的PAM的配置文件(位于/etc/PAM.d下),最后调用认证文件(位于/lib/security下)进行安全认证。通常情况下,在Linux系统安装完成后会在/etc/PAM.d路径下为我们提供了一些默认的配置文件。另外,大家要知道/lib/security目录是认证文件的默认存放位置。/etc/PAM.d路径下的默认配置文件是我们进行PAM配置的模板,通常情况下我们根据安全需要对于进行修改或者添加相应的项即可。
3.PAM认证的构成,PAM模块
客观地说PAM认证还是比较复杂的,简单地讲它包括四种常见认证类型(module type):即auth认证管理、account用户管理、password密码认证管理、session会话管理。以/etc/PAM.d/login为例,我们可以看到它的配置文件,区域1中的auth、account、password、session等都是认证类型。区域2中的required、 requisite 、sufficient 、optional是认证的流程控制。最后面的区域3就是认证的PAM文件了。(图2)
4.PAM认证的流程
为了便于大家深入了解PAM认证的流程,我们以验证用户登录的PAM-login为例进行说明。PAM认证流程是从行首验证到行尾,逐条认证。比如用户登录服务器,共有十条auth类型认证,假设第一条认证失败,一般情况后九条也必须要认证。为什么就一般情况呢?其实还有非一般情况。那么这个用户动作成功与否是要看auth认证后面的区域2是怎么处理的。在图2中看到处理字段有required和optional,其中required代表认证必须通过,也就是说,无论成功多少条语句,只要失败一条,那么认证就失败。在图2中看到的区域3就是认证的模块了,第二行中的“PAM_securetty.so”就是这个文件。在RHEL中,认证多是用相对路径。
5.PAM认证测试
PAM_securetty.so是一个认证模块文件,该认证模块只对root用户有效,当root登录系统时,会查看有没有安全终端,安全终端就是/etc/securetty文件里的东西,比如你运行“W”命令看到TTY下面的东西就是安全终端。如果有安全终端就通过认证,否则失败。有些管理员为了安全,不让root用户直接登录,他会把/etc/securetty文件清代空,这就保证了在有root密码时,也不能够在本地登录。
为了以下的实验方便,能看出效果来,我们把“auth required PAM_securetty.so”这条认证加入SSH服务的PAM模块谁文件里(/etc/PAM.d/sshd)的第一行,目的就是让SSH服务应用这条认证。大家可在控制台窗口中执行“vi etc/PAM.d/sshd”然后添加这条认证语句。同样的道理,如果把这条语句加到login文件(默认这条认证是被注销掉的,我们取消前面的#就可以了),控制的是从本地控制台登录,同样的话如果把这条语句加入到sshd文件内,那么它将控制的是从远程登录服务器22端口的过程。
下面我们试着SSH登录系统看看效果,在控制台中执行命令“ssh -l root localhost”,可以看到无论我们的root用户的密码正确与否都无法通过SSH远程登录到系统,可见上面的认证已经生效。在一般情况下,为了服务器的安全,大家通过PAM认证拒绝root远程登录系统。 (图4)
6.PAM认证的处理方式
了解了认证类型的工作方式,我们还应该深入的理解认证的处理方式,在图2中看到,它的认证处理方式是required,表示这一模块的认证是必须成功的,但如果失败,认证过程不会即刻终止,PAM将继续下一个同类型认证。上面“PAM_securetty.so”认证失败了,但认证并没有结束,认证的“指针”还在向下走。如图4中所示,在root用户SSH登录认证失败的前提下还提示用户输入密码,虽然认证不可能成功。
处理过程中除了required,还有requisite、sufficient和optional,我们再来看看requisite的效果。还用SSH服务为例,把/etc/PAM.d/sshd文件第一行中的“auth required PAM_securetty.so”改成“auth requisite PAM_securetty.so”。再次尝试登录,发现和图4没有什么差别,也是输入3次密码后被拒绝了。但是细心的读者如果一边看文章一边尝试着实验的话,你会发现当你在输入密码时,用required反应的速度要慢一些,并且在系统日志中是没有记录的,认证同样是失败的。这说明required和requisite类似的地方是认证必须通过,而不同的是如果失败,认证过程将立即终止,不会去认证下面的条目。(图5)
7.限制root登录控制台
我们修改用/etc/PAM.d/login来限制root登录控制台,打开login文件删除第二行中的#,取消对“auth required PAM_securetty.so”的注销。然后我们本地登录服务器,通过测试我们发现当用required时,你在输入root及密码后,你得到了一个拒绝信息,用requisite时,当你输入root回车时同样会得到拒绝信息登录失败,这是由刚才的认证方式触发的。
8.PAM认证可选模块
在PAM认证中,sufficient表示如果认证成功,那么对这一类型的模块认证是充足的了,其他的同类模块将不会再检验,当认证失败,它会进行下一条认证,如果下面同类型的认证成功,结果依然成功。optional表示这一模块认证是可选的,也不会对认证成功或失败产生影响,这个就比较危险了。比如我们在/etc/PAM.d/sshd文件内加入“auth required/lib/security/PAM_listfile.so item=user sense=allow file=/etc/sshusers onerr=succeed”其含义是只允许出现在/etc/sshuser文件内的用户远程登录。然后我们执行命令“ssh -l root localhost”,当sshusers文件没有root用户时候,登录失败,很明显他被PAM模块拒绝了。那么我们改一下认证文件,将required改成sufficient,尝试再次登录,结果成功登录。
总结:PAM认证是Linux服务器系统最主要的安全认证模式,掌握PAM认证对于加强系统安全非常重要。本文结合理论与实践对PAM认证做了一定的分析,实际上关于PAM认证是一个大课题,希望以后有机会和大家进一步分享基于PAM认证的Linux系统安全技巧和经验。
备注:
服务
每个使用PAM的程序定义它自己的服务名称。login程序定义其服务类型为login,ftpd程序定义其服务类型为ftp,等等。一般来说,服务类型就是存取该服务的程序的名字,而不是提供服务的程序。
配置文件
目录/etc/pam.d被用来配置所有的PAM应用程序。(在早期的PAM版本中用的是 /etc/pam.conf;但是若/etc/pam.d不存在的话,仍旧会找/etc/pam.conf,不过记住,这是一个过时的文件。)。每一个应用程序(确切的说是服务)都有它自己的配置文件。
一个真实的文件可能如下:
#%PAM-1.0 auth required /lib/security/pam_securetty.so auth required /lib/security/pam_pwdb.so shadow nullok auth required /lib/security/pam_nologin.so account required /lib/security/pam_pwdb.so password required /lib/security/pam_cracklib.so password required /lib/security/pam_pwdb.so shadow nullok use_authtok session required /lib/security/pam_pwdb.so
第一行是注释。任何以#开头的行都是注释。以下的三行排列着用于login认证的三个模块其中第一行用以确认用户是否以root登入,允许登入的tty被列在文件/etc/securetty 中(如果文件存在的话)第二行将会使用户被提示输入口令并校验口令。第三行表示查文件/etc/nologin是否存在,如果存在就显示其内容,而且如果用户不是root,则禁止其登入。即便第一个模块失败了,也要完成三个模块的校验。这是一种安全上的考虑 ---这种设计永远不要让用户知道他或她们为什么会被拒绝,否则会让其更容易突破认证。您可以将“required”改成“requisite”来修改这种认证方式。也就是说,如果有任何“requisite”模块以失败返回,整个PAM认证将终止再调用其它模块也以失败返回。第五行表示任何必要的记帐信息要被记载。例如,如果设置使用影子口令,pam_db.so 模块将被执行以检查该帐户是否失效或者用户口令是否超期而需要修改。第六行(该行需要折行来写)用以指定如果login程序改变用户的口令,它应当使用 pam_pwdb.so来完成。(这仅在auth模块检测到口令需要被改变时,例如一个影子口令已经过期时才使用)最后一行表示pam_pwdb.so模块将被用来管理当前的会话过程。而目前该模块什么也不做;它可以被替换为别的所需的模块。要注意配置文件中每一行的顺序不是任意的。尽管required模块以什么顺序被调用并没有多大关系,但是还有其它一些控制符,其中optional很少在红帽子LINUX中使用,而 sufficient 和requisite就要求行的顺序不能颠倒。
让我们来看一下rlogin的认证配置:
auth required /lib/security/pam_securetty.so auth sufficient /lib/security/pam_rhosts_auth.so auth required /lib/security/pam_pwdb.so shadow nullok auth required /lib/security/pam_nologin.so
这和login的描述极为相似,但是其中比login的多一行模块描述,而且模块的顺序也不同。首先,pam_securetty.so模块将禁止以root从不安全的终端登入。这将有效的阻止任何root方式的远程登入。如果您不想禁止的话(在这种情况下,我们建议您的机器要么没和Internet 相连,要么呆在一个配置良好的防火墙后面),把这一行删掉就是了。其次,pam_nologin.so 模块将检查/etc/nologin,如上所述。第三点,如果pam_rhosts_auth.so模块认证通过,PAM就立即以成功返回而不再做任何口令校验。如果pam_rhosts_auth.so认证失败,该失败将被忽略,继续调用pam_pwdb.so模块进行正常的口令认证。如果您在securetty认证失败后不想让系统继续以口令询问的话,您可以把pam_securetty.so模块的required 改为 requisite。
参考: http://os.51cto.com/art/200909/151949.htm
http://os.51cto.com/art/200512/13544.htm