排查 Linux 下 su 认证失败问题

LinuxBeginner
立即练习

介绍

Linux 中的「su」(substitute user,切换用户)命令是一个强大的工具,允许用户临时切换到另一个用户账户(通常是 root 用户)来执行管理任务。然而,su 认证可能会失败,导致无法获取权限并产生潜在的安全风险。本实验将引导你完成排查 Linux 下 su 认证失败的过程,涵盖常见原因、配置设置以及 su 安全使用的最佳实践。

理解 su 命令及基本用法

在本步骤中,你将学习 Linux 中的 su 命令如何允许用户将当前身份切换为另一个用户。这对于执行需要提升权限的管理任务非常有用。

让我们探索 su 命令的基本用法并了解其工作原理。

su 的基本用法

在 LabEx 虚拟机环境中打开终端。你可以使用以下语法运行 su 命令:

su [options] [username]

如果不指定用户名直接运行 su,它默认切换到 root 用户:

su

该命令的目标是 root,但 Ubuntu 通常会锁定 root 密码认证。此处认证失败是预期现象。不要启用 root 密码登录,也不要更改平台账户;下文所有成功登录测试均使用临时实验用户。

让我们创建一个测试用户来进行练习:

sudo adduser testuser

根据提示输入所需信息。仅对这个临时测试账户,使用 DemoUser123! 作为练习密码。绝不要更改 labex 的密码或 sudo 组成员关系。

现在,让我们尝试切换到该用户:

su testuser

出现提示时,输入你为 testuser 设置的密码。认证成功后,你的提示符会发生变化,表明你现在正以 testuser 的身份操作。

要验证是否已成功切换用户,请运行:

whoami

输出应显示:

testuser

要返回到原来的用户,只需输入:

exit

使用带选项的 su

su 命令支持多个选项。最常用的是 -(连字符)选项,它提供了一个完整的登录环境:

su - testuser

这不仅切换了用户身份,还执行了以下操作:

  • 切换到目标用户的主目录
  • 设置目标用户的环境变量
  • 提供一个登录 shell

尝试运行此命令并观察差异:

pwd

输出应显示 testuser 的主目录:

/home/testuser

输入以下命令退出 testuser:

exit

对 su 命令的这些基本了解将有助于我们在接下来的步骤中排查认证失败问题。

常见的 su 认证失败及其原因

在本步骤中,你将创建并检查常见的 su 认证失败场景。了解这些失败原因是解决问题的第一步。

测试认证失败

让我们故意制造一些认证失败,以便更好地理解它们。

首先,尝试使用错误的密码切换到 testuser:

su testuser

输入错误的密码。你将看到类似以下的错误信息:

su: Authentication failure

接下来,尝试切换到一个不存在的用户:

su nonexistentuser

你将看到类似以下的错误信息:

su: user nonexistentuser does not exist

认证失败的常见原因

1. 密码错误

认证失败最常见的原因就是输入了错误的密码。这可能是由于:

  • 拼写错误
  • 开启了 Caps Lock(大写锁定)
  • 忘记了密码

2. 账户限制

某些账户可能被配置为禁止登录或密码已过期:

让我们修改测试用户来演示这一点:

sudo usermod -L testuser

-L 选项会锁定临时 testuser 账户的密码认证。现在尝试:

su testuser

即使输入正确的密码,你也会看到认证失败。

-U 选项会移除此密码锁定。仅使用以下命令解锁这个测试账户:

sudo usermod -U testuser

3. PAM 配置问题

可插拔认证模块(PAM)系统控制着 Linux 中的认证。PAM 配置问题可能导致 su 失败。

让我们检查 su 命令的 PAM 配置:

cat /etc/pam.d/su

该文件包含 su 命令特定的 PAM 配置。查找可能限制访问的行,例如:

auth       required   pam_wheel.so

如果取消注释,该行会将 su 访问权限限制为仅限 wheel 组成员。

4. su 二进制文件的权限问题

su 命令的二进制文件必须具有正确的权限才能正常工作:

ls -l $(which su)

输出应类似于:

-rwsr-xr-x 1 root root 71816 Apr 18  2022 /usr/bin/su

权限中的 s 表示设置了 setuid 位,允许程序以其所有者(root)的权限运行,而不是以运行它的用户身份运行。

5. 检查认证日志

在 LabEx 虚拟机中排查认证失败时,可以使用 lastb 查看失败的登录记录:

sudo lastb | head

该命令读取 /var/log/btmp 并显示最近失败的认证尝试,包括系统记录的失败 su 尝试。

例如,一次失败的 su 尝试可能会显示包含目标用户和终端会话的条目。

了解这些常见的 su 认证失败原因将帮助你在接下来的步骤中更有效地识别和解决问题。

配置 su 命令的访问控制

在本步骤中,你将对一个临时目标账户测试 PAM 组规则。你不会启用 root 密码登录,也不会限制平台访问。

准备临时账户

从原来的 labex Shell 开始。使用 sudo 前先确认当前身份:

whoami

结果必须为 labex。创建第二个调用者和一个独立目标,然后只为这些临时账户设置密码:

sudo adduser --disabled-password --gecos '' testuser2
sudo adduser --disabled-password --gecos '' su-lab-target
printf '%s\n' 'testuser2:DemoOther123!' 'su-lab-target:DemoTarget123!' | sudo chpasswd
sudo groupadd sugroup
sudo usermod -aG sugroup testuser

只有 testuser 是 sugroup 的成员。新的登录 Shell 会加载该组成员关系。两次调用者测试所用的目标密码均为 DemoTarget123!。

应用只针对特定目标的 PAM 规则

PAM 通过 /etc/pam.d/su 控制 su 的认证。初始化已将原文件保存到 /opt/labex/su-demo 下。以下前置配置仅在目标为 su-lab-target 时执行组检查。对于其他所有目标(包括 labex),第一条规则会跳过下一条规则。use_uid 检查调用者的真实身份,group=sugroup 指定允许的组。

sudo python3 - <<'PY'
from pathlib import Path
original = Path('/opt/labex/su-demo/pam-su.original').read_text()
prefix = """## Lab-only rule for su-lab-target

auth [success=1 default=ignore] pam_succeed_if.so quiet user != su-lab-target

auth required pam_wheel.so use_uid group=sugroup

"""
Path('/etc/pam.d/su').write_text(prefix + original)
PY

原始 PAM 规则保留在这段前置配置之后。组成员关系不能代替密码认证。不要将 labex 添加到演示组,也不要编辑任何 SSH、sudo 或平台账户配置。

测试组外调用者

从 labex 切换到 testuser2,使用密码 DemoOther123!:

su - testuser2

在该 Shell 中,使用目标的正确密码 DemoTarget123! 尝试切换到限定的目标账户:

su - su-lab-target

由于 testuser2 不属于 sugroup,此操作必须因认证错误而失败。失败的 su 不会创建新 Shell。退出一次即可返回 labex:

exit
whoami

继续前,确认 whoami 显示 labex。

测试组内调用者

使用步骤 1 中的密码 DemoUser123! 切换到 testuser:

su - testuser
id
su - su-lab-target

输入目标密码 DemoTarget123!。此次切换应成功。确认目标身份:

whoami

输出应为 su-lab-target。这里打开了两个 Shell,所以需要退出两次:先回到 testuser,再回到 labex:

exit
exit
whoami

确认 whoami 显示 labex。绝不要在临时用户的 Shell 中运行恢复命令。

恢复原始策略

从 labex 恢复已保存的配置,并与原始文件比较:

sudo cp -p /opt/labex/su-demo/pam-su.original /etc/pam.d/su
sudo cmp /opt/labex/su-demo/pam-su.original /etc/pam.d/su

比较成功时没有输出。演示组和用户仍保留以供诊断,而 su 已重新使用原始策略。

排查并解决 su 认证失败

在本步骤中,你将使用系统化的流程来排查并解决 su 认证失败问题。

诊断认证失败

当你遇到 su 认证失败时,请遵循以下系统步骤进行诊断:

步骤 1:检查错误信息

错误信息可以提供有关失败性质的重要线索。常见的错误信息包括:

  • su: Authentication failure - 通常表示密码错误。
  • su: user username does not exist - 指定的用户账户不存在。
  • su: permission denied - 访问控制限制阻止了该操作。

步骤 2:验证用户账户

确保目标用户账户存在且未被锁定:

grep testuser /etc/passwd

这应该在密码文件中显示 testuser 的条目,确认账户存在。

检查账户是否被锁定:

sudo getent shadow testuser | cut -d: -f2 | cut -c1

这只显示临时账户密码字段的第一个字符,不会显示密码哈希。开头的 ! 表示密码认证已被锁定。

步骤 3:检查访问控制限制

正如我们在上一步中所学,PAM 配置可能会限制 su 访问。检查是否存在此类限制:

grep -v "^#" /etc/pam.d/su | grep pam_wheel

如果返回包含 pam_wheel.so 的行,则 su 访问权限可能被限制为特定组成员。

步骤 4:检查系统日志

失败的登录记录可以提供有关认证失败的有用信息:

sudo lastb | head

查找与你失败的 su 尝试相关的条目,这可以提供额外的上下文。

解决常见的 su 认证失败

现在,让我们了解常见的 su 认证失败问题及其解决方法:

1. 密码错误

如果你输入了正确的密码但仍然认证失败,可能需要重置密码:

printf '%s\n' 'testuser:DemoUser123!' | sudo chpasswd

这只会将临时 testuser 的密码重置为已知的练习值,不会更改 labex 或 root。

2. 账户锁定

如果账户被锁定,请解锁它:

sudo usermod -U testuser

3. 访问控制限制

如果访问控制限制阻止了 su 访问,你可以:

a. 将用户添加到所需的组:

sudo usermod -aG sugroup testuser2

这会把 testuser2 添加到 sugroup 中。

b. 在本实验中,通过恢复保存的原始文件,仅移除演示策略:

sudo cp -p /opt/labex/su-demo/pam-su.original /etc/pam.d/su

这会恢复完全一致的原始 su 策略,而不是禁用任意认证规则。

4. 文件权限问题

检查 su 二进制文件的权限,不要修改平台二进制文件:

ls -l "$(command -v su)"

预期的 setuid 位显示为所有者执行权限位置上的 s。如果平台二进制文件已损坏,请使用全新的 VM,不要更改其权限。

测试修复结果

应用修复后,测试 su 认证是否正常工作:

su - testuser

出现提示时输入 testuser 的密码。如果成功,你应该以 testuser 身份登录。

运行 whoami 确认当前为 testuser,然后运行一次 exit 返回 labex。不要将 root 密码登录作为成功测试:临时账户登录才是这里的成功用例。

这些排查步骤和修复方法解决了最常见的 su 认证失败问题。通过系统地诊断和解决这些问题,你可以确保 su 命令在你的系统上正常运行。

su 安全使用的最佳实践

在本步骤中,你将回顾安全使用权限的方法,并确认演示没有改变平台访问权限。

单条管理命令优先使用 sudo

Sudo 可以授予并记录单次管理操作的权限,而无需共享 root 密码。在 labex Shell 中列出 root 主目录,不要启动 root 登录 Shell:

sudo ls /root

保留平台现有的 sudo 策略。你可以查看允许执行的命令,而不更改策略:

sudo -l

将认证更改限定在必要范围内

在生产系统中,管理员通过获准的配置工作流管理 root 登录、密码质量和认证策略。本练习不会修改 SSH 设置、labex 密码或 labex 的组成员关系。强密码策略或多因素认证都需要各自的实现;本教程没有配置其中任何一项。

确认临时 su 策略已移除:

sudo cmp /opt/labex/su-demo/pam-su.original /etc/pam.d/su

没有输出表示策略与保存的原始文件一致。

审计失败的认证尝试

使用失败登录数据库调查未成功的尝试:

sudo lastb | head

这会读取 /var/log/btmp,不会显示每一次成功的 su 会话。仅根据系统实际写入的记录进行判断;在生产环境中,应调查重复失败的情况。

使用登录环境并明确返回

连字符选项会启动目标用户的登录环境。使用 testuser 的密码 DemoUser123!:

su - testuser
whoami
exit
whoami

两次身份检查应依次显示 testuser 和 labex。exit 只关闭由 su 创建的 Shell。VM 保留原始的平台登录、sudo 访问权限和 su 策略。

总结

在本实验中,我们探索了 Linux 中的 su 命令,并学习了如何排查常见的认证失败问题。我们涵盖了:

  1. 理解 su 命令的基本用法及其工作原理
  2. 识别 su 认证失败的常见原因,包括密码错误、账户限制和 PAM 配置问题
  3. 配置 su 命令的访问控制以增强安全性
  4. 通过系统诊断排查并解决 su 认证失败
  5. 实施 su 安全使用的最佳实践,包括尽可能使用 sudo、配置强密码策略以及定期审计 su 使用情况

通过应用这些技术和最佳实践,你可以确保 su 命令正常运行,同时维护 Linux 系统的安全性。请记住,适当的认证管理是系统管理和安全的关键方面。