T2、PAM 认证
PAM(Pluggable Authentication Modules,可插拔认证模块)是 Linux 和类 Unix 系统中的一套灵活的认证框架。它允许系统管理员通过模块化配置来定义用户认证方式和策略,而无需修改应用程序代码。以下是 PAM 的基础概念和使用方法。
生产环境想要用好 PAM,一定要读懂官方文档 https://docs.rockylinux.org/guides/security/pam/
下面只是提炼一个大概,对 PAM 有一个初步的了解。
PAM 的核心概念
模块化设计:
- PAM 使用多个模块,每个模块负责特定的认证功能(如密码验证、双因素认证等)。
- 这些模块一般位于
/lib64/security
目录中,视系统而定。
配置文件:
- PAM 的配置文件通常位于
/etc/pam.d/
目录中,每个服务(如sshd
、sudo
、login
等)都有对应的配置文件。 - 配置前要找到相关的入口,否则不知道要配置哪个基础文件,比如跟登陆 login 相关的,就要先查看/etc/pam.d/login,其中包含 password 相关的指令
password include system-auth
,然后去修改 system-auth 基础文件,来控制密码复杂度。
控制标志:
- 每个 PAM 规则包含一个控制标志,决定了该模块的认证结果如何影响整体认证。
required
:模块必须成功,失败会继续认证下去,但最终结果为失败。requisite
:模块必须成功,失败会立即终止认证。sufficient
:模块成功后,后续模块将被忽略。optional
:模块的结果不会影响整体认证。include
:包含另一个配置文件。比如auth include password-auth
,通常这个文件包含一系列关于密码验证的配置选项,如密码的复杂度要求、最小长度等。
四种管理任务:
- 认证管理(
auth
):验证用户身份(例如密码验证)。 - 账户管理(
account
):检查账户有效性(如是否被锁定)。 - 密码管理(
password
):处理密码相关操作(如更改密码)。 - 会话管理(
session
):设置和清理会话(如挂载目录、日志记录)。
如何使用 PAM
查看 PAM 配置
查看 PAM 的配置文件(例如 SSH 的 /etc/pam.d/sshd
):
cat /etc/pam.d/sshd
示例配置内容:
#%PAM-1.0
auth required pam_sepermit.so
auth include password-auth
account required pam_nologin.so
account include password-auth
password include password-auth
session required pam_selinux.so close
session required pam_loginuid.so
session optional pam_keyinit.so force revoke
session include password-auth
修改 PAM 配置
修改 PAM 配置文件来增加或调整认证方式。例如,强制锁定多次密码失败的账户:
-
编辑
/etc/pam.d/common-auth
或/etc/pam.d/sshd
(视服务而定):auth required pam_tally2.so deny=3 unlock_time=900
deny=3
:允许 3 次错误登录。unlock_time=900
:账户锁定 15 分钟。 -
检查配置是否生效:
faillog -u username
添加双因素认证
使用 pam_google_authenticator
模块启用双因素认证
-
安装 Google Authenticator:
sudo apt install libpam-google-authenticator
-
编辑
/etc/pam.d/sshd
,添加:auth required pam_google_authenticator.so
-
配置用户的 TOTP:
google-authenticator
进入交互式配置,生成密钥和二维码、回答配置问题、保存的文件。
密钥信息会保存在用户的
~/.google_authenticator
文件中。确保文件权限为 600。 -
确保 SSH 支持密码和 TOTP 认证,编辑
/etc/ssh/sshd_config
:ChallengeResponseAuthentication yes
然后重启 SSH:
systemctl restart sshd
配置密码复杂度
通过 pam_pwquality
强化密码复杂度
-
编辑
/etc/pam.d/common-password
或/etc/pam.d/system-auth
,添加:password requisite pam_pwquality.so retry=3 minlen=16 ucredit=-1 lcredit=-1 dcredit=-1 ocredit=-1
minlen=16
:密码最小长度 16。ucredit=-1
:至少 1 个大写字母。lcredit=-1
:至少 1 个小写字母。dcredit=-1
:至少 1 个数字。ocredit=-1
:至少 1 个特殊字符。/etc/pam.d/common-password
是 PAM 框架的配置文件,直接关联到登录或密码管理服务。 -
编辑
/etc/security/pwquality.conf
以设置全局密码策略:minlen = 16 dcredit = -1 ucredit = -1 lcredit = -1 ocredit = -1
pwquality.conf 是
pam_pwquality.so
模块的配置文件,用于提供更详细的密码质量策略。它不会直接被 PAM 使用,而是通过
pam_pwquality.so
模块被加载。
验证 PAM 配置
在更改 PAM 配置后,建议测试配置是否正常
-
创建测试用户:
useradd testuser passwd testuser
-
登录系统测试:
su - testuser
-
检查日志文件获取认证结果:
tail -f /var/log/auth.log # Debian/Ubuntu tail -f /var/log/secure # RHEL/CentOS
自定义 PAM
服务是如何借用 PAM 认证的,比如 sshd 是如何关联到 pam 框架的,如果我有一个新服务 sixd,也要密码登陆,如何借用 pam 框架认证?
sshd
(OpenSSH Daemon)通过 PAM 框架来实现认证,这是因为 sshd
被配置为使用 PAM 模块来验证用户身份。要理解和实现类似的功能,需要了解 PAM 的工作原理以及如何将一个新服务集成到 PAM 中。
SSHD 是如何关联到 PAM
-
PAM 配置文件:
sshd
的 PAM 配置文件位于/etc/pam.d/sshd
,它定义了sshd
使用哪些 PAM 模块以及认证流程。例如:#%PAM-1.0 auth required pam_sepermit.so auth include password-auth account required pam_nologin.so account include password-auth password include password-auth session required pam_selinux.so close session required pam_loginuid.so session optional pam_keyinit.so force revoke session include password-auth
-
UsePAM
配置: 在/etc/ssh/sshd_config
中,有一项关键配置:UsePAM yes
当
UsePAM
设置为yes
时,sshd
将调用 PAM 框架来处理用户认证和其他安全功能。 -
PAM 模块的加载: PAM 框架会根据
/etc/pam.d/sshd
的配置,加载对应的 PAM 模块(如pam_unix.so
、pam_tally2.so
等),完成密码验证、账户检查等任务。
为新服务 sixd
集成 PAM 框架
如果你开发了一个新服务 sixd
,并希望通过 PAM 框架实现密码认证,可以按照以下步骤操作:
-
创建 PAM 配置文件
为
sixd
创建一个 PAM 配置文件,例如/etc/pam.d/sixd
:# PAM configuration for sixd auth required pam_unix.so auth required pam_faildelay.so delay=2000000 account required pam_unix.so password required pam_unix.so session required pam_limits.so
auth
:负责用户认证(如密码验证)。account
:检查账户状态(如账户是否被锁定)。password
:处理密码更改请求。session
:管理会话(如资源限制)。 -
在代码中调用 PAM
你的服务需要使用 PAM API 完成认证。以下是一个简单的伪代码示例(基于 C 语言):
#include
#include #include static struct pam_conv conv = { misc_conv, NULL }; int main() { pam_handle_t *pamh = NULL; int retval; const char *username = "testuser"; retval = pam_start("sixd", username, &conv, &pamh); if (retval != PAM_SUCCESS) { fprintf(stderr, "PAM start failed: %s\n", pam_strerror(pamh, retval)); return 1; } retval = pam_authenticate(pamh, 0); if (retval != PAM_SUCCESS) { fprintf(stderr, "Authentication failed: %s\n", pam_strerror(pamh, retval)); pam_end(pamh, retval); return 1; } retval = pam_acct_mgmt(pamh, 0); if (retval != PAM_SUCCESS) { fprintf(stderr, "Account management failed: %s\n", pam_strerror(pamh, retval)); pam_end(pamh, retval); return 1; } printf("Authentication successful!\n"); pam_end(pamh, PAM_SUCCESS); return 0; } pam_start()
:初始化 PAM 会话并加载/etc/pam.d/sixd
配置。pam_authenticate()
:执行用户认证。pam_acct_mgmt()
:检查账户状态。pam_end()
:清理 PAM 会话。 -
编译和运行服务
将上述代码编译为可执行文件并运行:
gcc -o sixd_auth sixd_auth.c -lpam -lpam_misc ./sixd_auth
-
测试 PAM 集成
测试用户登录是否符合
/etc/pam.d/sixd
中的规则。例如:- 使用一个普通用户尝试登录。
- 验证密码错误次数限制或其他 PAM 策略是否生效。
-
配置服务
将你的服务设计为使用 PAM API 进行认证,并配置为启动时调用
/etc/pam.d/sixd
。
注意事项
-
权限问题: 确保你的服务运行时具备读取
/etc/shadow
的权限,否则无法通过pam_unix.so
进行密码验证。 -
日志检查: 使用以下命令检查认证日志,定位问题:
tail -f /var/log/auth.log # Debian/Ubuntu tail -f /var/log/secure # RHEL/CentOS
-
增强安全性:
- 可结合 PAM 模块(如
pam_google_authenticator.so
)实现双因素认证。 - 使用模块(如
pam_tally2.so
或pam_fail2ban
)限制登录尝试次数。
- 可结合 PAM 模块(如
-
备份配置: 修改
/etc/pam.d/
配置文件前,务必备份原文件。