关于Linux 系统中的PAM配置和使用 如何配置和使用PAM

翻译自How to Configure and Use PAM in Linux。作者:Aaron Kili。

如果想要详细细致的了解 Linux-PAM ,推荐参考官方指导The Linux-PAM System Administrators’ Guide

说明:在查找PAM相关资料的过程中,发现的这篇文章,由于PAM理解起来确实有些挑战,个别地方介绍的都是一知半解。本篇对PAM的整体结构、参数和配置示例等,都给了一个比较清晰的介绍,对于理解PAM及其使用很有帮助。

当然,要想真正全面的了解和使用Linux-PAM,还是上面推荐的官方的《The Linux-PAM System Administrators’ Guide》。

简介

Linux-PAM(Pluggable Authentication Modules 的缩写,从 Unix-PAM 架构演变而来)是一套强大的共享库,用于在 Linux 系统中动态验证用户对应用程序(或服务)的身份。

它将多个低级别身份验证模块集成到一个高级 API 中,为应用程序提供动态身份验证支持。这允许开发人员独立于底层身份验证系统编写需要身份验证的应用程序。

许多现代 Linux 发行版默认支持 Linux-PAM(以下简称“PAM”)。在本文中,将解释如何在 Ubuntu 和 CentOS 系统中配置高级 PAM。

在继续之前,请注意:

  • 作为系统管理员,最重要的是掌握 PAM 配置文件如何定义应用程序(服务)和执行实际身份验证任务的可插拔身份验证模块 (PAM) 之间的连接。您不一定需要了解 PAM 的内部工作原理。
  • PAM 有可能严重改变 Linux 系统的安全性。错误的配置可能会部分或完全禁用对系统的访问。例如,意外删除 /etc/pam.d/* 下的配置文件 和/或 /etc/pam.conf 可能会将您锁定在自己的系统之外!

运行机制

如下是一个最常见的 login 示例程序,其中包括了二进制 login 可执行程序,该程序会动态链接 libpam.so 库,该库会读取 /etc/pam.d/login 配置文件,并根据配置文件中的内容,按照顺序生成不同栈。

然后,会根据不同的栈以及配置执行相关的动作。

如何检查一个程序是否支持 PAM(How to Check a Program is PAM-aware)

如果一个应用程序 (例如 login) 想使用 PAM 提供的机制,那么需要链接到 libpam.so 库,否则就不支持 PAM 机制,可以通过如下命令查看。

$ ldd /usr/bin/login | grep pam
libpam.so.0 => /lib64/libpam.so.0 (0x00007fc79c03e000)
libpam_misc.so.0 => /lib64/libpam_misc.so.0 (0x00007fc79be3a000)

默认程序名与相关的 PAM 配置文件是相同的,当然,也允许通过配置文件进行配置,指定不同的配置文件名称。

验证时会按照顺序检查,也就是所谓的流程栈 (Stack) ,是认证时执行步骤、规则的堆叠,体现了自上而下的执行顺序,而且可以被引用。

在 Linux 中如何配置 PAM(How to Configure PAM in Linux)

PAM 的主要配置文件是 /etc/pam.conf 和 包含每个 PAM 感知应用程序/服务的 PAM 配置文件的/etc/pam.d/ 目录

如果 /etc/pam.d/ 目录存在,PAM 将忽略/etc/pam.conf文件。

主配置文件pam.conf的语法如下。该文件由写在一行上的一系列规则组成(可以使用”\”转义字符扩展规则),并且注释前面带有“#”标记,其注释扩展到行的末尾。

每个规则的格式是一个以空格分隔的标记集合(前三个不区分大小写)。我们将在后续章节中解释这些标记。

service type control-flag module module-arguments 

此处:

  • service:实际应用程序名称。
  • type:模块类型/上下文/接口。
  • control-flag:指示模块在其身份验证任务中失败时 PAM-API 的行为。
  • module:PAM 的绝对文件名或相对路径名。
  • module-arguments:空格分隔的令牌列表,用于控制模块行为。

/etc/pam.d/ 目录中每个文件的语法与主文件的语法相似,由以下形式的行组成:

type control-flag module module-arguments

下面是在 /etc/pam.d/sshd 文件中找到的规则定义(没有模块参数)的示例,它表示当 /etc/nologin 存在时,不允许非 root 登录:

account required pam_nologin.so

理解 PAM 管理组和控制标志(Understanding PAM Management Groups and Control-flags)

PAM 身份验证任务分为四个独立的管理组。这些组管理典型用户对受限服务请求的不同方面。

一个模块(module)关联以下管理组类型之一:

  • account:提供账户验证服务:用户密码是否过期?用户是否允许访问所请求的服务?
  • authentication:对用户进行身份验证并设置用户凭据。
  • password:负责更新用户密码,与认证模块(authentication modules)协同工作。
  • session:管理在会话开始和会话结束时执行的操作。

PAM 可加载对象文件(模块(modules))位于以下目录中:/lib/security//lib64/security,具体取决于体系结构。

支持的控制标记(control-flags)是:

  • requisite:失败立即将控制权返回给应用程序,指示模块(modules)失败的性质。 requisite —— 必要条件。
  • required:所有required的模块都成功,libpam 才能将成功返回给应用程序。 required —— 必需,需求的。
  • sufficient:假设所有前面的模块都成功了,对应模块的成功会导致立即将成功返回应用程序(而模块的失败被忽略)。
  • optional:对应模块的成功或失败一般不记录。

除了以上是关键字之外,还有另外两个有效的控制标志:

  • include:包括所有给定类型的行,这些类型来自作为该控制表示参数的特定配置文件。
  • substack:包括所有给定类型的行,这些类型来自作为该控制表示参数的特定配置文件。

此处应为原文小失误:原文中两行解释一样。

  • include: include all lines of given type from the configuration file specified as an argument to this control.
  • substack: include all lines of given type from the configuration file specified as an argument to this control.

如何通过 PAM 限制对 SSH 服务的 root 访问(How to Restrict root Access to SSH Service Via PAM)

作为一个示例,我们将配置如何使用 PAM 禁用 root 用户通过 SSH 和登录程序访问系统。在这里,我们通过限制对登录和 sshd 服务的访问来禁用 root 用户对系统的访问。

我们可以使用 /lib/security/pam_listfile.so 模块,它提供非常大的灵活性限制特定账户的权限。

打开和编辑 /etc/pam.d/ 目录下的目标服务文件,如下所示:

$ sudo vim /etc/pam.d/sshd
OR
$ sudo vim /etc/pam.d/login

在这两个文件中添加如下规则。

auth    required       pam_listfile.so \
        onerr=succeed  item=user  sense=deny  file=/etc/ssh/deniedusers

解释以上的每个位置:

  • auth:是模块类型(或上下文)。—— module type (or context)
  • required:是一个控制标志,表示如果模块被使用,它必须通过,否则整体结果将失败,无论其他模块的状态如何。
  • pam_listfile.so:是一个模块(module ),提供了一种基于任意文件拒绝或允许服务的方法。
  • onerr=succeed:模块参数。
  • item=user:模块参数,指定文件中列出和应该检查的内容。
  • sense=deny:模块参数,指定如果在文件中找到要采取的动作,如果在文件中找不到该项(item),则请求相反的动作。
  • file=/etc/ssh/deniedusers:模块参数,指定每行包含一个项(item)的文件。

接下来,我们需要创建文件 /etc/ssh/deniedusers 并在其中添加名称 root :

$ sudo vim /etc/ssh/deniedusers

保存更改并关闭文件,然后设置所需的权限:

$ sudo chmod 600 /etc/ssh/deniedusers

从现在开始,上述规则将告诉 PAM 查询 /etc/ssh/deniedusers 文件并拒绝任何列出的用户访问 SSH 和登录服务。

如何在 Linux 中配置高级 PAM(How to Configuring Advanced PAM in Linux)

要编写更复杂的 PAM 规则,可以使用以下形式的有效控制标志(control-flags):

type [value1=action1 value2=action2 …] module module-arguments

其中 valueN 对应于在定义该行的模块中调用的函数的返回代码。您可以从在线 PAM管理员指南(PAM Administrator’s Guide) 中找到支持的值。一个特殊值是default,这意味着所有未明确提及的 valueN。

actionN 可以采用以下形式之一:

  • ignore:如果此action与模块堆栈一起使用,则模块的返回状态将不会影响应用程序获得的返回代码。
  • bad:表示返回码应该被认为是模块失败的指示。如果此模块是堆栈中第一个发生故障的模块,则其状态值将用于整个堆栈的状态值。
  • die:相当于 bad 但可能会终止模块堆栈,PAM 会立即返回给应用程序。
  • ok:这会告诉 PAM,系统管理员认为这个返回码应该直接影响整个模块堆栈的返回码。
  • done:等同于 ok 但可能会终止模块堆栈,PAM 立即返回到应用程序。
  • N(an unsigned integer):相当于 ok 但可能会跳过堆栈中的下 N 个模块。
  • Reset:此action清除模块堆栈状态的所有内存,并从下一个堆栈模块重新启动。

四个关键字中的每一个:required; requisite; sufficient; 和 optional,在 [...] 语法方面都有一个等效的表达式,这允许您编写更复杂的规则,它们是:

  • required: [success=ok new_authtok_reqd=ok ignore=ignore default=bad]
  • requisite: [success=ok new_authtok_reqd=ok ignore=ignore default=die]
  • sufficient: [success=done new_authtok_reqd=done default=ignore]
  • optional: [success=ok new_authtok_reqd=ok default=ignore]

以下是来自现代 CentOS 7 系统的示例。让我们考虑 /etc/pam.d/postlogin PAM 文件中的这些规则:

#%PAM-1.0
# This file is auto-generated.
# User changes will be destroyed the next time authconfig is run.
session     [success=1 default=ignore] pam_succeed_if.so service !~ gdm* service !~ su* quiet
session     [default=1]   pam_lastlog.so nowtmp showfailed
session     optional      pam_lastlog.so silent noupdate showfailed

这是另一个 /etc/pam.d/system-auth PAM 文件的示例配置:

# grep -v ^# /etc/pam.d/system-auth
auth        required      pam_env.so
auth        sufficient    pam_unix.so nullok try_first_pass
auth        requisite     pam_succeed_if.so uid >= 500 quiet
auth        required      pam_deny.so
 
account     required      pam_unix.so
account     sufficient    pam_succeed_if.so uid < 500 quiet
account     required      pam_permit.so
 
password    requisite     pam_cracklib.so try_first_pass retry=3
password    sufficient    pam_unix.so md5 shadow nullok try_first_pass use_authtok
password    required      pam_deny.so
 
session     optional      pam_keyinit.so revoke
session     required      pam_limits.so
session     [success=1 default=ignore] pam_succeed_if.so service in crond quiet use_uid
session     required      pam_unix.so

第一部分AUTH表示,当用户登录的时候,首先会通过 auth 类接口对用户身份进行识别和密码认证。所以在该过程中验证会经过几个带 auth 的配置项。

其中的第一步是通过 pam_env.so 模块来定义用户登录之后的环境变量, pam_env.so 允许设置和更改用户登录时候的环境变量,默认情况下,若没有特别指定配置文件,将依据 /etc/security/pam_env.conf 进行用户登录之后环境变量的设置。

然后通过 pam_unix.so 模块来提示用户输入密码,并将用户密码与 /etc/shadow 中记录的密码信息进行对比,如果密码比对结果正确则允许用户登录,而且该配置项的使用的是“sufficient”控制位,即表示只要该配置项的验证通过,用户即可完全通过认证而不用再去走下面的认证项。不过在特殊情况下,用户允许使用空密码登录系统,例如当将某个用户在 /etc/shadow 中的密码字段删除之后,该用户可以只输入用户名直接登录系统。

下面的配置项中,通过 pam_succeed_if.so 对用户的登录条件做一些限制,表示允许 uid 大于 500 的用户在通过密码验证的情况下登录,在 Linux 系统中,一般系统用户的 uid 都在 500 之内,所以该项即表示允许使用 useradd 命令以及默认选项建立的普通用户直接由本地控制台登录系统。

最后通过 pam_deny.so 模块对所有不满足上述任意条件的登录请求直接拒绝,pam_deny.so 是一个特殊的模块,该模块返回值永远为否,类似于大多数安全机制的配置准则,在所有认证规则走完之后,对不匹配任何规则的请求直接拒绝。

第二部分ACCOUNT的三个配置项主要表示通过 account 账户类接口来识别账户的合法性以及登录权限。

第一行仍然使用 pam_unix.so 模块来声明用户需要通过密码认证。第二行承认了系统中 uid 小于 500 的系统用户的合法性。之后对所有类型的用户登录请求都开放控制台。

第三部分PASSWORD会通过 password 口另类接口来确认用户使用的密码或者口令的合法性。第一行配置项表示需要的情况下将调用 pam_cracklib 来验证用户密码复杂度。如果用户输入密码不满足复杂度要求或者密码错,最多将在三次这种错误之后直接返回密码错误的提示,否则期间任何一次正确的密码验证都允许登录。需要指出的是,pam_cracklib.so 是一个常用的控制密码复杂度的 pam 模块,关于其用法举例我们会在之后详细介绍。之后带 pam_unix.so 和 pam_deny.so 的两行配置项的意思与之前类似。都表示需要通过密码认证并对不符合上述任何配置项要求的登录请求直接予以拒绝。不过用户如果执行的操作是单纯的登录,则这部分配置是不起作用的。

第四部分SESSION主要将通过 session 会话类接口为用户初始化会话连接。其中几个比较重要的地方包括,使用 pam_keyinit.so 表示当用户登录的时候为其建立相应的密钥环,并在用户登出的时候予以撤销。不过该行配置的控制位使用的是 optional,表示这并非必要条件。之后通过 pam_limits.so 限制用户登录时的会话连接资源,相关 pam_limit.so 配置文件是 /etc/security/limits.conf,默认情况下对每个登录用户都没有限制。关于该模块的配置方法在后面也会详细介绍。

可见,不同应用程序通过配置文件在认证过程中调用不同的 pam 模块来定制具体的认证流程。其中我们不难看出,其实可以根据实际的需要对 pam 的配置文件进行修改以满足不同的认证需求


图片来源&参考

未经允许随便转载:看过够 » 关于Linux 系统中的PAM配置和使用 如何配置和使用PAM

赞 (8) 打赏

评论 0

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

微信扫一扫打赏