Linux-PAM

来源:互联网 发布:js中string转date 编辑:程序博客网 时间:2024/05/16 08:52
PAM(Pluggable Authentication Modules )是由Sun提出的一种认证机制。它通过提供一些
动态链接库和一套统一的API,将系统提供的服务 和该服务的认证方式分开,使得系统管理
员可以灵活地根据需要给不同的服务配置不同的认证方式而无需更改服务程序,同时也便于
向系 统中添加新的认证手段。
PAM最初是集成在Solaris中,目前已移植到其它系统中,如Linux、SunOS、HP-UX 9.0等。

一、PAM的结构

PAM的整个框架结构如下图所示:


系统管理员通过PAM配置文件来制定认证策略,即指定什么服务该采用什么样的认证方法;应
用程序开发者通过在服务程序中使用PAM API而实现对认证方法的调用;而PAM服务模块(se
rvice module)的开发者则利用PAM SPI(Service Module API)来编写认证模块(主 要是
引出一些函数pam_sm_xxxx( )供libpam调用),将不同的认证机制(比如传统的UNIX认证方
法、Kerberos等)加入到系统中;PAM核 心库(libpam)则读取配置文件,以此为根据将服
务程序和相应的认证方法联系起来。
二、PAM支持的四种管理界面:

1、认证管理(authentication management)
主要是接受用户名和密码,进而对该用户的密码进行认证,并负责设置用户的一些秘密
信息。
2、帐户管理(account management)
主要是检查帐户是否被允许登录系统,帐号是否已经过期,帐号的登录是否有时间段的
限制等等。
3、密码管理(password management)
主要是用来修改用户的密码。
4、会话管理(session management)
主要是提供对会话的管理和记账(accounting)。

三、PAM的文件:

/usr/lib/libpam.so.* PAM核心库
/etc/pam.conf或者/etc/pam.d/ PAM配置文件
/usr/lib/security/pam_*.so 可动态加载的PAM service module
对于RedHat,其目录不是/usr/lib,而是/lib。

四、PAM的配置:

PAM的配置是通过单个配置文件/etc/pam.conf。RedHat还支持另外一种配置方式,即通过配
置目录/etc/pam.d/,且这种的优先级要高于单 个配置文件的方式。

1、使用配置文件/etc/pam.conf

该文件是由如下的行所组成的:
service-name module-type control-flag module-path arguments

service-name 服务的名字,比如telnet、login、ftp等,服务名字“OTHER”代表所有没有
在该文件中明确配置的其它服务。
module-type 模块类型有四种:auth、account、session、password,即对应PAM所支持的
四种管理方式。同一个服务可以调用多个 PAM模块进行认证,这些模块构成一个stack。
control-flag 用来告诉PAM库该如何处理与该服务相关的PAM模块的成功或失败情况。它有四
种可能的 值:required,requisite,sufficient,optional。
required 表示本模块必须返回成功才能通过认证,但是如果该模块返回失败的话,失败
结果也不会立即通知用户,而是要等到同一stack 中的所有模块全部执行完毕再将失败结果
返回给应用程序。可以认为是一个必要条件。
requisite 与required类似,该模块必须返回成功才能通过认证,但是一旦该模块返回
失败,将不再执行同一stack内的任何模块,而是直 接将控制权返回给应用程序。是一个必
要条件。注:这种只有RedHat支持,Solaris不支持。
sufficient 表明本模块返回成功已经足以通过身份认证的要求,不必再执行同一stack
内的其它模块,但是如果本模块返回失败的话可以 忽略。可以认为是一个充分条件。
optional表明本模块是可选的,它的成功与否一般不会对身份认证起关键作用,其返回
值一般被忽略。
对于control-flag,从Linux-PAM-0.63版本起,支持一种新的语法,具体可参看Linux
PAM文档。
module-path 用来指明本模块对应的程序文件的路径名,一般采用绝对路径,如果没有给出
绝对路径,默认该文件在目录/usr/lib/security下 面。
arguments 是用来传递给该模块的参数。一般来说每个模块的参数都不相同,可以由该模块
的开发者自己定义,但是也有以下几个共同 的参数:
debug 该模块应当用syslog( )将调试信息写入到系统日志文件中。
no_warn 表明该模块不应把警告信息发送给应用程序。
use_first_pass 表明该模块不能提示用户输入密码,而应使用前一个模块从用户那里
得到的密码。
try_first_pass 表明该模块首先应当使用前一个模块从用户那里得到的密码,如果该
密码验证不通过,再提示用户输入新的密码。
use_mapped_pass 该模块不能提示用户输入密码,而是使用映射过的密码。
expose_account 允许该模块显示用户的帐号名等信息,一般只能在安全的环境下使用
,因为泄漏用户名会对安全造成一定程度的威 胁。

2、使用配置目录/etc/pam.d/(只适用于RedHat Linux)

该目录下的每个文件的名字对应服务名,例如ftp服务对应文件/etc/pam.d/ftp。如果名为x
xxx的服务所对应的配置文件/etc/pam.d/xxxx不存 在,则该服务将使用默认的配置文件/et
c/pam.d/other。每个文件由如下格式的文本行所构成:
module-type control-flag module-path arguments
每个字段的含义和/etc/pam.conf中的相同。

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/ passw
d和/etc/shadow进行认证;通过了pam_unix_auth模块的认证之后,还要继续用pam_listfil
e模块来检查该用户是否出现在文件/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/ftpuser
s

五、密码映射(password-mapping)

密码映射允许用户在不同的认证机制下使用不同的密码,其中有一个主密码(primary pass
word),其它密码为次密码(secondary passwords,可能有多个)。主密码用来对次密码进
行加密。在主密码认证通过后,认证模块利用主密码将加密过的次密码(也称为 mapped pa
ssword)解密,并对次密码进行认证。
注:如果使用了一次性密码的机制,就不使用密码映射。

所有服务模块必须支持如下4个映射选项(在第四部分已经简单解释过):

1、use_first_pass

这个选项指示本模块不能提示用户输入密码,而是使用已有的密码,即从第一个向用户提示
输入密码的模块那里取得密码,并对该密码进 行认证。

2、try_first_pass

这个选项指示本模块首先尝试使用已有的密码,即从第一个向用户提示输入密码的模块那里
取得密码,并对该密码进行认证。如果密码认 证失败,则再提示用户输入密码。

3、use_mapped_pass

这个选项指示本模块不能向用户提示输入密码,而应使用映射过的密码,即利用主密码将加
密过的次密码解密出来并进行认证。

4、try_mapped_pass

这个选项指示本模块首先尝试使用映射过的密码,即利用主密码将加密过的次密码解密出来
并进行认证。如果密码认证失败,则再提示用 户输入密码。

密码映射的例子:

下面是/etc/pam.conf中关于login服务的配置。这里login共有3种认证机制:Kerberos、UN
IX和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的调用)。

#include <security/pam_appl.h>

/* 回调函数 */
static int login_conv(int num_msg, struct pam_message **msg, struct pam_response
**response, void *appdata_ptr);
struct pam_conv pam_conv = {login_conv, NULL};
pam_handle_t *pamh; /* 进行认证的PAM句柄 */

void main(int argc, char *argv[], char **renvp)
{
/* 初始化,并提供一个回调函数 */
if ((pam_start("login", user_name, &pam_conv, &pamh)) != PAM_SUCCESS)
login_exit(1);

/* 设置一些参数 */
pam_set_item(pamh, PAM_TTY, ttyn);
pam_set_item(pamh, PAM_RHOST, remote_host);

while (!authenticated && retry < MAX_RETRIES)
{
status = pam_authenticate(pamh, 0); /* 密码认证管理,检查用户输入
的密码是否正确 */
authenticated = (status == PAM_SUCCESS);
}

if (status != PAM_SUCCESS)
{
fprintf(stderr,"error: %s ", pam_strerror(pamh, status)); /* 显示错误原
因 */
login_exit(1);
}

/* 通过了密码认证之后再调用帐户管理API,检查用户帐号是否已经过期 */
if ((status = pam_acct_mgmt(pamh, 0)) != PAM_SUCCESS)
{
if (status == PAM_AUTHTOK_EXPIRED)
{
status = pam_chauthtok(pamh, 0); /* 过期则要求用户更改密码 */
if (status != PAM_SUCCESS)
login_exit(1);
}
}

/* 通过帐户管理检查之后则打开会话 */
if (status = pam_open_session(pamh, 0) != PAM_SUCCESS)
login_exit(status);

/* 设置用户组 */
setgid(pwd->pw_gid);

/*
* Initialize the supplementary group access list before
* pam_setcred because PAM modules might add groups
* during the pam_setcred call
*/
initgroups(user_name, pwd->pw_gid);

status = pam_setcred(pamh, PAM_ESTABLISH_CRED);
if (status != PAM_SUCCESS)
login_exit(status);

/* 设置真实的用户ID(或者有效的用户ID)*/
setuid(pwd->pw_uid);

pam_end(pamh, PAM_SUCCESS); /* PAM事务的结束 */


/*
此处可用来实现与login有关的其它内容
*/
}

/* 出错则清理现场并退出 */
static void login_exit(int exit_code)
{
if (pamh)
pam_end(pamh, PAM_ABORT);
exit(exit_code);
}


/* 这个回调函数被PAM认证模块调用以便显示错误信息或者或者用来取得用户输入,采用图
形界面的服务程序则应使用图形界面来取得 用户输入或显示提示信息*/
int login_conv(int num_msg, struct pam_message **msg, struct pam_response **resp
onse, void *appdata_ptr)
{
while (num_msg--)
{
switch (m->msg_style)
{
case PAM_PROMPT_ECHO_OFF:
r->resp = strdup(getpass(m->msg));
break;
case PAM_PROMPT_ECHO_ON:
(void) fputs(m->msg, stdout);
r->resp = malloc(PAM_MAX_RESP_SIZE);
fgets(r->resp, PAM_MAX_RESP_SIZE, stdin);
/* add code here to remove from fputs */
break;
case PAM_ERROR_MSG:
(void) fputs(m->msg, stderr);
break;
case PAM_TEXT_INFO:
(void) fputs(m->msg, stdout);
break;
default:
log_error();
break;
}
}
return (PAM_SUCCESS);
}

七、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 提供logdaemon风格的登录控制 /etc/security/access.conf

pam_chroot 提供类似chroot命令的功能


pam_cracklib 对密码的强度进行一定的检查 库文件libcrack和字典文件
/usr/lib/cracklib_dict

pam_deny 总是无条件地使认证失败

pam_env 设置或取消环境变量 /etc/security/pam_env.conf

pam_filter 对输入输出流进行过滤 filters

pam_ftp.so 对匿名ftp用户进行认证

pam_group 当用户在指定的终端上请求指定的 /etc/security/group.conf
服务时赋予该用户相应的组权限

pam_issue 在提示用户输入用户名之前显示 /etc/issue
/etc/issue文件的内容

pam_krb4 对用户密码进行Kerberos认证 相应的Kerberos库文件

pam_lastlog 在用户登录成功后显示关于 /var/log/lastlog
用户上次登录的信息,并维护
/var/log/lastlog文件。

pam_limits 限制用户会话所能使用的系统资源 /etc/security/limits.conf

pam_listfile 根据指定的某个文件决定是否 例如/etc/ftpusers
允许或禁止提供服务

pam_mail 检查用户的邮箱中是否有新邮件 /var/spool/mail/xxxx

pam_mkhomedir 为用户建立主目录 /etc/skel/

pam_motd 显示/etc/motd文件的内容 /etc/motd

pam_nologin 根据/etc/nologin文件的存在与否 /etc/nologin
来决定用户认证是否成功

pam_permit 总是无条件地使认证成功


pam_pwdb 作为pam_unix_xxxx模块的一个替代。/etc/pwdb.conf
使用Password Database通用接口
进行认证。

pam_radius 提供远程身份验证拨入用户服务
(RADIUS)的认证


pam_rhosts_auth 利用文件~/.rhosts和 /etc/hosts.equiv和~/.rhosts
/etc/hosts.equiv对用户进行认证。

pam_rootok 检查用户是否为超级用户,如果
是超级用户则无条件地通过认证。


pam_securetty 提供标准的Unix securetty检查 /etc/securetty

pam_time 提供基于时间的控制,比如限制 /etc/security/time.conf
用户只能在某个时间段内才能登录

pam_unix 提供标准的Unix认证 /etc/passwd和 /etc/shadow

pam_userdb 利用Berkeley DB数据库来检查 Berkeley DB
用户/密码

pam_warn 利用syslog( )记录一条告警信息


pam_wheel 只允许wheel组的用户有超级用户
的存取权限

参考资料:

1、DCE/OSF-RFC 86.0
2、Linux-PAM documentation & source code
3、Sun Solaris PAM documentation




@@

Linux-PAM(Pluggable Authentication Modules). 有人翻译成“可插拔式认证模块”, 或是“可插入式认证模块”. 它表示一种性能健硕而且灵活方便的用户级认证方式。目前,PAM已经成为了Linux, BSD和其他一些*Nix操作系统的首选认证方式。特别是在Linux上,几乎所有的daemon和一些与授权有关的命令都通过PAM来进行验证。他们在编译时都无一例外的加入了对PAM的支持。PAM可以说是Linux系统的安全守护神。那么,PAM到底是怎样运作的呢?

PAM主要是由一组共享库文件(share libraries, 也就是.so文件)和一些配置文件组成的。当你在请求服务的时候,具有PAM认证功能的应用程序将与这些.so文件进行交互,以便得知是否可以授权给发起请求的用户来使用服务,比如su, vsftp, httpd,等。如果认证成功了,那么这个用户便可以使用服务或完成命令,如果认证失败了,那么这个用户将不能使用服务,同时,PAM将向指定的log文件写入警告信息。我们可以将PAM看作是一个中间裁判,它不依赖于任何应用或服务。你完全可以升级这些应用或服务而不必管PAM的共享库的更新或升级,反之亦然。所以它非常的灵活。

PAM的认证过程是通过对一些服务或应用的配置文件来控制的。通常,这些配置文件在/etc/pam.d目录下。cd到这个目录,你会看到很多你很熟悉的应用或服务的名称。比如说login. 那么当用户login的时候,PAM到底做了什么呢?我们看看这个login的PAM配置文件:

代码:
#%PAM-1.0auth required pam_stack.so service=system-authauth required pam_nologin.soaccount required pam_stack.so service=system-authpassword required pam_stack.so service=system-auth# pam_selinux.so close should be the first session rule#session required pam_selinux.so closesession required pam_stack.so service=system-authsession optional pam_console.so# pam_selinux.so open should be the last session rule#session required pam_selinux.so multiple open
这里有些PAM的术语:
首先是配置文件的格式:
代码:
servicemodule-typecontrol_flagmodule_pathargs
service - 由于现代的PAM配置文件都是以服务程序的名字分开配置,所以基本上service这个项已经省去了。但在有些还使用一个pam.conf大文件配置所有的PAM服务的BSD上,还有这一项。

module_type – 控制使用什么类型的管理机制。
auth – 认证管理。做两件事:1.检验用户是否是真正声称的那个用户,比如,要求用户输入用户名和密码来声明自己。2.这个模块可以通过PAM自身的印证机制赋予用户一些特权,或是加入组。
account – 用户管理。 是非认证式的对用户赋予/阻止使用一些系统资源。比如说,用户登录的时间限制,密码的期限等。
password – 密码认证管理。是用来管理用户的密码认证标记(token)的。比如,用户密码的尝试次数等。
session – 会话管理。比如在会话前中后所要执行的一些事情,如记录会话信息, 对如可展开会话的控制等。

control_flag – 可以理解成对PAM认证的流程控制。比如说如果成功,下一步应该怎么办?如果不成功,又应该怎么办?还有就是按怎样的顺序来进行认证,等等。
required – 表示这一模块的认证是必须成功的,但如果失败,认证过程不会即刻终止,PAM将继续下一个同类型的模块认证。
requisite – 和required类似,只是如果失败,认证过程将立即终止。
sufficient – 表示如果认证成功,那么对这一类的模块认证是充足的了,其他的模块将不会再检验。
optional – 表示这一模块认证是可选的,也不会对认证成功或失败产生影响。我没怎么用过这个。
include - 有点类似于DNS或xinetd的include。表示将包括其他的一些认证,这样就可以建立一个分离式的配置文件管理机制。

module_path
使用的认证模块的位置,最为保险的是使用绝对路径。不过PAM有自己的PATH环境,在RHEL4中,大部分是使用的相对路径。如果你是缺省安装,有没有挪动过那些.so文件的位置,使用相对路径是没问题的。(缺省路径一般是:/lib/security)

args – 在认证时传给模块的一些变量。比如用什么文件,对于什么uid, 失败的处理等等。类似于赋给一个命令一些参数。

好了,对于PAM的结构有了基本的了解,我们来看看PAM是如果控制login的。从上至下对于login的PAM配置文件的翻译可以为:
1.用pam_stack.so这个认证模块检测system-auth服务的每一项,看这个请求用户是否能通过认证。这一项是必须检验成功的。system-auth可以理解为一个 “systemwide“全局性的PAM配置文件,也就是说所有的PAM文件都将首先检测system-auth。这就是通过pam_stack.so service=system-auth这一语句来完成的。
2.如果第一项失败了,则整个认证将失败,但无论认证是否成功失败,继续检测第二项,pam_nologin.so.看看系统是否有nologin文件存在。一般在/etc/nologin.如果这个文件存在,则只有root才能登录,其他任何用户都不能。
3.继续检测第三项,用system-auth来检测对用户的管理。
4.继续检测第四项,用system-auth来检测对密码的管理。
5.继续检测第五项,用system-auth来检测会话的控制。
6.继续检测第六项,用pam_console.so来检测用户的登录来源,如果从console,则配置一些console下的资源。这一项是可选的。

按照这个认证过程,我们可以举个例子: userA 和userB。UserA是系统用户而userB是个虚拟用户,只给vsftp用的。那么当userA和userB登录的时候,PAM将利用pam_unix.so来检测用户是否在/etc/passwd和/etc/shadow中。显然userA将成功,而userB将失败。成功的用乎将继续检测其诸如password已经retry的次数,是否sync了passwd和shadow文件,是否是nis 用户,password的加密方式,登录后的系统资源利用情况(pam_limits.so)等等。最后是pam_console.so,如果用户是从vt或本地的X 会话登录,PAM将如何配置文件权限...

几个常用的PAM认证模块的介绍
1.pam_access.so – 缺省配置文件是/etc/security/access.conf (当然,通过“accessfile=/path/to/file” argument, 还可以自行指定配置文件。 通过加入这个认证模块到你想要控制的服务器PAM配置文件,你可以实现对某些服务的userbase级控制。如vsftp, samba,等。编辑/etc/security/access.conf文件,加入你想要控制的用户,可以赋予/阻止他们从特定的来源登录服务器。
2.pam_cracklib.so – 用字典方式检测password的安全性。有一些很有用的arguments, 比如准许retry的次数,多少个字符可以和上次的密码重复,最小的密码长度等等。
3.pam_deny.so – 一个特殊的PAM模块,这个模块将永远返回否。类似大多数的安全机制配置准则,一个严谨的安全规则的最后一项永远是否。
4.pam_limits.so – 类似Linux的ulimit命令,赋给用户登录某个会话的资源限度。如core文件的大小,memory的用量,process的用量,等等。
5.pam_listfile.so – 高度自定义的一个认证模块。理论上你可以用这个模块来控制任何服务。Arguments有:
代码:
item=[tty|user|rhost|ruser|group|shell]sense=[allow|deny]file=/path/to/the/fileapply=[usre|@group]
比如,我想在pop3服务的PAM配置文件中加入:
代码:
auth required pam_listfile.so item=user sense=deny file=/etc/security/dovecot.deny onerr=fail
然后我建立/etc/security/dovecot.deny文件,在里面我加上userA的用户名。这样,userA就无法登录pop3服务器了。原因是“sense=deny“。当然,你也可以配置成“sense=allow“,这样在这个文件里的用户就成了可以登录的用户了,不过你得加入所有你想赋予登录权限的用户,因为不在这个文件中的用户将被DENY!
6.pam_permit.so – 和pam_deny.so正好相反,这个模块将永远返回真。自己从没用过,也许你可以告诉我为什么我需要这个模块?!
7.pam_rootok.so – root用户将通过认证。
8.pam_securetty.so – 将用/etc/securetty文件来检测root用户的登录来源,不在securetty文件中的来源一律禁止!
9.pam_tally.so – 主要用来记录,重置,和阻止失败的登录(次数)。
10.pam_wheel.so – 如果有这个模块,那个只有在wheel组里的用户可以得到root权限。
11.pam_xauth.so – 如果有这个模块,那么在su, sudo的时候,xauth的cookies将同时传到那个用户。(是不是想起来什么了?)



@@@

1. 介绍

Linux-PAM (Linux下的可插入式认证模组) 是一套共享函数库,允许系统管理员来决定应用程式如何识别用户.

换句话说,就是用不着(重写和)重新编译一个(支援PAM的)程式,就可以切换它所用的认证机制. 你可以整个的升级你的认证系统而不用去管应用程式本身.

传统上,当一个应用程序有身份识别的需求,它就不得不把某一种验证算法写进去. 例如,就传统的UN*X系统而言,核对使用者身份的方法就是要求用户输入正确的密码. 这密码,除了开头的两个字符作为"salt",剩下的是加密过的(经由crypt(3)). 接著用户被验证这个加密过的密码是否与他在密码档(就是/etc/passwd文件)中他的那笔记录的第二栏相符.在这样的系统里,绝大部份权限的授予是基于这种单一的认证机制. 权限决定于个人的识别码(uid)和不同群组的成员.服务和程式是否可用由个人和群组的识别码决定.传统上,群组关系经由/etc/group文件中的记录来赋予.

不幸的是,随着计算机速度的不断提高,再加上满世界的关于网路计算的介绍,使得象这样曾是安全的验证机制,变得易受攻击了.面对这样的现实,新的验证方法正在持续的开发中.

Linux-PAM项目的目标是把赋权部分的开发以可靠的合适的鉴定模式从软件中分离出来。这目标已经通过提供一组库函数实现了,应用程序可以用这些函数来请求验证某个用户。这个 PAM 由特定的系统文件配置,/etc/pam.conf (或者是在/etc/pam.d/里的一系列配置文件) 以经由特定的可用的认证模组来鉴定某个用户的请求。这些个模组通常位于/usr/lib/security目录并且以可动态加载的目标文件的形式出现(参见 dlopen(3)).
2. 文中的说明

在继续阅读之前, 请记住本文假定提到的文件位于默认的目录。这个默认的目录我们遵循RFC(RFC-86.0,见 bibliography)中的约定。如果你正用一个支持PAM但是却选择以不同的方式发布这些文件的发布版的Linux(或是其他的OS) (Red Hat就是这样的发布版), 那你从文章中直接拷贝例子的时候就要注意一下了.

举个例子, where it is explicit, 本文假定PAM可加载目标文件(就是 模块)位于这个目录: /usr/lib/security/. 可是, Red Hat Linux, 为遵循Linux文件系统标准(the FSSTND),把这些文件放在/lib/security. 在使用本文的例子时请小心的做一些转换的工作。
3. 概观

For the uninitiated,我们开始于考虑一个例子。我们来说说一个应用程序提供一些服务给用户; login 就是这样的程序。 Login 做两件事,它首先确认提出请求的用户正是他们自己,第二步提供给他们所请求的服务:就login而言服务即是一个命令行外壳(command shell)(如bash,tcsh,zsh之类。)以这个用户的身份去跑。

传统上,前一个步骤通过login提示用户输入密码然后确认系统是否同意登入;接着确认(就系统而言)用户确实是提出要求的那人。这类工作就是Linux-PAM的典型应用。

从应用程序员的角度看(在这个例子里就是写login程序的人), Linux-PAM处理认证的工作——确认用户的身份。

Linux-PAM的*性在于,你,系统管理员有权来决定实施怎样的验证方案。你有权来设定你的系统里的任何支持PAM的应用程序的验证方案。就是说,你可以将验证方案设计成单纯的信任>任何人(pam_permit)到像偏执狂似的通过视网膜扫描,声音识别和一个密码!

举例说明你所面对的*性,考虑以下情形:系统管理员(家中的父母)希望提高他的使用者(孩子们)的算术能力。她可以设置他们喜欢玩的“Shoot 'em up”(游戏,当然得支持PAM)通过提问小于12的一对随机数的乘积的办法来进行认证。很明显不管游戏本身如何,他们会很快学会乘法表。等他们再大些,认证可以升级到包括多位除法!(译者:我已经准备用这种办法来教我宝贝女儿学加减乘除了。)

Linux-PAM处理四种独立的(管理)工作。它们是: 认证管理; 帐号管理; 会话期间管理;和密码管理。 The association of the preferred management scheme with the behavior of an application is made with entries in the relevant Linux-PAM configuration file. 管理的功能由配置文件中指定的模块 来完成。这文件的语法在 below部分讨论。

下面的插图描述了Linux-PAM的整个组织结构。

+----------------+
| application: X |
+----------------+ / +----------+ +================+
| authentication-[---->--\--] Linux- |--<--| PAM config file|
| + [----<--/--] PAM | |================|
|[conversation()][--+ \ | | | X auth .. a.so |
+----------------+ | / +-n--n-----+ | X auth .. b.so |
| | | __| | | _____/
| service user | A | | |____,-----'
| | | V A
+----------------+ +------|-----|---------+ -----+------+
+---u-----u----+ | | |
| auth.... |--[ a ]--[ b ]--[ c ]
+--------------+
| acct.... |--[ b ]--[ d ]
+--------------+
| password |--[ b ]--[ c ]
+--------------+
| session |--[ e ]--[ c ]
+--------------+

By way of explanation, 图的左边表示一个应用程序:X. 这应用程序有和Linux-PAM 库的接口并且在认证方面没有什么特别之处. Linux-PAM 函数库 (图的中部) 查询PAM配置文件的内容并且装入适用于程序 X 的模块. 这些模块进入四个管理组( 图的中下部)中的一个,并且以它们出现在配置文件中的顺序堆叠起来 . 这些模组由Linux-PAM呼叫后,为应用程序执行不同的认证工作 . 需要用户提供或提供给用户的文本信息,可以通过使用应用程序提供的conversation函数来交换.

3.1 Getting started

以下段落由Seth Chaiklin供稿:

到现在为止,我们描述了PAM如何工作在一个理想世界里,
在这儿所有应用程序都被正确编写.
然而,到此时(1998年10月), 这距离现实还太远.
因此,在你试图把PAM用于你的系统时,还得考虑一些实际因素.

Why bother, is it really worth all the trouble?

如果你运行Linux作为单用户系统, 或者在一个所由用户都可信任的环境, 那么用PAM就没什么实际优势.

Ed: 事实上还是有一个好处, 你可以令认证变哑, 就象没有任何认证....像Win95.

在网络环境里, 很显然,关于用户你必需多想点, it is clear that you need to think a little more about how users etc., are authenticated:]

如果运行Linux作为服务器, 提供一些不同的服务 (e.g., 经由密码控制的WWW区域限制, PPP),
那PAM就有一些实际的和有趣的价值. 尤其是, 通过使用使用模块, PAM 能够使
一个程序经过几个不同的密码库来查找, 哪怕那个程序没有专为那密码库写的代码.
下面有一些例子Here are some examples of the possibilities
that this enables.

o Apache 有一个模块提供PAM服务. 认证特定的目录权限可以让PAM来控制,
这意味着,所有PAM能调用的模块都可以被Apache使用,包括RADIUS,NIS,NCP
(NCP用来经由Novell的密码库认证).

o pppd 有一个PAM化了的版本(来自 RedHat) 现在有可能用一系列的数据库来验证
ppp用户. 作为对基于Linux的密码库(/etc/passwd,/etc/shadow)的扩充, 你可以
用PAM模块来进行基于Novell密码库或NT(NTLM)密码库的认证.

o 以上两则例子可以有组合应用.想象一下你办公室/部门的用户已经经过用户名/密码
认证登入Novell或NT.如果你想要他在Linux下的应用也用相同的用户名/密码
(为PPP登入,web服务,或者只是普通的shell登入),你可以通过PAM进行基于这些已
存在的数据库(译者注:Novell的或者NT的)的用户认证,而无须在Linux和LAN服务器里
各自维护独立的数据库.

我可以让所有需要有用户认证的程序都来用PAM吗?

有的可以,有的不行.可以的是那些你能得到源代码,并且可以加入适当的PAM函数的程序.
不行的是那些你无法得到源代码,并且可执行程序没有加入PAM的功能.

也就是说, 如果一个程序打算要用PAM,那么它必须在程序里直接的包含PAM函数.
不这样做就不可能用PAM.

我怎么知道程序是否已经含有PAM的代码了呢?

一个快速的(但不总是可靠)的方法是执行ldd <程序>
如果 libpam 和 libpam_misc 不在程序所需的函数库之列,那么它将不会用PAM.
然而,这两个函数库还是可能已经包含进程序了,不过问题依然存在,因为把PAM
写死在程序不会如你期望的工作.所以一个更可靠的方法是做一下的测试:

在/etc/pam.d目录里,需要为程序设有一个配置文件.具体的文件名是写死在程序里的.
通常和程序名一样,但却不总是这样.为举例说明,假设程序名字叫"pamprog",配置文件
是/etc/pam.d/pamprog.

在/etc/pam.d/pamprog里写这两行:

auth required pam_permit.so
auth required pam_warn.so


现在试着执行pamprog. 配置文件的第一行是说所有用户都被允许. 第二行会在你的
syslog 文件(或者其它你的syslog会写的文件) 里写一个warning.
如果这测试是成功的,那么你就知道你有一个"懂"pam的程序,并且你可以开始更有趣的工作:
决定如何在你的/etc/pam.d/pamprog里堆彻PAM模块.

4. Linux-PAM的设定档

Linux-PAM 给系统管理员提供了相当大的*性来设定系统里程式的权限赋予. 由PAM控制的系统安全的本地配置可以包含在以下两个地方: 或者是一个单一的系统文件: /etc/pam.conf; 或者是/etc/pam.d/ 目录下的文件. 本章我们来讨论这些文件的语法和一般的选项.
4.1 设定档的语法

请注意, 在这些文件里 Linux-PAM 特有的符号是不区分大小写的. 而模块的路径,是大小写敏感的,因为它标识的是Linux下的文件的名字. 而任何模块参数的大小写分别由各个模块定义.

除以下的行之外,为系统管理员方便,还有两个特殊的字符: 注解由'#'开头,结束于行结束,另外,模块的描述行可以以 '\'脱字符延续到下一行.

通常/etc/pam.conf里的每一行有以下格式:

service-name module-type control-flag module-path arguments

接下来,我们来解释每个栏位的意思.另一种(也是常被采用的)设置Linux-PAM 的方法是通过/etc/pam.d/里的文件来实现.在我们解释完上面的那行之后, 我们就来讨论这种方法.

service-name

这笔记录相关的服务名称.通常这服务名称是特定应用程序的名字.比如, `ftpd', `rlogind' 和 `su' 这些. .

有一个保留的服务名称,它是用来定义默认的认证机制的. 它就是`OTHER',大小写无关.注意,当已经有为指定服务定义了模块,那么 `OTHER' 记录会被忽略.
module-type

模块的四种(目前是)类型.这四种类型是:

* auth; 这种模块类型确定有关用户认证的两方面. 第一,它确认用户就是他们自己,这通过指示应用程序提示用户输入密码或者其它证实身份的方法.第二,这类模块会赋予成员资格 Secondly, the module can grant group membership (independently of the /etc/groups file discussed above) or other privileges through its credential granting properties.
* account; 这些模块处理非认证级的帐号管理. 典型的用法是基于一天的不同时间段来限制/允许访问某服务,当前可用的系统资源 (最大用户数)或者限制特定用户---'root只能从控制台登录.
* session; 首先, 这类模块和一系列动作有关,指在用户得到/失去服务时要做的事. 这包括记录用户的登录/登出,挂载必须的目录等等.
* password; 这最后一种类型在更新用户的认证标志时需要. 通常,各个基于"质问/回答"(译注:指传统的用户名/密码的认证方法)的认证方法(auth)有一个对应的此模块.

control-flag

控制符用来指示当某一模块返回成功或失败时PAM如何动作. 既然模块可以被堆叠 (同种类型的模块按先后顺序执行,一个接一个), 控制符决定每个模块的重要程度.应用程序不会直接接收'/etc/pam.conf' 里列出的每一个模块的成功或失败的结果. 相应的是,它只从Linux-PAM接收一个 成功 或 失败 的结论. 这些模块的执行顺序就是它们在 /etc/pam.conf里的记录的顺序;排在前面的记录在排在后的记录之前被执行. 在Linux-PAM 0.60版本里, 这个control-flag 可以有两种语法来定义.

简单一些(也是过去的)语法是用一个限定词指示相关模块的重要程度. 有四个关键字: required, requisite, sufficient 和 optional.

Linux-PAM 将这四个关键字解释为:

* required; 需要的,这表明此模块返回成功值对于整个module-type的成功是必要的. 此模块的返回失败并不会传回给用户直到剩下的模块(同样module-type)都执行过.
* requisite; 必要的,类似 required, 只不过, 当这类模块返回失败时,整个控制会立刻回到应用程序. 返回值同第一个需要的 或 必要的模块返回的失败. 注意,这标志可以用来防止 required or requisite module to fail. Note, this flag can be used to protect against the possibility of a user getting the opportunity to enter a password over an unsafe medium. It is conceivable that such behavior might inform an attacker of valid accounts on a system. This possibility should be weighed against the not insignificant concerns of exposing a sensitive password in a hostile environment.
* sufficient; 充分的,这模块返回的成功会被认为已经 充分满足Linux-PAM 库确认这类模块(module-type)是成功的条件. 如果没有先前的requisite 模块返回了失败,那么不再会有其它'堆叠' 的模块被呼叫. (注意, 这种情况下,随后的requisite 模块就不会 被呼叫.). 这模块返回的失败不会看作是致命的错误而至影响应用程序从这module-type 得到成功的结果.
* optional; 可选的,正如这名字一样,此?control-flag 致使模块对最终的成功或失败的结果不会产生决定性的影响. 一般,Linux-PAM 在确定整个模块堆成功活失败时忽略这模块. 然而, 当从之前或后续的模块得不到明确的成功或失败的结果时,这模块将决定返回给应用程序的状态. 后种情况会出现在比如当其它模块返回PAM_IGNORE 时.

更复杂(新)的语法则更明确,使管理员有更多的控制用户认证的空间. 这种控制符以方括号包含,由一系列的value=action 对组成:

[value1=action1 value2=action2 ...]

这里的 valueI 有以下值 return values: success; open_err; symbol_err; service_err; system_err; buf_err; perm_denied; auth_err; cred_insufficient; authinfo_unavail; user_unknown; maxtries; new_authtok_reqd; acct_expired; session_err; cred_unavail; cred_expired; cred_err; no_module_data; conv_err; authtok_err; authtok_recover_err; authtok_lock_busy; authtok_disable_aging; try_again; ignore; abort; authtok_expired; module_unknown; bad_item; conv_again; incomplete; 和 default. 最后的 (default) 被用来定义当没有明确定义时的默认动作.

actionI 可以是一个正数或者是以下标识: ignore; ok; done; bad; die; 和 reset. 当以一个正数J 作为action 时,它的作用是指示以下J个模块将被跳过. 通过这种手段, 管理员可以开发出适度复杂的模块堆叠,它以许多不同的路径执行. 至于以何种路径则决定于某个模块的反应.

* ignore - 此类模块的返回状态将不会影响应用程序所得到的返回值.
* bad - 这表示相应的返回值将被认为是模块失败. 如果此模块是堆叠中的第一个失败的模块, 它的状态值将作为整个堆叠的状态.
* die - 和 bad 相同,不过会终止整个模块堆叠,PAM立即返回到应用程序.
* ok - 这告诉PAM 管理员要让此返回值直接作用于整个模块堆叠的返回. 换句话说, 如果堆叠的原先状态会导致返回 PAM_SUCCESS, 这模块的返回值将会覆盖这结果. 请注意:如果堆叠的原先状态保存着一些意为模块失败的值,这'ok'将不会用来覆盖那样的值.
* done - 和 ok 一样, 不过会终止整个模块堆叠, PAM立即返回到应用程序.
* reset - 清除储存模块堆叠状态的内存并且重新开始下一组堆叠.

来体会一下这种新语法的强大之处, 从 Linux-PAM-0.63起, 客户插件**的概念被引进. 这多少使PAM支援从C/S应用程序固有的传输协议进行机器-机器的认证成为可能.(?) 通过 ``[ ... value=action ... ]'' 的语法, 使应用程序对支援binary prompt?的客户端采用binary prompt?, 而对旧有的客户端则向后兼容的采用另一种认证模式. 够灵活吧?
module-path

是可动态加载目标文件的路径; 也即可插入式模块 本身. 如果路径的首字符是 `/', 那它被作为一个完整路径. 如果不是这样, 那模块的路径则会加上默认的模块路径: /usr/lib/security (见 above).
args

args 是一组传给模块的参数. 类似一般Linux的指令的参数. 通常, 合法的参数是可选的并且是模块特有的. 无效的参数会被模块忽略, 可是, 当抓到一个无效参数, 模块被要求写一个错误信息到 syslog(3). 下一节有一个一般 选项的列表.

设定档里如果有任一行有格式错误, 那通常会导致认证流程失败. 相应的错误信息会通过呼叫syslog(3)写入系统日志.
4.2 基于目录的设定

从0.56版开始有比单个配置文件更灵活的做法, 可以通过/etc/pam.d/里的文件来配置libpam. 这种方法,/etc/pam.d/里的文件名和服务名(service-name)相同(小写): 这是各服务的个性化设置档.

Linux-PAM 可以编译成两种模式之一. 首选的模式是使用/etc/pam.d/ 或/etc/pam.conf设定,但不是同时两者皆可.也就是说, 如果</etc/pam.d/目录存在那么libpam仅使用这目录里的文件当作设定档. 当/etc/pam.d/不存在时就用/etc/pam.conf. 另一种模式是(是RedHat4.2以上版本的模式)按顺序同时用/etc/pam.d/和/etc/pam.conf. 在这种模式下,/etc/pam.d/里的设定会覆盖/etc/pam.conf.

/etc/pam.d/里的文件的语法和/etc/pam.conf相似,由以下格式组成:

module-type control-flag module-path arguments

唯一的差别是service-name不再出现.service-name是给定的配置文件名. 例如,/etc/pam.d/login 里包含了login的配置.

此种设置方法比起处理单个文件有很多优点. 列举如下以帮助读者来决定采用何种方案:

* 遗漏应用程序的配置的机会比较小. 当手工编辑设定档时也少设定一个栏位.
* 更易于维护. 配置某个应用程序不会有妨碍到别的应用程序的危险.
* 建立不同的服务的配置文件为到某个文件的符号连接也是可能的. 这使保持不同的应用程序采用一致的系统策略变得容易些. (It should be noted, to conserve space, it is equally possible to hard link a number of configuration files. However, care should be taken when administering this arrangement as editing a hard linked file is likely to break the link.)
* 更快的配置文件解析,只有和此服务相关的条目才会解析.
* 采用文件系统的文件权限可以限制个别Linux-PAM设定档的读权限.
* 包管理变得更简单. 每次当有新程序安装时,只需要附上/etc/pam.d/xxxxxx.

4.3 通用的可选参数

一下是一些基本所有模块都识别的可选参数.参数(包含这些)通常是可选的.

debug

呼叫 syslog(3) 函数在系统日志里记录下debug信息.
no_warn

指示模块不要丢warning信息给应用程序.
use_first_pass

这模块将不会提示用户输入密码,它可以得到前面输入过的密码(从上一个auth模块)并且用它.如果那密码不正确,那么用户就不被认证.(这模块只对auth和password模块有意义.)
try_first_pass

这模块会先拿前面输入过的密码来认证(从上一个auth模块).如果通不过认证,就提示用户输入密码.(这模块只对auth模块有意义.)
use_mapped_pass

这参数目前没有任何Linux-PAM发布的模块支援,因为可能会违反美国加密软件出口限制.在美国国内,模块开发者当然可以自由的实现它(他国的开发者也一样). For compatibility reasons we describe its use as suggested in the DCE-RFC 86.0, see section bibliography for a pointer to this document.

use_mapped_pass 指示模块拿前一个模块生成的认证明文来产生一个加/解密的的键 ,以这键来安全的存储/取得此模块所需的认证标识. In this way the user can enter a single authentication token and be quietly authenticated by a number of stacked modules. Obviously a convenient feature that necessarily requires some reliably strong encryption to make it secure. This argument is intended for the auth and password module types only.
expose_account

通常模块暴露用户帐号的有关信息不是个安全的策略. 有时象用户名,用户的家目录,首选的shell这些信息可被用来攻击这帐号. 可是,这些信息不被视为威胁:在一个可信的环境里当要求输入密码时显示用户的全名, 这被叫做"易用性".expose_account是个标准的模块参数,当管理员觉得合适(译注: 指暴露用户帐号的信息)时可以使模块和帐户信息少些离散.

4.4 设定档的范例

在这章,我们给出一些可以出现在Linux-PAM的设定档里的条目的范例. 作为第一次尝试配置你的系统,你可能会得的比实现它们更糟糕.
默认策略

对于关键的系统,最好是有个适度安全的OTHER条目.以下是个"偏执狂"的设定 (以此开始不是个坏想法!):

#
# default; deny access
#
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

Whilst fundamentally a secure default, this is not very sympathetic to a misconfigured system. For example, such a system is vulnerable to locking everyone out should the rest of the file become badly written.

pam_deny (在后面的章节里解释)不够复杂.比如,它被呼叫时不会记录任何信息, 如此除非用户告诉管理员说他不能执行某应用程序,管理员可能因为不知道他的系统被错误配置而已经远远的走开了.

把下面的两行加在前面的例子之前就可给管理员提供合适的警告.

#
# default; wake up! This application is not configured
#
OTHER auth required /usr/lib/security/pam_warn.so
OTHER password required /usr/lib/security/pam_warn.so

两行 ``OTHER auth''是堆叠的范例.

如果用/etc/pam.d/下的文件来设定,相应的设定档如下:

#
# default configuration: /etc/pam.d/other
#
auth required /usr/lib/security/pam_warn.so
auth required /usr/lib/security/pam_deny.so
account required /usr/lib/security/pam_deny.so
password required /usr/lib/security/pam_warn.so
password required /usr/lib/security/pam_deny.so
session required /usr/lib/security/pam_deny.so

这是唯一完整的配置/etc/pam.d的例子, 大体上能说明如何转换剩下的例子到这种配置方案.

对于不重要的主机,管理员不想要Linux-PAM的强大能力,以下(从/etc/pam.conf)里节选的行仿效了历史上的Linux的设定.

#
# default; standard UNIX access
#
OTHER auth required /usr/lib/security/pam_unix_auth.so
OTHER account required /usr/lib/security/pam_unix_acct.so
OTHER password required /usr/lib/security/pam_unix_passwd.so
OTHER session required /usr/lib/security/pam_unix_session.so

通常这提供了大多数应用程序一个能执行的环境.不过大多数不代表所有. 如果想要提供anonymous-ftp,就要对ftpd多加几行.

要开放anonymous-ftp, 得用下面几行来替换默认(OTHER)设定.

#
# ftpd; add ftp-specifics. These lines enable anonymous ftp over
# standard UNIX access (the listfile entry blocks access to
# users listed in /etc/ftpusers)
#
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

注意,第二行是必须的,因为如果某特定的服务在/etc/pam.conf里存在任何条目, 那么默认的设定就会被服务程序(这里指ftpd)忽略. 又一次,这还是个模块堆叠的例子. 用了sufficient控制符.这是说 ``如果这个模块认证了用户,就忽略会面的auth模块 ''. 还有它用了``use_first_pass''参数, 这指示UNIX认证模块不要提示用户输入密码,而是采用ftp模块已经获得的那个密码.

5. Linux-PAM的安全问题

这一章讨论以安全的方式使用Linux-PAM的一些好习惯. 目前还可怜的少....欢迎提供建议!
5.1 如果弄错了

Linux-PAM 有可能严重改变你系统的安全级别.你可以选择没有防护或绝对安全 (不允许访问).通常, Linux-PAM 容易犯后种错误. 任何设定档的错误将会部分或完全禁止对系统的访问.

在配置Linux-PAM时最可能遭遇的最生动的问题是删除设定档: /etc/pam.d/* 和/或 /etc/pam.conf. 这将会把你关在自己的系统门外.

为了恢复, 最好赌一下重开机进入单用户模式然后设定正确的文件. 下面是从David Wood的救生email改写而来:

注意: 一下假定进入单用户模式不需要输入密码. 然而, Debian和其他一些发布版不是这样的. Init会呼叫sulogin来要求输入root的密码.程序sulogin 不用PAM,所以毁坏掉的PAM设定不会破坏这程序.

> 那我先在还能做些什么苦差呀?

好,不要惊慌. 你首先要认识到的是这种事情会发生在50%的从未碰过PAM的用户身上.
这已经不止发生一两次了,每次都不一样,但是最终,每次解决方法总是一样的.

首先,我希望你设定了LILO的延时.如果是的,重开机,按下shift或者tab或其它什么键,
然后输入:

LILO boot: linux single

(把 'linux' 替换成你的linux启动字串).
这会把你带进系统而不用登入. 想知道从控制台破掉一台Linux主机是多容的事?
现在知道了吧.

如果没法那样做,那你就要一个启动软盘和一个根文件系统盘象slachware的rescue.gz.
(Red Hat的安装盘有这样的模式.)

总之,重点是要进入到root提示符.

然后, 我假设你还没有完全打烂你的PAM安装包 - 仅仅是破坏了设定档.
这里是重新设定PAM的步骤:

cd /etc
mv pam.conf pam.conf.orig
mv pam.d pam.d.orig
mkdir pam.d
cd pam.d

然后用vi在这目录下创建一个叫"other"的文件.包含下面四行:

auth required pam_unix_auth.so
account required pam_unix_acct.so
password required pam_unix_passwd.so
session required pam_unix_session.so

现在你有了PAM的最简单的设置了, 这象你以前用的方式一样工作.
所有的事情又魔法似的能运作了.
来试着按ALT-F2从另一控制台登入. 如果无法登入, 你就有了大麻烦了,或者打错了什么.
奇怪的是如果你在设定档里输错了东西, 你不会从控制台得到任何错误 - 错误只会记录
在日志档里. 所以看看那儿!(tail /var/log/messages.)

从现在起你可以回头做实际设定, 但愿这首次经历没把你搞懵了. :/

一些要点 (to make everything "right" with Red Hat...):

从RedHat安装目录安装最新的pam, pamconfig, and pwdb , 下一个指令

rpm -Uvh [或需要加上 --force too] pam-* pamconfig-* pwdb-*

然后确认你安装(或重装)了最新版的libc, util-linux, wuftp, 和 NetKit. 或许
还有相关的x应用程序, 像xlock,但我还从没有用过.(注:这篇文章写的比较早,那时候
X程序很少)

5.2 防止采用一个脆弱的"other"设定.

拥有一个脆弱的默认设定(OTHER)是件坏事. OTHER是所有面向PAM的程序的默认设定,如果它很脆弱, 你的系统就有可能变得易受攻击.

这里有个"other"设定的例子.pam_deny 模块会拒绝所有访问同时pam_warn模块会在在系统日志里记下auth.notice:

#
# The PAM configuration file for the `other' service
#
auth required pam_deny.so
auth required pam_warn.so
account required pam_deny.so
account required pam_warn.so
password required pam_deny.so
password required pam_warn.so
session required pam_deny.so
session required pam_warn.so

6. 可用模块的参考指南

以下是目前Linux-PAM可用的各种模块的具体说明. 通常这些模块可以自由使用. 除非特别指出.

在拷贝下面的例子时也请注意 on text conventions above里的备注.
6.1 access 模块
概要

模块名:

pam_access
作者:

Alexei Nogin <alexei@nogin.dnttm.ru>
维护者:

作者
提供的管理组:

account
Cryptographically sensitive:
安全等级:
代码清洁度:
系统依赖:

需要一个设定档:/etc/security/access.conf
网络接口:

如果设定了就通过PAM_TTY , 否则尝试呼叫ttyname()从标准输入文件描述符得到tty名字.标准的 gethostname(), yp_get_default_domain(), gethostbyname() 呼叫. NIS 用来提供网络用户组的支持.

概述

提供logdaimon(?)类型的登录访问控制.
Account component

识别的参数:
描述:

这模块提供基于登录名称和主机(或域名),internet地址(或网络数),或者非网络登录的终端名字的录访问控制.诊断信息通过syslog(3)记录. 来自Wietse Venema的logdaemon-5.6里的login_access.c经过A. Nogin修改后采用.
例子/建议用法:

推荐使用. 例如,在管理像NIS服务器和邮件服务器时, 你需要有一些活动的帐号, 但却不想所有这些帐号都有登录的权限.

对于/etc/pam.d类型的设定方式,你的模块放在/lib/security里, 把下面一行加在 /etc/pam.d/login, /etc/pam.d/rlogin, /etc/pam.d/rsh 和 /etc/pam.d/ftp前面:

account required /lib/security/pam_access.so

注意, 除非你的系统忽略.rhosts, 否则这模块不会产生作用. 见pam_rhosts_auth的文档.

在发布包里包含有一个 access.conf 的样本.

6.2 Chroot
概要

模块名:

pam_chroot
作者:

Bruce Campbell <brucec@humbug.org.au>
维护者:

Author; proposed on 20/11/96 - email for status
提供的管理组:

account; session; authentication
Cryptographically sensitive:
安全等级:
代码清洁度:

Unwritten.
系统依赖:
网络接口:

要求是 localhost.

概述

这模块的目的是对一般用户进行透明的包裹, 这可以把他们置于一个伪装的文件系统 (比如, 他们的'/' 实际上是 /some/where/else).

如果你有几个不同类的用户, 并且你对于安全性有一点点偏执, 那这模块将非常有用. 这可以用来限制哪些用户能看到什么, 并且限制他们只能执行哪些程序.
Account component:

Need more info here.
Authentication component:

Need more info here.
Session component:

Need more info here.

识别的参数:

Arguments and logging levels for the PAM version are being worked on.
描述:
范例/建议用法:

提供一组合理的程序 - 仅放入 'cat', 'ls', 'rm', 'cp' 和 'ed' 有点...

不要太极端 (比如, 你可以为每个用户设定各自分开的环境, 但这样会太浪费磁盘空间.)

6.3 Cracklib 可插入的密码强度检查程序
概要

模块名:

pam_cracklib
作者:

Cristian Gafton <gafton@redhat.com>
维护者:

作者.
提供的管理组:

password
Cryptographically sensitive:
安全等级:
代码清洁度:
系统依赖:

需要系统库 libcrack 和系统字典: /var/cache/cracklib/cracklib_dict.
网络接口:

概述

这模块可以插入给定程序的password堆叠来提供密码的强度检验.

这模块以以下流程运行: 它首先呼叫Cracklib例程来检查密码的强度; 如果Cracklib认可, 那么模块会经行额外一些检查. 这包括:

* Palindrome - 新密码是否为旧密码的回文?
* Case Change Only - 新密码是否只是拿旧密码改了些大小写?
* Similar - 新密码是否太像旧密码? 这由一个参数控制, difok 这是新旧密码的相差字符能被接受的最小个数, 模式是10个或者新密码的1/2长, 二者取小的那个.
* Simple - 新密码是否太简单? 这由五个参数控制: minlen, dcredit, ucredit, lcredit 和 ocredit. 这些参数如何生效以及默认值是什么见参数一节.
* Rotated - 新密码是否为旧密码的轮转?
* Already used - 密码是否曾经用过? 先前用过的密码保存在/etc/security/opasswd里.

不带参数的配置这模块可以很好的工作在标准的unix密码加密环境. 对于MD5加密, 密码可以长于8个字符,那么这模块的默认设定就使用户选择一个满意的密码变得困难了. 显然, 对于新密码不能包含多于一半的旧密码的字符的要求就成了一个不一般的限制了. 比如, 旧密码"the quick brow fox jumped over the lazy dogs" 将难于更改... 此外, 默认设定允许密码短至5个字符. 对于采用md5加密算法的系统, 加大允许的最短密码长度会是个好主意. One can then allow more credit for different kinds of characters but accept that the new password may share most of these characters with the old password.
Password component

识别的参数:

debug; type=XXX; retry=N; difok=N; minlen=N; dcredit=N; ucredit=N; lcredit=N; ocredit=N;
描述:

这部件的动作是提示用户输入密码然后通过比对系统字典和一连串规则来检查它的强度以识别出差劲的选择.

默认动作是提示用户输入一个密码, 检查强度, 然后, 如果通过检查, 提示第二次输入密码 (用来检验第一次的输入是正确的). 这之后, 密码被当作新的认证标识传送给随后的安装的模块.

默认的动作可以用一些参数改成许多不同的方式:

* debug - 这选项令此模块写入信息到syslog(3)以显示此模块的现为(此选项不会 把密码信息写入日志档).
* type=XXX - 提示用户输入密码的默认提示符是: ``New UNIX password: '' 和 ``Retype UNIX password: ''. 用此参数可以把 "UNIX" 替换成 XXX.
* retry=N - 本模组要求新密码(用来检查强度)的默认次数是1次. 用这参数可以增加到N次.
* difok=N - 这参数会改变允许新旧密码的字符差异为至少10个这样的默认值. 此外, 如果有一半的字符不同, 新密码就会被采用.
* minlen=N - 可接受的最短的密码长度+1. 此外对于新密码的长度, 对于每个不同种的字符 (其它,大写,小写 和数字),会得到"加分" (长度+1). 此参数的默认值是9, 这对于旧的UNIX密码体系已经够了, 但是对于利用md5的额外安全性或许太小了. 注意, Cracklib本身有一对长度的限制: 4, 写死在程序里的"路太短"的限制;6,定意的限制.这两个限制会不经过参考minlen 而被检查出来. 如果你要允许密码长度短至5, 你要么不要使用此模块要么重新编译crack库并重新编译此模块.
* dcredit=N - 这是对于新密码因包含数字而得到"加分"的限制. 如果你有小于或等于N个数字, 每个数字将会对整个长度+1来迎合当前minlen 的值. dcredit的默认是1, 对于小于10的minlen 推荐此值.
* ucredit=N - 这是对于新密码因包含大写字符而得到"加分"的限制. 如果你有小于或等于N个大写字符, 每个大写字符将会对整个长度+1来迎合当前minlen 的值. ucredit的默认是1, 对于小于10的minlen 推荐此值.
* lcredit=N - 这是对于新密码因包含小写字符而得到"加分"的限制. 如果你有小于或等于N个小写字符, 每个小写字符将会对整个长度+1来迎合当前minlen 的值. lcredit的默认是1, 对于小于10的minlen 推荐此值.
* ocredit=N - 这是对于新密码因包含其它字符而得到"加分"的限制. 如果你有小于或等于N个其它字符, 每个其它字符将会对整个长度+1来迎合当前minlen 的值. ocredit的默认是1, 对于小于10的minlen 推荐此值.

范例/建议用法:

为举例说明如何使用此模块, 我们列出如何将此模块和pam_unix 部件堆叠:

#
# 下面两行堆叠了两个password类型的模块. 在这例子里, 用户有3次机会输入健壮的密码.
# "use_authok"参数确保pam_unix模块不再另外提示输入密码,
# 而是采用由pam_cracklib提供的密码.
#
passwd password required pam_cracklib.so retry=3
passwd password required pam_unix.so use_authtok

另外一个例子(以/etc/pam.d/passwd的格式)是用md5密码加密的情形:

#%PAM-1.0
#
# 下面两行采用MD5系统, 密码长度最少14+出现数字的最多2个"加分"+
# 出现其它字符的最多2个"加分", 并且至少有3个字符没有出现在旧密码中.
#
password required pam_cracklib.so \
difok=3 minlen=15 dcredit= 2 ocredit=2
password required pam_unix.so use_authtok nullok md5

6.4 死锁模块
概要

模块名:

pam_deny
作者:

Andrew G. Morgan <morgan@parc.power.net>
维护者:

current Linux-PAM maintainer
提供的管理组:

account; authentication; password; session
Cryptographically sensitive:
安全等级:
代码清洁度:

清洁的.
系统依赖:
网络接口:

概述

这模块用来拒绝访问. 它永远透过PAM架构告知程序失败. 正如概述 above里提到的, 这模块适合用在默认(OTHER)条目.
Account component

识别的参数:
描述:

这部件除了返回失败外不做任何动作, 返回类型是 PAM_ACCT_EXPIRED.
范例/建议用法:

把这模块堆叠在account 里将会阻止用户通过应用程序(引用Linux-PAM的帐户管理函数pam_acct_mgmt())获取访问.

下面的例子使登入变得不可能:

#
# add this line to your other login entries to disable all accounts
#
login account required pam_deny.so

Authentication component

识别的参数:
描述:

这部件除了返回失败什么也不做, 当pam_authenticate()被呼叫(当应用程式试图认证用户时)时返回值是PAM_AUTH_ERR; 当pam_setcred()被呼叫(当建立连接并设置用户证书时 -- 在具体实现中这函数不太可能被呼叫)时返回 PAM_CRED_UNAVAIL .
范本/建议用法:

为拒绝默认程序的访问, 在你的Linux-PAM里包含下面一行:

#
# add this line to your existing OTHER entries to prevent
# authentication succeeding with default applications.
#
OTHER auth required pam_deny.so

Password component

识别的参数:
描述:

模块的这部件会阻止用户有机会修改密码. 它总是返回PAM_AUTHOK_ERR.
范本/建议用法:

这模块可以用来阻止应用程序更新申请者的密码. 比如, 为阻止login 在用户的旧密码过期后自动提示输入新密码, 应该把下面一行放在你的设定档里:

#
# add this line to your other login entries to prevent the login
# application from being able to change the user's password.
#
login password required pam_deny.so

Session component

识别的参数:
描述:

模块的这一方面会阻止应用程序在主机上开启会话.
范本/建议用法:

和其它的session模块一起工作, 那模块也许显示一下"当日消息". 这模块可以用来阻止用户开启shell. 如有pam_motd在先, 我们或可用下面的设置来阻止用户登录并提示用户现在是系统维护时间:

#
# An example to see how to configure login to refuse the user a
# session (politely)
#
login session required pam_motd.so \
file=/etc/system_time
login session required pam_deny.so

6.5 Set/unset 环境变量
概要

模块名:

pam_env
作者:

Dave Kinchlea <kinch@kinch.ark.com>
维护者:

Author
提供的管理组:

Authentication (setcred)
Cryptographically sensitive:
安全等级:
代码清洁度:
系统依赖:

/etc/security/pam_env.conf
网络接口:

概述

这模块允许(取消)设定环境变量. Supported is the use of previously set environment variables as well as PAM_ITEMs such as PAM_RHOST.
Authentication component

识别的参数:

debug; conffile=configuration-file-name; envfile=/env-file-name; readenv=/0|1
描述:

这模块允许你(取消)设定任意的环境变量为固定字串, 先前的环境参数和/或PAM_ITEM.

通过设定档(默认是,/etc/security/pam_env.conf, 但是可由connfile 参数改变) 进行所有的控制. 每行由变量名开始, 每个变量有两个可选项: DEFAULT和OVERRIDE. DEFAULT 用来设定变量的默认值, 如果没有指定默认值则设为空字串. OVERRIDE 告诉pam_env如果变量以设定就覆盖(覆盖" "默认值). 如果未设定OVERRIDE, 则假定为""并且不会覆盖其它值.

VARIABLE [DEFAULT=[value]] [OVERRIDE=[value]]

(也许不存在的)环境变量可以指定值为${string} 并且(也许不存在的)PAM_ITEM 可以用来指定值:&{string} . $和& 可以由反斜线脱意为一般字符 (成为\$本生). 双引号可以用来封装有空格的值 (但是不可以用作变量名)必须整个被引号包含并且里面不应该有引号或者脱意的引号.

这模块还可以解析包含单纯的每行是键=值格式的文件(默认是/etc/environment). 可以用 envfile 旗标设定默认文件并且可以设定readenv 旗标为1或0来决定是否启用这选项.

这模块的行为可以由以下旗标来更改: flags:

* debug - 往syslog(3)写更多的信息.
* conffile=filename - 默认的设定档是/etc/security/pam_env.conf. 这选项可以覆盖此默认. 必须提供完整的文件名,目录+文件名.
* envfile=filename - 默认从/etc/environment 里读键=值对来设定变量. 这选项覆盖默认文件. 必须提供完整的文件名,目录+文件名.
* readenv=0|1 - 打开或关闭读取envfile指定的文件(0=关闭,1=开启). 默认是开启.

范本/建议用法:

更多的用法见pam_env.conf .

6.6 filter 模块
概要

模块名:

pam_filter
作者:

Andrew G. Morgan <morgan@parc.power.net>
维护者:

作者.
提供的管理组:

account; authentication; password; session
Cryptographically sensitive:

Not yet.
安全等级:
代码清洁度:

在Linux系统下可以干净的被编译.
系统依赖:

需要安装filters .
网络接口:

概述

这模块用来提供给类似ttysnoop(需要一些参考)的程序一个可选的插件. 因为还没有为这功能所写的插件出现, 这模块目前只是个玩具. 提供给这模块的唯一一个插件仅是对输入输出流做大小写转换. (这会变得非常讨厌并对基于termcap的编辑器不太友好)
Account+Authentication+Password+Session components

识别的参数:

debug; new_term; non_term; runX
描述:

每个组建都有呼叫过滤器的能力. 过滤器总是以所属应用程序的权限被execv(2) 而 不是 以用户的权限. 因此这些过滤器并不总能被用户不经关掉相关会话而杀掉.

这模块的行为会被传给它的参数相当程度的左右:

* debug - 这选项增加模块被执行时写进syslog(3)的信息量.
* new_term - 过滤器的默认动作是会设定PAM_TTY 为用户连上应用程序时所用的终端代号. 此参数指示过滤器可以设定PAM_TTY 为一个过滤了的伪终端.
* non_term - 不要试图设定PAM_TTY .
* runX - 模块必须得知道何时呼叫过滤器. 这参数告知过滤器何时被呼叫, 参数后面是各自的过滤器的完整路径和过滤器执行时的参数.

X 所允许的值是 1 和 2. 这指示过滤器执行的确切时间. 阅读 Linux-PAM的模块开发指南会对解释此观念有所帮助. 基本上, 针对每个管理组都有多至两个呼叫此模块的函数.

在 authentication 和 session 部件里, 实际上有两个不同的函数. 对于authentication, 这两个函数是_authenticate 和_setcred -- 此时 run1 意味着在呼叫_authenticate时执行过滤器而run2 意味着呼叫_setcred时运行过滤器. 对于session来说, run1 意指在_open_session 阶段运行过滤器, run2 在 _close_session 作用.

对于account部件. run1 和 run2 的任何一个被运行.

对于password部件, run1 用来指示当_chauthtok第一次被执行(PAM_PRELIM_CHECK阶段)时呼叫过滤器,run2 指示第二次时(tt/PAM_UPDATE_AUTHTOK/阶段)时呼叫.

范本/建议用法:

在写作本时, 这模块鲜有实际应用. 如兴趣所致, 你可以试着把下面几行加入你的login的设定.

#
# An example to see how to configure login to transpose upper and
# lower case letters once the user has logged in(!)
#
login session required pam_filter.so \
run1 /usr/sbin/pam_filter/upperLOWER

6.7 匿名访问模块
概要

模块名:

pam_ftp.so
作者:

Andrew G. Morgan <morgan@linux.kernel.org>
维护者:

作者.
提供的管理组:

authentication
Cryptographically sensitive:
安全等级:
代码清洁度:
系统依赖:
网络接口:

提示用户输入email地址; 易受欺骗的.(XXX - 需要加工)

概述

此模块的意图是提供一个可插入式的匿名ftp访问模式. mode of access.
Authentication component

识别的参数:

debug; users=XXX,YYY,...; ignore
描述:

此模块会拦截用户名和密码. 如果用户名是 ``ftp'' 或 ``anonymous'', 用户的密码以'@'为分隔符被分解成PAM_RUSER 和 PAM_RHOST 两部分; these pam-items being set accordingly. The username is set to ``ftp''. In this case the module succeeds. Alternatively, the module sets the PAM_AUTHTOK item with the entered password and fails.

此模块的行为可以有以下旗标修改:

* debug - 往syslog(3) 写更多的信息.
* users=XXX,YYY,... - 替代 ``ftp'' 或 ``anonymous'', 提供给以逗号分开的用户以匿名访问; ``XXX,YYY,...''. 申请人可以输入这些用户名之一, 返回的用户名设定为列表中的第一个用户;``XXX''.
* ignore - 不关心用户的email地址(如果提供).

范本/建议用法:

见 above.

6.8 群组访问模块
概要

模块名:

pam_group
作者:

Andrew G. Morgan <morgan@parc.power.net>
维护者:

作者.
提供的管理组:

authentication
Cryptographically sensitive:
安全等级:

对于针对setgid状态的文件可访问性敏感.
代码清洁度:
系统依赖:

需要/etc/security/group.conf 文件. 可被编译成带有或不带libpwdb.
网络接口:

仅通过正确的PAM_TTY 项.

概述

此模块提供基于用户名以及他们从哪个终端请求服务的群组设定. It takes note of the time of day.
Authentication component

识别的参数:
描述:

此模块不用于认证用户, 而是用来赋予用户组的身份(在认证模块的凭证设定阶段). 这些组身份基于他们请求的服务. 组身份列在/etc/security/group.conf .
范本/建议用法:

为使这模块正常运作,必需先要有格式正确的/etc/security/groups.conf . 此文件的格式如下.组身份基于服务应用程序满足此设定档的任意行来赋予. 没一行有如下格式(注解以`#'开头):

services ; ttys ; users ; times ; groups

前四个栏位和pam_time的etc/security/pam_time.conf语法相同, 最后的栏位, groups, 是以逗号(或者空格)分开的一个组的列表. 如果用户的应用程序满足前四个栏位, 用户就被赋予列表中的组身份.

通常, 这模块对于分配用户特有的文件访问权限有帮助. 问题是一旦用户得到了组身份, 他就可以创建一个setgid 的属于某群组的程序. 这之后, 当用户不再是这个组的成员时, 他们可以通过这程序获取组身份. 之所以用户访问的文件系统如此重要, 是一旦文件系统被加载为nosuid时, 这样的程序就无法执行. 为使这模块提供任何级别的安全性, 用户能有写权限的所有文件系统都应该被加载成nosuid模式.

pam_group 模块的功能和/etc/group平行. 如果用户已被此模块赋予了任何组身份, 他还另外被赋予/etc/group里的相关组身份.

6.9 Add issue file to user prompt
概要

模块名:

pam_issue
作者:

Ben Collins <bcollins@debian.org>
维护者:

Author
提供的管理组:

Authentication (pam_sm_authenticate)
Cryptographically sensitive:
安全等级:
代码清洁度:
系统依赖:
网络接口:

概述

此模块在当提示输入用户名时显示发布文件(/etc/issue).
Authentication component

识别的参数:

issue=issue-file-name; noesc;
描述:

此模块允许你在提示用户输入用户名之前显示出发布信息. 默认状态下也会解析发布文件中的脱意代码,类似有些通用的getty(\x 格式).

识别的脱意代码:

* d - 当前日期
* s - OS名称
* l - 当前tty的名字
* m - 本系统的架构(i686, sparc, powerpc, ...)
* n - 主机名
* o - 域名
* r - OS的版本发行号(例如 2.2.12)
* t - 当前时间
* u - 当前登入的用户数
* U - 类似u, 它能区分用"user" 还是 "users" (比如. "1 user" or "10 users")
* v - OS版本/构建日期(比如. "#3 Mon Aug 23 14:38:16 EDT 1999" on Linux).

以下旗标可以用来改变此模块的行为:

* issue - 替换默认发布文件
* noesc - 不解析脱意代码

范本/建议用法:

login auth pam_issue.so issue=/etc/issue

6.10 The Kerberos 4 module.
概要

模块名:

pam_krb4
作者:

Derrick J. Brashear <shadow@dementia.org>
维护者:

作者.
提供的管理组:

authentication; password; session
Cryptographically sensitive:

采用相关 API
安全等级:
代码清洁度:
系统依赖:

相关库- libkrb, libdes, libcom_err, libkadm; 和一组Kerberos的头文件.
网络接口:

从网络上的Kerberos的票据中心得到Kerberos的票据授权票.

概述

此模块提供了进行Kerberos密码认证的界面, 它能从Kerberos的票据授权服务器取得票据授权票, 离线时毁掉票据, 和修改Kerberos密码.
Session component

识别的参数:
描述:

此部件目前会设定环境变量 KRBTKFILE (虽然目前还没法export这变量), 以及当登出时删除用户的票据(要等到login 支持 PAM_CRED_DELETE ).
范本/建议用法:

直到我们能通过Linux-PAM 改变环境.

Password component

识别的参数:

use_first_pass; try_first_pass
描述:

这部件改变用户的Kerberos密码, 它首先凭旧密码从密码修改服务得到活动钥匙, 然后发送新密码给那服务.
范本/建议用法:

仅能用于真实的real Kerberos v4 kadmind. It cannot be used with an AFS kaserver unless special provisions are made. Contact the module author for more information.

Authentication component

识别的参数:

use_first_pass; try_first_pass
描述:

此模块通过从Kerberos服务器申请票据授权票来验证用户的Kerberos密码, 并且可选的如果本机键文件存在就从尝试此票据中获取本机的主机键并和本机的键文件比对.

它还会把票据记录在文件以便后序使用, 并且在当离线是删除票据文件(目前还不行,除非login会呼叫PAM_CRED_DELETE).
范本/建议用法:

此模块可以同采用MIT v4 的Kerberos服务器协同工作. 可以加以修改已使其支持AFS类型的Kerberos. 为防止密码算法的不一致,目前还没有支持.

6.11 The last login module
概要

模块名:

pam_lastlog
作者:

Andrew G. Morgan <morgan@parc.power.net>
维护者:

作者.
提供的管理组:

auth
Cryptographically sensitive:
安全等级:
代码清洁度:
系统依赖:

用到/var/log/lastlog里保存的信息.
网络接口:

概述

此模块用于维护/var/log/lastlog 文件. 当程序呼叫pam_open_session()函数时写入一个条目并且在呼叫pam_close_session()时完成此条目. 这函数还可以显示一条关于最后一次登录的信息. 如果应用程序已经有此功能, 则没有必要使用此模块.
Authentication component

识别的参数:

debug; nodate; noterm; nohost; silent; never
描述:

此模块用于无论用户从何种支援PAM的应用程序登录系统都提供"Last login on ..." 这样的信息. 此外, 此模块还维护/var/log/lastlog 档.

可有一下旗标改变此模块的行为:

* debug - 往syslog(3)里写入更多的信息.
* nodate - 当显示最后登录的信息时隐藏具体日期.
* noterm - 当显示最后登录的信息时隐藏终端名称.
* nohost - 当显示最后登录的信息时隐藏客户机名称.
* silent - 不显示任何最后登录信息: 仅仅更新/var/log/lastlog .
* never - 如果/var/log/lastlog 没有包含此用户的任何曾经登录的信息, 则显示用户从未登录的信息: ``welcome..." .

范本/建议用法:

此模块可以用来在用户login后显示是否有新邮件. 下面是一个以/etc/pam.conf配置的样本:

#
# do we have any mail?
#
login session optional pam_lastlog.so

注意, 有些应用程序也许自己会实现这些功能. 这种情况下就不必使用此模块了.

6.12 资源限制模块
概要

模块名:

pam_limits
Authors:

Cristian Gafton <gafton@redhat.com>
Thanks are also due to Elliot Lee <sopwith@redhat.com> for his comments on improving this module.
维护者:

Cristian Gafton - 1996/11/20
提供的管理组:

session
Cryptographically sensitive:
安全等级:
代码清洁度:
系统依赖:

需要有/etc/security/limits.conf 设定档并且内核要支持资源限制. 也使用libpwdb 库.
网络接口:

概述

此模块通过Linux-PAM 的 开启-会话的钩子来设定用户会话能够获取的资源的限制. 由下面会讨论的设定档来更精确的支配动作.
Session component

识别的参数:

debug; conf=/path/to/file.conf
描述:

通过设定设定档/etc/security/limits.conf 的内容来设定用户会话的资源限制. uid=0 的用户不受此约束.

以下旗标可以用来改变此模块的行为:

* debug - 往syslog(3)写入冗长的记录.
* conf=/path/to/file.conf - 指定一个替换的limits设定档.

范本/建议用法:

为使用此模块, 系统管理员必须首先建立一个 root只读 的文件(默认是 /etc/security/limits.conf). 这文件描述了superuser想强迫用户和用户组的资源限制. uid=0的帐号不会受限制.

设定档的每一行描述了一个用户的限制,以下面的格式:

<domain> <type> <item> <value>

上面列出的栏位可以填下面的值:...
<domain> 可以是:

* 一个用户名
* 一个组名,语法是@group
* 通配符*, 定义默认条目

<type> 可以有一下两个值:

* hard 为施行硬 资源限制. 这些限制由superuser设定,由Linux内核施行. 用户不能提升他对资源的需求到大于此值.
* soft 为施行软 资源限制. 用户的限制能在软硬限制之间上下浮动. 这种限制在普通用法下可以看成是默认值.

<item> 可以是以下之一:

* core - 限制core文件的大小(KB)
* data - 最大的资料大小 (KB)
* fsize - 最大的文件尺寸 (KB)
* memlock - 最大能锁定的内存空间(KB)
* nofile - 最多能打开的文件
* rss - 最大的驻留程序大小(KB)
* stack - 最大的堆栈尺寸(KB)
* cpu - 最大的CPU 时间(分钟)
* nproc - 最多的进程数
* as - 地址空间的限制
* maxlogins - 用户的最多登录数
* priority - 用户进程执行时的优先级

要完全不限制用户(或组), 可以用一个(-)(例如: ``bin -'', ``@admin -''). 注意,个体的限制比组限制的优先级高, 所以如果你设定admin组不受限制, 但是组中的某个成员被设定档中某行限制, 那么此用户就会依据这样被限制.

还应该注意, 所有的限制设定只是每个登录的设定. 他们际不是全局的,也不是永久的 ; 之存在于会话期间.

在limits 的设定档中, ``#'' 开头的行为注解.

pam_limits 模块会通过syslog(3)报告它从设定档中找到的问题.

下面是个设定档的样本:

# EXAMPLE /etc/security/limits.conf file:
# =======================================
# <domain> <type> <item> <value>
* soft core 0
* hard rss 10000
@student hard nproc 20
@faculty soft nproc 20
@faculty hard nproc 50
ftp hard nproc 0
@student - maxlogins 4

注意, 对同一个资源(见@faculty)的软限制和硬限制 - 这建立了用户可以从指定服务会话中得到的默认和最大允许的资源数.

对于需要进行资源限制的服务例程(如login), 把下面一行放在/etc/pam.conf 里此服务的设定的最后一行(通常在pam_unix session后面):

#
# Resource limits imposed on login sessions via pam_limits
#
login session required pam_limits.so

6.13 The list-file module
概要

模块名:

pam_listfile
作者:

Elliot Lee <sopwith@cuc.edu>
维护者:

Red Hat Software:
Michael K. Johnson <johnsonm@redhat.com> 1996/11/18
(if unavailable, contact Elliot Lee <sopwith@cuc.edu>).
提供的管理组:

authentication
Cryptographically sensitive:
安全等级:
代码清洁度:

clean
系统依赖:
网络接口:

概述

list-file模块提供基于任意文件的对服务例程的拒绝或允许的设定
Authentication component

识别的参数:

onerr=succeed|fail; sense=allow|deny; file=filename; item=user|tty|rhost|ruser|group|shell apply=user|@group
描述:

这模块先获取指定类型的项目 -- user 指定用户名, PAM_USER; tty 指定请求建立时的获取的终端名, PAM_TTY; rhost 指定请求建立的主机 (如果有), PAM_RHOST; ruser指定对方主机中发起连接请求的用户名(如果可以), PAM_RUSER -- 然后寻找这些项目是否出现在filename中. filename每行包含一个项目. 如果找到对应项目, 那么如果 sense=allow, 则返回PAM_SUCCESS, 认证请求成功; 否则如果 sense=deny, 就返回PAM_AUTH_ERR, 认证请求失败.

如果有错误发生(比方, 如果 filename 不存在, 或者参数不完整), 那么如果onerr=succeed, 就返回PAM_SUCCESS , 否则如果onerr=fail, 就返回PAM_AUTH_ERR 或者 PAM_SERVICE_ERR.

附加的参数, apply=, 能够限制应用程序只对指定的用户 (apply=username)或指定的组(apply=@groupname)适用本规则. 这个附加的限制只对tty,rhost 和shell有意义.

除了这最后一个参数外, all arguments should be specified; do not count on any default behavior, as it is subject to change.

此模块不授予任何证书.
范本/建议用法:

传统的``ftpusers'' 认证可以由/etc/pam.conf下面的条目实现:

#
# deny ftp-access to users listed in the /etc/ftpusers file
#
ftp auth required pam_listfile.so \
onerr=succeed item=user sense=deny file=/etc/ftpusers

注意,列在/etc/ftpusers 里的用户将不允许访问ftp服务.

要只允许指定的用户可以登录, 你可以在pam.conf里设定以下的条目:

#
# permit login to users listed in /etc/loginusers
#
login auth required pam_listfile.so \
onerr=fail item=user sense=allow file=/etc/loginusers

要什这正常工作, 所有允许登录的用户都应该列在/etc/loginusers. 除非你明确的要试着把root所在门外, 否则在你这样设定好, 登出之前最好确认: 要么root列在/etc/loginusers, 要么列表里有用户可以su 成root.

6.14 The mail module
概要

模块名:

pam_mail
作者:

Andrew G. Morgan <morgan@linux.kernel.org>
维护者:

Author
提供的管理组:

Authentication (credential) Session (open)
Cryptographically sensitive:
安全等级:
代码清洁度:
系统依赖:

默认的邮件目录:/var/spool/mail/
网络接口:

概述

此模块查看用户的邮件目录并指示里面是否有邮件. whether the user has any mail in it.
Session component

识别的参数:

debug; dir=direcory-name; nopen; close; noenv; empty; hash=hashcount; standard; quiet;
描述:

此模块给用户提供"you have new mail" 的服务. 它可以嵌入到任何有凭证钩子的应用程序里. 它给一个信息指示用户的邮件目录中是否有最新的邮件. 此模块还设定Linux-PAM的环境变量 MAIL 为用户的邮件目录.

以下旗标可以用来改变此模块的行为:

* debug - 往syslog(3)里写入更多信息.
* dir=pathname - 从给定的pathname查找用户的邮件. 默认的邮件位置是/var/spool/mail. 注意,如果提供的pathname 以`~'开头, 意指目录是在用户的家目录里.
* nopen - 指示当用户获取证书时不要打印任何信息, 这旗标用来设定MAIL环境变量而不用显示任何信息.
* close - 指示模块当用户被撤回证书时检查是否有邮件.
* noenv - 不要设定MAIL 环境变量.
* empty - 当用户的邮箱是空的时候显示这状态.
* hash=hashcount - 邮件目录的hash深度. 比如, hashcount = 2 意味着邮箱是/var/spool/mail/u/s/user.
* standard - 旧的 "You have..." 格式, 不显示具体的邮箱位置. 同样实现"empty".
* quiet - 只在有新邮件时才报告.

范本/建议用法:

此模块用来当用户登录到系统是提示他有新邮件. 下面是/etc/pam.conf 的样本:

#
# do we have any mail?
#
login session optional pam_mail.so

注意,有些应用程序会自己实现这功能, 这种情形下,就不必使用此模块了.

Authentication compent

authentication 部件和session部件一样运作, 除了他在pam_setcred()阶段被激活.
6.15 在首次登录是创建用户家目录
概要

模块名:

pam_mkhomedir
作者:

Jason Gunthorpe <jgg@ualberta.ca>
维护者:

Ben Collins <bcollins@debian.org>
提供的管理组:

Session
Cryptographically sensitive:
安全等级:
代码清洁度:
系统依赖:
网络接口:

概述

为通过认证的用户按需创建家目录.
Session component

识别的参数:

debug; skel=skeleton-dir; umask=octal-umask;
描述:

此模块对于帐号集中管理(NIS,NIS+,或LDAP)并且多系统访问的分布式系统有用处. 它不需要管理员在每个系统都去建用户的家目录,而是当用户第一次成功登录时自动创建. skeleton目录(通常是/etc/skel/)用来拷贝默认文件, 这模块也为创建的文件设定umask.

以下旗标可以用来改变此模块的行为:

* skel - 从skeleton目录处拷贝默认文件到新创建的家目录.
* umask - 和你在shell下设umask同样格式的八进制数.

范本/建议用法:

session required pam_mkhomedir.so skel=/etc/skel/ umask=0022

6.16 输出motd文件
概要

模块名:

pam_motd
作者:

Ben Collins <bcollins@debian.org>
维护者:

Author
提供的管理组:

Session (open)
Cryptographically sensitive:
安全等级:
代码清洁度:
系统依赖:
网络接口:

概述

此模块在成功登录时输出motd文件 (默认是/etc/motd) .
Session component

识别的参数:

debug; motd=motd-file-name;
描述:

此模块允许你当成功登录后有任意的motd(当日消息)输出. 默认的文件是 /etc/motd, 但是可以设定为任意文件.

以下旗标可以用来改变此模块的行为:

* motd - 如果不打算用默认文件, 这里指定文件.

范本/建议用法:

login session pam_motd.so motd=/etc/motd

6.17 The no-login module
概要

模块名:

pam_nologin
作者:

Written by Michael K. Johnson <johnsonm@redhat.com>
(based on code taken from a module written by Andrew G. Morgan <morgan@parc.power.net>).
维护者:

Michael K. Johnson <johnsonm@redhat.com>
提供的管理组:

authentication
Cryptographically sensitive:
安全等级:
代码清洁度:

1个关于dropping const的警告
系统依赖:
网络接口:

概述

提供标准的Unix nologin的认证.
Authentication component

识别的参数:
描述:

提供标准的Unix nologin的认证. 如果存在/etc/nologin 文件, 则只有root允许登录; 其他用户会得到一个错误信息并且不能登入. 所有用户(root 或 其它用户) 会显示/etc/nologin里的内容.

如果不存在/etc/nologin , 此模块返回成功.
范本/建议用法:

为使此模块生效, 所有登录方法都要由此模块来把关. 为和传统UNIX的nologin相同作用, 它应该被作为required方法, 并且放在任何sufficient之前.

6.18 The promiscuous module
概要

模块名:

pam_permit
作者:

Andrew G. Morgan, <morgan@parc.power.net>
维护者:

Linux-PAM 维护者.
提供的管理组:

account; authentication; password; session
Cryptographically sensitive:
安全等级:

非常低. 极度小心的使用.
代码清洁度:

Clean.
系统依赖:
网络接口:

概述

此模块非常不安全. 必须谨慎使用. 它的动作是永远允许访问. 不做任何其它事情.
Account+Authentication+Password+Session components

识别的参数:
描述:

不管用在哪种管理组, 这模块的动作只是简单的返回 PAM_SUCCESS -- 操作成功.

在认证部件里, 用户名会被获取. 很多应用程序在不知道用户名时会觉得不合理.
范本/建议用法:

很难找到应用此模块的正当理由. 可是, 它还是有些合理的应用. 比如, 系统管理员想要关闭工作站的帐号管理, 同时又要允许登录, 那么她可以用下面的配置条目设定ligin:

#
# add this line to your other login entries to disable account
# management, but continue to permit users to log in...
#
login account required pam_permit.so

6.19 The Password-Database module
概要

模块名:

pam_pwdb
作者:

Cristian Gafton <gafton@redhat.com>
and Andrew G. Morgan <morgan@linux.kernel.org>
维护者:

作者.
提供的管理组:

account; authentication; password; session
Cryptographically sensitive:
安全等级:
代码清洁度:
系统依赖:

需要正确的配置libpwdb
网络接口:

概述

此模块是pam_unix_..的可插入式的替代品. 它使用Password Database的通用接口. http://linux.kernel.org/morgan/libpwdb/index.html.
Account component

识别的参数:

debug
描述:

参数 debug 令此模块的帐号管理功能在动作时syslog(3)更多的信息. (由别的功能支持的参数被忽略掉, 但是会在syslog(3) 记录下错误信息.

基于以下的 pwdb_元件: expire; last_change; max_change; defer_change; warn_change, 此模块执行确认帐号和密码状态的任务. 至于后来, 它可以给用户提出修改密码的建议或者, 通过PAM_AUTHTOKEN_REQD的返回, 延迟为用户提供服务直到他创建了一个新密码. 以上列出的条目在Password Database Library Guide里有解释. documented in the Password Database Library Guide (见上面的链接). 如果用户记录不包含一个或者更多这些条目, 对应的shadow 检查不被执行.
范本/建议用法:

在帐号管理模式, 这模块可以象下面的用法:

#
# 确保用户帐号和密码依然有效
#
login account required pam_pwdb.so

Authentication component

识别的参数:

debug; use_first_pass; try_first_pass; nullok; nodelay; likeauth
描述:

参数 debug 令模块的认证功能写入syslog(3)更多的信息.

如果用户的official密码为空, 此模块的默认动作是不允许用户访问服务. 参数nullok 用来使此默认失效.

当给出参数try_first_pass, 在提示用户输入密码之前, 模块会拿通过之前堆叠的 auth模块认证的密码来试. 参数use_first_pass 迫使模块使用上述的密码并且永远不会提示用户 - 如果没有可用的密码或密码不能通过认证, 用户将被禁止访问.

参数 nodelay 用来阻止认证部件在认证失败时的延时请求. 默认动作是请求一个一秒钟以上的失败-延迟.

由别的功能支持的参数被忽略掉, 但是会在syslog(3) 记录下错误信息.

有个帮手程序, pwdb_chkpwd, 用来检查用户的密码(当密码报存在一个只读数据库时). 此程序非常简单,只检查当前用户的密码. 它被此模块的认证部件以当前用户的身份显式的呼叫. 这样象xlock这样的程序就不需被设成setuid-root而可以工作.

The likeauth argument makes the module return the same value when called as a credential setting module and an authentication module. This will help libpam take a sane path through the auth component of your configuration file.
范本/建议用法:

此模块的完整功能由一个恰当的/etc/pwdb.conf来控制, 指定的用户数据库控制用户认证的来源.

Password component

识别的参数:

debug; nullok; not_set_pass; use_authtok; try_first_pass; use_first_pass; md5; bigcrypt; shadow; radius; unix
描述:

pam_pwdb模块的这一部分执行更新用户密码的任务. 受惠于libpwdb的灵活性, 此模块可以把用户密码从一个数据库搬到另一个去, 也许以动态的方式使用户密码记录安全 (此时还处于初期ALPHA阶段!) - 这正是shadow, radius 和 unix 参数的意图.

在传统的UNIX密码数据库(这里保存着用户的加密密码)的情况下, 参数md5用来采用MD5的加密算法以取代传统的 crypt(3)呼叫. 还有种选择, 参数 bigcrypt 采用DEC(数字设备公司)的对标准UNIX的crypt()的算法进行`C2'扩展的算法以加密超过8位长的密码.

参数nullok 用来允许改变一个原先为空的密码. 如果没有此参数, 空的密码会当成是被锁住的帐号.

参数use_first_pass 用来阻止选择旧的和新的密码,而是采用password里此模块之前的模块所保留的密码. 参数try_first_pass用来防止当pam_pwdb 跟随另一个password模块时用户重复输入也许是共享的旧密码 - 如果旧密码不正确, 再提示用户输入. 参数use_authok 用来迫使 此模块设定新密码时采用 password堆叠里先前的模块提供的值. (这用法在先前介绍的Cracklib一节里有个范本).

参数 not_set_pass 用来告诉模块不去关心给/从其它(堆叠的)密码模块提供/获取可用的旧密码或新密码.

参数debug 使此模块的password功能syslog(3)更多的动作的信息. 其它参数会往syslog(3) 写进错误信息.
范本/建议用法:

有关如何将此模块与可插入式密码检查模块,pam_cracklib一起堆叠的例子, 请见上面的pam_cracklib一节.

Session component

识别的参数:
描述:

模块的此部件没有参数. 它的作用就是在用户会话开始和结束时往syslog(3) 里记录用户名和服务类别.
范本/建议用法:

session部件的用法是单纯的:

#
# pwdb - unix like session opening and closing
#
login session required pam_pwdb.so

6.20 The RADIUS session module
概要

模块名:

pam_radius
作者:

Cristian Gafton <gafton@redhat.com>
维护者:

作者.
提供的管理组:

session
Cryptographically sensitive:

此模块不用来处理密码
安全等级:
代码清洁度:

在编译 /usr/include/rpc/clnt.h时gcc报告一个警告. Hey, is not my fault !
系统依赖:
网络接口:

是的; 这是个网络模块(独立于应用程序).

概述

此模块用来提供用户从RADIUS服务器认证的会话服务. 目前阶段, 唯一提供的功能是以RADIUS服务器当一个帐号服务器来使用.
Session component

识别的参数:

debug - 冗余的信息写进syslog(3).
描述:

此模块用来提供用户从RADIUS服务器认证的会话服务. 目前阶段, 唯一提供的功能是以RADIUS服务器当一个帐号服务器来使用.

(There are few things which needs to be cleared out first in the PAM project until one will be able to use this module and expect it to magically start pppd in response to a RADIUS server command to use PPP for this user, or to initiate a telnet connection to another host, or to hang and call back the user using parameters provided in the RADIUS server response. Most of these things are better suited for the radius login application. I hope to make available Real Soon (tm) patches for the login apps to make it work this way.)

当开启一个会话时, 此模块发送一个``Accounting-Start'' 消息给RADIUS服务器, 服务器将会记录/更新此用户的有关记录. 而当会话关闭时, 一个``Accounting-Stop'' 消息会发给RADIUS服务器.

此模块无须其它的必要条件以使其工作. 兴趣所致, 你要安装一个RADIUS服务器, 然后以此服务器为一个集中的帐号管理服务器, 忘掉wtmp/last/sac这些东西.
范本/建议用法:

为使服务(例如login)使用此模块, 把下面一行加入/etc/pam.conf, 放在此服务的最后一行(通常在session段的pam_unix之后):

login session required pam_radius.so

把login替换成你想要的其它服务名.

此模块大量使用了libpwdb0.54preB或其后版本的API. 默认情况下, 它会从 /etc/raddb/server读取RADIUS服务器的设定(主机名和加密方法). 这是libpwdb默认编译时的设定, 目前没有办法不经重编译libpwdb来改变这个默认设定. 我正在为libpwdb的radius支持进行扩展以使其提供运行时可设定功能.

还请注意libpwdb还需要你提供RADIUS的目录(/etc/raddb/dictionary).

6.21 The rhosts module
概要

模块名:

pam_rhosts_auth
作者:

Al Longyear <longyear@netcom.com>
维护者:
提供的管理组:

authentication
Cryptographically sensitive:
安全等级:
代码清洁度:

干净.
系统依赖:
网络接口:

呼叫标准的inet_addr(), gethostbyname() 函数.

概述

此模块为传统的如rlogin和rsh的服务提供基于网络的认证.
Authentication component

识别的参数:

no_hosts_equiv; no_rhosts; debug; no_warn; privategroup; promiscuous; suppress
描述:

此模块的认证机制基于两个文件: /etc/hosts.equiv (或为_PATH_HEQUIV 定意在#include <netdb.h>) 和 ~/.rhosts. 首先, 列在前一个文件里的主机会被当成localhost一般对待. 第二, 后一个用户自己的文件的条目用来对照"远程主机 远程用户"到当前主机的帐号. 如果远程主机列在/etc/hosts.equiv,并且远程用户的帐号和本机用户一致或者远程用户的帐号在个人设定档中有登记则访问被允许.

用户的私人设定档会有些限制:它必须是一个常规文件(POSIX.1定意为S_ISREG(x)) ; 它必须属于superuser或本用户;出了所有者之外其它用户必须不可写.

此模块认证从远程主机(内部用PAM_RHOST指定)连线的远端用户 (内部用PAM_RUSER指定). 因此, 应用程序如果要兼容此认证模块, 它们必须在呼叫pam_authenticate()之前设定好这些条目. 模块本生没有能力去独立的侦测这些网络连接信息.

至于root的访问, 除非使用hosts_equiv_rootok选项, /etc/host.equiv将被忽略. 替代的是, superuser必须有设定正确的私人设定档.

此模块的动作可有一下旗标修改:

* debug - 记录冗余的信息到syslog(3). (XXX - 事实上, 此模块目前不记录任何信息, 请自愿的修复它!)
* no_warn - 不要给用户发送更多的有关失败的警告信息. (XXX - 此模块当前不会发布任何警告信息, 请自愿的修复它!)
* no_hosts_equiv - 忽略/etc/hosts.equiv .
* hosts_equiv_rootok - 允许superuser也使用 /etc/hosts.equiv. 如果没有这选项,/etc/hosts.equiv 不被superuser帐号考虑. 如果同时有no_hosts_equiv, 此选项会失效.
* no_rhosts - 忽略所有用户的私人设定档:~/.rhosts.
* privategroup - 通常, ~/.rhosts 必须不能为除了所有者之外的任何人可写. 此选项针对组所有者和进行认证的拥有者同名的文件放宽组写的权限. 为减小此选项可能带来的安全隐患, 此模块还检查用户是否为那个组的唯一成员.
* promiscuous - 有此选项, 以`+' 作为主机名将导致所有的主机都被赋予访问权限. 没有此选项, `+'的记录会被忽略, debug选项会往syslog里记录一个警告.
* suppress - 这将阻止模块在当认证失败时syslog(3) 警告信息. 这选项主要用来使日志免于无意义的错误记录, 尤其是当模块被当成sufficient模式所用时.

范本/建议用法:

为允许用户从信任的远程主机登录, 你得把下面一行加入你的/etc/pam.conf, 并且在其他会提示用户输入密码的模块之前 :

#
# No passwords required for users from hosts listed above.
#
login auth sufficient pam_rhosts_auth.so no_rhosts

注意, 在这个例子里, 系统管理员关闭了所有个人的 rhosts设定档. 还请注意, 此模块可用来设定成只允许在/etc/host.equiv文件里指定的远程主机登录, 只要把sufficient改成required.

6.22 The root access module
概要

模块名:

pam_rootok
作者:

Andrew G. Morgan <morgan@parc.power.net>
维护者:

Linux-PAM maintainer
提供的管理组:

authentication
Cryptographically sensitive:
安全等级:
代码清洁度:

Clean.
系统依赖:
网络接口:

概述

此模块用在superuser希望不需要输入密码就能获取访问权限的情形.
Authentication component

识别的参数:

debug
描述:

此模块认证uid是0的用户. 创建成setuid-root的应用程序通常保留用户的uid但是以有效的-uid的权限执行. 真实的uid会被检查.
范本/建



【发表回复】【查看论坛原帖】【添加到收藏夹】【关闭】

--------------------------------------------------------------------------------
ipod 回复于:2004-08-19 15:14:34
完全版?谢谢楼主先



--------------------------------------------------------------------------------
gentoo 回复于:2004-08-19 15:46:27
谢谢!



--------------------------------------------------------------------------------
thomassun 回复于:2004-08-20 11:12:39
Part 2:
议用法:

对于su的传统的用法是允许superuser不经输入密码的变更为其它次要的用户的身份. 为在Linux-PAM里实现这种行为, 下面两行需要加入设定档:

#
# su authentication. Root is granted access by default.
#
su auth sufficient pam_rootok.so
su auth required pam_unix_auth.so

注意. 对于以superuser执行(或者在系统开机时被开启)的程序, 应该不要用此模块去认证用户.

6.23 The securetty module
概要

模块名:

pam_securetty
作者:

Elliot Lee <sopwith@cuc.edu>
维护者:

Red Hat Software:
currently Michael K. Johnson <johnsonm@redhat.com>
(if unavailable, contact Elliot Lee <sopwith@cuc.edu>).
提供的管理组:

authentication
Cryptographically sensitive:
安全等级:
代码清洁度:
系统依赖:

/etc/securetty file
网络接口:

为使此有意义的, 需要应用程序设定正确的PAM_TTY.

概述

提供标准的UNIX的安全的tty的认证.
Authentication component

识别的参数:
描述:

提供标准的Unix安全tty的检查, 除非PAM_TTY的值列在 /etc/securetty里, 对root的认证将会失败. 对所有其他用户, 则为成功.
范本/建议用法:

规范的用法, 这模块应该作为required的认证方法出现在任何 sufficient 的认证之前.

6.24 Time control
概要

模块名:

pam_time
作者:

Andrew G. Morgan <morgan@parc.power.net>
维护者:

Author
提供的管理组:

account
Cryptographically sensitive:
安全等级:
代码清洁度:
系统依赖:

需要一个设定档:/etc/security/time.conf
网络接口:

仅通过PAM_TTY

概述

运行一个规范得很好的系统偶尔也会包含对特定服务的有选择的限制访问. 此模块提供了对系统服务的时间上的访问控制. 它的行为由一个设定档决定. 此模块可以设定成基于用户名, 时间, 星期, 具体服务和请求服务时的终端名的对(单个)用户的拒绝访问.
Account component

识别的参数:
描述:

此模块基于设定档中的制定的规则进行动作:/etc/security/time.conf. m每个规则有如下格式,

services;ttys;users;times

每个规则占一行, 结束于换行符或者注解的开始:`#'. 由分号`;' 分隔成四个栏位. 这些栏位是:

* services - 由此规则影响的服务名的逻辑列.
* ttys - 指示受此规则保护的终端名字的逻辑列表逻辑列表.
* user - 此规则作用到的用户的逻辑列表.

逻辑列表意味一串符号(和适当的PAM_相关), 包含不超过一个的通配符:`*', 和可选的非操作符的前置:`!'. 这一串表达式由两个逻辑操作符连接:& (逻辑与)和| 逻辑或). 两个例子:!morgan&!root, 表示此规则不会应用到用户morgan和root;tty*&!ttyp*, 表示此规则仅对控制台终端而不是伪终端适用.
* times - 此规则的适用时间的逻辑列表. 每个元件的格式是周/时间-范围. 周由两个字符指定.比如, MoTuSa, 表示周一周二和周六. 注意重复的周被 复位; MoTuMo 表示周二, MoWk 意为除了周一的所有工作日. 两个字符的组合可以是,

Mo Tu We Th Fr Sa Su Wk Wd Al

最后两个词是周末和 每周的整个7天.

时间范围部分是一对24时制的时间, HHMM, 以一个连字符隔开 -- 表示开始和结束的时间. 如果结束时间早于开始时间, 就假定是到第二天的这个结束时间. 例如, Mo1800-0300 表示允许的时间是从周一的晚上6点到第二天早上3点.

注意, 时间的限制只有在当前3个栏位都满足用户请求服务的应用时才适用.

为了便利和可读性, 一条规则可以由`\换行符'结尾以超过一行.
范本/建议用法:

要使用此模块可以在Linux-PAM的设定档里加入下面的行:

#
# apply pam_time accounting to login requests
#
login account required pam_time.so

这里, 我们把这模块应用在login的服务.

可以放在/etc/security/time.conf里的规则举例如下:

login ; tty* & ; !ttyp* ; !root ; !Al0000-2400

除了root,禁止所有用户在任何时间从控制台登录.
games ; * ; !waster ; Wd0000-2400 | Wk1800-0800

games (使用Linux-PAM的某游戏) 只在非工作时间可以访问. 此规则不限制用户waster.

注意, 目前还没有一个后台进程去强制终止一个超过时间范围的会话. 这要有个对策.

错误格式的规则会作为错误记录在 syslog(3).

6.25 The Unix Password module
概要

模块名:

pam_unix
作者:
维护者:

作者.
提供的管理组:

account; authentication; password; session
Cryptographically sensitive:
安全等级:
代码清洁度:
系统依赖:
网络接口:

概述

这是标准Unix的认证模块. 它从系统库呼叫标准的调用来获取和设定帐号信息以及认证信息. 通常这些从/etc/passwd和/etc/shadow文件(如果开启了shadow功能)获得.
Account component

识别的参数:

debug; audit
描述:

参数debug 使此模块的帐户相关的函数syslog(3)更多的它的动作的信息 (属于此模块的其它功能的参数会被直接忽略掉, 但是别的参数会当成错误而被 syslog(3)). 参数audit会丢出更多的信息.

基于以下的shadow 元素: expire; last_change; max_change; min_change; warn_change, 此模块执行确认帐号和密码状态的工作. 至於后面, 它可以建议用户改变密码或, 通过返回PAM_AUTHTOKEN_REQD, 延迟给用户提供服务直到其生成一个新密码. 列在上面的那些元素在GNU Libc的info文档里有解释. 如果用户的记录里没有包含一个或者更多的这些元素, 相对的shadow检查将不被执行.
范本/建议用法:

在帐号管理模式下, 可以这样来安装此模块:

#
# Ensure users account and password are still active
#
login account required pam_unix.so

Authentication component

识别的参数:

debug; audit; use_first_pass; try_first_pass; nullok; nodelay
描述:

参数debug 使此模块的帐户相关的函数syslog(3)更多的它的动作的信息. 参数audit会丢出更多的信息.

此模块的默认设定是如果正式的密码为空则不允许用户访问服务. 参数nullok 用来使此默认设定无效.

当给出参数try_first_pass, 在提示用户输入密码之前, 模块会拿通过之前堆叠的 auth模块认证的密码来试. 参数use_first_pass 迫使模块使用上述的密码并且永远不会提示用户 - 如果没有可用的密码或密码不能通过认证, 用户将被禁止访问.

参数 nodelay 用来阻止认证部件在认证失败时的延时请求. 默认动作是请求一个一秒钟以上的失败-延迟.

属于此模块的其它功能的参数会被直接忽略掉, 但是别的参数会当成错误而被 syslog(3).

一个帮手程序, unix_chkpwd, 在当用户的密码报存在一个读保护的数据库里时提供对用户密码的检查. 这个程序非常简单, 它仅仅检查呼叫它的用户的密码. 它被此模块的认证部件以用户的名义来透明的呼叫. 如此象xlock这样的程序就不需被设成setuid-root而可以工作.
范本/建议用法:

此模块的正确功能可以由一个适当的/etc/nsswitch.conf 来支配, 那里指定的用户数据库确定用来认证的用户记录的来源.

在帐号管理模式下, 可以这样来安装此模块:

#
# Authenticate the user
#
login auth required pam_unix.so

Password component

识别的参数:

debug; audit; nullok; not_set_pass; use_authtok; try_first_pass; use_first_pass; md5; bigcrypt; shadow; nis; min; max; obscure; remember
描述:

pam_unix 模块的这一部分执行更新用户密码的任务.

对于传统的UNIX用户数据库(同时保存用户密码), 参数md5 用来采用MD5的加密法以对抗不安全的传统的 crypt(3)调用. 还有种选择, 参数 bigcrypt 采用DEC(数字设备公司)的对标准UNIX的crypt()的算法进行 `C2'扩展的算法以加密超过8位长的密码.

参数nullok 用来允许改变一个原先为空的密码. 如果没有此参数, 空的密码会当成是被锁住的帐号.

参数use_first_pass 用来阻止选择旧的和新的密码,而是采用password里此模块之前的模块所保留的密码. 参数try_first_pass用来防止当pam_pwdb 跟随另一个password模块时用户重复输入也许是共享的旧密码 - 如果旧密码不正确, 再提示用户输入. 参数use_authok 用来迫使 此模块设定新密码时采用 password堆叠里先前的模块提供的值. (这用法在先前介绍的Cracklib一节里有个范本).

参数 not_set_pass 用来告诉模块不去关心给/从其它(堆叠的)密码模块提供/获取可用的旧密码或新密码.

参数debug 使此模块的密码相关的函数syslog(3)更多的它的动作的信息. 其它参数会被当成错误信息记录在syslog(3). 参数audit会丢出更多的信息.

通过设定nis 参数, pam_unix 会试图采用NIS RPC来设定新密码.

参数remember 带有一个值. 这值是为每个用户保存的最近使用的密码的个数. 它们被保存在/etc/security/opasswd 以防止用户频繁的交替使用同样的一组密码.

参数min 和 max 允许控制密码的常度. 有个固定的默认值是1到8. 这些值本身算在内.

参数obscure 允许一些额外的密码检查. 这效仿原始的shadow包里的含糊检查, 这过程和pam_cracklib模块非常相像(不做字典检查), 它执行以下一些检查:

* Palindrome - 新密码是否为旧密码的回文? 回文是指顺着读和反着读都一样的词(比如madam和radar).
* Case Change Only - 新密码是否只是拿旧密码改了些大小写?
* Similar - 新密码是否太像旧密码?
* Simple - 新密码是否太简单? 这决定于密码的长度和采用不同种字符的个数(比如,字母, 数字...).
* Rotated - 新密码是否为旧密码的轮转?(比如,"billy"和"illyb")

范本/建议用法:

标准用法:

#
# Change the users password
#
passwd password required pam_unix.so

和可插入式密码检查模块,pam_cracklib 关联堆叠的例子:

#
# Change the users password
#
passwd password required pam_cracklib.so retry=3 minlen=6 difok=3
passwd password required pam_unix.so use_authtok nullok md5

Session component

识别的参数:
描述:

模块的此部件没有参数. 它的作用就是在用户会话开始和结束时往syslog(3) 里记录用户名和服务类别.
范本/建议用法:

session部件的用法是单纯的:

#
# session opening and closing
#
login session required pam_unix.so

6.26 The userdb module
概要

模块名:

pam_userdb
作者:

Cristian Gafton <gafton@redhat.com>
维护者:

作者.
提供的管理组:

authentication
Cryptographically sensitive:
安全等级:
代码清洁度:
系统依赖:

需要有 Berkeley DB.
网络接口:

概述

在一个.db数据库里查找用户并且与报存在这数据库中的密码进行比对.
Authentication component

识别的参数:

debug; icase; dump; db=XXXX;
描述:

此模块用来与储存在BerkeleyDB数据库里的资料对用户/密码进行验证. 数据库以用户名为索引, 和用户名对应的栏位是以明码形式保存的密码, so caution must be exercised over the access rights to the DB database itself.. 模块以交互机制从用户端获取输入的密码. 如果此密码用在其他认证模块(象pam_unix )的前面, 那么你得要告诉那些模块从PAM_AUTHTOK(由此模块设定)处读取输入的密码.

模块的默认动作可以由以下的参数改变:

* debug - 给syslog(3)提供更多的调信息.
* icase - 忽略大小写的密码比对.
* dump - 往log里下载数据库里所有的的记录.(呀, 默认情况下不要这样做!)
* db=XXXX - 使用XXXX这个数据库文件. 注意, Berkeley DB通常会在文件名后面加上扩展名, 所以你得像 /etc/foodata 这样指定文件而不是/etc/foodata.db.

范本/建议用法:

这是一个ftp服务的设定档(通常是 /etc/pam.d/ftp ), 会接受用户名/密码对存放在/tmp/dbtest.db中的用户登入.

#%PAM-1.0
auth required pam_listfile.so item=user sense=deny file=/etc/ftpusers onerr=succeed
auth sufficient pam_userdb.so icase db=/tmp/dbtest
auth required pam_unix.so shadow nullok try_first_pass
auth required pam_shells.so
account required pam_unix.so
session required pam_unix.so

6.27 Warning logger module
概要

模块名:

pam_warn
作者:

Andrew G. Morgan <morgan@parc.power.net>
维护者:

作者.
提供的管理组:

authentication; password
Cryptographically sensitive:
安全等级:
代码清洁度:
系统依赖:
网络接口:

记录远程用户和远程主机的信息(如果可以知道相关的pam-items)

概述

此模块主要用来记录试图进行认证或者更新密码的动作.
Authentication+Password component

识别的参数:
描述:

往syslog(3)里记录服务名,终端名,用户名,远端用户名和远程主机. 不是所有的项目都能侦测到, but instead obtained from the standard pam-items.
范本/建议用法:

在设定档一节 above有一个范本 .

6.28 The wheel module
概要

模块名:

pam_wheel
作者:

Cristian Gafton <gafton@redhat.com>
维护者:

作者.
提供的管理组:

authentication
Cryptographically sensitive:
安全等级:
代码清洁度:
系统依赖:
网络接口:

概述

只给属于whell(gid=0)群组的用户授予root的访问权限.
Authentication component

识别的参数:

debug; trust; deny; group=XXXX
描述:

此模块用来实现所谓的重要人物 群组. 默认设定时, 如果请求的用户是wheel 的组成员就赋予其root的的访问权限. (首先, 模块检查组wheel是否存在. 如果不存在,那么id=0的组被当作wheel.

模块的默认动作可以通过在/etc/pam.conf里设定以下参数来改变:

* debug - 提供更多的调试信息给syslog(3).
* trust - 此选项指示模块当一个请求root权限的用户是wheel组的成员时返回PAM_SUCCESS. 这种情况的默认动作是返回 PAM_IGNORE . 使用trust 选项可以使 wheel的组成员未经输入密码就能成为root. 小心使用.
* deny - 这选项用来推翻模块的行为逻辑. 如果一个属于wheel组的用户试图得到uid=0 的权限时, 就禁止访问(wheel这个词也许就变得毫无意义!): 其目的是为了接下来的group= 参数而为.
* group=XXXX - 代替对gid=0的组的眷顾, 而使用用户自己定意XXXX组. 这里的XXXX是组的名字而不是组的ID.

范本/建议用法:

为把能取得superuser权限的用户限制在wheel里, 使用下面的设定:

#
# 默认给root赋权限(rootok), 只有wheel的组成员有可能成为root( wheel), 但仍然必须
# 通过unix_auth的认证.
#
#
su auth sufficient pam_rootok.so
su auth required pam_wheel.so
su auth required pam_unix_auth.so

7. 文件

/usr/lib/libpam.so.*

提供给应用程序访问Linux-PAM API的共享库.
/etc/pam.conf

Linux-PAM的设定档.
/usr/lib/security/pam_*.so

Linux-PAM 的动态可装载目标文件(模块)的主要所在位置.