如何通过PAM禁止部分用户登录

如何通过 PAM 限制对 SSH 服务的根访问

如题。客户提出这样一个需求:限制和允许部分账号的SSH登录,限制名单可调。乍一看,这需求完全不合理啊?这又要改多少代码?但------PAM从脑海中一闪而过,想到一个办法,不改代码,也有办法。

PAM是如何运作的?

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

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

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

在我们继续之前,请注意:

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

如何检查程序是否可识别 PAM

要使用 PAM,应用程序/程序需要"识别 PAM";它需要专门编写和编译才能使用 PAM。要确定程序是否"PAM 感知",请使用 ldd 命令检查它是否已使用 PAM 库编译。例如sshd:

bash 复制代码
$ sudo ldd /usr/sbin/sshd | grep libpam.so
    ................
	libpam.so.0 => /lib/x86_64-linux-gnu/libpam.so.0 (0x00007effddbe2000)
    ................

如何在 Linux 中配置 PAM

PAM 的主配置文件是 /etc/pam.conf/etc/pam.d/ 目录包含每个 PAM 感知应用程序/服务的 PAM 配置文件。如果目录存在,PAM 将忽略该文件。

主配置文件的语法如下。该文件由写在一行上的规则列表组成(您可以使用 "\" 转义字符扩展规则),注释前面带有 "#" 标记并延伸到行的下一端。

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

service type control-flag module module-arguments

  1. service:服务:实际应用程序名称。
  2. type:类型:模块类型/上下文/接口。
  3. control-flag:指示模块在其身份验证任务中失败时 PAM-API 的行为。
  4. module:PAM 的绝对文件名或相对路径名。相对路径的根一般是/lib
  5. module-arguments:用于控制模块行为的空格分隔的标记列表。若模块本身不接收参数则可以忽略。

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

bash 复制代码
type control-flag module module-arguments

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

account required pam_nologin.so

了解 PAM 管理组和控制标志

PAM 身份验证任务分为四个独立的管理组。这些组管理典型用户对受限服务的请求的不同方面。模块与以下管理组类型之一相关联:

  1. account:提供账号验证服务:用户密码是否过期?是否允许此用户访问请求的服务?
  2. authentication:对用户进行身份验证并设置用户凭据。
  3. password:负责更新用户密码并与身份验证模块协同工作。
  4. session:管理在会话开始时和会话结束时执行的操作。即登录成功时和注销退出时。用的最多的是在登录成功时创建用户的HOME目录。

PAM 可加载对象文件(模块)应位于以下目录中:/lib/security//lib64/security,具体取决于体系结构。支持的控件标志包括:

  1. requisite:必要条件:故障立即将控制权返回给应用程序,指示第一个模块故障的性质。
  2. required:PAM认证要求所有这些模块成功才能成功,全部成功后才能将成功返回给应用程序,无视两个模块中间的返回操作。有的同学的某些配置不起作用,原因就是在这里了。
  3. sufficient:足够:假设前面的所有模块都已成功,则此模块的成功会导致立即成功返回到应用程序(忽略此模块的失败)。
  4. optional:可选:此模块的成功或失败一般不记录。

除了上述关键字之外,还有另外两个有效的控制标志:includesubstack:包括指定为此控件的参数的配置文件中给定类型的所有行。

如何通过 PAM 限制对 SSH 服务的根访问

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

我们可以使用 /lib/security/pam_listfile.so 模块,它在限制特定帐户的权限方面提供了极大的灵活性。在 /etc/pam.d/ 目录中打开并编辑目标服务的文件,如下所示。

bash 复制代码
$ sudo vim /etc/pam.d/sshd
OR
$ sudo vim /etc/pam.d/login

在两个文件中添加此规则:

bash 复制代码
auth    required       pam_listfile.so \
        onerr=succeed  item=user  sense=deny  file=/etc/ssh/deniedusers

再详细解释上述规则中的令牌:

  1. auth:身份验证:是模块类型(或上下文)。
  2. required:必需:是一个控制标志,表示如果使用模块,则无论其他模块的状态如何,它都必须通过,否则总体结果都将失败。
  3. pam_listfile.so:一个模块,它提供了一种基于任意文件拒绝或允许服务的方法。
  4. onerr=succeed:模块参数。出错返回成功。防止操作失误:文件不存在导致所有账号都无法登录。
  5. item=user:模块参数,指定文件中列出并应检查的内容。
  6. sense=deny:模块参数,指定在文件中找到时要执行的操作,如果在文件中找不到该项,则请求相反的操作。此操作就是客户需求的关键实现。
  7. file=/etc/ssh/deniedusers:模块参数,指定每行包含一个项目的文件。

接下来,我们需要创建文件 /etc/ssh/deniedusers 并在其中添加名称 root:从现在开始,上述规则将告诉 PAM 查阅 /etc/ssh/deniedusers 文件,并拒绝任何列出的用户访问 SSH 和登录服务。

如何在 Linux 中配置高级 PAM

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

bash 复制代码
type [value1=action1 value2=action2 ...] module module-arguments

其中 valueN 对应于为其定义行的模块中调用的函数的返回代码。您可以从在线 PAM 管理员指南中找到支持的值。特殊值是默认值,这意味着所有值 N 都没有明确提及。操作 N 可以采用以下形式之一:

  1. ignore:忽略:如果此操作用于模块堆栈,则模块的返回状态不会对应用程序获取的返回代码产生影响。
  2. bad:错误:指示应将返回代码视为模块失败的指示。如果此模块是堆栈中第一个失败的模块,则其状态值将用于整个堆栈的状态值。
  3. die:等同于坏,但可能会终止模块堆栈,PAM 会立即返回到应用程序。
  4. ok:确定:这指示 PAM 系统管理员认为此返回代码应直接影响整个模块堆栈的返回代码。
  5. done:等效于 ok,但可能会终止模块堆栈,PAM 会立即返回到应用程序。
  6. N(无符号整数):等效于 ok,但可能会跳过堆栈中接下来的 N 个模块。
  7. reset:重置:此操作将清除所有内存中的模块堆栈状态,并使用下一个堆叠模块重新启动。

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

  1. required: [success=ok new_authtok_reqd=ok ignore=ignore default=bad]
  2. requisite: [success=ok new_authtok_reqd=ok ignore=ignore default=die]
  3. sufficient: [success=done new_authtok_reqd=done default=ignore]
  4. optional: [success=ok new_authtok_reqd=ok default=ignore]

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

bash 复制代码
#%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 文件中的另一个示例配置:

bash 复制代码
#%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 是一个功能强大的高级 API,它允许依赖于身份验证的程序向 Linux 系统中的应用程序提供真实用户。它功能强大,但理解和使用起来非常具有挑战性。在本文中,我们已经解释了如何在 Ubuntu 和 CentOS 中配置 PAM 的高级功能。如果您有任何问题或意见要分享,欢迎留言评论。

|-----|-------------------------------|
| 作者: | 岬淢箫声 |
| 日期: | 2023年10月24日 |
| 版本: | 1.0 |
| 链接: | http://caowei.blog.csdn.net |

相关推荐
王哲晓19 分钟前
Linux通过yum安装Docker
java·linux·docker
OkeyProxy22 分钟前
怎麼在Ubuntu上設置全局代理
ubuntu·代理模式·proxy模式·ip代理·海外ip代理
gopher951132 分钟前
linux驱动开发-中断子系统
linux·运维·驱动开发
码哝小鱼1 小时前
firewalld封禁IP或IP段
linux·网络
鼠鼠龙年发大财1 小时前
【x**3专享】安装SSH、XFTP、XShell、ARM Linux
linux·arm开发·ssh
nfgo1 小时前
快速体验Linux发行版:DistroSea详解与操作指南
linux·ubuntu·centos
Rookie_explorers2 小时前
Linux下go环境安装、环境配置并执行第一个go程序
linux·运维·golang
weixin_424215842 小时前
shell运算实战案例-KFC点餐系统
linux·centos
小黑爱编程2 小时前
【LInux】HTTPS是如何实现安全传输的
linux·安全·https
BeyondESH3 小时前
Linux线程同步—竞态条件和互斥锁(C语言)
linux·服务器·c++