接手一台英文版红帽系统的服务器,第一件事往往不是看业务,而是确认各种密码能不能用。新员工入职、老员工离职、合同交接、密码过期,甚至只是某次手滑把密码改错了,都逃不过"修改红帽系统root密码和普通密码"这一步。这篇文章把我这些年处理红帽系Linux密码问题的完整思路写下来,从忘记root密码的救援重置,到普通用户密码的批量管理,再到改完密码却登不进去的排错链路,一条线讲透。本文面向刚接触Linux服务器维护的初学者,也适合已经带了几年机器、偶尔被密码问题卡住的运维,内容以RHEL 7/8/9为主,CentOS系也适用。
有一点先声明:这篇文章讲的全是你对自己服务器的合法管理操作。无论密码多容易忘、多难改,改动前最好确认这台机器的归属和权限,别在不明来历的主机上试手。
1. 动手前的三件事:确认版本、会话状态与控制台可达性
很多人一上来就重启机器,结果发现救援模式根本进不去,或者进去了不知道改哪一行,白折腾半小时。真正的问题不在于"会不会按几个键",而在于你对这台机器的基本情况心里没数。我建议动手前先做三件很小的事。
1.1 先确认红帽系统版本与内核引导方式
不同版本的红帽系统,救援手段完全不一样。RHEL 7、8、9默认都是GRUB2引导,但引导项的行名、可用的内核参数略有差别;再老一些的RHEL 6用的是GRUB1,界面和操作方式又是另一套。保险起见,先在能登录的状态下执行:
cat /etc/redhat-release uname -a第一行会告诉你系统是RHEL 7.9还是8.10还是9.4之类的具体版本,第二行能看到内核架构和版本。另一个需要确认的是机器是UEFI引导还是传统BIOS引导,虚拟机控制台的启动界面会直接体现:UEFI模式进入GRUB后菜单里常见linuxefi开头的行,BIOS模式常见linux或linux16开头。这一步决定了后面救援操作往哪一行追加参数。
如果在生产环境里不方便执行命令,也可以直接在控制台上看启动日志,但最好还是提前确认,别等到重启了才发现自己连内核行都找不到。
1.2 区分"忘密码"和"改密码"两条路线
这是整篇文章最重要的一次分流:
- 如果当前root密码还记得,或者你手上有能登录的普通用户,直接走常规修改流程,用
passwd、chage这些命令就行,没必要冒险重启系统。 - 如果root密码已经忘了,普通用户也没有sudo权限,那唯一的正规路径就是通过控制台进入救援式环境,绕开登录认证去重置密码。
这两条路线千万别搞混。我见过有人明明还记得密码,却为了展示"技术"重启进救援模式,结果触发了SELinux重标记,白白增加故障风险。能用常规命令解决的问题,就不要上重启的手段。
1.3 控制台访问是救援的前提条件
这是一个经常被忽略的前提:救援流程必须通过物理控制台、虚拟机的VNC/控制台窗口才能完成,靠SSH远程是行不通的。
原因是救援模式本质上是中断正常的系统启动流程,在进入完整用户环境之前就给你一个shell。这个时候网络栈可能根本没起来,SSH服务更不可能在线,你唯一的"眼睛"和"手"就是控制台。所以在动手之前,先确认两点:
- 如果是物理机,你是否能走到机房或者用带外管理卡连上远程控制台。
- 如果是虚拟机,虚拟化管理平台的控制台窗口能否正常打开、能否看到GRUB界面。
很多人在私有云平台上开了虚拟机,控制台经常因为浏览器插件、权限问题打不开,等到需要救援才发现已经晚了。我的习惯是:新交付的虚拟机先测试一次控制台能否正常访问,这比测试别的都实在。
2. root密码忘记后的救援流程:rd.break 实战
说句实话,root密码忘记这种场景,对红帽系统来说几乎是"标准剧本"。只要你能碰到控制台,重置密码就是十分钟内的事。这一节详细拆解我实际使用的流程,顺便解释每一步背后的原理。
2.1 rd.break 的工作原理
rd.break这个参数是systemd时代的产物,它出现在内核引导参数里,作用是让内核在真正切换根文件系统(switch_root)之前先停住。此时根文件系统会被挂载到/sysroot,默认是只读状态,而你会在一个极简的initramfs环境里获得root权限的shell。
可以这么理解:系统启动就像进一栋大楼,正常流程是进门、去房间、开展工作。rd.break相当于在你刷开门禁、还没走进办公室之前,让保安把你拦在门口盘问一遍。盘问的过程中你拿着所有钥匙,只是大楼里的房间还有一个玻璃罩子罩着(根文件系统只读),需要先把这个罩子挪开才能改里面的东西。
这个机制比老式的single单用户模式更可靠。在RHEL 7之后的版本里,单用户模式会受SELinux、systemd配置影响,有时反而更难搞,rd.break的环境更干净、更可控。
2.2 完整操作步骤与逐项说明
下面是针对RHEL 7/8/9的完整流程,每一步我都会说明操作意图。
第一步:重启系统,在GRUB菜单界面按e进入编辑模式
不是按回车直接启动,一定按e。回车是正常启动,按e才会出现可编辑的引导参数界面。
第二步:找到以linux或linuxefi开头的那一行
这一行很长,包含内核路径和一堆参数(比如quiet、rhgb)。把光标移到这一行的行尾,先敲一个空格,再输入:
rd.break注意之前的参数和rd.break之间必须有空格,否则会连成一个不存在的参数,系统会忽略掉它。
第三步:按Ctrl-x或F10启动
系统会开始引导,屏幕会滚动很多内核日志,最后停在一个提示符上,通常是:
switch_root:/#看到这个提示符,说明你已经成功进入救援环境。可能有的人看到一堆英文看不懂就慌,其实只要看到switch_root和/#就能确定成功了。
第四步:重新挂载根文件系统为可写
提示符出现后,第一件事不是chroot,而是把/sysroot重新挂载为可写:
mount -o remount,rw /sysroot如果不做这一步,你会发现后面passwd改密码时报"文件系统只读"错误。因为根文件系统默认以只读方式挂载在/sysroot,不先改成可写,所有的修改都会失败。
第五步:进入真实的根环境
chroot /sysroot此时提示符会变成类似:
[root@主机名 /]#现在你看到的就是这台服务器真实的根文件系统目录结构。这一步的意义是让passwd等命令读取到真正的/etc/shadow,而不是initramfs环境里的临时文件。
第六步:重置root密码
passwd root系统会要求输入两次新密码。英文版系统的提示是New password:和Retype new password:,如果看到passwd: all authentication tokens updated successfully.就说明密码已经写入了。
第七步:创建SELinux重标记文件
这一步很多人会漏掉,但它极其重要:
touch /.autorelabel先不用深究原理,你只要知道:在你刚才这套救援环境里修改密码时,文件的SELinux安全上下文标签很可能被打乱。创建这个标记文件,系统在下次启动时会自动重新为所有文件打上正确的SELinux标签,避免启动后服务异常、登录失败。后面我还会在排错章节里继续展开。
第八步:退出并重启
exit reboot先exit退出chroot环境,回到switch_root:/#,再执行reboot。有些环境下reboot可能不生效,也可以直接按虚拟机控制台的强制重启按钮,但前提是前面的修改已经写入磁盘。
启动过程可能会比平时慢,因为系统在做SELinux重标记,控制台会出现一堆restorecon相关的英文日志,不用紧张,等它跑完自动进入登录界面就行。
2.3 不同版本红帽系统的引导参数差异
我在实际操作中遇到过不同版本的操作差异,整理成表格方便对照:
| 系统版本 | GRUB类型 | 需要编辑的行 | 追加参数 |
|---|---|---|---|
| RHEL 7 | GRUB2 | linux16或linux | rd.break |
| RHEL 8 | GRUB2 | linuxefi(UEFI)或linux(BIOS) | rd.break |
| RHEL 9 | GRUB2 | linuxefi或linux | rd.break |
| RHEL 6(旧) | GRUB1 | kernel | single或init=/bin/bash |
老版本红帽系统也可以用single直接进单用户模式,但在RHEL 7之后,single模式有时会要求输入root密码才能进入,失去了救援意义。所以我现在几乎只用rd.break,无论UEFI还是BIOS都适用。
另一个常见参数是init=/bin/bash,它的效果是跳过systemd直接启动一个bash。这个方式有局限:根文件系统同样只读,需要手动mount -o remount,rw /,而且SELinux的坑一个都不会少。相比之下,rd.break的操作路径更统一,我推荐优先使用。
2.4 忘记 .autorelabel 会踩什么坑
这个坑我踩过不止一次,值得单独写一段。第一次在测试机上做密码重置时,我修改完密码直接reboot,完全没想到SELinux的事。结果系统确实起来了,root密码也确实改成新的了,但SSH怎么都连不上,控制台登录进去一看,一堆SELinux denial相关的报错。
原因说起来也简单:正常系统里/etc/shadow文件带有一个专有的SELinux上下文标签,SSH进程、login进程才能正常读取。在rd.break环境里,文件系统可能处于一个"未正确标记"的状态,用passwd改写文件时,新写入的内容没有继承到正确的标签。重启后SELinux强制模式(Enforcing)发现标签不对,就把读取操作给拦了。
解决方式就是我上面写的touch /.autorelabel。系统下次启动时看到这个文件,会对整个文件系统做一次自动重标记,相当于把所有文件的上下文标签重新刷一遍。代价是启动时间变长,但安全可靠。
有一种情况可以省略这一步:如果你的系统在/etc/selinux/config里已经把SELinux设置成了disabled或permissive,那密码重置后SELinux不会拦截,可以不创建autorelabel。但默认安装的红帽系统几乎都是Enforcing,所以我的建议是:不管三七二十一,先touch再说,最坏只是多等几分钟启动时间。
3. 能登录时改root密码的标准姿势
不是每次都要走到救援模式那一步。大部分时候密码还没忘,只是需要按安全策略定期更换,或者交接时强制改密。这时候用什么命令、带什么参数、怎么配合密码策略,都是有讲究的。
3.1 passwd 命令的基本参数与交互流程
最基础的修改方式:
passwd这条命令会修改当前登录用户的密码。如果你现在是以root身份登录,那改的就是root;如果你以普通用户登录,改的就是这个普通用户。交互过程会先要求输入当前密码,再输入两次新密码。
root用户修改任意用户的密码,则直接指定用户名:
passwd root passwd zhangsanroot修改别人密码时不需要输入该用户的当前密码,这是权限差异带来的行为差别。很多刚入行的朋友在这里疑惑过:为什么给同事重置密码时系统不问我"旧密码"?因为root在本地系统里的权限就是最大,passwd认定"有root身份就够了"。
查看某个用户的密码状态用:
passwd -S root passwd -S zhangsan英文系统会输出类似:
root PS 2025-01-01 0 99999 7 -1 (Password set, SHA512 crypt.)字段含义分别是:用户名、状态、上次修改时间、最小修改间隔、最大修改间隔、提醒天数、宽限天数。状态里最常见的两个值是PS(密码已设置)和LK(锁定)。后面会用到这个命令判断账户是否被锁。
3.2 用 chage 控制密码有效期与过期策略
单纯改密码不够,有安全基线要求的场景一定会涉及密码有效期。chage是专门管这个的命令,查看策略:
chage -l root输出内容里能直接看到最近一次修改密码的日期、密码最小/最大有效天数、过期前提醒天数等。常用的参数有:
| 参数 | 作用 | 示例 |
|---|---|---|
-M | 密码最大有效天数 | chage -M 90 root |
-m | 密码最小修改间隔 | chage -m 7 root |
-W | 过期前提醒天数 | chage -W 15 root |
-d | 将上次修改日期设为指定值 | chage -d 0 zhangsan |
-E | 账户失效日期 | chage -E 2025-12-31 zhangsan |
其中最常用的是-M 90,对应"90天强制改密"的常见制度。还有一招很实用:新员工入职或临时账户开通后,想让对方第一次登录就必须改密码,执行:
chage -d 0 用户名这条命令把上次修改日期归零,系统一看"上次改密时间点不存在/无效",就会强制用户在下次登录时先设置新密码。这在批量开账号、临时权限下放时非常好用。
3.3 root密码的安全强度与 pwquality 配置
有时候你明明执行了passwd,设置的密码还挺长,系统却提示强度不够。这是因为红帽系统默认启用了密码质量检查模块。
核心配置文件在:
/etc/security/pwquality.conf常见配置项和作用:
minlen = 14 # 密码最小长度 dcredit = -1 # 至少包含1位数字 ucredit = -1 # 至少包含1个大写字母 lcredit = -1 # 至少包含1个小写字母 ocredit = -1 # 至少包含1个特殊符号注意dcredit这类项的值是负数时表示"至少包含多少个该类型字符",如果值是正数则表示"最多允许出现多少个该类型字符"。这个理解反了会出大问题。我见过有人把dcredit = -1改成1,以为是"至少要1个数字",实际含义变成了"最多允许1个数字",导致密码检查行为完全反了。
还有一个容易被忽略的行为差异:root修改密码时,即使用户设置的密码强度不够,passwd也只会出现一行BAD PASSWORD警告,然后照常接受。普通用户则不行,强度不够会被直接拒绝。这是红帽有意设计的管理员特权,但如果你的安全制度要求"所有人都必须强密码",就得靠审计脚本去发现这种漏洞。
4. 普通用户密码的修改、锁定与批量管理
普通用户的密码管理比root更细碎,因为用户数量多、状态杂、权限边界不清晰。这一节讲清楚单用户改密、账户锁定、批量处理三个场景。
4.1 单用户改密与权限边界
普通用户改自己的密码:
$ passwd Current password: New password: Retype new password: passwd: all authentication tokens updated successfully.注意普通用户改自己密码必须要先输入当前密码,这是防止别人趁你离开时偷改你密码的一道防线。root替普通用户改密码则不需要旧密码:
# passwd zhangsan权限边界的含义要清楚:普通用户无法重置自己的密码如果忘记,因为第一步就要输入当前密码;普通用户如果连当前密码都不记得,唯一能做的就是找root或走管理流程。所以很多企业里"忘记密码"求助IT的场景,本质上就是让有权限的管理员执行一条passwd。
4.2 临时禁用账户:passwd -l 与 usermod -L
员工离职、账号暂时不用、怀疑密码泄露时,不会直接删用户(因为用户可能还拥有文件,删除用户会导致文件归属变乱),而是先锁定。
passwd -l zhangsan passwd -u zhangsan锁定后查看状态:
passwd -S zhangsan输出里的状态字段会从PS变为LK。原理上,passwd -l是在/etc/shadow的密码字段开头加了一个!,让任何密码都无法匹配成功。解锁就是去掉这个!。
这里必须提一个重要的坑:passwd -l只锁定密码登录,不会影响SSH密钥登录。如果这台机器上配置过免密登录的公钥,即使你锁定了账户,对方依然能用SSH密钥直接进来。所以真正要临时封禁一个账户,我通常组合使用:
usermod -L zhangsan usermod -s /sbin/nologin zhangsan-s /sbin/nologin会把登录shell改成不可交互的nologin,即使SSH密钥想登进来也会在shell启动阶段被拒绝。同时还要检查该用户是否在~/.ssh/authorized_keys里留了密钥,必要时候删除或改名。
4.3 批量改密:chpasswd 与 /etc/shadow 字段解读
批量重置多个用户的密码,一条条passwd显然低效,用chpasswd:
echo "zhangsan:NewPass@2024" | chpasswd也可以提前准备一个文本文件,每行格式用户名:新密码:
chpasswd < users.txt执行后没有输出就是成功,可以用passwd -S抽查几个用户确认。批量生成随机密码可用openssl rand或pwgen:
for i in zhangsan lisi wangwu; do p=$(openssl rand -base64 12) echo "$i:$p" | chpasswd echo "$i -> $p" done这里把URL安全字符过滤一下更稳妥,避免生成带反感字符的密码。
理解批量改密背后的机制,就绕不开/etc/shadow文件。它是一个纯文本文件,只有root能读取和修改,每行对应一个用户。标准格式有9个字段,用冒号分隔:
zhangsan:$6$随机盐$加密结果:19456:0:99999:7:::| 字段 | 含义 |
|---|---|
| 1 | 用户名 |
| 2 | 加密密码($6$开头表示SHA512,$5$是SHA256,$1$是MD5,!前缀表示锁定) |
| 3 | 上次修改密码日期(自1970-01-01起的天数) |
| 4 | 最小修改间隔天数 |
| 5 | 最大修改间隔天数 |
| 6 | 过期前提醒天数 |
| 7 | 过期宽限天数 |
| 8 | 账户失效日期 |
| 9 | 保留字段 |
手动编辑shadow文件很危险。我亲眼见过有人为了重置密码直接用vi改这个文件、误删了一个冒号,结果整个用户无法登录,连root都排查了半天。因为字段数一旦不对,本地认证模块会认为该用户记录损坏。所以我的原则是:能用命令改密码就绝不手编shadow,命令会做格式校验,手动编辑没有兜底。
5. 改完密码却登不进去:排错链路复盘
密码明明改成功了,SSH却进不去,这种情况在运维里太常见了。而且越是紧急时候越容易出,心情一急就容易瞎试,把问题越搞越大。这一节把我会走的排查链路完整写出来。
5.1 SSH登录失败先看 /var/log/secure
发现登不进去,我第一步永远是看日志,而不是重复试密码。英文版系统下,日志是英文,但关键词就那几个,记住它们比查词典有效。
tail -50 /var/log/secure常见的关键词和对应问题:
| 日志内容片段 | 含义 |
|---|---|
Failed password for root from 192.0.2.10 | 密码错误,或SSH只接受密钥认证 |
Connection closed by authenticating user root | 认证失败后连接被关闭 |
pam_unix(sshd:auth): authentication failure | PAM认证失败,注意后面有没有locked字样 |
User root from 192.0.2.10 not allowed | 该用户被SSH配置禁止登录 |
pam_faillock(sshd:auth): user root | 触发账户锁定机制 |
如果日志里只看到Failed password,大概率是你新密码没改对、或者SSH服务端配置的问题。检查/etc/ssh/sshd_config里这几项:
PermitRootLogin yes PasswordAuthentication yes如果PasswordAuthentication no,那么密码对不对根本不重要,SSH压根不接受密码认证,只认密钥。很多刚上手的人在这里卡很久,以为是密码问题,实际是SSH配置把密码登录这条路堵死了。
5.2 pam_faillock 锁定与解锁
有一种情况很隐蔽:你在另外一个终端上反复输错了几次密码,触发了系统的账户锁定策略。之后即使你通过救援模式把密码改对了,锁定的标记依然存在,登录还是会被拦。
RHEL 7之后用的是pam_faillock模块,查看和重置的命令:
faillock --user root faillock --user root --reset查看输出里Failed的次数和最近失败时间,如果有记录就说明账户确实被锁过。重置后立刻再试登录,往往就通了。这个细节在"救援模式改完密码仍无法登录"的场景里尤其常见,我遇到过好几次,因为救援模式不会帮你清理失败计数,这个坑必须靠手动重置。
5.3 SELinux context 异常引发的登录问题
前面在救援流程里提过.autorelabel,这里再说透一点。如果你在rd.break环境里改了密码,但没有创建/.autorelabel,系统启动后可能会出现这样的现象:控制台能登录,SSH连不上,或者SSH登进来之后敲任何跟认证相关的命令都异常。
处理方式有两种:
第一种,如果系统还能进控制台,以root登录后执行:
restorecon -Rv /etc /var这条命令会递归地恢复/etc和/var下文件的SELinux上下文标签。/etc/shadow在/etc下,自然会被修复。不过要注意,restorecon按默认规则恢复,如果你之前手动给某些文件设过特殊标签,可能被一并重置,所以生产环境里更推荐autorelabel整盘重刷。
第二种,如果你已经登不进任何会话,只能再次进入rd.break环境,重新执行:
mount -o remount,rw /sysroot chroot /sysroot touch /.autorelabel exit reboot启动时系统会自动重标签。这个过程会持续几分钟,控制台会滚动大量restorecon日志,别中途断电或强制重启,否则标签刷到一半,系统可能起不来。
5.4 密码文件权限被改坏的恢复
还有一类问题不常见,但一旦发生就非常致命:/etc/passwd、/etc/shadow、/etc/group这几个文件的权限被错误修改。比如有人图方便执行了chmod 777 /etc/shadow,或者操作失误导致文件owner不对。表现是:系统提示密码正确,但认证模块拒绝读取shadow文件,怎么都登录不了。
正常的权限应该是:
ls -l /etc/passwd /etc/shadow /etc/group /etc/gshadow| 文件 | 正确权限 | owner |
|---|---|---|
/etc/passwd | 644 | root:root |
/etc/shadow | 600 | root:root |
/etc/group | 644 | root:root |
/etc/gshadow | 600 | root:root |
修复方法也很直接,在救援环境或root shell里执行:
chown root:root /etc/passwd /etc/shadow /etc/group /etc/gshadow chmod 644 /etc/passwd /etc/group chmod 600 /etc/shadow /etc/gshadow顺手检查一下/etc/passwd里每个用户对应的shell路径是否存在,因为如果/sbin/nologin或/bin/bash路径写错,SSH登录时也会报错。
一旦动了这些系统文件,我建议改完后立刻开一个新SSH会话测试,确认能登进去了再继续别的操作。千万别在只有一个SSH连接的情况下一边改文件一边刷新网页,改挂了可就真的要跑机房了。
6. 个人实操心得与建议
最后写点不吐不快的心得。这些东西不是手册里能学到的,是我这些年处理密码问题攒下来的习惯。
第一,永远先在这台机器上做一次演练再上生产环境。可以在虚拟机里打一个快照,改密码前先记录原始状态,演练完直接恢复快照。把rd.break流程、SELinux重标记流程走一遍,等真出了问题,你已经知道每个英文提示背后意味着什么,不会慌。
第二,改完密码不要急着退出当前会话。尤其是SSH远程操作时,先用su -或者重新开一个SSH窗口,确认新密码能正常登录,再关掉旧会话。我吃过一次亏:在唯一一个SSH会话里改了root密码,改完顺手把会话关掉,结果新密码有一个字符记错,直接把自己锁在外面,最后只能去控制台救援。这个教训太深刻了。
第三,密码更新记录要留痕。公司里改密不是改完就完事,什么时候改的、为什么改的、改了哪些用户的密码,这些信息在审计时都是救命的数据。红帽系统里可以通过日志回溯修改记录,比如/var/log/secure中会有password changed相关的记录,我自己还会额外维护一个变更记录表,写上操作人和时间。
第四,定期巡检所有账户的密码状态。用一条命令就能过一遍:
awk -F: '{print $1, $2}' /etc/shadow | grep -v '!'或者用chage -l逐个用户查看。重点找出长久未改密的账户、即将过期的账户、以及密码字段异常(比如空密码)的账户。空密码字段意味着该用户不需要密码就能登录,这是非常严重的风险点。
密码管理这件事,看起来只是几条命令,背后却涉及系统认证、PAM模块、SELinux、SSH配置多个层面。把这套流程走顺了,以后再遇到"登录不了"的问题,你的排查思路就会清晰很多:先分心存不存在密码问题,再看认证日志,然后逐层排除SSH、PAM、SELinux的因素。我在实际工作中发现,把这些基本功打扎实,比会一堆花哨的自动化脚本有用得多。