linux极简小知识:28、在linux中如何配置和使用PAM[译]

1,863 阅读4分钟

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

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

说明:在查找PAM相关资料的过程中,发现的这篇文章,由于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 可能会将您锁定在自己的系统之外!

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

要使用 PAM,应用/程序需要“PAM aware”;需要专门编写和编译才能使用 PAM。要确定程序是否“PAM-aware”,可使用 ldd 命令检查它是否已经与 PAM 库一起编译。

检查sshd的例子:

$ sudo ldd /usr/sbin/sshd | grep libpam.so

	libpam.so.0 => /lib/x86_64-linux-gnu/libpam.so.0 (0x00007effddbe2000)

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

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

如果 /etc/pam.d/ 目录存在,PAM 将忽略/etc/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/smartcard-auth PAM 文件的示例配置:

#%PAM-1.0
# This file is auto-generated.
# User changes will be destroyed the next time authconfig is run.
auth        required      pam_env.so
auth        [success=done ignore=ignore default=die] pam_pkcs11.so nodebug wait_for_card
auth        required      pam_deny.so

account     required      pam_unix.so
account     sufficient    pam_localuser.so
account     sufficient    pam_succeed_if.so uid < 1000 quiet
account     required      pam_permit.so

password    required      pam_pkcs11.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

有关更多信息,请参见 pam.d 手册页:

man pam.d 

最后,可以在 Linux-PAM 文档(documentation for Linux-PAM) 中找到对配置文件语法和所有 PAM 模块的全面描述。

总结

PAM 是一个强大的高级 API,它允许依赖于身份验证的程序向 Linux 系统中的应用提供用户验证。它功能强大,但理解和使用也非常有挑战性。