公司动态

Linux用户密码永不过期设置:从原理到实战,解决服务账户认证中断问题

📅 2026/8/5 5:52:48
Linux用户密码永不过期设置:从原理到实战,解决服务账户认证中断问题
1. 项目概述从一次运维“小事故”说起那天下午我正忙着处理一个线上服务的性能调优突然收到监控告警提示一台核心业务服务器的某个应用服务连接异常。登录服务器一看日志里赫然写着“Authentication failure”认证失败。心里咯噔一下第一反应是密码泄露或者被暴力破解了赶紧用我的管理员账号SSH上去一切正常。仔细排查发现出问题的只是一个普通的业务运行账号并非root。灵光一闪我立刻想到了一个平时容易被忽略的“小”设置——用户密码过期策略。果不其然用chage -l命令一查这个账号的密码已经超过了90天系统强制要求更改。就是这个看似不起眼的默认安全策略差点引发了一次计划外的服务中断。在Linux世界里尤其是企业生产环境或遵循严格安全基线如等保的系统中为新创建的用户设置一个默认的密码过期时间比如90天是再常见不过的操作。这源于一个古老但有效的安全理念定期更换密码可以降低因密码长期不变而被破解或泄露的风险。然而这个“为你好”的策略在实际运维中却可能带来不少麻烦。比如用于自动化脚本、持续集成/持续部署CI/CD流水线、数据库连接或后台服务的“非交互式”账户它们的密码一旦过期就会导致脚本执行失败、服务无法启动、数据库连接中断等一系列连锁反应而且这类问题往往隐蔽且难以第一时间定位。所以我们今天要深入探讨的就是如何理解和处理Linux用户的密码过期策略。核心目标很明确将一个新用户或现有用户默认的90天密码过期策略修改为永不过期同时确保操作的安全与合规。这绝不仅仅是执行一条命令那么简单背后涉及到对Linux身份认证机制的理解、对安全策略的权衡以及在不同场景下的最佳实践。无论你是刚接触Linux的新手还是需要管理大批量服务器的运维工程师掌握这套方法都能让你在“安全”与“便利”之间找到更优雅的平衡点。2. 密码过期策略的底层原理与核心命令解析在动手修改之前我们必须先搞清楚Linux系统是如何管理用户密码生命周期的。这不仅仅是记住一两条命令更是理解其运作机制这样才能在遇到复杂问题时心中有数。2.1/etc/shadow文件密码信息的保险库Linux用户的密码信息确切说是密码的哈希值及其相关属性并不存储在大家熟悉的/etc/passwd文件中而是存放在/etc/shadow这个更安全的文件里。只有root用户才有权限读取它。我们可以用sudo cat /etc/shadow命令查看某一行的内容格式如下username:$6$salt$hashed_password:last_changed:min:max:warn:inactive:expire:对我们来说最关键的是第5个字段即max字段它表示密码有效的最长天数。这正是控制密码多久后过期的核心参数。max90表示密码在更改后90天失效。max99999这是一个约定俗成表示“永不过期”的值99999天约等于273年可视为永久。max0或max-1根据不同的Linux发行版和PAM可插拔认证模块配置也可能表示密码永不过期或立即过期但为了最大兼容性通常使用99999。其他相关字段也值得了解last_changed上次密码更改时间从1970年1月1日至今的天数。min两次密码更改之间的最小间隔天数防止用户频繁改回原密码。warn密码过期前多少天开始警告用户。inactive密码过期后账户被完全禁用前的宽限天数。expire账户被禁用的绝对日期自1970年1月1日后的天数。注意直接编辑/etc/shadow文件是极其危险的操作格式错误或误删一个冒号都可能导致用户无法登录。强烈建议使用专门的命令工具来修改。2.2chage命令管理密码时效的瑞士军刀chagechange age命令是专门用来修改用户密码和账户过期信息的官方工具它提供了友好且安全的交互式与非交互式操作方式。常用参数详解chage -l username列出指定用户的所有密码和账户过期信息。这是你的首要诊断工具。# 示例输出 Last password change : Mar 15, 2024 Password expires : Jun 13, 2024 # 90天后 Password inactive : never Account expires : never Minimum number of days between password change : 0 Maximum number of days between password change : 90 # 关键参数 Number of days of warning before password expires : 7chage -M days username设置密码保持有效的最大天数-M即--maxdays。这是实现“永不过期”的核心命令。sudo chage -M 99999 username将用户username的密码设置为永不过期。chage -m days username设置密码更改的最小间隔天数-m即--mindays。如果设为0表示用户可以随时更改密码。chage -W days username设置在密码过期前多少天开始警告用户-W即--warndays。chage -I days username设置密码过期后账户被锁定前的非活动宽限天数-I即--inactive。如果设为-1则禁用此功能。chage -E date username设置账户过期的绝对日期-E即--expiredate。日期格式为 YYYY-MM-DD。设置为-1表示账户永不过期。chage -d days username设置上次密码更改时间-d即--lastday。设置为0-d 0有一个非常实用的技巧它会强制使用户在下次登录时立即更改密码并且将“上次更改时间”重置为当前日期。这常用于管理员为用户初始化密码后要求用户首次登录自行修改。交互式模式直接运行sudo chage username系统会提示你输入各个字段的值适合一次设置多个参数。2.3usermod命令的补充作用usermod命令主要用于修改用户账户的基本属性但它也提供了一个参数来设置密码过期时间usermod -f days username其中-f参数后的days表示密码过期后到账户被禁用之间的非活动天数对应/etc/shadow的inactive字段。注意它不能直接设置密码有效的最大天数-M。要设置永不过期依然需要配合chage -M 99999使用。usermod -f -1 username可以将非活动天数设置为永不过期即密码过期后账户也不会被禁用。实操心得对于单纯的密码过期策略管理chage命令更专业、更直观。usermod通常在创建用户或修改用户主要属性如家目录、登录shell、用户组时连带设置非活动期。我个人的习惯是修改过期策略首选chage清晰明了。3. 分步实操将用户密码策略修改为永不过期了解了原理和工具后我们进入实战环节。假设我们需要处理一个名为deploy的服务账户将其密码策略从90天过期改为永不过期。3.1 第一步诊断当前状态在修改任何配置之前查看当前状态是黄金法则。这能帮你确认问题也为之后可能的回滚提供依据。sudo chage -l deploy记录下输出特别是Password expires和Maximum number of days between password change这两个字段的值。3.2 第二步执行修改命令使用chage命令的-M参数进行修改。设置一个极大的数字来实现“永不过期”。sudo chage -M 99999 deploy这条命令的作用是将用户deploy的密码最大有效天数修改为99999天。为什么是99999这是历史沿袭和广泛兼容的惯例。在早期系统中/etc/shadow的字段是数值型-1可能被解释为特殊值如立即过期而一个极大的正数如99999能明确表达“永久”的意图且被所有主流Linux发行版和PAM模块所支持。3.3 第三步验证修改结果执行修改命令后必须立即验证是否生效。sudo chage -l deploy检查输出。现在Password expires字段应该显示为never并且Maximum number of days between password change字段应该从90变成了99999。# 期望的修改后输出示例 Last password change : Mar 15, 2024 Password expires : never # 已变为永不过期 Password inactive : never Account expires : never Minimum number of days between password change : 0 Maximum number of days between password change : 99999 # 已修改 Number of days of warning before password expires : 73.4 第四步可选的其他相关设置为了让这个服务账户更“安静”我们通常还会调整其他相关参数取消密码过期前的警告对于服务账户警告信息没有意义可以关闭。sudo chage -W 0 deploy允许随时更改密码将最小修改间隔设为0如果之前不是的话。sudo chage -m 0 deploy确保账户本身永不过期sudo chage -E -1 deploy清除密码过期后的非活动锁定sudo chage -I -1 deploy # 或者使用 usermod sudo usermod -f -1 deploy完成以上步骤后deploy这个账户的密码就真正实现了“永不过期”并且不会因为密码策略产生任何干扰性的警告或锁定。重要提示这些操作需要root权限或通过sudo执行。在生产环境中操作前务必在测试环境验证并确保你有修改目标用户信息的权限。4. 不同场景下的策略与实践考量“永不过期”并非放之四海而皆准的真理。我们必须根据账户的实际用途来决定是否以及如何应用这一策略。4.1 场景一服务账户/系统账户强烈建议永不过期典型账户nginx,mysql,redis,deploy,jenkins等。特点由系统或应用自动使用无人交互登录。密码或密钥通常写在配置文件中。策略必须设置为永不过期。否则密码一旦过期相关服务会在某个深夜默默崩溃且日志报错可能不直观排查成本极高。操作按照第3章的方法为这些账户设置chage -M 99999。进阶安全实践对于这类账户更好的安全实践是禁止其交互式登录。可以通过将其登录shell设置为/sbin/nologin或/bin/false来实现sudo usermod -s /sbin/nologin deploy同时使用SSH密钥对或应用级别的令牌如Kubernetes的ServiceAccount、数据库的本地socket认证来代替密码认证是更安全的选择。4.2 场景二普通个人用户账户通常不建议永不过期典型账户员工的工作账号、开发者的个人账号。特点人工交互式登录使用者可以接收到期警告并自行修改。策略遵循公司安全策略。如果安全合规要求定期改密则应保留过期策略如90天。强制修改密码是许多安全基线如等保2.0的要求。操作保持默认或按策略设置。可以使用chage -M 90 -W 7 username来设置90天过期并在到期前7天开始警告。例外情况对于一些极少数需要长期访问、且修改密码会带来巨大协调成本的特定个人账户例如负责关键备份脚本的维护员账户且该脚本遍布多台服务器在经过严格审批和风险评估后可酌情设置为永不过期但必须记录在案并配合其他监控手段。4.3 场景三批量用户管理自动化脚本当需要为数十上百个服务账户修改策略时手动操作是不可接受的。这里给出一个简单的批量操作脚本示例#!/bin/bash # 文件名disable_password_expiry.sh # 描述批量将指定列表中的用户密码设置为永不过期 USER_LISTdeploy nginx mysql redis jenkins app_user1 app_user2 for USER in $USER_LIST; do # 检查用户是否存在 if id $USER /dev/null; then echo Processing user: $USER sudo chage -M 99999 -W 0 -m 0 $USER # 验证 echo Verification for $USER: sudo chage -l $USER | grep -E \Maximum|expires\ echo --- else echo User $USER does not exist, skipping. fi done脚本说明将需要修改的用户名放入USER_LIST变量。循环遍历每个用户使用id命令检查其是否存在。对存在的用户执行chage命令一次性设置最大天数、警告天数和最小间隔。输出验证信息便于核对。注意事项在生产环境运行任何批量脚本前务必先在测试环境充分验证。可以先在脚本中加入echo预览将要执行的命令确认无误后再移除echo正式执行。4.4 场景四新用户创建的默认策略修改如果你希望所有新创建的用户默认就是密码永不过期而不是每次创建后再手动修改则需要修改系统的默认配置文件。找到默认配置在大多数Linux发行版如RHEL/CentOS, Fedora, Ubuntu中创建用户时的默认值由/etc/default/useradd文件定义。修改关键参数sudo vim /etc/default/useradd找到INACTIVE和EXPIRE行但注意这个文件通常不直接定义密码的最大有效期-M。密码的默认过期策略更多地与/etc/login.defs文件相关。修改/etc/login.defssudo vim /etc/login.defs查找以下两个关键参数PASS_MAX_DAYS 90# 将90改为99999PASS_WARN_AGE 7# 密码过期前的警告天数可按需修改修改此文件仅对之后新创建的用户生效对已存在的用户无效。重要提醒修改系统默认配置影响深远需谨慎评估。通常更推荐的做法是在自动化创建用户的脚本或Ansible/Puppet等配置管理工具中显式地为服务账户设置chage -M 99999这样策略更清晰也更易于审计。5. 常见问题排查与安全加固建议即使掌握了基本操作在实际环境中仍会遇到各种“坑”。下面是一些典型问题及其解决方法。5.1 问题排查速查表问题现象可能原因排查命令与解决方案用户登录时被强制要求立即改密且无法跳过。1. 密码已过期。2. 管理员使用了chage -d 0 username强制下次登录改密。3. 首次登录且密码为初始默认密码。sudo chage -l username查看状态。解决若为服务账户应改为永不过期 (chage -M 99999)。若为个人账户用户需按要求设置新密码。服务如MySQL、Cron Job突然失败日志显示认证错误。服务运行所使用的系统账户密码已过期。sudo chage -l 服务账户名。解决立即将该服务账户密码设为永不过期并重启服务。使用chage -M 99999后chage -l显示仍有过期日期。1. 命令未以root权限执行修改失败。2. 可能修改了错误的用户。3. 极少数情况PAM配置覆盖了本地设置。1. 确认使用sudo。2. 再次执行并验证。3. 检查/etc/shadow文件该用户的第五字段是否已变为99999。账户被锁定无法登录提示“Your account has expired”。账户的绝对过期日期 (-E) 已到或密码过期后非活动期 (-I) 已过。sudo chage -l username查看Account expires和Password inactive。解决sudo chage -E -1 username解除账户过期sudo chage -I -1 username解除非活动锁定。批量修改后如何快速检查哪些用户密码即将过期需要巡检。编写脚本解析/etc/shadow或使用chage -l输出。例如for u in $(cut -d: -f1 /etc/passwd); do sudo chage -l $u | grep -E ^[^:]*:5.2 安全加固与最佳实践将密码设为永不过期会降低一项安全控制措施因此必须用其他安全实践来补偿。使用强密码或密钥对于任何永不过期的账户必须设置高强度、复杂的密码长于16位混合大小写字母、数字、特殊字符。更好的方式是禁用密码登录改用SSH密钥对。# 在目标服务器上将公钥追加到对应用户的 ~/.ssh/authorized_keys 文件中 # 并确保 ~/.ssh 目录权限为 700authorized_keys 文件权限为 600 chmod 700 ~/.ssh chmod 600 ~/.ssh/authorized_keys限制登录方式与来源通过配置/etc/ssh/sshd_config可以禁止密码认证、限制特定用户或IP地址登录。# /etc/ssh/sshd_config PasswordAuthentication no # 禁用密码登录 AllowUsers deploy192.168.1.0/24 # 只允许特定网段IP使用deploy用户登录启用账户活动监控使用工具如auditd或简单的日志监控跟踪永不过期账户的登录行为及时发现异常。# 查看所有登录记录 last # 查看认证相关日志Ubuntu/Debian grep \authentication failure\ /var/log/auth.log # 查看认证相关日志RHEL/CentOS grep \authentication failure\ /var/log/secure定期审计与复核建立流程定期如每季度审查所有设置为密码永不过期的账户确认其是否仍有存在的必要并检查其安全配置如密钥、网络策略是否依然有效。考虑使用集中式身份管理在大型环境中使用FreeIPA、OpenLDAP或Active Directory通过SSSD等集中式身份管理系统。密码策略可以在中央服务器统一配置和管理更加规范和高效。将Linux用户密码从90天过期改为永不过期是一个在便利性与安全性之间寻求平衡的具体操作。对于无人值守的服务账户这是保证系统稳定运行的必需操作对于人员账户则需严格遵守组织的安全合规要求。关键在于理解其背后的原理/etc/shadow,chage掌握正确的操作方法并能根据不同的使用场景灵活应用。同时牢记“能力越大责任越大”为永不过期的账户配上更强的安全防护措施才能构建一个既稳健又安全的系统环境。下次再遇到服务莫名认证失败时希望你能第一时间想起这个“密码过期”的隐藏关卡。