Chinaunix首页 | 论坛 | 博客
  • 博客访问: 131386
  • 博文数量: 36
  • 博客积分: 2092
  • 博客等级: 大尉
  • 技术积分: 390
  • 用 户 组: 普通用户
  • 注册时间: 2010-05-04 17:33
文章分类
文章存档

2011年(18)

2010年(18)

我的朋友

分类: LINUX

2011-07-15 10:57:04

Pluggable Authentication Modules for Linux 可插拨认证模块
pam模块负责了系统中各服务认证的工作。各种服务的pam配置文件在/etc/pam.d/目录下。pam的模块存放在/lib/security/目录下面,模块的说明文档在/usr/share/doc/下。
检查服务是否提供了pam验证:运行命令  ldd /服务/命令路径/服务名 ;看有没有加载libpam.so模块。(此命令也可以检查libwrap.so模块,查看服务是否支持TCP_wrappers)
配置文件的格式如下:     Module-type    control-flag      module-path    arguments
PAM验证类型Module-type:
    * auth 验证使用者身份,提示输入账号和密码
    * account 基于用户表、时间或者密码有效期来决定是否允许访问
    * password 禁止用户反复尝试登录,在变更密码时进行密码复杂性控制
    * session 进行日志记录,或者限制用户登录的次数
PAM验证控制类型(Control Values)用于PAM验证类型的返回结果。
    * required 验证失败时仍然继续,但返回Fail(用户不会知道哪里失败)/ 必须的,但在前一个模块认证错误后继续下一个模                       块的认证,认证的结果是失败的
    * requisite 验证失败则立即结束整个验证过程,返回Fail/如果认证失败,停止认证的过程
    * sufficient 验证成功则立即返回,不再继续,否则忽略结果并继续/足够的,充分条件,满足这个条件,可以跳过接下来的认证
    * optional 无论验证结果如何,均不会影响(通常用于session类型)/ 可选的,正确或错误都通过
module-path  模块路径 
arguments   模块参数规则
很多pam配置文件都调用了system-auth配置文件。这个配置文件是一个公共的服务,修改这个文件,会影响其他服务的认证。
        
实验1:目的:限制用户登录次数错误,锁定策略
需要的pam模块:pam_tally2.so
#vi /etc/pam.d/login
增加一行:  auth    requisite   deny=2  lock_time=10  unlock_time=300
实验2:目的:用pam_filelist.so模块禁止让指定用户登录
login配置文件:/etc/pam.d/login
增加一行:auth          requisite           pam_filelist.so                   item=user         sense=deny      onerr=succeed         file=/etc/userlist
然后在文件/etc/userlist中写入禁止登录的用户名。指定的用户登录时,直接拒绝。没有写入文件的用户,在满足接下来的验证条件后,再登录系统。
故障检测
当系统验证出现问题时,首先应当检查/var/log/messages或者/var/log/secure中的输出信息,根据这些信息判断用户账号的有效性。如果是因为PAM验证故障,而引起root也无法登录,只能使用single user或者rescue模式进行排错。
几个例子
#vi click.c
内容:
#include
#include
#include
static struct pam_conv conv = {
 misc_conv, //定义在pam_misc.h中, 方便你编程
 NULL
};
int main(int argc, char *argv[])
{
 pam_handle_t *pamh=NULL;
 int retval;
 const char *user="root"; //用户名设置为系统上的一个合法用户
 if(argc == 2) {
  user = argv[1];
 }
 if(argc > 2) {
  fprintf(stderr, "Usage: check_user [username]/n");
  exit(1);
 }
 retval = pam_start("check_user", user, &conv, &pamh);
 /* 开始 */
 if (retval == PAM_SUCCESS)
  retval = pam_authenticate(pamh, 0);
 
 /* 认证是不是该用户? 提示你输入一个密码 */
 if (retval == PAM_SUCCESS)
  retval = pam_acct_mgmt(pamh, 0);
 /* 账号是否有效? */
 if (retval == PAM_SUCCESS) {
  fprintf(stdout, "Authenticated/n");
 } else {
  fprintf(stdout, "Not Authenticated/n");
 }
 if (pam_end(pamh,retval) != PAM_SUCCESS) {
  /* 结束 */
  pamh = NULL;
  fprintf(stderr, "check_user: failed to release authenticator/n");
  exit(1);
 }
 return ( retval == PAM_SUCCESS ? 0:1 ); /* indicate success */
}
编译要这样:#gcc check.c -ldl -lpam -lpam_misc -o check_user
编译得到这个check_user这个可执行程序之后,在/etc/pam.d/目录下,添加一个文本文件,保存为check_user(要同源码 pam_start函数的第一个参数一样)
#Vi /etc/pam.d/check_user
内容:
auth required /lib/security/pam_unix_auth.so
account required /lib/security/pam_unix_acct.so
接下来便是验证这个程序了:[root@ecy c]# ./check_user
Password:
Authenticated
ok,输入密码为源码中users对应的用户的密码。通过这个程序能略知PAM的工作方式。
从来没有意识到PAM在Linux运用如此之广,重要如此之大。
我们知道,当我们登陆系统的时候,是要运行login程序的,在/etc/pam.d/目录下是有一个login文件的,查看下里面的内容:
[root@ecy pam.d]# cat login
#%PAM-1.0
auth [user_unknown=ignore success=ok ignore=ignore default=bad] pam_securetty.so
auth       include      system-auth
account    required     pam_nologin.so
account    include      system-auth
password   include      system-auth
# pam_selinux.so close should be the first session rule
session    required     pam_selinux.so close
session    required     pam_loginuid.so
session    optional     pam_console.so
# pam_selinux.so open should only be followed by sessions to be executed in the user context
session    required     pam_selinux.so open
session    required     pam_namespace.so
session    optional     pam_keyinit.so force revoke
session    include      system-auth
session    optional     pam_ck_connector.so
我开始意识到是不是我们的login程序也象上面那个check_user程序一样调用了大量PAM的API,于是我要验证一下:
[root@ecy pam.d]# strings /bin/login | grep pam
libpam.so.0
pam_close_session
pam_set_item
pam_authenticate
pam_strerror
pam_setcred
pam_start
pam_getenvlist
pam_acct_mgmt
pam_end
pam_chauthtok
pam_get_item
pam_open_session
libpam_misc.so.0
呵呵,确实是这样的。
Linux中几乎所有的服务都用到了PAM,比如vsftpd。
[root@ecy pam.d]# strings /usr/sbin/vsftpd | grep pam
libpam.so.0
pam_close_session
pam_set_item
pam_authenticate
pam_setcred
pam_start
pam_acct_mgmt
pam_end
pam_open_session
tunable_pam_service_name
pam_service_name
dodgy nmsg in pam_conv_func
可见PAM对于Linux正常运行所具有的重要意义。
PAM的核心库放在/lib/目录下,可动态加载的库放在/lib/security目录下。在/etc/security/console.apps目录下有很多配置文件,很多sys-config-*的文件,事实上/usr/bin/sys-config-*都只是/usr/bin/consolehelper这个可执行文件的符号链接,不知道具体是如何运作的。如果将这个/etc/security/console.apps目录下相应的项删除掉,那么在终端再输入相应的命令就会提示错误了,这些配置文件应该是用于PAM管理终端会话的。
阅读(1571) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~