如何使用PAM在Ubuntu12.04VPS上配置身份验证
状态: 已弃用
本文介绍了不再受支持的 Ubuntu 版本。 如果您当前正在运行运行 Ubuntu 12.04 的服务器,我们强烈建议您升级或迁移到受支持的 Ubuntu 版本:
原因: Ubuntu 12.04 已于 2017 年 4 月 28 日终止生命周期 (EOL) and no longer receives security patches or updates. This guide is no longer maintained.
请参阅: 本指南可能仍可用作参考,但可能不适用于其他 Ubuntu 版本。 如果可用,我们强烈建议使用为您正在使用的 Ubuntu 版本编写的指南。 您可以使用页面顶部的搜索功能来查找更新的版本。
介绍
PAM 或 Pluggable Authentication Modules 是存在于 Linux 和类 Unix 操作系统上的抽象层,用于启用各种服务之间的身份验证。
作为身份验证服务和需要用户身份验证的应用程序之间的中介,该系统允许这两层优雅地集成并更改身份验证模型,而无需重写代码。 这是通过使用模块来实现的。
在本指南中,我们将研究 Ubuntu 12.04 VPS 上的 PAM 系统,尽管大多数现代 Linux 发行版应该以类似的方式运行。
幕后花絮:PAM 的基本要素
可插拔身份验证的工作原理
我们每天在 Linux 环境中与之交互的许多普通应用程序实际上都在后台使用 PAM。
必须使用 PAM 库支持编写应用程序。 要获取系统上可以以某种方式使用 PAM 的应用程序列表,请键入:
ldd /{,usr/}{bin,sbin}/* | grep -B 5 libpam | grep '^/'
/bin/login: /bin/su: /sbin/mkhomedir_helper: /sbin/pam_tally2: /usr/bin/chfn: /usr/bin/chsh: /usr/bin/passwd: /usr/sbin/atd: /usr/sbin/chpasswd: /usr/sbin/cron: /usr/sbin/newusers: /usr/sbin/sshd:
您可以通过键入以下内容来检查特定应用程序的 PAM 功能:
ldd $(哪个prog_name ) | grep libpam
如果它返回任何东西,那么它可以使用 PAM。
如您所见,许多常见的实用程序和工具实际上使用 PAM 作为中介来执行它们的任务。
PAM 组织
Linux 版本的 PAM 将模块功能划分为不同的类别,具体取决于它们所涉及的过程部分。 以下是对类别的简要说明:
- 身份验证功能:身份验证模块验证用户的身份验证凭据。 这意味着它会检查用户是否可以提供有效的凭据。
- Account Functions:这些模块负责决定尝试登录的帐户是否有权访问它此时请求的资源。 PAM 允许您指定可以根据预定条件拒绝或允许用户的控件。
- Session Functions:这些模块建立了用户登录或注销后将被建立和拆除的环境。 会话文件可以确定需要运行哪些命令来准备环境。
- 密码功能:这些模块负责更新各种服务的认证细节。 如果需要更改服务的密码,该模块可以帮助与服务通信并修改正确的值。
每次程序成功使用 PAM 进行身份验证时,都会引用这些模块类别中的前两个。 如果需要,会话模块将在前两个模块之后运行。 密码模块是按需访问的。
在目录结构方面,PAM配置文件存放在/etc/pam.d
:
ls /etc/pam.d
atd chsh common-password cron other su chfn common-account common-session login passwd sudo chpasswd common-auth common-session-noninteractive newusers sshd
该目录通常为每个将请求 PAM 身份验证的应用程序提供一个配置文件。 如果应用程序调用 PAM 但没有关联的配置文件,则应用“其他”配置文件。
在配置文件中,通常会调用包含以“common-”开头的配置文件。 这些是通用配置文件,其规则应适用于大多数情况。
可以使用以下命令定位配置文件中引用的模块:
ls /lib/*/security
pam_access.so pam_keyinit.so pam_permit.so pam_tally.so pam_debug.so pam_lastlog.so pam_pwhistory.so pam_time.so pam_deny.so pam_limits.so pam_rhosts.so pam_timestamp.so pam_echo.so pam_listfile.so pam_rootok.so pam_umask.so . . .
在这个目录中查看可以使用哪些类型的模块。 几乎所有的模块都有手册页,可以描述它们的用法。
PAM 如何评估身份验证
当应用程序查询 PAM 系统进行身份验证时,PAM 会读取相关的 PAM 配置文件。
配置文件包含 PAM 模块列表以及应如何处理它们。 依次调用每个模块,对模块的每次调用都会产生成功或失败的结果。
基于这些值,配置文件然后决定它是否应该向调用者返回“身份验证正常”消息,或者向其发送身份验证失败消息。
配置可能会在调用模块返回第一个故障时失败,或者可以配置替代策略。 例如,系统可能允许 LDAP 用户进行身份验证。 如果失败,它可能会检查本地用户列表。
每个配置文件的行从上到下评估,除非行评估导致配置文件的其余部分被跳过。
如何阅读政策路线
配置文件中的每一行都包含以下语法,每个字段由空格分隔。
[service] type control module-path [module-arguments]
位于 /etc/pam.d
中的文件不包括服务字段,而是以它所服务的应用程序命名配置文件。 如果没有 pam.d 目录,则需要一个 /etc/pam.conf
文件,并且必须在每行开头列出相关应用程序。
Type 是提供的服务类型。 它是上面列出的四个类别之一(身份验证、帐户、密码、会话)。
Control 指定接收到模块调用的返回状态时采取的动作。 它可以是这些值中的任何一个(并且还可以采用更复杂的语法,这里不会涉及):
- required:如果模块调用失败,这将导致认证失败。 但是,仍会调用剩余的指定模块。
- requisite:这与 required 的行为完全相同,但会立即导致身份验证失败,而不是调用其余模块。
- sufficient:此控制意味着如果此行成功(假设还没有所需的模块失败),则身份验证将立即返回成功,而不运行其余模块。 这一行的失败只是跳到下一个模块调用。
- optional:这些行的成功或失败与整体身份验证的成功或失败无关,除非它们是其类型的唯一模块调用。
- include:此行表示应从另一个配置脚本中读取给定类型的行。 这通常用于引用“通用”文件。
- substack:这个类似于includes,但是失败或者成功都不会导致整个文件的退出,只会退出子栈。
Module-path 是要调用的 pam 模块的名称。
Module-arguments 是传递给模块的可选参数。 有时这些对于模块知道如果成功要采取什么行动是必要的。
单个文件还可以引用必须使用以下语法检查的其他文件:
@包括配置文件
这将读入整个配置文件,这与“包含”控件类型不同,后者仅读入相同类型的行。
检查示例配置
通过查看 /etc/pam.d
目录中的一些示例,我们可以了解客户端是如何配置的。
打开描述“atd”身份验证要求的文件,这是一个调度守护进程。
less /etc/pam.d/atd
auth required pam_env.so @include common-auth @include common-account @include common-session-noninteractive session required pam_limits.so
第一行调用“pam_env”模块。 如果查看手册页,您会看到该模块用于设置一些环境变量,这些变量默认存储在 /etc/security/pam_env.conf
中。 这是“必需的”,意味着如果此模块返回“失败”,整个配置将失败,但这不应该发生。
接下来的三行读入“common-auth”、“common-account”和“common-session-noninteractive”文件以处理它们各自的角色。
最后一行调用“pam_limits”模块,该模块检查 /etc/security/limits.conf
文件或 /etc/security/limits.d/
目录。 这可用于强制限制可以同时使用服务的用户数量等。
通过查看引用的文件,我们可以更全面地了解正在进行的所有检查。
检查 common-auth 文件
我已经从文件中删除了注释以压缩信息。
less /etc/pam.d/common-auth
auth [success=1 default=ignore] pam_unix.so nullok_secure auth requisite pam_deny.so auth required pam_permit.so auth optional pam_ecryptfs.so unwrap
第一行还不是我们讨论过的。 我们可以看出它正在调用“pam_unix”模块,该模块提供通过“/etc/nsswitch.conf”文件配置的标准unix身份验证。 通常这只是意味着按预期检查 /etc/passwd
和 /etc/shadow
文件。
传递给 unix 模块的“nullok_secure”参数指定没有密码的帐户是可以的,只要登录信息使用 /etc/securetty
文件检查。
具有“[success=1 default=ignore]”的控制字段是这个示例的奇怪部分。 它取代了简化的“必需”、“足够”等参数,并允许进行更细粒度的控制。
在这种情况下,如果模块返回成功,它会跳过下一个“1”行。 默认情况下,处理模块的所有其他返回值,导致该行被忽略并继续前进。
第二行的控制值为“requisite”,意思是如果失败,整个配置立即返回失败。 它还调用“pam_deny”模块,每次调用都会返回失败。
这意味着这将永远失败。 唯一的例外是跳过此行时,即第一行成功返回时发生的情况。
第三行为必填项,调用“pam_permit”模块,每次都返回成功。 这只是在此时重置当前的“通过/失败”记录,以确保没有之前的一些奇怪值。
第四行被列为可选,并使用“unwrap”选项调用“pam_ecryptfs”模块。 这用于使用提供的密码解包密码,然后将用于挂载私有目录。 这仅在您使用此技术时才相关,这就是它是可选的原因。
检查普通账户文件
我们将查看“atd”配置中引用的下一个文件。 再次,为简洁起见,我将删除评论。
less /etc/pam.d/common-account
account [success=1 new_authtok_reqd=done default=ignore] pam_unix.so account requisite pam_deny.so account requisite pam_permit.so
该文件中的几乎所有内容都与“common-auth”文件中的内容相似。 第一行要求使用“pam_unix”模块进行帐户检查。
模块可以根据调用的“类型”执行不同的功能。 对于帐户调用,pam_unix 检查帐户是否未过期并且不受基于时间的登录限制的控制。
如果通过,它会跳过它下面的“pam_deny”调用,然后在最后处理允许规则。 另一方面,如果它失败,它会向下移动到拒绝行并以失败退出。
检查 common-session-noninteractive 文件
下一节提供非交互式程序或环境的会话检查。
less /etc/pam.d/common-session-noninteractive
session [default=1] pam_permit.so session requisite pam_deny.so session required pam_permit.so session optional pam_umask.so session required pam_unix.so session optional pam_ecryptfs.so unwrap
前三行可能看起来很奇怪。 此时您应该能够理解程序流程,但它们可能看起来很随意和多余。 第一行总是成功,下一行被跳过,第三行总是成功。
之所以采用这种方式,是因为许多 PAM 配置是自动生成的,并且会在其他 PAM 感知身份验证方法可用时进行修改以提供更实质的规则。 这只是创建了一个框架,可以在其中插入新规则以影响以后的程序流程。
第四行是对“pam_umask”模块的调用,标记为可选。 这将设置会话的文件创建掩码。 它将检查许多不同的文件位置以尝试找到相关的 umask 位置。
第五行是对 pam_unix 模块的再次调用。 因为这是一种“会话”类型的调用,所以 unix 模块的行为再次不同。 在这种情况下,它使用系统的实用程序实现日志记录。
最后一行再次调用“pam_ecryptfs”。 它执行与它在“auth”文件中的位置类似的功能。
结论
最初掌握 PAM 可能非常复杂。 但是,对系统如何工作以及如何将不同组件连接在一起的基本了解对于开发健全的身份验证程序至关重要。
虽然您可能不了解配置 PAM 规则的所有内容,但最好了解哪些系统可以防止非法使用计算机。
当您实施新的身份验证方案(如 LDAP)时,了解 PAM 尤其重要。 必须完全或有条件地更改身份验证方案以使用新系统。