PAM是一套应用程序接口(Application Programming Interface, API,他提供了一连串的验证机制,只要使用者将验证阶段的需求告知 PAM 后, PAM 就能够回报使用者验证的结果 (成功或失败)。

PAM 用来进行验证的数据称为模块 (Modules),每个 PAM 模块的功能都不太相同。

PAM模块设置语法

PAM 借由一个与程序相同文件名的配置文件来进行一连串的认证分析需求。当执行passwd命令时,PAM的流程如下所示:

  1. 使用者开始执行 /usr/bin/passwd 这支程序,并输入密码;
  2. passwd 调用 PAM 模块进行验证;
  3. PAM 模块会到 /etc/pam.d/ 找寻与程序 (passwd) 同名的配置文件;
  4. 依据 /etc/pam.d/passwd 内的设置,引用相关的 PAM 模块逐步进行验证分析;
  5. 将验证结果 (成功、失败以及其他讯息) 回传给 passwd 这支程序;
  6. passwd 这支程序会根据 PAM 回传的结果决定下一个动作 (重新输入新密码或者通过验证!)
# cat /etc/pam.d/passwd
#%PAM-1.0
auth       include	system-auth
account    include	system-auth
password   substack	system-auth
-password   optional	pam_gnome_keyring.so use_authtok
password   substack	postlogin

在passwd的配置文件当中,除了第一行宣告 PAM 版本之外,其他任何“ # ”开头的都是注解,而每一行都是一个独立的验证流程, 每一行可以区分为三个字段,分别是验证类别(type)、控制标准(flag)、PAM的模块与该模块的参数。 

验证类别(Type):

  • auth:这种类别主要用来检验使用者的身份验证,这种类别通常是需要密码来检验的, 所以后续接的模块是用来检验使用者的身份。
  • account:大部分是在进行授权,这种类别则主要在检验使用者是否具有正确的使用权限。
  • session:管理使用者在这次登陆 (或使用这个指令) 期间,PAM 所给予的环境设置。 这个类别通常用在记录使用者登陆与登出时的信息。
  • password:这种类别主要在提供验证的修订工作。

四种验证类型一般是先验证身份(auth);然后系统才能够借由使用者的身份给予适当的授权与权限设置 (account);进而登陆与登出期间的环境才需要设置, 也才需要记录登陆与登出的信息 (session);如果在运行期间需要密码修订时,才给予 password 的类别。

控制标准(control flag):

  • required:此验证若成功则带有 success (成功) 的标志,若失败则带有 failure 的标志,但不论成功或失败都会继续后续的验证流程。 由于后续的验证流程可以继续进行,因此相当有利于数据的登录 (log) ,这也是 PAM 最常使用 required 的原因。
  • requisite:若验证失败则立刻回报原程序 failure 的标志,并终止后续的验证流程。若验证成功则带有 success 的标志并继续后续的验证流程。
  • sufficient:若验证成功则立刻回传 success 给原程序,并终止后续的验证流程;若验证失败则带有 failure 标志并继续后续的验证流程。
  • include:包含一个新的配置文件进行验证。
  • substack:与 include 类似,区别是include 调用文件执行时有 die 或者 bad 则立即返回调用处,而 substack 则等待文件执行完。
  • optional:非验证功能,大多仅在显示信息方面应用
PAM 控制旗标所造成的回报流程

login的PAM验证机制流程

依据验证类别 (type) 来看,然后先由 login 的设置值去查阅,如果出现“ include system-auth ” 就转到 system-auth 文件中的相同类别,去取得额外的验证流程就是了。然后再到下一个验证类别,最终将所有的验证跑完, 就结束这次的 PAM 验证。

# cat /etc/pam.d/login 
#%PAM-1.0
auth [user_unknown=ignore success=ok ignore=ignore default=bad] pam_securetty.so
auth       substack     system-auth
auth       include      postlogin
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    include      postlogin
-session   optional     pam_ck_connector.so


# cat /etc/pam.d/system-auth
#%PAM-1.0
# This file is auto-generated.
# User changes will be destroyed the next time authconfig is run.
auth        required      pam_env.so
auth        required      pam_faildelay.so delay=2000000
auth        sufficient    pam_unix.so nullok try_first_pass
auth        requisite     pam_succeed_if.so uid >= 1000 quiet_success
auth        required      pam_deny.so

account     required      pam_unix.so
account     sufficient    pam_localuser.so
account     sufficient    pam_succeed_if.so uid < 1000 quiet
account     required      pam_permit.so

password    requisite     pam_pwquality.so try_first_pass local_users_only retry=3 authtok_type=
password    sufficient    pam_unix.so sha512 shadow nullok try_first_pass use_authtok
password    required      pam_deny.so

session     optional      pam_keyinit.so revoke
session     required      pam_limits.so
-session     optional      pam_systemd.so
session     [success=1 default=ignore] pam_succeed_if.so service in crond quiet use_uid
session     required      pam_unix.so

验证阶段

  1. 经过 pam_securetty.so 判断,如果使用者是 root 时,则会参考 /etc/securetty 的设置;
  2. 跳转到system-auth配置文件
  3. 经过 pam_env.so 设置额外的环境变量;
  4. 经过 pam_unix.so 检验密码,若通过则回报 login 程序;
  5. 若不通过则继续往下以 pam_succeed_if.so 判断 UID 是否大于 1000 ,若小于 1000则回报失败
  6. 否则再往下以 pam_deny.so 拒绝连线。

授权阶段

  1. 先以 pam_nologin.so 判断 /etc/nologin 是否存在,若存在则不许一般使用者登陆;
  2. 跳转到system-auth配置文件
  3. 接下来以 pam_unix.so 及 pam_localuser.so 进行帐号管理
  4. 再以 pam_succeed_if.so 判断 UID 是否小于 1000 ,若小于 1000 则不记录登录信息。
  5. 最后以 pam_permit.so 允许该帐号登陆。

密码阶段

  1. 跳转到system-auth配置文件
  2. 先以 pam_pwquality.so 设置密码仅能尝试错误 3 次;
  3. 接下来以 pam_unix.so 通过 sha512, shadow 等功能进行密码检验,若通过则回报 login 程序
  4. 若不通过则以 pam_deny.so 拒绝登陆。

会议阶段

  1. 先以 pam_selinux.so 暂时关闭 SELinux;
  2. 以 pam_loginuid.so 规范不同的 UID 权限;
  3. 打开 pam_selinux.so 的功能。
  4. 跳转到system-auth配置文件
  5. 使用 pam_limits.so 设置好使用者能够操作的系统资源;
  6. 登陆成功后开始记录相关信息在登录文件中;