PAM(Pluggable Authentication Modules,可插拔认证模块)是一种灵活的认证框架,用于在 Linux 和其他类 Unix 系统上管理用户的身份验证。PAM 允许系统管理员通过配置不同的认证模块来定制应用程序和服务的认证方式,而不需要修改这些应用程序的源代码。
0、PAM 介绍
PAM 的核心概念
PAM 提供了一个模块化的认证系统,它由一系列模块和规则组成,来决定用户如何被认证、账户如何管理、密码如何处理以及如何管理用户会话。PAM 系统的设计使得它可以根据需要轻松增加或修改认证方式,而不会影响系统上的应用程序。
PAM 的主要功能:
- 身份验证(Authentication):验证用户身份,通常通过密码或其他认证方式(如指纹、双因素认证等)。
- 账户管理(Account Management):管理用户账户的状态,如账户是否过期、是否被锁定等。
- 密码管理(Password Management):控制密码的设置、修改,以及强制密码策略(如复杂度、到期等)。
- 会话管理(Session Management):管理用户会话的开始和结束,通常用于初始化或清理用户登录/注销时的环境。
PAM 的工作流程
PAM 通过读取位于 /etc/pam.d/
目录下的配置文件来确定如何对某个服务进行认证。每个应用程序(如 SSH、sudo
、login
等)都有自己独立的 PAM 配置文件。例如,SSH 服务的 PAM 配置文件是 /etc/pam.d/sshd
,本地登录的配置文件是 /etc/pam.d/login
。
每个 PAM 配置文件定义了一组模块,这些模块按照预定顺序执行。根据模块的执行结果,决定用户是否能够通过认证,或者账户是否被允许访问。
PAM 配置文件结构
每个 PAM 配置文件由若干行组成,每行定义了一个模块的使用方式。每行的格式如下:
<模块类型> <控制标记> <模块路径> <可选参数>
-
模块类型(Module Type):定义模块的功能,分为四类:
auth
:身份验证模块,用于验证用户身份。account
:账户管理模块,用于管理用户账户的状态(如账户是否过期等)。password
:密码管理模块,用于控制密码的设置和更新。session
:会话管理模块,用于处理用户登录和退出时的操作。
-
控制标记(Control Flag):决定当模块执行成功或失败时该如何处理。常见的控制标记有:
required
:模块必须成功执行,如果失败了,会继续执行后续模块,但最终结果为失败。requisite
:模块必须成功,如果失败了,立即返回失败,不继续执行其他模块。sufficient
:如果该模块成功,则立即返回成功,不再执行其他模块。如果失败了,继续执行其他模块。optional
:模块的结果不会影响最终的认证结果,除非它是唯一的模块。
-
模块路径(Module Path):指定要调用的 PAM 模块,通常位于
/lib/security/
目录下。 -
可选参数(Optional Arguments):用于传递给模块的配置参数。
PAM 配置文件示例
以下是一个 PAM 配置文件 /etc/pam.d/login
的简单示例:
auth required pam_env.so
auth required pam_unix.so
account required pam_unix.so
password required pam_unix.so
session required pam_unix.so
-
auth:
pam_env.so
:在用户登录时设置环境变量。pam_unix.so
:通过传统的 Unix 方式(如/etc/passwd
和/etc/shadow
)验证用户密码。
-
account:
pam_unix.so
:检查账户状态,确认用户是否有权限登录,密码是否过期。
-
password:
pam_unix.so
:用于更改用户密码。
-
session:
pam_unix.so
:管理用户会话的开始和结束,负责登录/注销时的必要操作。
PAM 的灵活性
PAM 的优势在于它的模块化设计。你可以为同一个服务组合多个模块,形成定制的认证方式。例如,你可以通过以下方式配置 SSH 登录:
- 检查
/etc/nologin
文件是否存在(维护模式时阻止登录)。 - 使用本地 Unix 密码进行验证。
- 引入多因素认证模块(如
pam_google_authenticator
)。 - 使用 LDAP 或 RADIUS 模块进行远程用户认证。
常见 PAM 模块
pam_unix.so
:传统 Unix 认证模块,使用/etc/passwd
和/etc/shadow
进行认证。pam_env.so
:设置环境变量。pam_tally2.so
:用于限制登录失败次数,防止暴力破解。pam_nologin.so
:如果/etc/nologin
文件存在,则阻止用户登录。pam_ldap.so
:通过 LDAP 进行用户认证。pam_google_authenticator.so
:使用 Google Authenticator 进行双因素认证。
1、登录认证限制
有个开发任务限制SSH登录和login(串口)登录的用户名,SSH只允许A用户登录,login只允许B用户登录。需要修改PAM配置。
查看验证文件
发现两个登录方式的验证规则都是/etc/pam_withunix
修改pam_withunix
在/etc/pam_withunix
文件的开头写入:
auth required /lib/security/pam_nologin.so
# Configuration for login service
auth [success=1 default=ignore] /lib/security/pam_succeed_if.so service != login
auth required /lib/security/pam_listfile.so item=user sense=allow file=/etc/defconfig/login_users onerr=fail
# Configuration for sshd service
auth [success=1 default=ignore] /lib/security/pam_succeed_if.so service != sshd
auth required /lib/security/pam_listfile.so item=user sense=allow file=/etc/defconfig/ssh_users onerr=fail
然后在/etc/defconfig/
目录分别添加ssh_users 、login_users 文件,文件中写入各种运行登录的用户的用户名。
/etc/defconfig/ssh_users 和 /etc/defconfig/login_users 是自定义路径名称的文件,可以随意填写。
如果是限制的用户不多,推荐方法:
不需要添加文件,对于编译更友好,无需新增系统文件了
如果login 登录必须是用户a
如果sshd 登录必须是用户b
# Configuration for login service
auth [success=1 default=ignore] /lib/security/pam_succeed_if.so service != login
auth requisite /lib/security/pam_succeed_if.so user = a
# Configuration for sshd service
auth [success=1 default=ignore] /lib/security/pam_succeed_if.so service != sshd
auth requisite /lib/security/pam_succeed_if.so user = b