Linux-PAM配置文件
PAM框架意为可拔插身份认证模块,该框架实现了通过模块化的方式配置Linux平台上的身份认证框架;我们常见的需要身份认证的应用,例如login、ssh、su等都可以接入PAM框架,使其能够方便的配置身份认证方式。
pam配置文件有两个路径:/etc/pam.conf和/etc/pam.d/,先来看pam.conf文件。
/etc/pam.conf 配置文件语法
pam的配置文件以stack的形式来组织,每个配置文件相当于一个栈;在配置文件中,每条规则一行,每行有五个字段:
1 | service type control module-path module-argument |
最后两个字段module-path和module-argument为需要调用的pam模块和传入模块的参数,根据模块的不同,支持的参数也不一样,这里就不过多分析;我们重点放在前三个字段上。
service
service字段通常是应用程序的名称,例如login,su等;通过service字段可以区分当前规则用于哪个应用程序。即login程序进行身份验证时,只会根据service为login的规则进行。
type
该字段用于标识规则对应的组;pam规则共有四个组,分别为:account、auth、password和session。
account这个类型的规则用于账户管理(不校验身份),例如根据时间来限制哪些用户可以登录,哪些用户不能登录。
authauth是我们最常见的规则类型,用于配置用户身份校验方式;比如我们可以将用户配置成简单的密码校验,也可以配置成多因素校验。password这个模块类型用于更新用户的登录标识,如密码等。
sessionsession类型用在用户登录之前或之后进行一些操作,例如在某个用户登录之后,挂载某个目录,或者在用户登录之前清除它的selinux标签。
注意,上面四种类型,他们的功能都不是绝对的;type字段最重要的功能是告诉当前规则中的pam模块去调用某些特定类型的函数;以pam_unix.so模块为例,如果存在如下两条规则:
1 | login session required pam_unix.so open |
在type为session的规则中,PAM框架会调用pam_unix.so模块中的pam_sm_open_session()方法;而在auth类型的规则中,则会调用pam_sm_authenticate()方法。
control
该字段表示当PAM模块未能成功完成校验任务时的行为;该字段有两种表示方法,简单写法共有6个值,复杂写法是方括号中加上键值对表示。
在简单写法中,control字段可以取以下值:required、requisite、sufficient、optional、include和substack。
required当前模块校验失败,整个PAM校验过程最终会返回失败,但是后续模块仍然会被调用。
requisite当前模块校验失败将直接返回上级应用,不会继续调用后续模块。
sufficient如果当前模块返回success,并且此模块之前的required模块没有返回失败,PAM会直接向上层应用返回成功,不继续调用后续模块;如果当前模块返回失败,PAM会继续调用后续模块,对最终结果没有影响。
optional仅在当前的
servicetype只有这一个模块时,这个模块返回成功或者失败才有意义。include将指定配置文件中的所有给定type的行包含到当前配置中.
substack功能上与
include相同,不同的是substack会创建一个子栈;子栈作为一个单独的模块执行,子栈中的done和die动作不会影响父栈,子栈中的跳转也不会跳转到父栈中;reset动作会初始化子栈。
control字段的复杂表示语法为:
1 | [value1=action1 value2=action2 ...] |
这里的valueN对应这条规则中,调用的pam模块相应函数的返回值,取值范围为:
1 | 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 |
这些值定义在头文件_pam_types.h中。
actionN表示当函数返回valueN时,相应的动作,可以取以下值:ignore、bad、die、ok、done、无符号整数和reset。
ignore模块的返回状态不会影响最终返回值。
bad该动作应用于返回失败的时候;如果这个模块是整个栈中第一个失败的模块,那么这个模块的返回值就是整个栈的最终返回值。
die功能上与b
ad一致,但是die动作将终止当前栈,即不再执行后续的规则,直接返回。ok如果在此动作之前,栈的返回状态为
PAM_SUCCESS,那么此动作对应的value将覆盖当前栈状态;如果之前的状态为failed,此动作对应的value就不会覆盖栈状态。done
功能上与ok相同,但是会终止当前栈,不再执行后续的规则,直接返回。
N(正整数)向下跳过N条规则,注意不能为0.
reset清除当前栈的所有状态,重新开始下一条规则。
其实简单写法就是复杂写法的一种缩写,简单写法的规则同样也可以用复杂写法表示,他们之间存在以下等式:
1 | required = [success=ok new_authtok_reqd=ok ignore=ignore default=bad] |
/etc/pam.d 目录中的配置文件
pam.d目录中的配置文件语法与pam.conf的略微不同;区别在于其只有四个字段
1 | type control module-path module-argument |
对应字段的取值范围和规则仍然与pam.conf相同;这里缺少的service字段体现在文件名上,即配置文件的文件名规则,与service相同。