第1章 介绍

Linux-PAM (Pluggable Authentication Modules for Linux) 是一套共享库,允许本地系统管理员选择应用程序如何验证用户。

换句话说,无需(重写和)重新编译 PAM 知晓的应用程序,就可以在它使用的身份验证机制之间切换。实际上,可以在不接触应用程序本身的情况下完全升级本地认证系统。

从历史上看,需要对给定用户进行身份验证的应用程序必须经过编译才能使用特定的身份验证机制。例如,在传统的 UN*X 系统的情况下,用户的身份是通过用户输入正确的密码来验证的。这个密码在以两个字符“salt”为前缀后被加密(使用 crypt(3))。如果此加密密码与系统密码数据库( /etc/passwd文件)中用户条目的第二个字段相同则该用户可通过谁。在这样的系统上,大多数(如果不是所有)形式的权限都是基于这个单一的身份验证方案授予的。特权以个人用户标识符 (UID) 和各种组的成员身份的形式出现。服务和应用程序的可用性基于用户的个人和群组身份。传统上,组成员资格是根据/etc/group文件中的条目分配的。

Linux-PAM 项目 的目的是将权限授予软件的开发与安全和适当的身份验证方案的开发分开。这是通过提供一个函数库来实现的,应用程序可以使用这些函数库来请求对用户进行身份验证。此 PAM 库使用系统文件 /etc/pam.conf(或位于/etc/pam.d/ 中的一系列配置文件)在本地进行配置,以通过本地可用的身份验证模块对用户请求进行身份验证。模块本身通常位于/lib/security/lib64/security目录中并采用可动态加载的目标文件的形式(请参阅dlopen (3))。

第2章 对文本的一些注解

在继续阅读本文档的其余部分之前,应该注意的是,本文假定某些文件位于某些目录中。在指定了它们的地方,我们在此处采用的用于定位这些文件的约定是相关 RFC(RFC-86.0,请参阅参考书目)的约定。如果您使用的是支持 PAM 的 Linux(或其他操作系统)发行版,但选择以不同的方式分发这些文件,直接从文本中复制示例时应该小心。

作为上述示例,在明确说明的情况下,文本假定 PAM 可加载目标文件( 模块)将位于以下目录中:/lib/security//lib64/security取决于体系结构。这通常是似乎与文件系统层次结构标准 (FHS) 兼容的位置。在 Solaris 上,它有自己的 PAM 许可版本和 UN*X 的一些其他实现,这些文件可以在/usr/lib/security中找到。 使用文本中的示例时,请小心执行必要的转录。

第3章 概述

对于初学者,我们首先考虑一个例子。我们采用一个应用程序,为用户提供一些服务; login就是这样一种程序。 Login做了两件事,首先确定提出请求的用户是他们声称的人,然后为他们提供请求的服务:在Login的情况下, 服务是一个以用户的身份运行的命令shell(bash、tcsh、zsh 等)。

传统上,前一步是通过 login应用程序提示用户输入密码,然后验证它是否与系统上的密码一致来实现的;因此验证就系统而言,用户就是他们声称的人。这是委托给Linux-PAM的任务。

从应用程序程序员(在本例中是编写login应用程序的人)的角度来看, Linux-PAM负责这个身份验证任务——验证用户的身份。

Linux-PAM 的灵活性在于,系统管理员,可以自由规定要使用的身份验证方案。您可以自由地为 Linux 系统上的任何/所有 PAM 知晓的应用程序设置方案。也就是说,您可以从简单的信任( pam_permit ) 之类的简单的方式到诸如视网膜扫描、声纹和一次性密码的组合之类的偏执的方式进行身份验证!

为了说明您面临的灵活性,请考虑以下情况:系统管理员(父母)希望提高其用户(孩子)的数学能力。她可以配置他们最喜欢的“射击游戏”(当然是 PAM可知晓的)来通过请求几个小于 12 的随机数的乘积来验证他们。很明显,如果游戏有什么好处他们很快就会学会 乘法表。随着它们的成熟,身份验证可以升级为包括(长)除法!

Linux-PAM处理四种不同类型的(管理)任务。它们是: 认证管理账户管理会话管理;和 密码管理。首选管理方案与应用程序行为的关联是通过相关Linux-PAM配置文件中的条目进行的 。管理功能由配置文件中指定的模块执行。此文件的语法在下面的部分中讨论 。

下图描述了Linux-PAM的整体组织结构 :

  +----------------+
  | application: X |
  +----------------+       /  +----------+     +================+
  | authentication-[---->--\--] Linux-   |--<--| PAM config file|
  |       +        [----<--/--]   PAM    |     |================|
  |[conversation()][--+    \  |          |     | X auth .. a.so |
  +----------------+  |    /  +-n--n-----+     | X auth .. b.so |
  |                |  |       __|  |           |           _____/
  |  service user  |  A      |     |           |____,-----'
  |                |  |      V     A
  +----------------+  +------|-----|---------+ -----+------+
                         +---u-----u----+    |      |      |
                         |   auth....   |--[ a ]--[ b ]--[ c ]
                         +--------------+
                         |   acct....   |--[ b ]--[ d ]
                         +--------------+
                         |   password   |--[ b ]--[ c ]
                         +--------------+
                         |   session    |--[ e ]--[ c ]
                         +--------------+

作为说明,图的左边代表应用;应用程序 X。这样的应用程序与Linux-PAM库进行交互,并且不知道其配置的身份验证方法的任何细节。(在中心)的 *Linux-PAM库查看PAM配置文件的内容并加载适用于应用程序-X的模块。这些模块属于四个管理组之一(位于中下),并按照它们在配置文件中出现的顺序堆叠。这些模块,当被Linux-PAM调用时,为应用程序执行各种身份验证任务。用户需要/或提供给用户的文本信息可以通过使用应用程序提供的*对话 功能进行交换。

如果程序要使用 PAM,则必须将 PAM 函数显式编码到程序中。如果您可以访问源代码,则可以添加适当的 PAM 函数。如果您无权访问源代码,并且二进制文件不包含 PAM 函数,则无法使用 PAM。

第4章 Linux-PAM 配置文件

目录

PAM知晓的权限授予应用程序启动时,它会激活其对 PAM-API 的附件。此激活会执行许多任务,最重要的是读取配置文件:/etc/pam.conf。或者,也可能是/etc/pam.d/目录中的内容 。此目录的存在将导致 Linux-PAM 忽略 /etc/pam.conf

这些文件列出了将执行此服务所需要的认证任务的PAM模块,以及在个别 PAM模块失败时 PAM-API 的适当行为。

4.1. 配置文件语法

/etc/pam.conf 配置文件的语法如下。该文件由一系列规则组成,每个规则通常放在一行中,但可以用转义的行尾:`<LF>’进行扩展。注释前面带有“#”标记并延伸到下一个行尾。

每个规则的格式是一个以空格分隔的标记集合,前三个不区分大小写:

service type control module-path module-arguments

服务 类型 控制 模块-路径 模块-参数

除了没有任何服务字段之外,目录/etc/pam.d/中包含的文件的语法是相同的 。在这种情况下, 服务/etc/pam.d/目录中文件的名称 。此文件名必须为小写。

PAM 的 一个重要特性是,可以堆叠多个规则来组合多个 PAM 的服务,用于给定的身份验证任务。

服务*通常是相应应用程序的熟知的名称:login和 su就是很好的例子。该 *service-name,other,保留给了默认的规则。只有提到当前服务的行(或在没有这样的行的情况下,other条目)才会与给定的服务应用程序相关联。

类型是该规则对应到管理组。它用于指定后续模块将与哪个管理组关联。有效条目是:

  • 帐户 account 此模块类型执行基于非身份验证的帐户管理。它通常用于根据一天中的时间、当前可用的系统资源(最大用户数)或申请用户的位置(仅在控制台上的“root”登录)来限制/允许对服务的访问。
  • 授权 auth 这种模块类型提供了验证用户的两个方面。首先,它通过指示应用程序提示用户输入密码或其他身份识别方式来确定用户就是他们声称的身份。其次,模块可以通过其凭据授予属性授予组成员资格或其他特权。
  • 密码 password 更新与用户关联的身份验证令牌需要此模块类型。通常,每种基于“质询/响应”的身份验证 (auth) 类型都有一个模块。
  • 会话 session 此模块类型与为用户提供服务之前/之后需要为他们做的事情相关联。这些事情包括记录有关打开/关闭与用户的某些数据交换、安装目录等的信息。

如果上面列表中的类型*值前面带有 *- 字符,如果由于系统中缺少某个模块而导致其无法加载,则该PAM 库将不会记录到系统日志中。这对于不总是安装在系统上并且不需要正确验证和授权登录会话的模块特别有用。

第三个字段control指示模块在其身份验证任务中失败时 PAM-API 的行为。这个控制字段有两种类型的语法:simple 类型有一个简单的关键字;更复杂的类型涉及方括号中的 value=action对的选择。

对于简单(历史)语法,有效控制 值为:

  • 必要的 required 这种 PAM 的失败将最终导致 PAM-API 返回失败,但只有在剩余的 堆叠模块(针对此 服务类型)被调用之后。
  • 必需的 requisite 就像required一样,但是,在这样的模块返回失败的情况下,控制权会直接返回给应用程序或上级 PAM 堆栈。返回值是与第一个失败的required或requisite模块相关联的值。请注意,此标志可用于防止用户有机会通过不安全的介质输入密码。可以想象,这种行为可能会告知攻击者系统上的有效帐户。这种可能性应该与在敌对环境中暴露敏感密码的重要问题进行权衡。
  • 充分的 sufficient 如果这样的模块成功并且先前*required * 模块没有失败,则 PAM 框架立即向应用程序或上级 PAM 堆栈返回成功,而不调用堆栈中的任何其他模块。sufficient模块的故障将被忽略并且 PAM 模块堆栈的处理将不受影响地继续。
  • 可选的 optional 此模块的成功或失败仅当它是堆栈中与此服务+类型关联的唯一模块时才重要 。
  • 包含 include 包括指定为该控件的参数的配置文件中给定类型的所有行。
  • 子堆栈 substack 包括指定为该控件的参数的配置文件中给定类型的所有行。这与include 的不同之处在于, 对子堆栈中的donedie动作的评估 不会导致跳过完整模块堆栈的其余部分,而只会跳过该子堆栈。子栈中的跳转也不能使求值跳出,在父栈中进行跳转时,整个子栈算作一个模块。reset操作会将模块堆栈的状态重置为子堆栈评估开始时的状态。

对于更复杂的语法,有效的control 值具有以下形式:

      [value1=action1 value2=action2 ...]

其中valueN对应于在定义该行的模块中调用的函数的返回代码。它可以从以下值中选择一个: successopen_errsymbol_errservice_errsystem_errbuf_errperm_deniedauth_errcred_insufficientauthinfo_unavailUSER_UNKNOWNmaxtriesnew_authtok_reqdacct_expiredsession_errcred_unavailcred_expiredcred_errno_module_dataconv_errauthtok_errauthtok_recover_errauthtok_lock_busyauthtok_disable_agingtry_againignoreabortauthtok_expiredmodule_unknownbad_itemconv_againincomplete,以及default

最后一个,default,意味着“所有valueN都没有明确提到”。请注意,完整的 PAM 错误列表可在 /usr/include/security/_pam_types.h找到。 该 actionN可以采取以下形式之一:

  • 忽略 当与模块堆栈一起使用时,模块的返回状态不会影响应用程序获得的返回代码。
  • 坏的 此操作表示应将返回代码视为模块失败的指示。如果此模块是堆栈中第一个发生故障的模块,则其状态值将用于整个堆栈的状态值。
  • 这 相当于 bad 终止模块堆栈和 PAM 立即返回应用程序的副作用。
  • 行 这告诉 PAM,管理员认为这个返回码应该直接影响整个模块堆栈的返回码。换句话说,如果堆栈的先前状态会导致返回PAM_SUCCESS,则模块的返回代码将覆盖此值。请注意,如果堆栈的前一个状态持有一些指示模块故障的值,则该“ok”值将不会用于覆盖该值。
  • 完毕 相当于 ok 的副作用是终止模块堆栈和 PAM 立即返回到应用程序。
  • N(无符号整数) 跳过堆栈中的下 N 个模块。请注意,不允许 N 等于 0,在这种情况下将被视为忽略*。侧效果取决于PAM函数调用:用于pam_authenticate, pam_acct_mgmt, pam_chauthtok和 *pam_open_session 它是忽略; 对于pam_setcred和 *pam_close_session,它是ignore*、ok或*bad 之一,*具体取决于模块的返回值。
  • 重置 清除模块堆栈状态的所有内存,并从下一个堆栈模块重新开始。

四个关键字中的每一个:必要的;必需的;充分的; 和可选的,在 […] 语法方面有一个等效的表达式。它们如下:

  • 必要的 [成功=ok new_authtok_reqd=ok 忽略=忽略默认值=坏]
  • 必需的

[success=ok new_authtok_reqd=ok ignore=ignore default=die]

充分的

[成功=完成 new_authtok_reqd=完成默认=忽略]

可选的

[成功=ok new_authtok_reqd=ok 默认=忽略]

module-path要么是应用程序要使用的 PAM 的完整文件名(以“/”开头),要么是来自默认模块位置的相对路径名: /lib/security//lib64/security/,具体取决于体系结构。

模块参数是一个空格分隔的令牌列表,可用于修改给定 PAM 的特定行为。将为每个单独的模块记录此类参数。请注意,如果您希望在参数中包含空格,则应使用方括号将该参数括起来。

最后修改日期: 25 11 月, 2022

作者

留言

撰写回覆或留言

发布留言必须填写的电子邮件地址不会公开。