2 通过 PAM 进行身份验证 #
Linux 在身份验证进程中使用 PAM(可插拔身份验证模块)作为用户和应用程序之间的中间层。PAM 模块在整个系统范围内可用,因此任何应用程序都可以请求 PAM 模块。本章介绍模块化身份验证机制的工作原理和配置方法。
2.1 PAM 是什么? #
系统管理员和编程人员经常要将访问限制在系统的某些部分或限制对应用程序某些功能的使用。没有 PAM,每次引入新的身份验证机制(例如 LDAP、Samba 或 Kerberos)时都必须对应用程序进行调整,而此过程非常耗时且容易出错。避免这些缺点的一种方法是将应用程序从身份验证机制中分开并将身份验证委托给集中管理的模块。每当需要使用新的必要身份验证模式时,只要调整或编写合适的 PAM 模块供相关程序使用即可。
PAM 的概念包括:
PAM 模块,用于特定身份验证机制的一组共享库。
模块堆栈,其中包含一个或多个 PAM 模块。
PAM 感知服务,需要使用模块堆栈或 PAM 模块进行身份验证。通常,服务是用户所熟悉的相应应用程序名称,例如
login
或su
。服务名称other
是默认规则的保留字。模块参数,可用于影响单个 PAM 模块的执行。
用于评估执行单个 PAM 模块所产生的每种结果的机制。如果为正值,则执行下一个 PAM 模块。对负值的处理方式取决于配置:“无影响,继续”到“立即终止”之间的所有选项都有效。
2.2 PAM 配置文件的结构 #
可通过两种方式配置 PAM:
- 基于文件的配置 (
/etc/pam.conf
) 每个服务的配置存储在
/etc/pam.conf
中。不过,出于维护和可用性原因,SUSE Linux Enterprise Server 中未使用此配置模式。- 基于目录的配置 (
/etc/pam.d/
) 依赖于 PAM 机制的每个服务(或程序)在
/etc/pam.d/
目录中都有各自的配置文件。例如,可以在/etc/pam.d/sshd
文件中找到sshd
的服务。
/etc/pam.d/
下的文件定义用于身份验证的 PAM 模块。每个文件都包含用于定义某个服务的行,而每行最多包含四个组成部分:
TYPE CONTROL MODULE_PATH MODULE_ARGS
组成部分的含义如下:
- TYPE
声明服务的类型。PAM 模块是成批处理的。不同类型的模块具有不同的用途。例如,一个模块检查口令,一个模块校验访问系统的位置,还有一个模块读取用户特定的设置。PAM 可以识别四种不同类型的模块:
auth
检查用户的真实性,传统方法是通过查询口令进行检查,但也可以通过芯片卡或生物特征(例如指纹或虹膜扫描)来实现此目的。
account
这种类型的模块会检查用户是否具有使用所请求服务的一般权限。例如,应执行这种检查以确保任何人都不能使用失效帐户的用户名登录。
password
这种类型的模块的用途是启用身份验证令牌的更改。这通常是一个口令。
session
这种类型的模块负责管理和配置用户会话。这些模块在身份验证前后启动,以记录登录尝试并配置用户的特定环境(邮件帐户、主目录、系统限制等)。
- CONTROL
指示 PAM 模块的行为。每个模块都可以具有以下控制标志:
required
在进行身份验证之前,必须先成功处理带有此标志的模块。在处理带有
required
标志的模块失败后,将继续处理带有相同标志的所有其他模块,之后用户才会收到有关身份验证尝试失败的消息。requisite
也必须成功处理带有此标志的模块,处理方式在很大程度上与带有
required
标志的模块类似。但是,如果某个带有此标志的模块失败,将立即向用户提供反馈并且不再继续处理其他模块。如果成功,则接着处理其他模块,就像带有required
标志的任何模块一样。requisite
标志可用作基本过滤器,检查进行正确身份验证所必需的某些条件是否存在。sufficient
在成功处理带有此标志的模块后,请求方应用程序会立即收到处理成功的消息并且不再处理其他模块,但前提是之前所有带有
required
标志的模块均未失败。带有sufficient
标志的模块失败没有任何直接后果,所有随后的模块都将按其各自的顺序进行处理。optional
带有此标志的模块成功或失败不会产生任何直接后果。此标志可用于只用来显示消息(例如,通知用户收到了邮件)而不采取任何进一步操作的模块。
include
如果给出此标志,则在此处插入指定为参数的文件。
- MODULE_PATH
包含 PAM 模块的完整文件名。如果模块位于默认目录
/lib/security
(对于 SUSE® Linux Enterprise Server 支持的所有 64 位平台,默认目录均为/lib64/security
)中,则无需显式指定此文件名。- MODULE_ARGS
包含用于影响 PAM 模块行为的选项的空格分隔列表,例如
debug
(启用调试)或nullok
(允许使用空口令)。
另外,/etc/security
下提供了用于 PAM 模块的全局配置文件,它们定义这些模块的确切行为(其中包括 pam_env.conf
和 time.conf
)。使用 PAM 模块的每个应用程序会调用一组 PAM 函数,这些函数随后将处理配置文件中的信息,并将结果返回给请求方应用程序。
为了简化 PAM 模块的创建和维护,现已引入 auth
、account
、password
和 session
模块类型的通用默认配置文件。这些配置取自每个应用程序的 PAM 配置。因此,对 common-*
中全局 PAM 配置模块进行的更新将在所有 PAM 配置文件中传播,而无需管理员更新每个 PAM 配置文件。
您可以使用 pam-config
工具维护全局 PAM 配置文件。此工具可自动将新模块添加到配置、更改现有模块的配置,或者从配置中删除模块(或选项)。它最大限度地减少甚至完全消除了维护 PAM 配置时所需的人工干预。
使用 64 位操作系统时,还可以包含 32 位应用程序的运行时环境。在这种情况下,请确保同时安装 32 位版本的 PAM 模块。
2.3 sshd 的 PAM 配置 #
以 sshd 的 PAM 配置为例:
/etc/pam.d/sshd
) ##%PAM-1.0 1 auth requisite pam_nologin.so 2 auth include common-auth 3 account requisite pam_nologin.so 2 account include common-account 3 password include common-password 3 session required pam_loginuid.so 4 session include common-session 3 session optional pam_lastlog.so silent noupdate showfailed 5
通过包含配置文件而不是将每个模块单独添加到相应的 PAM 配置,您可以在管理员更改默认设置后自动获取更新的 PAM 配置。以前,在 PAM 发生更改或安装新应用程序后,您需要手动调整所有应用程序的所有配置文件。而现在 PAM 配置是通过中央配置文件进行的,每个服务的 PAM 配置都将自动继承所有的更改。
第一个 include 文件 (common-auth
) 调用 auth
类型的三个模块:pam_env.so
、pam_gnome_keyring.so
和 pam_unix.so
。请参见 例 2.2 “auth
部分的默认配置 (common-auth
)”。
auth
部分的默认配置 (common-auth
) #auth required pam_env.so 1 auth optional pam_gnome_keyring.so 2 auth required pam_unix.so try_first_pass 3
| |
| |
|
整个 auth
模块堆栈处理完后,sshd
才会获得有关登录是否成功的反馈。堆栈中带有 required
控制标志的所有模块都必须成功处理,sshd
才能收到有关正面结果的消息。如果其中的某个模块不成功,则仍将继续处理整批模块,在此之后 sshd
才能得到处理失败的通知。
成功处理所有 auth
类型的模块后,将处理另一条 include 语句,在本例中为例 2.3 “account
部分的默认配置 (common-account
)”中的语句。common-account
仅包含一个模块:pam_unix
。如果 pam_unix
返回的结果证明用户存在,则 sshd 会收到一条处理成功的消息,然后处理下一批模块 (password
),如例 2.4 “password
部分的默认配置 (common-password
)”中所示。
account
部分的默认配置 (common-account
) #account required pam_unix.so try_first_pass
password
部分的默认配置 (common-password
) #password requisite pam_cracklib.so password optional pam_gnome_keyring.so use_authtok password required pam_unix.so use_authtok nullok shadow try_first_pass
同样,sshd
的 PAM 配置仅涉及一条 include 语句,该语句引用了 password
模块的默认配置(位于 common-password
中)。每当应用程序请求获取身份验证令牌的更改信息时,都必须成功完成这些模块(控制标志为 requisite
和 required
)。
更改口令或另一个身份验证令牌需要进行安全检查。这项检查是通过 pam_cracklib
模块实现的。随后使用的 pam_unix
模块带有来自 pam_cracklib
的任何旧口令和新口令,因此用户在更改口令后无需再次进行身份验证。此过程可确保不能绕过 pam_cracklib
所执行的检查。每当配置了 account
或 auth
类型来指出口令失效时,还应使用 password
模块。
session
部分的默认配置 (common-session
) #session required pam_limits.so session required pam_unix.so try_first_pass session optional pam_umask.so session optional pam_systemd.so session optional pam_gnome_keyring.so auto_start only_if=gdm,gdm-password,lxdm,lightdm session optional pam_env.so
最后,调用 session
类型的模块(捆绑在 common-session
文件中)以根据相关用户的设置来配置会话。pam_limits
模块装载文件 /etc/security/limits.conf
,该文件可以定义某些系统资源的使用限制。再次处理 pam_unix
模块。pam_umask
模块可用于设置文件模式创建掩码。由于此模块带有 optional
标志,因此此模块的失败将不会影响整个会话模块堆栈的成功完成。当用户注销时,将再次调用 session
模块。
2.4 PAM 模块的配置 #
某些 PAM 模块是可配置的。配置文件位于 /etc/security
中。本节简要介绍与 sshd 示例相关的配置文件 — pam_env.conf
和 limits.conf
。
2.4.1 pam_env.conf #
pam_env.conf
可用于定义每次调用 pam_env
模块时为用户设置的标准化环境。它允许您使用以下语法预设环境变量:
VARIABLE [DEFAULT=VALUE] [OVERRIDE=VALUE]
- VARIABLE
要设置的环境变量的名称。
[DEFAULT=<value>]
管理员要设置的默认 VALUE。
[OVERRIDE=<value>]
可能由
pam_env
查询并设置的值,覆盖默认值。
有关如何使用 pam_env
的典型示例是 DISPLAY
变量的调整,每当发生远程登录时,该变量就会改变。例 2.6 “pam_env.conf”中显示了这一点。
REMOTEHOST DEFAULT=localhost OVERRIDE=@{PAM_RHOST} DISPLAY DEFAULT=${REMOTEHOST}:0.0 OVERRIDE=${DISPLAY}
第一行将 REMOTEHOST
变量的值设置为 localhost
,每当 pam_env
不能确定任何其他值时就会使用该值。DISPLAY
变量又包含 REMOTEHOST
的值。在 /etc/security/pam_env.conf
的注释中可以找到详细信息。
2.4.2 pam_mount.conf.xml #
pam_mount
用于在登录期间挂载用户主目录,以及在注销期间从中心文件服务器用来存放所有用户主目录的环境中卸载这些主目录。使用此方法就无需挂载一个完整的 /home
目录(通过该目录可访问所有用户主目录),而是仅挂载即将登录的用户的主目录。
安装 pam_mount
后,/etc/security
中会提供 pam_mount.conf.xml
的模板。在手册页 man 5
pam_mount.conf
中可以找到元素的说明。
可以使用 YaST 完成此功能的基本配置。选择请参见第 20.5 节 “配置客户端”。
› › 以添加文件服务器。
cryptsetup
2.0 中已添加了 LUKS2 支持;从 SUSE Linux Enterprise Server 12 SP3 开始,SUSE Linux Enterprise Server 在 pam_mount
中包含了 LUKS2 支持。
2.4.3 limits.conf #
可以在 pam_limits
模块将会读取的 limits.conf
中基于用户或组设置系统限制。该文件可让您设置硬限制(即不能超出的限制)和软限制(即可以暂时超出的限制)。有关语法和选项的详细信息,请参见 /etc/security/limits.conf
中的注释。
2.5 使用 pam-config 配置 PAM #
pam-config
工具可帮助您配置全局 PAM 配置文件 (/etc/pam.d/common-*
) 和多个选定的应用程序配置。如需受支持模块的列表,请使用 pam-config --list-modules
命令。使用 pam-config
命令可以维护 PAM 配置文件。可将新模块添加到 PAM 配置,删除其他模块,或修改这些模块的选项。更改全局 PAM 配置文件时,无需手动调整单个应用程序的 PAM 设置。
pam-config
的简单用例包括:
自动生成全新的 Unix 样式 PAM 配置。: 让 pam-config 创建最简单的可行设置,供您以后扩展。
pam-config --create
命令创建简单的 Unix 身份验证配置。pam-config 不负责维护的现有配置文件将被重写,但会以*.pam-config-backup
的形式保留备份副本。添加新的身份验证方法。: 可通过简单的
pam-config --add --ldap
命令将新的身份验证方法(例如 LDAP)添加到 PAM 模块堆栈。在适用的情况下,LDAP 将添加到所有common-*-pc
PAM 配置文件中。添加调试以进行测试。: 为确保新的身份验证过程按预期工作,请对所有 PAM 相关操作开启调试。
pam-config --add --ldap-debug
为 LDAP 相关的 PAM 操作启用调试。在systemd
日志中可以看到调试输出(请参见第 21 章 “journalctl
:查询systemd
日志”)。查询您的设置。: 在最终应用您的新 PAM 设置之前,请检查该设置是否包含您要添加的所有选项。
pam-config --query --
MODULE 命令列出所要查询的 PAM 模块的类型和选项。去除调试选项。: 最后,当您对设置性能完全满意时,请从设置中去除调试选项。
pam-config --delete --ldap-debug
命令为 LDAP 身份验证禁用调试。如果您为其他模块添加了调试选项,请使用类似的命令关闭这些选项。
有关 pam-config
命令和可用选项的详细信息,请参见 pam-config(8)
的手册页。
2.6 手动配置 PAM #
如果您偏向于手动创建或维护 PAM 配置文件,请确保对这些文件禁用 pam-config
。
当您使用 pam-config --create
命令从头开始创建 PAM 配置文件时,此命令会创建从 common-*
到 common-*-pc
文件的符号链接。pam-config
仅修改 common-*-pc
配置文件。去除这些符号链接会有效禁用 pam-config,因为 pam-config 仅对 common-*-pc
文件运行,而在没有符号链接的情况下,这些文件不起作用。
pam_systemd.so
如果您要创建自己的 PAM 配置,请务必包含配置为 session
optional
的 pam_systemd.so
。不包含 pam_systemd.so
可能会导致 systemd
任务限制出现问题。有关细节,请参见 pam_systemd.so
的手册页。
2.7 更多信息 #
安装 pam-doc
软件包后,可以在 /usr/share/doc/packages/pam
目录中找到以下附加文档:
- README 文件
在此目录的顶层,有一个
modules
子目录提供了可用 PAM 模块的 README 文件。- Linux-PAM 系统管理员指南
此文档包含系统管理员应该了解的有关 PAM 的所有内容。它讨论了一系列主题,从配置文件的语法到 PAM 的安全特性。
- Linux-PAM 模块编写人员手册
此文档从开发人员的角度对多个主题进行了总结,提供了有关如何编写符合标准的 PAM 模块的信息。
- Linux-PAM 应用程序开发人员指南
此文档包含要使用 PAM 库的应用程序开发人员所需了解的所有内容。
- PAM 手册页
PAM 及其各个模块都随附了手册页,其中全面概述了所有组件的功能。