Linux用户管理核心指南:删除用户、密码策略与su切换的边界

📅 发布时间:2026/9/9 20:24:31
Linux用户管理核心指南:删除用户、密码策略与su切换的边界 接手一台生产服务器时最让我紧张的往往不是装软件而是清账号。早几年我也觉得 Linux 用户管理没什么难度useradd 建人passwd 设密码userdel 删人su 切 root四个命令就能走完大半流程。直到有一次我自以为把一个离职员工的账号删干净了第二天却发现他留下的定时任务还在跑备份系统里还躺着一个以他命名的目录一个常驻进程也因为他之前的启动身份继续占着资源。那一刻我才意识到用户管理真正难的地方不在命令本身而在账号背后那串看不见的关联UID、属主文件、进程、定时任务、登录状态、sudo 授权。这篇文章围绕删除用户、用户密码、su 切换这三块常见操作把命令背后的边界和坑一次讲清楚。1. 用户管理不是背命令而是管住账号背后的“关联关系”1.1 一个 Linux 账号身上远远不止 /etc/passwd 里那一行只要接受过一次 Linux 基础培训都知道用户信息存在 /etc/passwd密码哈希存在 /etc/shadow组信息在 /etc/group。但要真去维护一台机器脑子里只留这三个文件名是不够的。我见过不少初学阶段的人把“删用户”理解成“把 /etc/passwd 里那一行删掉”这个理解方向不算错但它忽略了账号作为一个运行实体身上还挂着另外几样东西家目录默认在 /home/username或按 /etc/passwd 里指定的路径。用户自己的定时任务存储位置随发行版略有差异常见目录如 /var/spool/cron。邮件缓冲/var/mail/username 或 /var/spool/mail/username。运行中的进程只要还有进程以这个 UID 在跑账号删掉后进程也不会自己消失。遍布文件系统的属主文件UID 为某个用户创建的日志、脚本、临时文件。sudo 授权/etc/sudoers 或 /etc/sudoers.d/ 里可能还有一条以该用户名为 key 的规则。共享组关系用户被删后组里可能还留着一条不再属于任何人的标签。关联项常见位置删除账号时是否自动清理账号基本信息/etc/passwduserdel 会删除对应行密码与时效信息/etc/shadow随账号删除家目录/home/username需要 -r 参数或手动归档邮件缓冲/var/mail/username部分发行版由 -r 处理需确认定时任务crontab 对应目录或服务通常不会自动清理运行中的进程由进程表中的 UID 关联不会自动停止分散的属主文件各文件系统不会自动处理sudo 授权/etc/sudoers.d/不会自动清理1.2 为什么“删一个用户”不像“删一行配置”因为账号不只是身份它还是一种资产归属。系统里所有以这个 UID 标注的文件本质上是“这个账号拥有的资源”。你把这个账号删了文件并不会跟着删除它们只是变成了一堆身份不明的孤儿文件。这在运维上意味着两件事安全上如果 UID 后续被复用新账号可能意外获得这批文件的访问权管理上审计时你很难说清楚这台机器上还有哪些数据是离职同事留下的。所以用户管理的本质是在维护“账号信息、资产归属、权限通道”三者之间的一致性。命令只是执行器判断才是关键。2. 删除用户真正麻烦的不是 userdel而是删完之后那堆“孤儿”2.1 userdel 到底删了什么在最常见的发行版里一条最基本的命令是sudo userdel username它的作用是删除 /etc/passwd、/etc/shadow、/etc/group 里和这个用户直接相关的记录使这个人无法再以原账号登录。但如果只执行这条命令你会发现很多和它相关的东西还留在原地。如果加上 -r 参数sudo userdel -r username在常见的 util-linux 实现里它会删除家目录和邮件缓冲。注意这句话的重点是“会删除这些”而不是“会清理所有关联”。定时任务、仍在运行的进程、散落在其他挂载点里的属主文件以及 sudo 授权通常都不会被自动带走。更需要注意的是 -f 参数强制删除往往很危险。当用户还有进程在跑、还处于登录状态时-f 会强行把账号删掉表面上“删干净了”实际上留下一个身份不明但仍在运行的进程后续你连它是谁启动的都查不出来。2.2 删除前先给这个用户的“资产”做一次盘点我强烈不建议一上来就执行 userdel -r。先花几分钟看看这个账号还挂在哪些东西上# 用户是否存在 id username getent passwd username # 是否还有进程 ps -u username -o pid,cmd # 是否还有定时任务 crontab -l -u username 2/dev/null # 家目录内容体量 du -sh /home/username # 在常见数据目录里粗略找一下属主文件 find /home /opt /srv /tmp -xdev -user username -ls 2/dev/null | head -50如果担心全盘扫描太慢不要一上来就在 / 上执行 find先覆盖常见数据目录再根据这台机器的实际挂载情况补路径。这一步的目的不是把每个文件都翻一遍而是让你心里有数删除之后会产生哪些不可逆影响。注意离职账号的家目录里往往有没来得及交接的脚本、备份和配置文件。先把目录移动或打包到归档区等确认不再需要再真正清理。不要在第一秒就物理删除家目录。2.3 一套更稳的删除顺序锁定 → 停用 → 归档 → 删除 → 复核我自己在实际处理账号时会按这个顺序走锁定账号让密码立刻失效sudo passwd -l username或sudo usermod -L username。先锁是为了避免对方在交接或清理期间还能通过新登录进入系统至于已经存在的活动会话需要配合进程收尾一起停。锁定密码解决的是入口问题不是会话问题。停掉相关进程和定时任务确认进程清单后再决定是优雅停止还是 kill定时任务如果确认不需要留底用sudo crontab -r -u username清掉。归档家目录和可能需要的属主文件sudo mv /home/username /backup/username_before_del_YYYYMMDD必要时打包压缩。删除账号如果家目录已经移走直接sudo userdel username然后手动检查 /var/mail 或 /var/spool/mail 下是否还有同名缓冲文件。复核残留id username应查询不到sudo ps -u username应无输出再看一眼 sudo 授权规则sudo grep -r username /etc/sudoers /etc/sudoers.d/这个流程看起来比一条 userdel -r 多花了几分钟但它保证了每一步都可回退、可追溯。尤其在生产环境里宁可多花时间归档也不要为省两分钟制造一个无法交代的残留账号。3. 用户密码设置只是开始生命周期和锁定策略才是关键3.1 手动改密码和脚本初始化应该用不同的方式交互式环境里改密码没什么好绕的passwd # 改当前用户自己的密码 sudo passwd username # 管理员为指定用户设置新密码真正容易出问题的是批量创建账号或批量初始化密码。我经常看到有人把密码直接写在命令行里再通过管道传给 passwd比如echo pass | passwd --stdin username。这种方式在少数发行版里能用但有两个明显问题一是命令参数会留在 shell 历史和进程列表里二是 passwd 的 --stdin 参数并非所有发行版都支持换个系统就翻车。更稳的批量写法是用 chpasswdecho username:NewPassword | sudo chpasswd不过哪怕用 chpasswd如果明文密码是通过命令行传进去的依然会留在 shell 历史里。更安全的做法是把密码交给密钥管理工具或者在脚本内部从一个只有 root 可读的临时文件读取。这个问题看着小但一旦系统里同时有几十个账号密码初始化就很容易变成安全事故。注意不要把明文密码直接写在 shell 命令参数里。密码一旦进历史记录别人只要拿到你的终端历史就等于拿到了账号。3.2 账号锁定、状态查看和 /etc/shadow 的关系密码并不是只存在 /etc/shadow 里哈希那一段。shadow 文件中一个用户对应的一行通常按冒号分成 9 段除了用户名和哈希还有最近修改时间、最短使用天数、最长使用天数、过期前提醒天数、账号过期时间等信息。日常管理不用背下每一段但至少要会用两个查看命令sudo passwd -S username # 查看密码状态 sudo chage -l username # 查看详细的密码时效用 passwd -S 查看时输出里会有单个字母的状态标记P 表示有可用密码L 表示被锁定NP 表示没有密码。锁定账号时passwd -l 和 usermod -L 在常见的 util-linux 实现里都会在 shadow 哈希前加上一个感叹号前缀让哈希失效如果你在排查问题时怀疑账号被锁先用 passwd -S 确认不要凭记忆猜。如果你需要的是一个时间段内有效的临时账号还可以设置账号过期sudo usermod -e 2025-12-31 username到期后账号的直接登录会失败数据还在方便后续需要恢复时重新启用也避免把临时账号变成永久入口。3.3 密码策略不是靠自觉而是靠 chage 和 PAM给普通用户设置密码之后还有一步经常被忽略密码策略。最基本的策略用 chage 管理sudo chage -M 90 -m 7 -W 14 username这里 -M 90 表示密码最长使用 90 天-m 7 表示最短 7 天-W 14 表示提前 14 天提醒。更复杂的长度、复杂度、历史记录限制通常由 PAM 模块负责并不由 chage 决定。如果你发现系统强制要求 8 位以上、必须含特殊字符而 chage 里并没有那么细的选项不用疑惑那些规则在 /etc/pam.d/ 下的认证配置里。需要特别说明边界密码过期策略并不适合所有账号。服务账号、自动化脚本使用的账号、数据同步账号它们通常不该有人类可用的密码更不该被强制要求定期改密。对一个服务账号强行设置 90 天过期可能让它在凌晨突然无法认证。此类账号的第一原则是“锁定 无密码 仅走受控通道”而不是“设置一个强壮密码”。4. su 切换并不是“切过去”这么简单4.1 su 和 su -本质区别在环境很多人第一次用 su 时会经历一个经典困惑执行 su输入密码后看起来已经是 root 了但敲 systemctl、ip 这类命令却提示 command not found。原因不在 su 切换失败而在环境变量。su username切换用户身份但大部分环境变量、当前目录都保留原来的样子。su - username模拟一次完整登录重新加载登录环境PATH、HOME、SHELL 等都会被重置为目标用户的标准值。所以如果 su 之后发现命令找不全通常不是系统坏了而是你用了不带 - 的 su。日常管理需要交互式 root 会话时我建议用su -而不是su。命令形式行为适用场景su username只切换身份保留原环境变量和当前目录临时切过去执行一两条命令su - username模拟完整登录加载登录环境想要干净的交互式会话su - username -c command以目标用户身份执行单条命令脚本、非交互环境su -s /bin/bash username指定 shell 切换目标用户默认 shell 不可用或想临时替换4.2 认证边界和非交互用法su 的认证逻辑也要说清楚。普通用户执行su root时验证的是 root 的密码root 执行su alice时一般不需要再输入 alice 的密码。这个设计决定了 su 的一个现实问题如果团队里每个人都为了切 root 而共享 root 密码那么这个密码一旦多次传递安全问题就失去了边界。这也是为什么很多生产环境更倾向用 sudo 而不是直接共享 root 密码。在脚本或 CI 环境里使用 su需要注意非交互场景。不要指望一个需要终端的 su 交互流程能在后台稳定运行。合理的写法通常是这样su - username -c cd /data ./deploy.sh不过如果目标用户的 shell 是 /sbin/nologin 或 /bin/false即使指定了 -csu 也可能直接退出。这类账号本来就不该作为可切换的目标用户排查时先确认这一点。注意在非交互环境里要用 su尽量在命令里带 -c 指定要执行的操作。不要在一个没有伪终端的后台环境里强行跑交互式 su结果往往不是卡住就是报错。4.3 能管理权限的不只有 susudo 才是更可控的通道从安全和管理角度我对 su 和 sudo 的判断是这样su 适合解决一次性的身份切换尤其是在单机救援或还没有配置 sudo 的场合sudo 适合解决“谁能在哪些主机上以什么身份执行哪些命令”的问题。sudo 用发起命令的用户自己的密码做认证授权规则可以精确到命令级别而且多数发行版会记录审计日志。相比之下su 一旦把 root 密码分发出去你能控制的粒度就变得很粗。如果你在维护一批服务器更建议把“切换到 root”这个动作收拢到 sudo 策略里先给运维人员最小够用的授权再配合日志审计。这样即便出了问题你也知道是哪台机器、哪个账号、在什么时间执行了什么命令。这不是说 su 没用而是说它应该被当成例外手段而不是日常习惯。5. 从“su: inaccessible or not found”讲开切换失败怎么查5.1 先把报错类型看清楚再动手运维里有个常见的坏习惯就是不看完整报错就开始猜。su 的问题其实可以从报错文本大致判断方向现象/报错优先怀疑确认方式su: user xxxx does not exist用户名拼错或这台机器没有这个用户getent passwd xxxxsu: authentication failure密码错误、账号锁定、密码过期passwd -S、chage -lsu: inaccessible or not foundsu 本体不存在或目标用户 shell 缺失/不可用command -v sugetent passwd 查 shellwarning: cannot change directory to /home/xx家目录不存在或权限有问题ls -ld /home/xx切过去后 command not found没用 su -PATH 没刷新改用 su -must be run from a terminal非交互环境里直接执行了交互式 su改用 su - user -c command这个表格不是要把所有错误都穷尽而是希望你先定位到“是哪一层出了问题”再决定从哪里排查。5.2 “inaccessible or not found”的五步排查链路在日常 Linux 服务器、精简容器或某些嵌入式环境里su: inaccessible or not found是一个会被反复遇到的报错。它比其他报错更让人困惑因为既不像“用户不存在”又不像“密码错误”。碰到这个报错时我一般按下面五层检查先查 su 本体是否存在command -v su、which su。很多极简容器和精简系统默认没有安装 su需要先通过包管理器安装 util-linux 或相应基础包。这一步经常被忽略因为大部分服务器教程默认 su 一定存在。再查目标用户的 shell。getent passwd username看最后一个字段也就是登录 shell。如果 shell 路径不存在、指向了被删除的解释器su 会找不到可执行的登录程序从而提示 inaccessible 或类似信息。确认 shell 文件本身可执行。ls -l /bin/bash检查权限必要时用 ldd 看一下动态库依赖是否完整。系统做过精简、迁移或升级后shell 依赖缺失也是可能的。检查账号锁定和密码时效。passwd -S username、chage -l username。如果账号被锁或密码已过期但 shell 又恰好异常报错会混在一起先解决 shell 的缺失再继续。查认证日志。在 RHEL 系的服务器上通常看 /var/log/secure在 Debian/Ubuntu 系看 /var/log/auth.log用最近几分钟的记录来定位是认证失败、PAM 拒绝还是 shell 启动失败。排查的关键不是背每个报错对应的修复命令而是形成“输入 → 命令本体 → 环境 → 权限 → 资源依赖”的固定顺序。顺序稳了很多问题即使没见过也能一步步缩小范围。6. 一张“用户生命周期”检查单比记一万个参数更耐用6.1 把用户管理拆成四个阶段每个阶段锁住三件事学到命令之后更值得沉淀的是流程。下面这张表是我在维护机器时反复用的框架适合写进运维交接文档也适合作为面试时表达“我懂用户管理”的骨架。阶段必做最容易犯的错创建用明确的参数指定家目录、登录 shell、附加组设置初始密码配置密码时效建完账号不设密码就直接交付附加组给得过大使用定期复核账号是否存在、sudo 授权是否还在、有无异常登录记录从不检查账号越堆越多变更岗位或职责变化时先调整组、sudo、目录权限而不是急着删号只加权限不清老权限权限越积越大停用/删除锁定 → 停进程 → 归档 → 删除 → 复核直接 userdel -r留下 crontab、进程、属主文件这张表的用法不是贴在墙上就算完而是每次做账号变更时按顺序过一遍。比如创建阶段很多人以为 useradd -m username 就结束了事实上你还要检查默认 shell 是否是 /bin/bash附加组是否最小够用初始密码是否通过受控方式设置密码策略是否已经生效。如果这些没做账号在创建当天就是敞开的。停用阶段也一样锁号和删除是两件事锁号只解决“进不来”删除才解决“不需要存在”。6.2 单机能跑通不等于多机也适用最后说一点边界。上面的命令和排查思路适合一台台维护的服务器环境。如果你的环境已经上了批量运维工具、统一认证或云平台托管那你要管理的就不是单机上的一条条记录而是账号数据的同步策略、过期时间和审计。即便如此核心原则没有变删除永远比创建更需要谨慎归档永远比清空更安全权限永远应该遵循最小够用。如果是多台机器优先考虑把用户管理的入口收拢到统一认证里单机的 /etc/passwd 维护会随着机器数量增长而失控如果你正在维护的是容器镜像或嵌入式系统还要注意 su 这类工具可能没有被打进去登录 shell 也可能被精简只有把账号、密码、shell 三个边界都确认清楚整个流程才算完整。回到开头那台让我吃教训的服务器。后来我给自己定了一条规矩凡是涉及账号删除不直接跑 userdel -r而是先把账号锁定把进程和定时任务盘一遍把家目录归档到带有日期的目录最后删除并复核。这个流程看起来多花了几分钟但它让每一次账号清理都成为可追溯的操作。用户管理的价值从来不体现在“一条命令跑得多快”而体现在你随时能回答这台机器上有哪些账号它们各自能做什么谁可以安全删除。搞懂了这一点userdel、passwd、su 这几个命令才算真正长在你身上。