运维安全02 - PAM介绍以及使用
一、PAM介绍
PAM(Pluggable Authentication Modules)即可插拔式认证模块。
它是一种高效且灵活的用户级别的认证方式,广泛应用于当前Linux服务器中作为主要的认证机制。
PAM允许系统管理员通过配置不同的认证模块来实现对用户的网段、时间、用户名、密码等多方面的认证。
PAM被称为“可插拔”主要是因为它提供了一种灵活、动态的方式来处理认证请求,而不需要修改应用程序本身。这种灵活性主要体现在以下几个方面:
模块化设计:PAM允许系统管理员通过配置文件来指定使用哪些认证模块以及它们的执行顺序和条件,而无需改动程序代码。这意味着不同的安全策略可以通过简单的配置更改来实现,极大地提高了系统的适应性和安全性。
易于扩展:开发者可以编写新的PAM模块以支持新的认证机制或服务,然后只需将这些模块添加到现有的PAM架构中,而不需要对依赖于PAM的应用程序进行任何修改。
动态加载:PAM框架能够在运行时根据需要加载相应的模块。这意味着如果一个特定的服务需要一种特殊的认证方式,它可以在启动时或首次尝试认证时才加载对应的PAM模块,从而减少了不必要的资源占用。
集中管理:通过统一的接口和配置文件,PAM使得认证逻辑可以从应用程序中分离出来,实现了集中管理和维护。这对于大型企业环境特别有用,因为它们可能需要针对不同的用户群体和服务类型实施复杂的访问控制策略。
使用PAM进行身份认证的服务:
本地登录服务:如
login
、gdm
(GNOME显示管理器)、kdm
(KDE显示管理器),这些服务用于本地用户登录。远程登录服务:如
sshd
(SSH守护进程),用于提供安全的远程登录功能。文件传输服务:如
vsftpd
(虚拟安全FTP守护进程),用于文件传输过程中的用户认证。网络共享服务:如
samba
,用于Windows与Linux之间的文件和打印机共享。
不使用PAM进行身份认证的服务:
数据库服务:如
MySQL-Server
,其用户认证通常由自身的权限管理系统处理。监控服务:如
Zabbix
,其认证机制独立于PAM,通常依赖于内置的用户管理和认证功能。
为什么需要使用PAM
灵活性:PAM允许系统管理员在不修改应用程序的情况下更换或更新认证机制。
集中管理:通过PAM,可以在整个网络中统一用户认证策略,简化了多台服务器的管理。
增强安全性:PAM支持多种安全模块,如密码复杂度检查、登录尝试次数限制等,有助于提高系统的整体安全性。
易于维护:由于PAM是模块化的,因此添加新的认证方法或移除旧的方法都非常简单,这降低了长期维护的成本。
如果不设置PAM将会怎么样
如果不为某个支持PAM的应用程序设置适当的PAM配置,则可能导致以下几种情况之一:
应用程序可能会回退到默认行为,即可能允许所有或拒绝所有连接尝试,具体取决于应用的设计。
在某些情况下,如果找不到有效的PAM配置,应用程序可能根本无法正常运行,导致服务不可用。
安全性降低,因为缺少了额外一层的认证控制,系统更容易受到攻击。
系统管理员失去了对特定服务用户访问控制的能力,无法实施细粒度的访问控制策略。
可以通过浏览器查看详细的PAM文档:
firefox /usr/share/doc/pam-1.1.8/html/Linux-PAM_SAG.html
PAM认证流程
PAM认证流程通常包括以下几个步骤:
服务请求:当用户试图访问一个受保护的服务时(如SSH登录),该服务会调用相应的PAM API来启动认证过程。
加载配置文件:服务程序根据其配置文件中的定义加载对应的PAM模块。
每个服务都有自己的PAM配置文件,位于
/etc/pam.d/
目录下。执行认证:PAM按照配置文件中指定的顺序依次调用各个模块进行认证。
这些模块可能涉及密码验证、账户有效期检查、会话设置等多个方面。
返回结果:所有模块执行完毕后,PAM将最终的认证结果(成功或失败)返回给原始的服务程序。
在 PAM 配置文件中(如
/etc/pam.d/sshd
或/etc/pam.d/login
),规则是按顺序从上到下依次执行的,并且它们的作用是 叠加的,但具体是否继续执行、是否认证成功,取决于每个模块的 控制标志(control flag) 和 返回结果。
认证类型
认证类型 | 功能描述 | 作用 | 操作 |
---|---|---|---|
auth | 验证用户身份,如检查用户名和密码是否正确 | 确保用户提供的身份信息是正确的 | 使用pam_unix.so 模块进行传统账号密码认证 |
account | 控制用户访问权限,如账户过期、时间限制等 | 防止过期账户或密码被使用 | 使用pam_access.so 模块基于IP地址限制登录 |
password | 管理密码策略,如复杂度检查、历史密码限制 | 防止暴力破解攻击,提高密码安全性 | 使用pam_cracklib.so 模块强制设置强密码 |
session | 管理会话,如日志记录、资源限制 | 监控用户行为,防止滥用系统资源 | 使用pam_limits.so 模块限制最大进程数 |
流程控制标记
流程控制标记 | 描述 | 特点 | 案例 |
---|---|---|---|
required | 验证失败时仍然继续执行后续模块,但最终返回fail | 用户不会知道具体哪个模块失败 | 在SSH服务中使用pam_access.so 限制特定IP登录 |
requisite | 验证失败时立即结束整个验证过程,返回fail | 效率高,一旦某个关键模块失败则立即终止 | 在登录过程中使用pam_nologin.so 阻止非root用户登录 |
sufficient | 验证成功则立即返回,不再继续执行后续模块;否则忽略结果并继续 | 如果某项条件已经足够证明用户身份,则无需再进行其他验证 | 使用pam_rootok.so 允许root用户直接切换到其他用户 |
optional | 无论验证结果如何均不会影响最终结果 | 常用于session类型,提供额外的信息或功能 | 使用pam_lastlog.so 记录用户的最后登录时间 |
include | 包含另一个配置文件中相同类型的行 | 用于简化配置,避免重复编写相同的模块配置 | 在/etc/pam.d/sshd 中包含password-auth 配置文件 |
substack | 垂直叠加一个模块栈嵌入到另一个模块栈中 | 形成更复杂的认证逻辑 | 在多因素认证中,将多个模块组合在一起进行验证 |
案例分析
SSH登录认证
场景:限制特定IP地址的用户登录。
配置步骤:
编辑
/etc/pam.d/sshd
文件。添加以下内容:
auth required pam_access.so accessfile=/etc/security/access.conf
在/etc/security/access.conf
中定义允许或拒绝的IP规则:
# 允许192.168.1.0网段的用户登录
+ : ALL : 192.168.1.
# 拒绝所有其他IP地址
- : ALL : ALL
密码复杂度管理
场景:强制用户设置符合复杂度要求的密码。
配置步骤:
编辑
/etc/pam.d/system-auth
文件。添加以下内容:
password required pam_cracklib.so minlen=12 dcredit=-1 ucredit=-1 lcredit=-1 ocredit=-1
参数解释:
minlen=12
:密码最小长度为12。dcredit=-1
:至少包含1个数字。ucredit=-1
:至少包含1个大写字母。lcredit=-1
:至少包含1个小写字母。ocredit=-1
:至少包含1个特殊字符。
资源限制
场景:限制用户最多同时运行50个进程。
配置步骤:
编辑
/etc/security/limits.conf
文件。添加以下内容:
* soft nproc 50
* hard nproc 100
参数解释:
soft
:软限制,用户可以自行调整。hard
:硬限制,只有root用户可以修改。nproc
:进程数限制。
会话日志记录
场景:记录用户的登录时间和终端信息。
配置步骤:
编辑
/etc/pam.d/login
文件。添加以下内容:
session optional pam_lastlog.so
常见问题
认证失败:检查PAM配置文件是否有语法错误,确保所有模块路径正确且存在。
性能问题:避免在认证过程中加载过多不必要的模块,合理选择模块类型和控制标志。
安全风险:定期更新PAM模块,遵循最佳安全实践,如启用账户锁定、密码复杂度检查等。
1.2 pam_rootok.so
功能:用于检查当前用户是否为超级用户(root)。
应用场景:
允许 root 用户无密码切换到其他账户(如
/bin/su
)。控制某些特权服务或脚本只能由 root 执行。
模块说明
该模块在认证过程中判断当前用户是否是 root。如果是,则返回成功;否则返回失败。
它常被用作 auth
类型的模块,通常与以下控制标志一起使用:
控制标志 | 含义 |
---|---|
sufficient | 如果当前模块成功,则跳过后续模块,直接通过认证 |
required | 即使模块失败,直接失败 |
你要登机前需要完成一系列检查项:
身份验证(必须通过 required)
是否 VIP 乘客(快速通道 sufficient)
情况 A:你是 VIP(对应
sufficient
)
第一项是“身份验证” → 必须通过
第二项是“是否 VIP” → 成功了就走快速通道
流程如下:
先检查身份 通过
然后发现你是 VIP 快速放行,后面的常规安检跳过!
这就是
sufficient
的作用:一旦成功,直接通过整个阶段,不再看后面的模块。
情况 B:你不是 VIP(但身份没问题)
第一项是“身份验证” 必须通过
第二项是“是否 VIP” 不是,但没关系,继续做后面的检查
这就是
sufficient
失败时的行为:不阻拦,继续往下走
情况 C:身份验证失败
第一项“身份验证” 失败(它是 required)
即使你是 VIP,也必须等到最后才知道是否允许通行(因为 required 必须全部成功)
这就是
required
的作用:不管后面模块有没有成功,它必须通过才行
实际 PAM 配置案例说明
以
/etc/pam.d/sshd
中的常见配置为例:auth required pam_access.so accessfile=/etc/security/access.conf auth sufficient pam_rootok.so auth include system-auth
pam_access.so
是 required
必须通过访问控制规则(比如 IP 白名单),否则不能继续。
pam_rootok.so
是 sufficient
如果当前用户是 root,直接认证成功,不需要再检查后面的密码或 PAM 认证。
system-auth
是 include
包含标准的用户名/密码认证流程。
PAM 配置文件一般位于 /etc/pam.d/
目录下。
/etc/pam.d/su
:控制su
命令的行为/etc/pam.d/sshd
:控制 SSH 登录行为(不推荐在此使用pam_rootok.so
)
案例演示
原始文件
#%PAM-1.0
auth sufficient pam_rootok.so
auth substack system-auth
auth include postlogin
account sufficient pam_succeed_if.so uid = 0 use_uid quiet
account include system-auth
password include system-auth
session include system-auth
session include postlogin
session optional pam_xauth.so
执行 su 命令
↓
[1] 是不是 root? ➜ 是 → 直接通过
↓
[2] 标准认证(输入密码)→ 成功继续,失败拒绝
↓
[3] 登录后处理(如提示信息)
↓
[4] 是不是 root? ➜ 是 → 跳过账户检查
↓
[5] 检查账户状态(是否锁定、是否允许登录等)
↓
[6] 修改密码相关逻辑(如果设置新密码)
↓
[7] 创建会话环境(如设置 PATH、记录日志)
↓
[8] 图形授权(可选,仅图形界面用)
↓
切换成功
允许 root 无密码切换到普通用户(默认行为)
编辑 /etc/pam.d/su
sudo vi /etc/pam.d/su
确保包含如下行
auth sufficient pam_rootok.so
测试切换
su - user1
预期行为:无需输入密码即可切换到 user1
禁止 root 无密码切换(强制输入密码)
修改
/etc/pam.d/su
文件内容如下:
# auth sufficient pam_rootok.so # 注释掉这一行
测试切换
su - user1
预期行为:提示输入 user1
的密码
1.3 pam_access.so
模块名称:pam_access.so
功能:基于用户名、终端(tty)、IP 地址或域名控制用户对系统的访问权限。
应用场景:
控制哪些用户可以从哪些 IP 登录系统
禁止特定用户从远程登录
限制某些服务仅允许本地登录
模块原理
pam_access.so
模块通过读取配置文件 /etc/security/access.conf
,根据其中定义的规则判断当前登录请求是否被允许。
该模块属于 auth
类型,通常用于服务的认证阶段,例如 SSH、login、su、vsftpd 等。
语法详解
每行格式如下:
<permission> : <user/group> : <origin>
参数说明:
字段 | 含义 | 示例 |
---|---|---|
<permission> | 权限标志:+ 允许,- 拒绝 | + , - |
<user/group> | 用户名或组名(可使用通配符) | root , @admin , ALL |
<origin> | 来源地址(IP、主机名、终端设备等) | 192.168.1.0/24 , tty1 , ALL |
案例演示
允许 root 仅从本地终端登录
编辑 access.conf:
sudo vi /etc/security/access.conf
添加以下内容:
tty1
、tty2
、tty3
是什么?它们是 Linux 系统中的 虚拟终端(Virtual Terminals),也叫 控制台终端(Console Terminals)。
你可以把它们理解为“本地物理键盘和显示器上的登录界面”。
# 允许 root 从本地终端登录
+ : root : tty1 tty2 tty3# 拒绝 root 从其他地方登录
- : root : ALL
2. 在对应服务中启用 pam_access.so(如 SSH)
编辑 /etc/pam.d/sshd
:
sudo vi /etc/pam.d/sshd
添加一行:
auth required pam_access.so accessfile=/etc/security/access.conf
测试效果
从本地终端切换到 root 成功
通过 SSH 登录 root 被拒绝
禁止所有用户从某个 IP 登录
修改 access.conf:
sudo vi /etc/security/access.conf
添加如下规则:
# 禁止来自 192.168.10.100 的所有用户登录
- : ALL : 192.168.10.100
2. 在服务中加载 pam_access.so(如 login 或 sshd)
确保服务的 PAM 配置文件中有:
auth required pam_access.so accessfile=/etc/security/access.conf
3. 测试效果
来自
192.168.10.100
的用户无法登录其他 IP 可以正常登录
仅允许 admin 组从特定网段登录
1. 创建 admin 组和用户(如果尚未创建)
groupadd admin
usermod -aG admin user1
2. 修改 access.conf:
sudo vi /etc/security/access.conf
添加如下规则:
# 允许 admin 组成员从 192.168.1.0/24 登录
+ : @admin : 192.168.1.# 拒绝 admin 组从其他来源登录
- : @admin : ALL
在服务中启用 pam_access.so(如 SSH)
在 /etc/pam.d/sshd
中添加:
auth required pam_access.so accessfile=/etc/security/access.conf
4. 测试效果
user1
从192.168.1.x
登录 成功user1
从其他网段登录 被拒绝
禁止所有非白名单用户登录
1. 修改 access.conf:
sudo vi /etc/security/access.conf
添加如下规则:
# 白名单用户可以登录
+ : user1 user2 @devops : 192.168.1. 10.0.0.# 默认拒绝所有其他用户
- : ALL : ALL
2. 在服务中启用 pam_access.so
确保 /etc/pam.d/sshd
或 /etc/pam.d/login
中包含:
auth required pam_access.so accessfile=/etc/security/access.conf
3. 测试效果
白名单中的用户和组可以从指定网络登录
其他用户一律被拒绝
注意事项
安全建议 | 说明 |
---|---|
避免将 pam_access.so 放在流程最后 | 如果前面模块已通过认证,它可能不会生效。建议放在 auth 阶段开头 |
不要只依赖 pam_access.so | 建议结合 pam_time.so 、pam_listfile.so 实现更细粒度控制 |
定期检查 access.conf 规则 | 避免误删或误写导致权限失控 |
测试环境验证后再部署生产 | 防止误配置导致自己被锁在外面 |
1.4 pam_listfile.so
模块名称:pam_listfile.so
功能:根据指定的文本文件中的用户列表,控制用户是否允许登录或执行某项服务。
应用场景:
实现基于白名单或黑名单的用户访问控制
控制某些服务仅允许特定用户使用(如 SSH、su、ftp 等)
模块说明
pam_listfile.so
是一个用于认证阶段的 PAM 模块。
它通过读取指定的文本文件,判断当前尝试登录的用户是否在该文件中,从而决定是否允许其继续登录。
模块支持以下两种匹配逻辑:
匹配类型 | 含义 |
---|---|
onerr=succeed | 如果文件不存在或无法读取,视为成功 |
onerr=fail | 如果文件不可用,视为失败 |
模块常用于实现自定义的黑白名单机制。
参数说明
auth required pam_listfile.so \file=/etc/security/<filename> \onerr=[succeed|fail] \item=[user|tty|rhost|ruser|group|shell] \sense=[allow|deny]
参数详解:
参数 | 说明 |
---|---|
file | 用户列表文件的完整路径 |
onerr | 当文件不可用时的行为 |
item | 要检查的内容,可选值包括:user, tty, rhost, ruser, group, shell |
sense | 匹配策略:allow 表示“文件中存在则允许”,deny 表示“文件中存在则拒绝” |
案例演示
仅允许特定用户通过 SSH 登录(白名单机制)
1. 创建白名单文件:
sudo vi /etc/security/ssh_users.allow
添加如下内容(每行一个用户名):
admin
devops
jenkins
2. 修改 SSH 的 PAM 配置文件:
sudo vi /etc/pam.d/sshd
在文件开头添加一行:
auth required pam_listfile.so \file=/etc/security/ssh_users.allow \onerr=fail \item=user \sense=allow
3. 测试效果
白名单中的用户可以登录
其他用户被拒绝
禁止特定用户通过 SSH 登录(黑名单机制)
1. 创建黑名单文件:
sudo vi /etc/security/ssh_users.deny
添加如下内容:
guest
testuser
修改 SSH 的 PAM 配置文件:
sudo vi /etc/pam.d/sshd
添加如下行:
auth required pam_listfile.so \file=/etc/security/ssh_users.deny \onerr=fail \item=user \sense=deny
3. 测试效果
黑名单中的用户 无法登录
其他用户 正常登录
限制 FTP 用户仅来自本地网络(IP 白名单)
创建 IP 白名单文件:
sudo vi /etc/security/ftp_ip.allow
添加如下内容:
192.168.1.
10.0.0.
2. 假设你使用的是 vsftpd,编辑其 PAM 配置文件:
sudo vi /etc/pam.d/vsftpd
添加如下行:
auth required pam_listfile.so \file=/etc/security/ftp_ip.allow \onerr=fail \item=rhost \sense=allow
3. 测试效果
来自白名单 IP 的用户 可以登录 FTP
非白名单 IP 被拒绝
限制 su 命令只能由特定组成员执行
创建允许执行
su
的组列表文件:
sudo vi /etc/security/su_group.allow
添加如下内容:
wheel
admin
2. 编辑 /etc/pam.d/su
:
sudo vi /etc/pam.d/su
添加如下行:
auth required pam_listfile.so \file=/etc/security/su_group.allow \onerr=fail \item=group \sense=allow
3. 测试效果
属于
wheel
或admin
组的用户 可以使用su
其他用户被拒绝
注意事项
安全建议 | 说明 |
---|---|
权限设置 | 确保白名单/黑名单文件的权限为 600 ,防止普通用户修改 |
避免将 pam_listfile 放在流程最后 | 如果前面模块已通过认证,它可能不会生效 |
日志监控 | 查看 /var/log/auth.log 或 /var/log/secure 监控被拒绝的登录尝试 |
测试环境验证后再部署生产 | 防止误配置导致自己被锁在外面 |
1.5 pam_time.so
模块名称:pam_time.so
功能:根据时间规则限制用户对服务的访问。
应用场景:
禁止用户在非工作时间登录系统
控制某些服务仅在特定时间段可用(如 SSH、login、FTP 等)
模块说明
pam_time.so
是一个用于认证阶段的 PAM 模块,它通过读取配置文件 /etc/security/time.conf
,根据当前的时间、服务名和用户名来判断是否允许用户进行登录或执行某个服务。
模块支持按 星期几 和 一天中的时间段 进行控制。
规则语法
每行格式如下:
参数说明
字段 | 含义 | 示例 |
---|---|---|
<service> | 服务名(如 sshd、login、ftp) | sshd , ALL |
<tty> | 终端设备(可选,如 tty1, pts/0) | tty1 , pts/* , ALL |
<users> | 用户名或组名(@表示组) | user1 , @admin , ALL |
<times> | 允许访问的时间范围(格式 HHMM-HHMM) | Wk0900-1700 , Al0000-2400 |
时间格式说明
Wk:工作日(周一到周五)
We:周末
Al:全天(所有日子)
Mo/Tu/We/Th/Fr/Sa/Su:具体星期几
HHMM:小时分钟格式,例如
0900
表示上午9点
案例演示
禁止 root 用户在非工作时间登录系统
编辑 time.conf:
sudo vi /etc/security/time.conf
添加如下规则:
login ; * ; root ; Wk0800-1800
表示:root 用户只能在 工作日(周一至周五)早上 8:00 到下午 6:00 登录系统。
2. 在 /etc/pam.d/login
中启用 pam_time.so:
sudo vi /etc/pam.d/login
添加一行:
auth required pam_time.so
3. 测试效果
工作时间 可以登录
非工作时间 被拒绝
限制开发人员只能在工作时间使用 SSH 登录
创建一个开发组并添加用户:
groupadd devops
usermod -aG devops developer1
2. 修改 time.conf:
sudo vi /etc/security/time.conf
添加如下规则:
sshd ; * ; @devops ; Wk0900-1800
3. 在 /etc/pam.d/sshd
中启用模块:
sudo vi /etc/pam.d/sshd
添加:
auth required pam_time.so
4. 测试效果
开发组成员在工作时间 可以 SSH 登录
非工作时间或非开发组成员 被拒绝
允许所有用户全天候访问 FTP 服务
修改 time.conf:
sudo vi /etc/security/time.conf
添加如下规则:
vsftpd ; * ; ALL ; Al0000-2400
2. 在 /etc/pam.d/vsftpd
中启用模块:
sudo vi /etc/pam.d/vsftpd
添加:
auth required pam_time.so
3. 测试效果
所有用户 随时可以使用 FTP
限制普通用户仅在晚上 7 点到 9 点登录
修改 time.conf:
sudo vi /etc/security/time.conf
添加如下规则:
login ; * ; user1 ; Al1900-2100
2. 在 /etc/pam.d/login
中启用模块:
auth required pam_time.so
3. 测试效果
晚上 7 点到 9 点之间 可以登录
其他时间 被拒绝
1.6 pam_tally2.so
模块名称:pam_tally2.so
功能:用于记录用户登录失败次数,并在达到设定阈值后锁定账户。
应用场景:
防止暴力破解攻击
锁定异常尝试登录的账户
自动解锁或手动解锁账户
模块说明
pam_tally2.so
是一个用于认证阶段的 PAM 模块。
它会跟踪用户每次登录失败的情况,并将计数写入 /var/log/faillog
文件中。
当用户连续输入错误密码超过指定次数时,该模块可以阻止进一步的登录尝试(即“锁定”账户),直到满足解锁条件(如超时或手动解锁)。
核心命令与工具
命令 | 功能 |
---|---|
pam_tally2 | 查看、重置、解锁用户的登录失败计数器 |
/var/log/faillog | 存储用户失败登录信息的文件 |
参数说明
auth required pam_tally2.so \file=/var/log/faillog \deny=<number> \unlock_time=<seconds> \even_deny_root \root_unlockable \onerr=succeed
参数详解
参数 | 含义 |
---|---|
deny=N | 设置最大失败次数,超过则锁定账户 |
unlock_time=N | 自动解锁时间(单位为秒),不设置则需手动解锁 |
even_deny_root | 对 root 用户也启用锁定机制 |
root_unlockable | root 可以解锁被锁定账户 |
onerr=succeed | 当模块出错时继续认证流程 |
file=path | 指定 faillog 文件路径,默认是 /var/log/faillog |
案例演示
场景一:限制所有用户最多尝试 5 次登录失败
修改服务的 PAM 配置文件(以 SSH 为例)
sudo vi /etc/pam.d/sshd
添加以下行到 auth
段开头:
auth required pam_tally2.so deny=5 unlock_time=300
2. 测试效果
尝试错误密码 5 次后 登录被拒绝
等待 5 分钟 账户自动解锁
查看当前失败次数
pam_tally2 --user=username
对 root 用户也启用登录失败锁定
修改
/etc/pam.d/sshd
或/etc/pam.d/login
auth required pam_tally2.so deny=3 unlock_time=600 even_deny_root
2. 测试效果
root 用户连续输错密码 3 次 被锁定
等待 10 分钟 自动解锁
手动解锁某个被锁定的用户
user1 5
表示已失败 5 次。
手动重置失败计数器
pam_tally2 --user=user1 --reset
结合其他模块使用(如 pam_access.so)
在 /etc/pam.d/sshd
中配置如下组合:
auth required pam_access.so accessfile=/etc/security/access.conf auth required pam_tally2.so deny=5 unlock_time=300 auth include system-auth
实现:
先检查 IP 白名单(pam_access)
再检查失败次数(pam_tally2)
最后进行标准认证(system-auth)
注意事项
安全建议 | 说明 |
---|---|
避免将 pam_tally2 放在流程最后 | 如果前面模块已通过认证,它可能不会生效 |
定期查看 faillog 日志 | 使用 pam_tally2 --list 或 faillog 命令查看异常行为 |
合理设置 deny 和 unlock_time | 过于敏感可能导致误锁,影响用户体验 |
测试环境验证后再部署生产 | 防止误配置导致自己被锁在外面 |
1.7 pam_limits.so
模块名称:pam_limits.so
功能:用于在用户登录时应用资源限制(如最大进程数、内存使用、打开文件数等)。
应用场景:
限制普通用户的系统资源使用
防止恶意用户或程序占用过多系统资源
控制服务运行时的资源上限
模块说明
pam_limits.so
是一个会话(session)类型的 PAM 模块,它在用户登录或启动服务时加载。
并根据配置文件 /etc/security/limits.conf
和 /etc/security/limits.d/*.conf
设置的规则对用户施加资源限制。
这些限制是通过 Linux 的 ulimit 系统调用来实现的。
配置文件
文件 | 作用 |
---|---|
/etc/security/limits.conf | 主配置文件 |
/etc/security/limits.d/*.conf | 子配置目录,可扩展自定义限制策略 |
语法详解
每行格式如下:
<domain> <type> <item> <value>
参数说明:
字段 | 含义 | 示例 |
---|---|---|
<domain> | 用户名、组名(前缀 @ 表示组)、* (所有用户) | user1 , @admin , * |
<type> | 类型:soft 或 hard | soft , hard |
<item> | 资源类型(见下表) | nofile , nproc , as |
<value> | 限制值(数字或 unlimited ) | 1024 , unlimited |
类型 含义 用户能否修改 soft
软限制 可以临时调整,但不能超过硬限制 hard
硬限制 最高上限,只有 root 才能修改
常用资源项(item)列表:
item 名称 | 含义 | 对应 ulimit 参数 |
---|---|---|
core | 最大 core dump 文件大小(KB) | -c |
data | 最大数据大小(KB) | -d |
fsize | 最大文件大小(KB) | -f |
memlock | 最大锁定内存地址空间(KB) | -l |
nofile | 最大打开文件数 | -n |
rss | 最大驻留集大小(KB) | -m |
stack | 最大堆栈大小(KB) | -s |
cpu | 最大 CPU 时间(分钟) | -t |
nproc | 最大进程数 | -u |
as | 地址空间限制(KB) | -v |
案例演示
限制所有用户最多打开 1024 个文件
编辑
/etc/security/limits.conf
:
sudo vi /etc/security/limits.conf
添加如下内容:
* soft nofile 1024
* hard nofile 2048
2. 在服务中启用 pam_limits.so(如 SSH)
编辑 /etc/pam.d/sshd
:
sudo vi /etc/pam.d/sshd
确保包含以下行:
session required pam_limits.so
3. 测试效果
ulimit -n
输出应为:
1024
限制 devops 组用户最多运行 50 个进程
修改 limits.conf:
sudo vi /etc/security/limits.conf
添加如下内容:
@devops soft nproc 50
@devops hard nproc 100
2. 重启 SSH 服务并测试
sudo systemctl restart sshd
切换到 devops 组用户后执行:
ulimit -u
输出应为:
50
允许 root 用户无限制使用资源
修改 limits.conf:
sudo vi /etc/security/limits.conf
添加如下内容:
root soft nofile unlimited
root hard nofile unlimited
root soft nproc unlimited
root hard nproc unlimited
2. 测试 root 用户资源限制
su - root
ulimit -n
ulimit -u
输出应为:
unlimited
限制某个服务(如 nginx)的最大内存使用
创建专用配置文件:
sudo vi /etc/security/limits.d/nginx.conf
添加内容:
nginx soft as 512000
nginx hard as 1024000
表示 nginx 用户最大地址空间分别为 512MB 和 1GB。
2. 重启 nginx 服务
sudo systemctl restart nginx
注意事项
安全建议 | 说明 |
---|---|
合理设置软硬限制 | 过低可能影响正常使用,过高可能引发资源滥用 |
避免将 pam_limits.so 放在流程最后 | 会话阶段模块通常不影响认证流程 |
区分 soft 与 hard 限制 | soft 可由用户自行调整,hard 只有 root 可修改 |
结合其他模块使用 | 推荐搭配 pam_tally2.so 、pam_access.so 实现更细粒度控制 |
定期检查日志和资源使用情况 | 使用 ulimit -a 、top 、htop 监控资源消耗 |
1.8 Cgroup 资源限制
控制组(Control Groups,简称 Cgroups)是 Linux 内核提供的一种机制,用于限制、记录和隔离进程组使用的物理资源(如 CPU、内存、磁盘 I/O 等)。
Cgroups 是实现容器技术(如 Docker)的关键组件之一。
接下来,将介绍如何使用 Cgroups 实现对 CPU 和内存的限制。
实现 CPU 限制
步骤 1: 挂载 Cgroups 文件系统
如果的系统尚未挂载 cgroup 文件系统,可以通过以下命令挂载:
sudo mount -t cgroup -o cpu,cpuacct cgroup /sys/fs/cgroup/cpu
步骤 2: 创建一个新的 Cgroup
创建一个新的 Cgroup 来管理的进程:
sudo mkdir /sys/fs/cgroup/cpu/mygroup
步骤 3: 设置 CPU 使用限制
绝对限制 (CPU shares)
每个 Cgroup 都有一个 cpu.shares
参数,默认值为 1024。
这个参数定义了该组相对于其他组的 CPU 使用权重。
例如,设置 mygroup
的 CPU 使用权重为 512:
echo 512 | sudo tee /sys/fs/cgroup/cpu/mygroup/cpu.shares
将 cgroup mygroup
的 CPU 权重设置为 512,表示该组的进程在争抢 CPU 时间时,获得的比例是默认值的一半(因为默认权重是 1024)。
Cgroup 名 | cpu.shares 值 | 占比 |
---|---|---|
groupA | 512 | 1/3 |
groupB | 1024 | 2/3 |
如果两个组都在争用 CPU,groupA 得到的 CPU 时间大约是 groupB 的一半。
相对限制 (CPU quota)
还可以通过设置 cpu.cfs_quota_us
和 cpu.cfs_period_us
来精确控制 CPU 使用量。
cpu.cfs_period_us
: 定义一个周期长度,默认为 100ms。cpu.cfs_quota_us
: 在一个周期内允许该组使用的 CPU 时间上限。
例如,限制 mygroup
在每 100ms 内最多使用 50ms 的 CPU 时间:
echo 50000 | sudo tee /sys/fs/cgroup/cpu/mygroup/cpu.cfs_quota_us
echo 100000 | sudo tee /sys/fs/cgroup/cpu/mygroup/cpu.cfs_period_us
步骤 4: 将进程添加到 Cgroup
要将某个进程加入到 mygroup
中,可以使用其 PID:
echo <PID> | sudo tee /sys/fs/cgroup/cpu/mygroup/tasks
实现 Mem 限制
步骤 1: 挂载 Cgroups 文件系统
确保已经挂载了 mem 控制器:
sudo mount -t cgroup -o memory cgroup /sys/fs/cgroup/memory
步骤 2: 创建一个新的 Cgroup
创建一个新的 Cgroup 来管理内存使用:
sudo mkdir /sys/fs/cgroup/memory/mygroup
步骤 3: 设置内存限制
总内存限制
设置 mygroup
可以使用的最大内存为 512MB:
echo 512M | sudo tee /sys/fs/cgroup/memory/mygroup/memory.limit_in_bytes
Swap 限制
如果还想限制 swap 的使用,可以设置 memory.memsw.limit_in_bytes
。
Swap 是 Linux 系统中用于扩展内存的一种机制。
当物理内存(RAM)不足时,Linux 内核会将一部分不常用的内存数据“换出”到磁盘上的 swap 空间,从而释放物理内存给更需要的程序使用。
你可以把它理解为:
物理内存(RAM):速度快但容量有限
Swap 空间:速度慢但容量大,是 RAM 的“后备仓库”
请注意,这需要系统支持 swap accounting,并且在挂载 cgroup 时必须包含
memsw
选项。
echo 768M | sudo tee /sys/fs/cgroup/memory/mygroup/memory.memsw.limit_in_bytes
上述命令设置了总的内存加上 swap 的限制为 768MB。
步骤 4: 将进程添加到 Cgroup
同样地,可以通过 PID 将进程添加到 Cgroup 中:
echo <PID> | sudo tee /sys/fs/cgroup/memory/mygroup/tasks
查看
列出属于该 cgroup 的所有进程 ID (PIDs)
cat /sys/fs/cgroup/cpu/mygroup/tasks