Linux 基础体系 · 第 7/85 篇。示例面向现代主流 Linux 发行版;发行版差异、权限和生产风险会明确说明。
Linux 用户认证与提权:账号、PAM、sudo、密码策略和审计
Linux 上一次“登录并执行命令”的结果,不是由某个单独文件决定的。它通常同时经过以下几层:
- 账号解析:用户名对应哪个 UID、主组和附加组?
- 认证:用户能否证明自己拥有某种凭据?
- 账号检查:账号是否过期、被锁定或禁止登录?
- 会话建立:环境变量、资源限制、挂载和审计上下文如何初始化?
- 授权与提权:当前进程能否执行目标操作,是否允许切换到更高权限?
- 审计:谁在什么时间、通过什么入口、以什么身份执行了什么操作?
“认证成功”只说明凭据校验通过;它不等于“可以执行任意命令”。sudo 也不是认证机制本身,而是一个根据授权规则执行特定命令的受控提权工具。
一、先区分身份、认证、授权和审计
1. Linux 进程真正使用的是 UID/GID
Linux 内核判断权限时主要看进程凭据,而不是用户名字符串。一个进程通常具有:
- 真实 UID(RUID):通常表示启动该进程的用户;
- 有效 UID(EUID):普通文件权限检查主要使用它;
- 保存的 set-user-ID(Saved UID):支持某些程序在运行期间恢复权限;
- 真实 GID、有效 GID 和附加组列表;
- capabilities:把传统 root 的部分能力拆分出来的权限集合。
一个简化的授权模型是:
其中:
- 是进程;
- 是目标对象或操作;
DAC是传统 Unix 自主访问控制;LSM可能是 SELinux、AppArmor 等强制访问控制;capability是内核能力检查;- 其他策略可能包括 seccomp、设备策略、容器边界等。
因此,拥有 UID 0 通常意味着权限极高,但现代系统上仍可能受到 LSM、容器、受限 capability 集合或内核配置的限制。反过来,非 root 进程也可能因为某个 capability 或 setuid 程序获得特殊能力。
例如:
id alice
getent passwd alice
getent group developers
可能得到:
uid=1001(alice) gid=1001(alice) groups=1001(alice),10(wheel),1002(developers)
1001:x:1001:1001:Alice:/home/alice:/bin/bash
developers:x:1002:alice
id 展示的是当前系统解析出的身份;getent 通过 NSS(Name Service Switch)查询账号数据库。账号来源不一定是本地文件,也可能是 LDAP、SSSD、NIS 或其他 NSS 模块。因此,直接读取 /etc/passwd 不能保证看到系统实际使用的全部账号。
认证、授权和审计的区别
- 认证(authentication):证明“你是谁”或“你掌握什么凭据”。
- 授权(authorization):决定“你可以做什么”。
- 会话管理(session management):登录成功后如何建立和清理运行环境。
- 审计(auditing):记录身份变化、命令执行和安全事件,以便追踪与取证。
下面这个反例很重要:
用户用正确密码通过了 PAM 的认证模块,但如果
/etc/sudoers没有允许该用户执行目标命令,sudo仍然会拒绝操作。
同样,用户已经被授权运行 /usr/bin/systemctl restart nginx,也不代表他能运行任意 shell;授权规则的对象是具体命令及其参数匹配关系,而不是“登录成功”这一状态。
二、账号数据库:/etc/passwd、/etc/shadow 与 NSS
/etc/passwd 保存身份映射,不保存密码
典型行如下:
alice:x:1001:1001:Alice Example:/home/alice:/bin/bash
七个字段依次是:
用户名:密码占位符:UID:GID:GECOS:家目录:登录 Shell
现代系统通常把第二字段设为 x,实际密码哈希保存在只有 root 或特定组可读的 /etc/shadow 中。
/etc/passwd 的权限通常类似:
-rw-r--r-- root root /etc/passwd
它需要对普通进程可读,因为大量程序需要将 UID 映射为用户名。真正需要保护的是密码验证材料和其他敏感账号属性。
/etc/shadow 的密码字段
典型格式:
alice:$y$j9T$...:19800:0:99999:7:::
各字段含义包括:
- 用户名;
- 密码哈希,特殊值还可能表示锁定或禁止密码登录;
- 上次修改密码的日期,单位通常是自 Unix epoch 起的天数;
- 修改密码后最少等待多少天;
- 密码最多有效多少天;
- 到期前多少天开始警告;
- 密码过期后多少天禁用账号;
- 账号失效日期;
- 保留字段。
密码哈希不是“可解密的密码”。验证过程通常是:
系统从 shadow 中取出算法和 salt,使用用户输入的密码重新计算,再以抗侧信道方式比较结果。现代发行版通常使用 yescrypt、bcrypt、SHA-512 等实现,具体算法由发行版和 PAM 配置决定。不要假设所有系统都使用同一种前缀或算法。
查看密码状态:
sudo passwd -S alice
sudo chage -l alice
可能看到:
alice P 03/01/2025 0 99999 7 -1
其中 P 通常表示存在可用密码;不同发行版输出格式略有差异。chage -l 比直接解析 shadow 更适合运维检查,因为它会把日期转换成人可读格式。
锁定密码不等于禁用整个账号
以下操作语义不同:
sudo passwd -l alice
sudo usermod --shell /usr/sbin/nologin alice
sudo usermod --expiredate 1 alice
passwd -l通常是在密码哈希前增加锁定标记,阻止该密码用于认证;nologin使通过该登录 shell 建立交互式会话失败,但不一定阻止所有服务使用该账号;- 过期账号会触发账号状态检查失败;
- SSH 密钥认证可能不依赖密码,因此“锁密码”不一定阻止密钥登录;
- 运行中的进程不会因为账号被锁定而自动终止。
禁用离职账号时,必须检查 SSH authorized keys、cron、systemd user service、API token、云平台凭据以及正在运行的进程,不能只执行 passwd -l。
三、从用户名到认证后会话:NSS 与 PAM 的数据流
Linux 登录程序通常不会自己实现全部认证逻辑,而是通过两个不同抽象层:
- NSS:把用户名、组名等名称解析为系统身份数据;
- PAM:把认证、账号检查、密码修改和会话管理交给可组合模块。
典型流程如下:
flowchart TD
A[login/sshd/sudo] --> B[NSS: 用户与组解析]
B --> C[PAM service 配置]
C --> D[auth: 验证凭据]
D --> E[account: 检查账号状态]
E --> F[password: 修改密码时使用]
E --> G[session: 打开会话]
G --> H[设置 UID/GID、环境、限制]
H --> I[启动 shell 或目标命令]
I --> J[session close 与日志]
图中的四类 PAM 管理组职责不同:
auth:验证凭据
例如密码、智能卡、OTP、指纹或 Kerberos 凭据。它回答:
当前请求者是否能通过指定的认证方式?
account:检查账号状态和访问条件
例如:
- 密码是否过期;
- 账号是否过期;
- 当前时间是否允许登录;
- 用户是否属于允许的组;
- 远程目录服务是否允许访问。
认证成功后,账号检查仍可能失败。
password:修改认证秘密
例如执行:
passwd
时,PAM 可以检查旧密码、密码复杂度、历史密码以及新密码哈希写入方式。
session:建立和关闭会话
常见工作包括:
- 写入登录记录;
- 设置
ulimit; - 创建运行时目录;
- 设置环境;
- 应用 SELinux 或其他安全上下文;
- 建立或销毁 systemd/logind 会话。
并不是所有程序都会完整使用四类模块。sshd、login、图形显示管理器、sudo 和 su 各自使用不同的 PAM service 名称,例如:
/etc/pam.d/sshd
/etc/pam.d/sudo
/etc/pam.d/login
/etc/pam.d/su
程序通常读取 /etc/pam.d/<service>,再按顺序执行模块。模块控制标志常见为:
required:失败会导致最终失败,但通常继续执行后续模块;requisite:失败后立即终止;sufficient:本模块成功且没有更早的 required 失败时,可提前成功;optional:通常不单独决定结果;- 方括号语法:允许更细粒度地映射返回码。
这里有一个故障边界:PAM 配置是“可执行安全策略”,不是普通配置文本。错误地修改 system-auth、common-auth 或发行版生成的聚合配置,可能同时破坏 SSH、sudo、图形登录和本地控制台。修改前应保留 root 控制台或现有 root 会话,并使用发行版提供的配置工具;不要在唯一远程会话中直接试验。
查看有效配置:
grep -vE '^\s*(#|$)' /etc/pam.d/sudo
grep -vE '^\s*(#|$)' /etc/pam.d/sshd
日志位置取决于发行版,常见查询方式:
sudo journalctl -b | grep -Ei 'pam|sshd|sudo|authentication'
sudo tail -f /var/log/auth.log # Debian/Ubuntu 常见
sudo tail -f /var/log/secure # RHEL/Fedora 常见
不要假定某个日志文件必然存在;systemd journal、rsyslog 配置和发行版默认值都会影响结果。
四、密码认证和密码策略:检查发生在哪里
密码策略至少包含三类不同问题:
- 密码内容质量:长度、字符空间、是否出现在泄漏字典中;
- 密码生命周期:最短修改间隔、最大有效期、过期宽限期;
- 在线猜测防护:失败次数、延迟、锁定或 MFA。
pam_pwquality 与密码内容
许多发行版使用 pam_pwquality,配置可能位于:
/etc/security/pwquality.conf
示例:
minlen = 14
retry = 3
dictcheck = 1
这些参数只影响通过该 PAM 路径修改密码的行为,不能自动约束:
- LDAP 服务端密码策略;
- 云平台控制台;
- 应用自己的账号数据库;
- 已存在的密码;
- SSH 公钥或硬件密钥认证。
“强制定期改密码”也不是无条件提高安全性。频繁轮换可能促使用户使用可预测的后缀;对人类可记忆密码,更重要的通常是足够长度、阻止已泄漏密码、MFA 和登录限速。是否设置最大有效期要结合合规要求和身份系统能力,而不是机械套用单一数值。
pam_faillock 与失败锁定
现代发行版常见 pam_faillock,但配置文件、调用位置和默认行为存在差异。它可能记录连续失败次数并临时锁定账号。例如查看帮助:
man pam_faillock
不要直接复制其他发行版的 PAM 行。应先确认当前系统是否使用该模块,以及失败计数存储目录和 root 用户处理方式。
失败锁定的主要风险是拒绝服务:攻击者可以故意对合法用户名发送错误密码,使账号被锁。生产策略通常需要在“抵御在线猜测”和“避免轻易锁死账号”之间取舍,并配合 IP、设备、MFA、速率限制和告警。
排障时,不能只看“密码正确”。应按顺序检查:
id alice
sudo passwd -S alice
sudo chage -l alice
sudo journalctl -u ssh -u sshd -b
sudo faillock --user alice # 仅在系统安装并启用该工具时使用
faillock 命令是否存在、参数是否一致取决于发行版和 PAM 版本。若确认误锁定,清除失败计数前要验证请求来源,避免把正在进行的暴力攻击隐藏掉。
五、sudo:基于规则的受控提权
sudo 的核心语义
执行:
sudo systemctl restart nginx
可抽象为:
- 当前用户运行
sudo; sudo解析当前用户、主机、目标用户和命令;- 读取 sudoers 规则;
- 必要时通过 PAM 认证当前用户;
- 检查是否允许该命令;
- 创建目标执行环境;
- 以目标用户身份执行命令;
- 记录授权和执行事件;
- 根据 timestamp 机制决定后续是否再次询问密码。
默认目标用户通常是 root,但可以用 -u 指定其他用户:
sudo -u deploy /usr/local/bin/reload-app
必须区分:
sudo command
sudo -i
sudo -s
sudo command:以目标身份执行一个命令;sudo -i:模拟目标用户的登录 shell,加载其登录环境;sudo -s:启动 shell,但环境处理方式与-i不同。
sudo -s 不等于安全沙箱。用户一旦获准运行可构造任意命令的解释器,就可能获得完整目标用户权限。
sudoers 的匹配模型
编辑规则应使用:
sudo visudo
visudo 会在保存前检查语法,避免直接编辑造成所有 sudo 规则失效。
一个受限示例:
Cmnd_Alias NGINX_RELOAD = /usr/bin/systemctl reload nginx
%webops ALL=(root) NGINX_RELOAD
Defaults:%webops use_pty
Defaults:%webops log_output
含义是:
%webops:组webops的成员;- 第一个
ALL:允许来自任意主机; (root):以 root 身份执行;NGINX_RELOAD:只匹配指定命令;use_pty:使用伪终端,降低某些交互风险;log_output:记录 I/O,但还需要确认日志存储与轮转配置。
验证规则:
sudo -l -U alice
sudo -u alice sudo -n /usr/bin/systemctl reload nginx
echo $?
-n 表示禁止交互式询问密码。若未缓存凭据或命令需要认证,它应失败而不是卡住等待输入。测试前提是你拥有 root 权限或已获授权,不要在生产服务上用“执行一次看看”的方式验证。
参数匹配的危险边界
以下规则风险很高:
alice ALL=(root) NOPASSWD: /usr/bin/vim
alice ALL=(root) NOPASSWD: /bin/bash
alice ALL=(root) NOPASSWD: /usr/bin/systemctl
原因不是这些程序本身“危险”,而是它们可以:
- 启动 shell;
- 读取或写入任意文件;
- 加载插件;
- 执行外部命令;
- 修改服务定义;
- 间接控制 root 运行的进程。
即使限制为某个脚本,也要检查脚本是否:
- 使用绝对路径调用工具;
- 清理或固定环境变量;
- 不读取用户可写配置;
- 不把用户参数拼接进 shell;
- 不通过相对路径加载模块;
- 不允许
--config、--editor、--pager等改变执行流的参数。
例如,允许:
alice ALL=(root) /usr/local/sbin/rotate-app-logs
只有在该脚本及其依赖链都由 root 拥有、不可被 alice 或其组写入时才有意义:
namei -l /usr/local/sbin/rotate-app-logs
stat -c '%A %U:%G %n' /usr/local/sbin/rotate-app-logs
NOPASSWD 只取消 sudo 自身的密码确认,不会绕过文件权限、SELinux 或目标命令的其他检查;但它会让盗用的会话更容易立即提权,因此应只用于明确的自动化场景。
sudo 环境和 timestamp
sudo 默认会清理部分环境变量,并可能通过 secure_path 固定 PATH。查看有效配置:
sudo -V
sudo -l
不要依赖用户传入的 PATH、LD_PRELOAD、PYTHONPATH、PERL5OPT 等变量。动态链接器通常会对 setuid 程序忽略部分环境变量,但不能把这种行为当成通用安全边界;不同执行方式、解释器和程序实现可能产生不同结果。
sudo 的认证缓存(timestamp)意味着用户在一段时间内重复执行 sudo 可能不再输入密码:
sudo -k
sudo -v
sudo -n id
sudo -k:使当前用户的缓存凭据失效;sudo -v:刷新或建立认证缓存,不执行命令;sudo -n id:测试无交互执行。
timestamp 不是永久登录令牌,重启、TTY、配置和 sudo 版本都会影响其行为。高风险操作可以使用:
sudo -k
sudo -v
sudo systemctl restart nginx
但这仍不能替代 MFA、短时凭据和良好的会话管理。
六、su、setuid 和 capabilities:提权不是只有 sudo
su 与 sudo 的区别
su 的核心动作是切换到另一个用户,常见用法:
su - alice
su -c '/usr/bin/id' alice
su - 会更接近目标用户的登录环境;不带 - 则保留更多当前环境。系统可能通过 /etc/pam.d/su 和 pam_wheel 限制哪些用户可以切换到 root。
sudo 则是“当前用户请求执行某条命令”,规则可以按用户、主机、目标用户和命令细分,并通常留下更明确的审计记录。生产环境不应把“所有运维人员知道 root 密码”作为主要授权模型。
setuid 的数据流
一个 owner 为 root 且设置 setuid 位的可执行文件,执行时可能产生:
执行前: RUID=1001, EUID=1001
execve(setuid-root-program)
执行后: RUID=1001, EUID=0
内核据此允许程序以 EUID 0 访问资源。程序必须自行验证调用者、参数和环境;一旦存在路径、参数、内存或配置漏洞,就可能变成任意 root 代码执行。
查找 setuid 文件:
sudo find / -xdev -type f -perm -4000 -ls 2>/dev/null
-xdev 限制在当前文件系统,避免跨入其他挂载点;这不是完整资产清单,容器、网络文件系统和 capability 文件仍需单独检查。
capabilities
Linux capabilities 将部分 root 能力拆开,例如:
CAP_NET_BIND_SERVICE:绑定低端口;CAP_NET_ADMIN:部分网络管理操作;CAP_SYS_ADMIN:范围极其广,常被称为“杂项超级能力”,不应轻视。
查看文件和进程能力:
getcap -r /usr/bin /usr/sbin 2>/dev/null
grep '^Cap' /proc/$$/status
文件 capability 可能让一个非 root 二进制执行敏感操作;因此审计提权面不能只查 setuid。CAP_SYS_ADMIN、CAP_SYS_PTRACE、CAP_DAC_OVERRIDE 等能力尤其需要结合实际服务边界评估。
七、SSH 登录与本地认证的关系
OpenSSH 服务端通常由 sshd 接收连接,并按照 sshd_config 允许的认证方法进行协商。常见方式包括:
- 公钥认证;
- 密码认证;
- keyboard-interactive,常被 PAM 用于 OTP 或其他交互式认证;
- GSSAPI/Kerberos;
- 基于证书的公钥认证。
检查实际生效配置:
sudo sshd -T
sudo sshd -T -C user=alice,addr=203.0.113.10,host=server.example
配置文件中常见:
PubkeyAuthentication yes
PasswordAuthentication no
KbdInteractiveAuthentication yes
UsePAM yes
PermitRootLogin no
这些选项的实际支持情况受 OpenSSH 版本和发行版补丁影响。修改后先检查语法:
sudo sshd -t
成功通常没有输出;有错误会显示文件和行号。确认新连接能够使用后,再重载服务:
sudo systemctl reload sshd # 某些 Debian 系统服务名为 ssh
PasswordAuthentication no 只关闭 SSH 的 password 方法,不等于关闭所有基于 PAM 的认证;keyboard-interactive 仍可能触发 PAM。另一方面,锁定本地密码也不一定阻止 SSH 公钥登录。
公钥登录常见文件是:
~/.ssh/authorized_keys
其权限和所有权应严格检查:
chmod 700 ~/.ssh
chmod 600 ~/.ssh/authorized_keys
chown -R alice:alice /home/alice/.ssh
如果启用了 StrictModes,家目录、.ssh 目录或 authorized_keys 可被不可信用户写入,sshd 可能拒绝使用它。审计 SSH 登录时,结合以下信息:
last -a
sudo journalctl -u sshd --since today
sudo ausearch -m USER_LOGIN,USER_AUTH -ts today
日志字段可能包含远端地址、认证方法和结果,但不能把日志中的用户名直接视为已完成授权;还要结合会话建立和后续 sudo 记录。
八、审计:记录“谁做了什么”,而不是只记录“登录成功”
sudo 日志
常见查询:
sudo journalctl _COMM=sudo --since today
sudo grep -i sudo /var/log/auth.log
可能记录:
alice : TTY=pts/2 ; PWD=/home/alice ; USER=root ; COMMAND=/usr/bin/systemctl reload nginx
这能回答“sudo 试图以谁执行什么命令”,但不一定记录命令产生的全部输出。若启用 I/O logging,需要配置安全的集中存储、访问控制和轮转。I/O 日志可能包含密码、令牌或业务数据,不能因为它是“审计数据”就无限期保存。
Linux Audit
auditd 可以在内核审计层记录登录、身份变化、执行和策略事件。示例查询:
sudo ausearch -m USER_LOGIN -ts today
sudo ausearch -m EXECVE -x /usr/bin/sudo -ts today
sudo aureport -au
不同发行版的规则加载方式不同,常见目录包括:
/etc/audit/rules.d/
规则应以发行版推荐方式加载,而不是直接覆盖运行中的规则。审计规则过于宽泛会造成高事件量、磁盘增长和性能压力;过于狭窄则无法还原攻击链。生产审计至少应覆盖:
- 身份认证成功与失败;
- sudo 授权和命令执行;
- UID/EUID 变化;
- 关键账号数据库修改;
- SSH 配置和 authorized_keys 修改;
- 关键服务、systemd unit 和计划任务变化;
- 审计服务自身被停止或规则被修改。
审计记录的完整性还取决于日志主机权限。如果攻击者取得 root,通常也可能篡改本地日志。因此高价值环境需要远程转发、集中存储、时间同步、访问隔离和告警规则;本地日志适合实时排障,但不能单独作为不可抵赖证据。
一次提权事件的关联方法
假设发现某服务配置被修改,应按时间线关联:
SSH 登录
-> PAM 认证与 session_open
-> sudo 授权
-> 目标命令 execve
-> 文件修改
-> sudo session_close / audit 事件
实际调查时使用:
sudo journalctl --since '2025-03-08 10:00' --until '2025-03-08 10:30'
sudo ausearch -ts 10:00:00 -te 10:30:00 -m USER_LOGIN,USER_AUTH,EXECVE,PATH
last -Fai
时间同步非常关键。没有可靠的 NTP/chrony,同一事件在 SSH、sudo、audit 和应用日志中的时间可能无法正确排序。
九、常见失败表现与诊断路径
1. “密码正确,但 SSH 仍然拒绝”
依次检查:
getent passwd alice
sudo passwd -S alice
sudo chage -l alice
sudo sshd -T | grep -Ei 'passwordauthentication|kbdinteractiveauthentication|usepam|allowusers|denyusers'
sudo journalctl -u sshd -b
可能原因包括:
- 账号不存在于实际 NSS 源;
- 账号过期或 shell 为
nologin; AllowUsers、AllowGroups、DenyUsers规则拒绝;PasswordAuthentication被关闭;- PAM account 模块拒绝;
- 失败锁定;
- 家目录或 authorized_keys 权限问题(公钥认证时);
- SELinux 或文件系统策略阻止访问。
不要通过关闭 SELinux、放宽目录权限来“验证是否是权限问题”;应先查看对应审计拒绝记录。
2. “sudo 说用户不在 sudoers”
执行:
sudo -l -U alice
getent group sudo
getent group wheel
Debian/Ubuntu 常见管理组是 sudo,RHEL/Fedora 常见是 wheel,但实际环境可能被定制。用户刚加入组后,已有登录会话中的附加组列表通常不会自动更新,需要重新登录;不能简单认为 id 的旧输出代表系统配置未生效。
3. “sudo 允许了脚本,但脚本仍然能被利用”
检查完整依赖链:
sudo namei -l /usr/local/sbin/rotate-app-logs
sudo find /usr/local/sbin -maxdepth 1 -type f -writable -ls
重点审查:
- 脚本解释器是否可被替换;
- 工作目录是否可写;
- 配置文件是否可写;
- 外部命令是否使用绝对路径;
- 参数是否经过严格解析;
- 是否调用编辑器、分页器或 shell;
- 运行用户是否能修改脚本使用的插件、模块或 socket。
sudoers 只约束入口命令;如果入口命令能间接执行任意代码,形式上的命令限制就失去意义。
4. “锁了账号,但用户仍能访问”
检查所有身份入口:
sudo passwd -S alice
sudo find /home/alice/.ssh -type f -maxdepth 2 -ls 2>/dev/null
ps -u alice -f
sudo crontab -u alice -l
sudo systemctl --user -M alice@ list-units 2>/dev/null
还要检查服务账号使用的 API token、云凭据、容器内账号和共享密钥。账号锁定只影响特定认证路径,不会撤销已经签发的凭据或杀死现有进程。
十、生产环境中的配置、验证与恢复
变更前保留回退路径
修改 SSH、PAM、sudoers 前:
- 保留一个已验证可用的 root 控制台或独立管理会话;
- 备份目标配置并记录校验值;
- 使用语法检查工具;
- 先建立新会话验证,再关闭旧会话;
- 准备恢复命令或带外控制台。
例如 sudoers:
sudo cp -a /etc/sudoers /root/sudoers.$(date +%F-%H%M%S)
sudo visudo -c
SSH:
sudo cp -a /etc/ssh/sshd_config /root/sshd_config.$(date +%F-%H%M%S)
sudo sshd -t
PAM 没有一个能保证所有发行版配置都正确的通用“检查命令”。恢复 PAM 的可靠方式通常是使用带外控制台、单用户/救援模式或发行版安装介质,恢复已知正确的配置,并检查相关包提供的默认文件。
授权验证必须测试正面和负面路径
假设希望 webops 只能重载 Nginx,应测试:
sudo -u alice sudo -n /usr/bin/systemctl reload nginx
sudo -u alice sudo -n /usr/bin/systemctl restart nginx
sudo -u alice sudo -n /usr/bin/systemctl reload sshd
预期是第一条按策略成功,后两条失败。若第一条失败,检查:
- 命令路径是否与 sudoers 完全一致;
- 用户是否已重新登录取得新组;
- sudoers 是否有更早或更宽泛的冲突规则;
- systemd 本身是否允许该操作;
- 目标服务是否存在及是否运行。
验证“失败路径”很重要。只测试允许命令,无法发现意外的通配符、别名展开或组继承。
发行版差异不能靠猜
以下内容经常不同:
- 管理组名称:
sudo或wheel; - SSH 服务名:
ssh或sshd; - 认证日志:
/var/log/auth.log、/var/log/secure或仅 journal; - PAM 聚合文件:
common-*、system-auth、password-auth; - 失败锁定模块和默认目录;
- 密码哈希默认算法;
- SELinux、AppArmor 及其默认启用状态。
因此应以以下命令确认实际状态,而不是根据发行版名称推断:
cat /etc/os-release
systemctl status ssh sshd 2>/dev/null
sudo sshd -T
sudo -V
十一、一个完整的安全判断框架
对于“用户 Alice 能否以 root 重载 Nginx”这个问题,不能只问“她有没有 sudo 权限”。完整条件可写成:
逐步代入:
getent passwd alice找到 UID 和 shell;- SSH 或 sudo 通过相应 PAM service 完成认证;
pam_unix、pam_faillock、账号过期模块等返回允许;- sudoers 精确匹配
/usr/bin/systemctl reload nginx; - sudo 固定 PATH、处理环境并建立目标身份;
- systemd、SELinux 和内核权限允许 systemctl 与服务管理;
- sudo、PAM、audit 和 journal 产生可关联记录。
任何一步失败,最终结果都可能是“拒绝”;但错误表现和日志位置不同。理解这条链路,才能把“密码问题”“PAM 问题”“sudo 规则问题”和“内核权限问题”分开诊断,而不是反复修改同一个配置文件。
Linux 用户认证与提权的安全边界,最终不在某一个开关,而在于:身份来源可验证、认证路径可解释、授权规则足够窄、提权程序依赖链可信、日志能够关联并且不只保存在本机。
系列导航与关联阅读
- 系列入口:Linux 完整学习路线:从内核与文件系统到网络、性能和生产运维
- 上一篇:Linux 权限完整指南:UID/GID、mode、umask、ACL 与 capabilities
- 下一篇:Linux 主机安全加固:最小化、SELinux/AppArmor、审计与漏洞治理
- 延伸:OpenSSH 完整指南:密钥、Agent、跳板、隧道和服务端加固
官方资料
本文依据 Linux 内核、systemd 与主流发行版官方文档重新梳理;正文与实验由 WR BLOG 编写。

评论
0 条讨论