十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

Linux密码修改无效排查:认证源、缓存与脚本全解析

Linux密码修改无效排查:认证源、缓存与脚本全解析 前几天处理了一个挺典型的账户问题现象一句话就能说清某台设备里有个叫ctxsys的系统账户运维按规范用passwd改了密码命令也是正常执行完的但结果完全没影响——用新密码登录被拒旧密码却能进跑在设备上的服务也一切照旧好像根本没改过一样。老实说这种“密码修改没有影响”的排查工单在运维里不算少见而且十有八九不是系统出故障而是改密码的人根本没弄明白这个账户的认证链路。这篇文章就把完整排查过程拆开讲一讲用ctxsys作为例子把“改完没反应”背后常见的几种原因、验证手段和最终修复流程都过一遍适合日常管设备、管 Linux 服务器、经常帮人重置密码的运维和系统管理员参考。1. 先看清现象别急着再去敲一遍 passwd1.1 “没有影响”至少有三张脸同样是“密码修改没有影响”不同环境里表现完全不一样对应的排查方向也天差地别。我处理过的类似工单里最常见的是这三种现象A新密码登不进去旧密码依然有效。这是最典型的一种给人的第一反应就是“密码没改成”于是很多人会再执行一次passwd ctxsys结果还是老样子。这种情况通常是密码确实写到了某个地方但登录认证时读取的并不是那个地方。现象B密码当时改成功了重启设备后又恢复成默认密码。这种更隐蔽白天改完测试正常第二天一开机全白搭。多半是设备有初始化脚本、定时任务或者出厂重置逻辑在背后捣乱。现象C系统登录的密码改了但某个服务、某个控制台完全不受影响甚至开放访问。很多新手会把这个当成故障其实这未必是坏事因为很多服务压根不认 Linux 系统密码改系统账户当然不会影响它。我建议所有接到类似问题的人都先花两分钟想清楚你观察到的“没影响”到底是哪一种有没有在另一个终端验证过验证时用的是 SSH、本地控制台还是某个应用界面这三个验证渠道对应的认证链路可能完全不同。把现象描述清楚了后面再排查会省很多时间。1.2 passwd 执行成功不代表密码真的改了很多人被“命令执行成功”这个假象误导了。passwd命令的本质是调用 PAM 的pam_chauthtok模块去修改认证后端里的密码它返回 0 只能说明这个修改动作在整个 PAM 配置链路上没有出错并不代表登录 SSH、控制台或某个服务时也会用同一个认证后端。打个比方passwd相当于你去物业前台改了业主名册上的电话但如果门禁系统实际读取的是监控室另一本登记表那改完当然“没影响”。系统里可能同时存在本地账户文件/etc/passwd、/etc/shadow、LDAP 目录账户、数据库用户、应用自带账号这些多套认证源它们之间并非天然同步。所以第一件事情不是急着再改一遍而是要确认ctxsys这个账户到底存在于哪套认证体系里当前登录入口认的又是哪套。2. 从认证链路入手找到系统里真正认账的那个“ctxsys”2.1 本地账户核查shadow 里的密码字段才是关键先做最基础的本地账户核查在 root 或 sudo 权限下依次执行这几条命令id ctxsys getent passwd ctxsys getent shadow ctxsys passwd -S ctxsys chage -l ctxsys重点看一下getent shadow ctxsys的输出它对应/etc/shadow文件里该账户的记录结构是ctxsys:$6$xxxxxxxxxxxxxxxx:19001:0:99999:7:::第一个字段是用户名第二个字段是加密后的密码哈希。如果哈希以$6$开头是 SHA512 算法以$y$开头是 yescrypt以!或*开头则说明账户处于锁定或无密码状态。passwd -S ctxsys返回的状态里P表示有可用密码L表示锁定NP表示没有密码。这里有一个很关键的排查点如果passwd -S ctxsys显示P/etc/shadow里的哈希也确实发生了变化说明本地文件层面的修改是成功的。这就要立刻转向下一个问题——登录时读的到底是不是/etc/shadow这个文件很多人在这里就卡住了反复用passwd改却不去看认证入口实际用的数据源。2.2 同名账户的坑本地用户与 LDAP、域账号冲突我遇到过一个非常经典的场景设备加入了企业的 LDAP 或域环境管理员在本地用useradd建了一个ctxsys但实际上域里也有一个同名账户。Linux 系统的用户解析顺序由/etc/nsswitch.conf决定如果里面配的是passwd: files ldap sss那么这个顺序意味着先查本地files再查 LDAP最后查 SSSD。可别以为先查本地就一定用本地用户还要看 UID 归属。用getent passwd ctxsys时如果返回的 UID 和/etc/passwd里那个本地账户的 UID 不一致说明getent命中的其实是目录服务里的账户。这种情况下你用passwd ctxsys改的是本地/etc/shadow但登录时系统按 nsswitch 顺序可能先匹配到了 LDAP/域账户密码校验走的是目录服务器本地密码当然一点影响都没有。解决办法不是傻傻地反复改本地密码而是要明确你到底想让哪个“ctxsys”生效如果要走目录服务就去改 LDAP/域里的密码如果必须用本地账户可以考虑调整 nsswitch 顺序、把本地账户改名或者直接把目录服务里的同名账户停用。2.3 别忽视缓存nscd、sssd 也会让密码“假装没改”还有一种容易被漏掉的元凶是认证缓存。很多系统跑着 nscd 或 sssd它们会把用户和密码哈希信息缓存到内存里减少后端认证压力。当你在后端改了密码缓存没过期的话新密码校验就可能失败旧密码反而还能继续用——现象上跟“没修改”完全一样。排查时先看服务是否在运行systemctl status nscd systemctl status sssd确认存在缓存后清理并重启服务nscd -i passwd systemctl restart nscd sss_cache -E systemctl restart sssd清理完缓存立刻重新测试登录。我处理过的工单里至少有两次是重启完 nscd 问题直接消失根本不用改密码。这个步骤虽然简单但很多人最开始都会忽略。3. 应用侧认证系统密码改了服务凭什么没影响3.1 哪些服务根本不用系统密码如果ctxsys只是某个平台或应用的内部管理账户那就可能出现一种情况系统层密码怎么改应用都不为所动。原因是很多服务根本不走 PAM 认证它们使用自己的用户库账号和密码都存在应用自己的数据库或配置文件里。比如数据库实例的管理账号密码是存在 MySQL、PostgreSQL 内部数据字典里的带 Web 管理界面的平台登录密码存在应用表里登录时通过应用代码校验SSH 如果配置了公钥登录密码根本不在认证链路里改系统密码自然不影响密钥登录有些服务用 token、证书或 Kerberos 票据做认证系统密码只是其中一个不常用的登录方式。遇到这种场景正确的做法是去改应用侧的口令而不是盯着/etc/shadow不放。比如 MySQL 用户可以用ALTER USER ctxsys% IDENTIFIED BY new_password;企业应用的 Web 控制台一般也有专门的“修改密码”入口或者有配套的管理命令。关键是要搞清楚“你手里的这个ctxsys到底是哪个认证域里的账户”。3.2 应用内置用户库怎么定位和修改快速判断应用用的是不是系统账户有一个很直接的指标登录一次应用然后去看系统认证日志。以最常用的 Linux 系统为例认证日志一般在/var/log/secure或/var/log/auth.log用tail -f盯着日志再登录一次应用看有没有生成 PAM 相关的记录。如果没有生成任何 PAM 记录说明应用认证根本没碰系统账户体系直接去查应用的配置文件和数据表。很多带控制台的企业软件会在安装目录下提供conf、config等文件夹里面可能有数据库连接串或用户配置。常见做法是找到应用使用的管理系统比如一些平台自带sysadmin或useradmin命令先--help看支持哪些参数通常都有重置密码的子命令。如果实在找不到最笨但有效的方法是去应用数据库里翻用户表找到ctxsys对应的记录然后按应用支持的密码哈希算法更新字段。注意直接改数据库表前一定要备份因为有些应用除了密码字段还会有 salt、状态位、多因子绑定这些关联数据漏改一个就会导致新密码依然无法登录。3.3 用认证日志追踪真实的认证来源搞定这一类问题最高效的做法是看日志不要靠猜。以 SSH 登录为例打开两个终端一个终端执行tail -f /var/log/secure另一个终端正常执行ssh ctxsys127.0.0.1然后观察日志里打印的内容。如果出现Accepted password for ctxsys说明这次的密码校验确实走了系统 PAM如果出现的是Accepted publickey for ctxsys那说明登录走的是公钥认证你在/etc/shadow里改密码当然不会影响这种登录。如果日志里根本没有ctxsys这个用户名的记录那就说明请求压根没有到系统认证层问题出在应用层。这里可以顺带查一下 SSH 服务的实际配置sshd -T | grep -i passwordauthentication\|usepam如果PasswordAuthentication no那任何系统密码都不会通过 SSH 生效如果UsePAM no修改/etc/shadow同样可能不起作用。认证日志是这类排查中最重要的证据来源学会看它能少走非常多弯路。4. 幕后黑手有没有程序在悄悄把密码改回去4.1 定时任务与开机脚本排查如果密码改完当时有效过一段时间或者重启后失效那基本可以确定有某个程序在定期重置或者覆盖密码。排查思路是先看定时任务crontab -l ls -la /etc/cron.d/ /etc/cron.daily/ /etc/cron.weekly/ /etc/cron.hourly/ systemctl list-timers再看开机启动脚本重点检查这些路径cat /etc/rc.local cat /etc/rc.d/rc.local systemctl list-unit-files | grep -E rc-local|init ls -la /etc/systemd/system/multi-user.target.wants/如果怀疑和ctxsys有关可以直接在几个常见目录里搜索关键字grep -rn ctxsys /etc /opt /usr/local/sbin /usr/local/bin /root 2/dev/null搜索chpasswd、passwd、shadow这些关键字也很有效。注意搜索结果可能很多先看有没有脚本把ctxsys的密码哈希硬编码在代码里。很多厂商设备的适配脚本会在开机时把内置账户重置为出厂默认密码修改/etc/shadow之后重启被覆盖就是这个原因。4.2 出厂镜像与云初始化脚本比定时任务更隐蔽的是初始化类组件。现在不少设备镜像和云主机都内置了 cloud-init、厂商 firstboot 脚本等东西它们会在实例首次启动时写用户、写密码、写 SSH Key。如果/var/log/cloud-init.log里有创建用户或设置密码的记录那就要注意这类初始化配置往往以模板形式存在系统分区单纯改/etc/shadow是持久化不了的。解决办法不是跟它赛跑而是找到初始化模板或配置源头。常见路径包括/etc/cloud/cloud.cfg /etc/cloud/cloud.cfg.d/ /opt/vendor/scripts/ /usr/local/etc/以 cloud-init 为例如果配置里写死了chpasswd的expire: false和密码列表那就把模板里ctxsys的密码哈希换成你自己的chpasswd -c SHA512生成的哈希再执行cloud-init clean后重启测试。如果找不到配置文件源头也可以反过来做一个持久化服务在每个开机阶段把密码强制覆盖为指定值保证“你说了算”但这属于兜底方案优先还是找到根因。4.3 安全策略拦截SELinux、PAM 的隐性干扰还有一种很容易被忽略的情况安全模块把写/etc/shadow的动作拦了但命令本身没有明显报错。SELinux 处于 enforcing 模式时某些进程如果对/etc/shadow没有写权限passwd可能返回成功但 shadow 文件实际没变。查看方法ausearch -m avc -ts recent如果有大量 AVC 拒绝记录先恢复文件的安全上下文再试restorecon -v /etc/shadowPAM 层也可能出问题。/etc/pam.d/passwd加载的pam_unix.so如果配置了异常参数或者密码策略模块pam_pwquality强制了复杂度而新密码不达标某些版本的实现甚至会把修改请求静默吞掉。排查时可以临时用chpasswd测试因为它走的是另一条调用路径如果chpasswd能成功写入而passwd不行那问题基本就锁定在 PAM 配置上。5. 实操一次完整的密码修复流程5.1 动手前先做快照再确定双通道保障修改账户密码虽然不算高风险操作但也别太随意。尤其是生产设备我建议按下面顺序准备先确认自己有 root 或 sudo 权限并且能同时打开两个终端会话。原因很简单万一改完密码发现自己被卡在外面第二个会话还能救场。记录当前状态作为变更前后对照passwd -S ctxsys getent passwd ctxsys awk -F: /^ctxsys:/{print $1, $2} /etc/shadow chage -l ctxsys注意不要直接打印完整的密码哈希可以把字段截断只看算法前缀和长度避免敏感信息落到终端日志里。备份/etc/shadowcp -a /etc/shadow /etc/shadow.bak.$(date %F)5.2 使用 chpasswd 强制写入并验证处理这种“改了没影响”的问题我一般不用交互式passwd而是用chpasswd它更可控并且能指定加密算法echo ctxsys:YourNewPass_2025 | chpasswd -c SHA512如果系统默认是 yescrypt也可以显式指定echo ctxsys:YourNewPass_2025 | chpasswd -c yescrypt执行后立刻验证passwd -S ctxsys awk -F: /^ctxsys:/{print $1, substr($2,1,10)} /etc/shadow这里用substr只取哈希前 10 个字符能确认哈希变了又不用暴露完整内容。接着在第二个终端测试登录ssh -o PreferredAuthenticationspassword ctxsys127.0.0.1如果工作正常而且确认本地账户就是业务使用的认证源可以顺手把密码设为首次登录强制修改chage -d 0 ctxsys这样即使攻击者拿到了初始密码也会被要求立即修改。5.3 把修改变成“永久生效”光在/etc/shadow里改还不够如果前面排查发现了初始化脚本、定时任务或应用内置用户库必须做三件事改源头把厂商脚本、cloud-init、应用配置里的默认哈希替换成新的哈希确保重启后不被覆盖。验证重启执行一次重启或至少执行相关初始化脚本确认ctxsys的密码哈希保持新值。固化记录把这个账户的认证源、修改时间、新密码哈希算法写入运维变更记录方便以后追溯。对于确实无法找到重置源头的情况可以创建一个 systemd oneshot 服务在每次启动时把密码设置好例如/etc/systemd/system/ensure-ctxsys-password.service[Unit] DescriptionSet ctxsys password on boot Aftermulti-user.target [Service] Typeoneshot ExecStart/usr/sbin/chpasswd RemainAfterExityes [Install] WantedBymulti-user.target但注意把明文密码放在 unit 文件里不是好习惯生产环境建议先通过安全的方式把密码下发到受保护的配置文件再通过脚本去读取。这个方案只作为兜底。5.4 几条操作禁忌踩过坑的人都知道不要直接vim /etc/shadow手改哈希。密码哈希字段看似简单但每个字段的含义、过期时间、锁定标记一旦写错账户可能直接无法登录排查成本远高于正常修改。不要用弱哈希算法。老系统里有些教程会教openssl passwd -1生成 MD5 密码可现代 Linux 默认已经是 SHA512 或 yescrypt不要为了兼容旧工具降低安全级别。不要改完密码不做登录验证。哪怕只是修改一个内部账户也应该在另一个终端实测所有“改完没影响”的工单最后都能靠一次干净的验证提前发现问题。不要忽略日志。无论最后有没有解决都要看一眼认证日志确认登录入口当时到底做了什么样的校验这比反复执行passwd有价值得多。6. 常见问题速查与经验总结6.1 故障速查表我把前面提到的问题整理成一张表格方便现场排查时按图索骥现象常见原因排查命令/方法解决方向passwd提示成功登录仍用旧密码认证源不是本地 shadow或走了缓存getent passwd ctxsys、查看/etc/nsswitch.conf改目录服务密码或清 nscd/sssd 缓存新密码进不去旧密码有效本地认证缓存未刷新nscd -i passwd; sss_cache -E重启缓存服务后重测重启后密码恢复默认开机脚本/初始化组件重置账户搜ctxsys、查/etc/rc.local、cloud-init修改初始化模板或加 systemd 兜底系统密码改了应用登录不受影响应用有自己的用户库查认证日志、应用配置改应用侧密码如ALTER USERSSH 用新密码登不进配置为公钥认证sshd -T、看/var/log/secure改用密钥管理或显式开启密码认证sudo 不提示密码配置了 NOPASSWDsudo -l这不是密码错误属于授权策略6.2 值得写进运维手册的检查项处理完这次ctxsys的问题之后我建议把下面几条固化成团队运维手册能省掉未来大量重复排查新建或接入一个系统账户前先明确它的认证源是本地、LDAP 还是应用自带写入账户台账。所有密码修改任务必须包含“修改前快照、修改后验证、重启后复核”三个动作。设备上线时把厂商默认账户、初始化脚本、定时任务一并梳理一遍避免“出厂账户复活”这种问题。对sudo、SSH 公钥、服务白名单这类“非密码认证”方式要有独立的授权管理流程不能和系统密码混为一谈。6.3 我踩过几次坑之后的个人体会说实话这类“密码修改没有影响”的问题大多数情况下不是系统 bug而是账户体系比我们以为的更复杂。我自己就栽过几次跟头第一次是没看 nsswitch 顺序在本地改了三天密码最后发现登录走的全是 LDAP第二次是没查开机脚本每次改完都被告知第二天又变回去最后发现是厂商初始化脚本里硬编码了默认哈希第三次是在没开第二个终端的情况下改密码结果把自己关在外面只能去机房物理连接。所以我现在的习惯很简单接到这类问题先看日志和数据源再动手改密码改完后一定用独立会话验证。这套流程虽然朴素但确实稳。最后再分享一个小技巧如果只是想让某个本地账户“彻底禁用密码登录”把/etc/shadow里密码字段前面加一个!就行这比直接删掉密码字段更安全也更容易恢复。但如果是想真正重置密码并生效记住一条主线——先确认认证源再修改最后验证三步缺一不可。
返回列表