前言
前面文章我们说明了 PAM 当中的基本概念与术语,接下来我们来说明有关 PAM 的配置文件。
在传统的旧的 PAM 中,配置文件为 /etc/pam.conf ,目前绝大多数的发行版都已经将该配置文件废弃。此文件包含操作系统所有有关身份认证的策略,一行表示某个服务中某个链中的配置语句,其语法为:
login auth required pam_nologin.so no_warn
从左到右依次是:针对的服务、能力类型(模块接口)、控制标志、模块名称、模块参数
策略由四个链组成,四个 PAM 能力类型中的每一个都有一个链,每个链是一系列配置语句,每个语句指定要调用的模块、要传递给模块的一些(可选)参数以及描述如何解释模块返回代码的控制标志(control flag)
有些服务并不使用所有的四个能力类型
OpenPAM 和 Linux-PAM 支持另外一种配置机制,即将策略文件集中放入到 /etc/pam.d/ 目录中,在该目录下,以服务名称作为文件名,表示针对这个服务的策略文件。
Shell > ls -l /etc/pam.d/
total 88
-rw-r--r--. 1 root root 232 Nov 27 03:04 config-util
-rw-r--r--. 1 root root 322 Nov 30 2023 crond
-rw-r--r--. 1 root root 701 Nov 27 03:04 fingerprint-auth
-rw-r--r--. 1 root root 715 Feb 9 2024 login
-rw-r--r--. 1 root root 154 Nov 27 03:04 other
-rw-r--r--. 1 root root 168 Apr 20 2022 passwd
-rw-r--r--. 1 root root 760 Nov 27 03:04 password-auth
-rw-r--r-- 1 root root 155 May 28 2024 polkit-1
-rw-r--r--. 1 root root 398 Nov 27 03:04 postlogin
-rw-r--r--. 1 root root 640 Feb 9 2024 remote
-rw-r--r--. 1 root root 143 Feb 9 2024 runuser
-rw-r--r--. 1 root root 138 Feb 9 2024 runuser-l
-rw-r--r-- 1 root root 153 Nov 27 03:04 smartcard-auth
-rw-r--r--. 1 root root 727 Aug 14 04:36 sshd
-rw-r--r--. 1 root root 214 Dec 18 01:38 sssd-shadowutils
-rw-r--r--. 1 root root 566 Feb 9 2024 su
-rw-r--r--. 1 root root 154 Feb 15 2024 sudo
-rw-r--r--. 1 root root 178 Feb 15 2024 sudo-i
-rw-r--r--. 1 root root 137 Feb 9 2024 su-l
-rw-r--r--. 1 root root 760 Nov 27 03:04 system-auth
-rw-r--r-- 1 root root 368 Dec 18 01:56 systemd-user
-rw-r--r--. 1 root root 84 Jun 22 2023 vlock
每个策略文件的内容最多由四个字段组成:
- TYPE – 能力类型,auth、session、password、account 中的其中一个
- CONTROL – 控制标志
- MOUDLE_PATH – 模块路径和以 .so 结尾的模块。对于 64 位的操作系统,所有的模块可在 /lib64/security/ 中找到
- MOUDLE_ARGS – 模块参数,可选。控制模块的行为。
Shell > grep -v ^# /etc/pam.d/sshd
auth substack password-auth
auth include postlogin
account required pam_sepermit.so
account required pam_nologin.so
account include password-auth
password include password-auth
session required pam_selinux.so close
session required pam_loginuid.so
session required pam_selinux.so open env_params
session required pam_namespace.so
session optional pam_keyinit.so force revoke
session optional pam_motd.so
session include password-auth
session include postlogin
在 /etc/security/ 目录下提供了 PAM 模块的全局配置文件,其定义了这些模块的确切行为。对于使用 PAM 模块的每个应用程序都会调用一组 PAM 函数,这些函数随后将处理配置文件中的信息,并将结果返回给请求方应用程序。
模块:实现特定身份验证功能的一个或多个相关函数的集合
由于 PAM 的策略是根据文件名确定的而不是在策略文件的内容中指定,因此同一个策略文件可以用于多个不同名称的服务。例如,对 ftp 服务使用和 sudo 服务相同的策略,可以执行以下操作:
Shell > cd /etc/pam.d/ && ln -s sudo ftp
策略文件内容
Shell > cat /etc/pam.d/system-auth
#%PAM-1.0
# This file is auto-generated.
# User changes will be destroyed the next time authselect is run.
auth required pam_env.so
auth sufficient pam_unix.so try_first_pass nullok
auth required pam_deny.so
account required pam_unix.so
password requisite pam_pwquality.so try_first_pass local_users_only retry=3 authtok_type=
password sufficient pam_unix.so try_first_pass use_authtok nullok sha512 shadow
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
Shell > cat /etc/pam.d/login
#%PAM-1.0
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
内容说明如下:
-
#%PAM-1.0
– 为 PAM1.0 声明此配置文件的版本,这是一个使用习惯,未来可以使用它来检查版本。 -
#
– 表示这是注释。 -
-session
– 其中的 "-" 表示即使模块不存在,也不会影响认证结果,更不会将此事件记录到日志中,对于那些可有可无的模块来说,这一特性非常有用。 -
include
– 特殊控制标志,表示将其他服务的策略文件内容加载包含进来。 -
substack
– 特殊控制标志,子栈,与 include 控制标志有细微不同,例如子栈中的 "requisite" 失败只会导致子栈本身终止并返回失败结果,而不会导致父栈立即终止。PAM 中的 "栈" 指的是执行步骤和规则,而对于子栈,指的是在一个栈中(父栈)嵌套另外一个栈(子栈)。 -
从内容中可以看到,控制标志的写法除了可以使用关键字外(它们叫它「关键字」模式),还有一种用 [value1=action1 value2=action2 … ] 的方式,该方式对应于该行模块中的调用函数的返回代码。很少用到。
-
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。
-
action 可以是它们中的其中一个:ignore、bad、die、ok、done、N(正整数,不允许等于0,因为等于0等同于 ok)、reset
-
-
*.so
– 模块的路径与模块名称 -
use_authtok nullok sha512 shadow
– 向模块传递的可选模块参数。可键入man 8 模块名
查看可以使用的附加模块参数。
system-auth
system-auth 是非常重要的 PAM 策略文件,主要负责用户登录系统的认证工作。不仅如此,其他程序或服务可通过 include 调用它,从而节省很多重新自定义配置的工作。当你不清楚如何配置时,需要先查询对应的资料或咨询相关技术人员。
该文件的内容如下:
Shell > cat /etc/pam.d/system-auth
#%PAM-1.0
# This file is auto-generated.
# User changes will be destroyed the next time authselect is run.
auth required pam_env.so
auth sufficient pam_unix.so try_first_pass nullok
auth required pam_deny.so
account required pam_unix.so
password requisite pam_pwquality.so try_first_pass local_users_only retry=3 authtok_type=
password sufficient pam_unix.so try_first_pass use_authtok nullok sha512 shadow
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
如您所见,该策略文件使用了完整的 4 个链,每个链对应一种能力类型,每种能力类型可以堆叠(即同种能力类型写多行,调用相同或不同的模块,请注意!PAM 将同一个模块在同一个链中出现的不同位置视为不同的、不相关的模块)
auth 链
三行 auth 能力类型开头的,表示这是堆叠起来的一个模块链。当用户登录的时候,首先会通过 auth 对用户身份进行识别与密码验证。
-
pam_env.so:定义用户登录之后的环境变量,默认情况下,如果没有指定配置文件,环境变量依据这个文件—— /etc/security/pam_env.conf 进行设置。
-
pam_unix.so:使用该模块来提示用户输入密码,并将用户密码与 /etc/shadow 中记录的密码信息进行对比,如果密码比对结果正确则允许用户登录,而且该配置项使用的是 "sufficient" 控制标记,即表示只要该配置项的验证通过,用户即可完全通过认证而不用再去请求其他模块。nullok 模块参数表示可被允许使用空密码。
-
pam_deny.so:通过 pam_deny.so 模块对所有不满足上述任意条件的登录请求直接拒绝,pam_deny.so 是一个特殊的模块,该模块返回值永远为否,类似于大多数安全机制的配置准则,在所有认证规则走完之后,对不匹配任何规则的请求直接拒绝。
account 链
- pam_unix.so:声明用户需要通过密码认证
password 链
-
pam_pwquality.so:对密码的复杂度进行检查,常用模块参数如下
- debug – 开启该参数,即将模块的 动作 信息写入到写入到 syslog
- authtok_type=XXX – 用于用户密码修改时的提示,默认为空,这里的空表示提示单词中的 UNIX 应该被替换成什么。默认是"New UNIX password: " 和 "Retype UNIX password: "
- try_first_pass – 表明该模块首先应当使用前一个模块从用户那里得到的密码,如果该密码验证不通过,再提示用户输入新的密码。
- local_users_only – 表示忽略不在本地 /etc/passwd 文件中的用户
- retry=N – 变更密码时允许重试密码的次数,默认 1 次
- minlen=N – 新密码最小可接受的长度,默认 8 位
- difok=N – 新、旧密码最少可接受多少个字符的不同,默认为 1
- dcredit=N – 当 N>0 时,表示密码中的数字可被允许的做大位数。当 N<0 时,表示新密码必须至少拥有多少位的数字。默认为0,即对新密码没有数字的要求。
- lcredit=N – 当 N>0 时,表示密码中小写字母可被允许的做大位数。当 N<0 时,表示新密码必须至少拥有多少位的小写字母。默认为0,即对新密码没有小写字母的要求。
- ucredit=N – 当N>0时,表示密码中的大写字母可被允许的做大位数。当 N<0 时,表示新密码必须至少拥有多少位的大写字母。默认为 0,即对新密码没有大写字母的要求。
- ocredit=N – 当 N>0 时,表示密码中特殊字符可被允许的做大位数。当 N<0 时,表示新密码必须至少拥有多少位的特殊字符。默认为0,即对新密码没有特殊字符的要求。
- maxrepeat=N – 拒绝包含 N 个以上相同连续字符的密码。默认值为0,表示此检查已禁用。
- maxsequence=N – 拒绝包含长度超过 N 的无变化的序列密码。类似 123456 与 abcdef 这样的就是无变化的序列密码。默认为 0 ,禁用该检查。
- maxclassrepeat=N – 拒绝包含同一类的 N 个以上连续字符的密码。默认值为0,禁用该检查。
- enforce_for_root – 默认情况下对 root 不生效,除非你写了这个参数。
-
pam_unix.so:常用参数如下
- nullok – 允许空密码
- sha512 – 更改密码后的加密算法
- use_authtok – 此参数指示模块不要提示用户输入新密码。相反,它接受以前的 password 功能类型里模块记录的任何密码。
- shadow – 在更新用户密码时创建影子密码。
session 链
同样的,这也是一个使用了多个模块的堆叠起来的链。
-
pam_keyinit.so – 用来确保调用过程中有会话密钥环。该模块只能用在 session 链中。
- revoke – 如果首先为该进程创建了会话密钥环,则当被调用的进程退出时,会导致调用进程的会话密钥环无效。
-
pam_limits.so – 限制资源使用的模块。注意!uid=0 的用户也会受到限制。默认情况下,限制的内容会首先读取这个配置文件—— /etc/security/limits.conf,然后读取 /etc/security/limits.d/ 目录下的所有 .conf 文件
-
pam_systemd.so – pam_systemd 会将用户会话注册到 systemd 登录管理器(也就是 systemd-logind.service)中,并同时注册到 systemd 控制组(control group)之中。只能用在 session 链中。
-
pam_succeed_if.so – 主要用来对用户登录做一些限制。从名字就可以看到,你需要定义判断的条件,它没有配置文件。基本语法为:
pam_succeed_if.so [flag...] [condition...]
-
flag 可以是:
- debug
- use_uid(使用uid而不是用户名)
- quiet(不要将失败或成功记录到系统日志中)
- quiet_fail
- quiet_success
- audit
-
conditon 是由三个字段组成——field、test、vaule to test。其中 filed 可以是
- user
- uid
- gid
- shell
- home
- ruser
- rhost
- tty
- service
-
一些示例:
pam_succeed_if.so quiet uid < 1000 pam_succeed_if.so quiet gid eq 1000 pam_succeed_if.so quiet gid <= 1000 pam_succeed_if.so quiet gid >= 1000 pam_succeed_if.so quiet user = root pam_succeed_if.so quiet user ingroup root
-
