debian 里面 PAM 需要下面几个包:
- libpam-runtime 含有常用的 pam 认证脚本(在 /usr/share/pam/common-*),pam_getenv(获得环境变量的程序)和一些帮助文件。
- libpam-modules 含有常用的 pam 模块和帮助文件。
- libpam-doc 帮助文档。
- libpam-* 一些特殊的 pam 模块。
传统 Unix 下用户认证一般要求用户输入用户名,然后是密码。但是这限制了认证的方式,也不利于编写程序人的目的。因为往往程序编写者是为了给用户提供另外一个功能,如果需要独立实现某种认证方式,那样并不能使其他的程序获得类似的好处。PAM 的出现给出了一种解决的方案。
我们来看一个 PAM 脚本包括哪些东西。一般 /etc/pam.conf 里面是 PAM 的配置,但是为了给每个程序设定独立的 PAM 脚本,一般放在 /etc/pam.d/<程序名>。因此,可以参考一下这些文件,看看下面我们所说的东西是如何应用到一个实际的例子上的。有四种类型的任务,account 用来在给出了用户名后检查一些信息,如帐户过期否,是否存在;auth 用于认证,即要求用某种方式,如输入密码证明自己是 account 里面所声明的人;password 用于更改密码相关信息;seesion 用于建立起需要的环境,如更改 UID、GID 等。每一个任务可以用多个模块检测,我们可以设定这个检测过程的性质,如 required 表明如果失败将会最终导致 PAM 返回 failure,但是这不会中断继续测试下面的模块;requisite 表明如果 fail 直接返回,这是因为在某些情况下,如登录用户 root 在不安全的信道上,如果输入了 root 不是立即中断的话,root 密码可能就在该信道上传输了,这种情况有必要直接在 accout 上 requisite 不是 root;sufficient 是指如果通过则可以忽略 required 的 failures,如果失败也不要紧(不影响最终结果);optional 成功与否当且仅当这是唯一的一个检测;include 用于包含其他的文件。
下面我们来看几个简单的例子,这是 su:
auth sufficient pam_rootok.so第一句话说明如果是 root 调用 su,那么就返回成功。后面通过 session 建立了环境变量、locale 并检查 mail。那么 common-auth 等文件里面有什么呢?common-auth 里面是
session required pam_env.so readenv=1
session required pam_env.so readenv=1 envfile=/etc/default/locale
session optional pam_mail.so nopen
@include common-auth
@include common-account
@include common-session
auth required pam_unix.so nullok_secure估计是要求验证,
account required pam_unix.so是 common-account 里面的,
session required pam_unix.so是 common-session 里面的。我们还可以更细致的建立自己的规则,这使用 [value=ret ...] 的形式,可选择的 value 有: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。返回值有 ignore(不对结果产生影响),bad(栈内第一个模块返回失败会作为总体返回值),die(直接退栈返回失败),ok(返回将修改类似 PAM_SUCCESS 的值,但是不会影响类似 bad 的 failure),done(如果成功将直接返回)和 reset(清除前面的栈内值)。比如我们定义的几个类型可以用如下的等价形式,
required在 /etc/pam.conf 里面,会在如上语法前加入命令如 su 名,但是现在多用 /etc/pam.d/ 每个命令建立自己的文件的形式。
[success=ok new_authtok_reqd=ok ignore=ignore default=bad]
requisite
[success=ok new_authtok_reqd=ok ignore=ignore default=die]
sufficient
[success=done new_authtok_reqd=done default=ignore]
optional
[success=ok new_authtok_reqd=ok default=ignore]
PAM 把很多功能用独立的 module 实现,这些模块有固定的格式,都放在 (/usr)/lib/security 目录里面。多数的 module 自己带有 man page,命名方式为 pam_*.so,配置文件多在 /etc/security/*.conf。下面介绍最常用的 38 个 modules:
- pam_access.so 控制用户访问(依据 username 和 host name/ip/mac 等),并将成功与否记录在日志中,配置文件在 /etc/security/access.conf。格式为 [+-]:username:from,+- 表示允许或者不允许,username 可以用 ALL EXCEPT 匹配。可选参数为 accessfile(指定配置文件路径),debug(syslog 记录更加详尽),fieldsep 默认是上面的 :,listsep 默认是空格或者 TAB。
- pam_cracklib.so 用于 password 的模块,可以利用 crack 对用户的密码进行要求,如避免使用老密码、使用老密码的变体(大小写变换、改动过少、回文等等)。可用参数有 debug,type(字符串,默认是 UNIX),retry(重试次数),difok(新密码与原密码不同的字符个数的最小值),difignore(有多少个字符就会忽略 difok),minlen(最小长度),dcredit(正整数表示数字获得的 credit,负数表示必须达到的个数),ucredit(大写字母),lcredit(小写字母),ocredit(其他字符),use_authtok(使用前面的 password 提供的 prompt),dictpath(cracklib 的路径)。
- pam_dubug.so 用于调试 PAM 的栈,可以让 pam_sm_* 函数返回对应的函数值。
- pam_deny.so 用于拒绝访问。
- pam_echo.so 用于显示文件内容,可用 file 指定位置,里面可以用 %s 等显示特殊信息。
- pam_env.so 用于指定环境变量或者去掉环境变量,可用 conffile 指定一个配置文件的路径,配置文件里面格式为 VAR DEFAULT=? OVERRIDE=?。另外可以用 envfile 指定 VAR=VAL 类型的环境变量表。
- pam_exec.so 用于执行一个进程,可以设定 seteuid。
- pam_faildelay.so 通过 delay 设定 auth 产生 faliure 时延迟的毫秒数。
- pam_filter.so 用于 filter stdin/stdout,可以在 /etc/security/pam_filter 里面找到一些常用的 filter,并用 filter= 指定路径。
- pam_ftp.so 用于提供一个匿名 ftp 的访问环境,但是不安全,不常使用。
- pam_group.so 用于提供 group 的权限,它通过 /etc/security/group.conf 的配置(终端、时间),对用户在 /etc/group 里面的 group 进行审查,决定是否给予对应的权利。
- pam_issue.so 和 pam_echo.so 类似,但是用 \d 类型指定一些变量。
- pam_keyinit.so 可以限制调用者的 keyring。
- pam_lastlog.so 用于显示上次登录信息。
- pam_limits.so 用于设定用户的 ulimits。
- pam_listfile.so 根据指定类型,如 tty、user、rhost、ruser、group、shell。可以用来确认用户如是否指定列表中所列出。
- pam_localuser.so 可以用 file 指定对应的 passwd 文件所在。
- pam_loginuid.so 用于指定登录后的 UID,这在登录程序中经常用到。
- pam_mail.so 用于通知用户是否有新邮件。
- pam_makehomedir.so 用于创建用户目录。在某些应用中,登录用户未必具有永久的 home。
- pam_motd.so 用于显示 MOTD(message of today)。
- pam_namespace.so 用于设定 SELinux 里面的 userspace。
- pam_nologin.so 根据 /etc/nologin 确定是否让用户登录。
- pam_permit.so 使得用户不管怎样都可以获得访问权。
- pam_rhost.so 根据 rhost 文件决定是否允许获得访问权。
- pam_rootok.so 如果是 root 则允许。
- pam_securetty.so 如果 tty 是列在 /etc/securetty 则允许。
- pam_selinux.so 设定 SELinux 的最基本环境。
- pam_shells.so 根据 /etc/shells 决定是否允许登录。
- pam_succeed_if.so 可以根据 UID、GID、shell 或者 username 进行条件运算的结果返回。
- pam_tally.so 统计尝试登录次数,并可以拒绝超过一定次数的用户。
- pam_time.so 登录时间进行限制。
- pam_umask.so 设定用户 umask。
- pam_unix.so 传统 unix 的认证方式。
- pam_userdb.so 使用 Berkeley db 认证。
- pam_warn.so 计入 syslog 日志。
- pam_wheel.so 检查用户是否 wheel 组。
- pam_xauth.so 用于传递 su 时 X server 的权限问题,即把原用户的 xauth 传递给 su 的用户。
下面,我们看看 PAM 还有那些有用的 package:
- libpam-gnome-keyring 使得用户登录 GNOME 之后自动打开 GNOME keyring。
- libpam-blue 对使用 blueteeth 设备进行登录认证。
- libpam-ck-connector 对终端用户的键盘输入作日志。
- libpam-devperm 将某些设备的属主改为登录用户。
- libpam-dotfile 允许用户使用多于一个密码。
- libpam-encfs 在用户登录后挂载加密文件系统。
- libpam-fprint 对指纹识别设备的支持。
- libpam-http 允许通过 Apache 的 http/https 登录。
- libpam-ldap 使用 ldap 查询登录。
- libpam-mount 在会话期间挂载文件系统。
- libpam-mysql 使用 MySQL 数据库进行认证。
- libpam-ncp 使用 Netware 服务器进行认证。
- libpam-p11 使用 PCKS#11 smart card 认证。
- libpam-passwdqc 是 pam_cracklib.so 的替代品。
- libpam-pqsql 使用 PostgreSQL 进行认证。
- libpam-pkcs11 类似 libpam-p11,但是似乎更完整。
- libpam-poldi 使用 Open PGP smart card。
- libpam-pwdfile 使用类似 /etc/passwd 文件进行认证。
- libpam-pwgen 产生可阅读密码供用户使用。
- libpam-rsa 使用 RSA 秘钥进行认证。
- libpam-shiled 锁定远程尝试密码的攻击者。
- libpam-slurm 使用 slurm 进行认证。
- libpam-smbpass 使用 SAMBA 密码认证。
- libpam-ssh 使用 ssh 方式,如果成功则设置 ssh-agent。
- libpam-thinkfinger 对 ThnikPAD 的指纹识别的支持。
- libpam-tmpdir 给每个用户设定自己的 /tmp。
- libpam-umask 调整用户的 umask。
- libpam-unix2 支持 blowfish 的与 pam_unix.so 兼容。
- libpam-pamusb 支持使用 usb 设备登录。
- libpam-chroot 登录后 chroot。
- libpam-cracklib
- libpam-musclecard 使用 Musclecard smartcard 进行认证。
- libpam-opie 使用 OPIE 进行认证(一次性密码)。
- libpam-optw 另外一种一次性密码。
- libpam-radius-auth 使用 RADIUS 认证。
- libpam-foreground 用户登录后为 console 进行记录,以确定程序使用的 foreground。
- libpam-afs-session 分布式文件系统 AFS。
- libpam-ccreds 当企业网络不可得时允许用户在本地登录。
- libpam-heimdal 使用 Heimdal Kerberos 认证。
- libpam-krb5 使用 Kerberos v5 认证。
- libpam-krb5-migrate-heimdal 提供从 Heimdal 到 krb5 的迁移。
- libpam-nufw 没看懂。
- libpam-openafs-kaserver, libpam-openafs-session 和 AFS 相关。
- libpam-shishi 是 Kerberos 5 的一种实现。