用过 Ubuntu 的人基本都遇到过这几类场景:装完系统要给家人或同事建一个登录账号、公司服务器上要开一个带 sudo 的临时账号、某天自己忘了密码被挡在系统外面,还有一类更加隐蔽——账号看起来一切正常,可就是反复出现安装软件失败、ssh 连不上、环境变量莫名其妙报错。这些问题绕来绕去,最终都会落到同一个词上:用户管理。
Ubuntu 的用户管理看起来就是几条命令,真正深入下去才会发现,细节全藏在权限模型和命令参数里。不走一遍完整流程,很多坑根本想不到。这篇文章我打算把用户管理的底层文件、核心命令、完整实操步骤和常见故障排查一次性讲透,新手可以照着动手操作,老手也能拿来查漏补缺——特别是 sudo 授权、家目录权限、SSH 密钥对接这些环节,踩过坑的人自然知道有多重要。
1. 用户管理到底在管什么
1.1 三个文件:passwd、shadow、group
Ubuntu 里所有用户信息最终都落在/etc/passwd、/etc/shadow、/etc/group三个文件上。我不建议你直接手动改这三个文件,除非你非常清楚自己在做什么,但理解它们的结构对排查问题帮助极大。
先看/etc/passwd,每一行对应一个用户,用冒号分成 7 个字段:
- 用户名
- 密码占位符(通常显示为
x,意思是真实密码不在这里) - UID(用户ID)
- GID(主组ID)
- 备注信息(GECOS,一般写真实姓名或用途)
- 主目录
- 登录 shell
我记得自己刚学 Linux 时也疑惑过,为什么cat /etc/passwd能直接看到所有人,却看不到任何密码。原因是密码 hash 早就被挪到了/etc/shadow,这个文件普通用户没有读取权限,只有 root 和部分特殊程序能访问。所以系统允许你用cat /etc/passwd查看用户列表,却不允许你用同样的方式看到密码信息。
/etc/shadow里每行也对应一个用户,除密码 hash 外还记录密码最后修改时间、最小最大修改天数、过期警告天数等策略字段。想看的话需要执行sudo cat /etc/shadow。
/etc/group是组信息,含组名、组口令占位符、GID 和组成员列表。很多新手容易忽略组的作用——一个用户能访问哪些文件,不只取决于他自己,还取决于他属于哪些组、组与文件之间的关系。这三个文件就是用户管理的“账本”,日常命令本质上都在读写它们。比如sudo useradd testuser后,系统会自动往/etc/passwd和/etc/shadow各加一行;把用户加到附加组,则改/etc/group。如果哪一天用户管理相关命令异常了,多半是这三个文件被改坏或权限出了问题。
1.2 超级用户、系统用户和普通用户的边界
Ubuntu 里的用户不分高低贵贱,只看 UID。UID 0 是超级用户 root,权限没有边界,能在系统里做任何事;UID 1 到 999 一般是系统用户,像 sshd、www-data、mysql 这些服务账户,它们通常没有可登录的 shell,只用来运行对应服务;从 UID 1000 开始是普通用户,系统安装时建立的第一个账号一般就是 1000 号。
这个划分背后是“最小权限原则”。每个服务用独立账号运行,权限只给到它需要的范围,出问题也只影响局部,不至于整个系统被攻破。这也是为什么服务故障时,第一反应应该是去看服务是以什么身份在跑,而不是盲目 sudo 重启然后再观察。
新手最常犯的问题,一是给系统服务账户或自己的普通账号乱加 sudo,二是把家目录权限随手设成 777。权限开得越宽,出事概率越高。后面会专门讲 sudo 授权怎么给才算克制。
2. 核心命令解析与选型理由
2.1 创建账号用 adduser 还是 useradd
Ubuntu 里有两个命令可以创建用户:交互式的adduser和底层的useradd。我日常操作中 80% 的建号场景都会用adduser,因为它会一步步询问设置密码、补充备注,并自动做好一堆准备工作:创建家目录、按模板往家目录里放默认配置文件、设置默认 shell。
useradd则接近“最小化”操作,默认不会创建家目录,也不设置密码,适合在脚本里批量建号用。比如要给几十个服务账号批量创建用户,你不可能一次次进入交互,用useradd -m -s /bin/bash -g users username这种组合就干净利落。
这里还有一点值得留意:adduser和useradd的参数体系并不完全一致。Ubuntu 的adduser底层是一个 Perl 脚本,不支持useradd里的很多底层参数;反过来,useradd也不会跟你交互。可以这样理解:adduser是把人穿戴整齐再领进门的秘书,useradd是给你一摞零件让你自己拼装的工具箱。
另外,/etc/skel这个目录值得认识一下。它是一个模板目录,里面预置了.bashrc、.profile、.bash_logout等配置文件,新建用户的家目录内容就是从这里拷贝过去的。如果你想给未来所有新建用户默认加某个配置,把文件放进/etc/skel即可,以后每次建号都会自动带上。这个机制很多人用了一年 Linux 都没注意过,但实际维护批量账号时非常有用。
2.2 密码、锁定与账号信息修改
passwd不只是改密码,还能锁账号、设过期策略。sudo passwd -l username会在 shadow 文件密码字段前加一个!,账号立即无法登录;sudo passwd -u username解锁;sudo passwd -e username强制用户下次登录时修改密码。临时账号到期封禁时用锁定比直接删除更稳妥,进可攻退可守。
usermod用来修改已有账号。最常用的场景是加附加组:
sudo usermod -aG sudo username注意这里必须带-a(append),否则用户会被从其他附加组里踢出去,只剩 sudo 这一个组。usermod -s /bin/bash可以改登录 shell,usermod -d /home/newdir可以改主目录,-L和-U也能锁和解锁账号,速度比 passwd 快,适合脚本里执行。
删除用户用userdel username,加-r会连家目录和邮件目录一起删除。我个人强烈建议删除前先确认这个用户没有活动进程,也没有重要文件残留,否则删完再想找回数据就难了。具体的排查方法放在第 4 章里展开。
2.3 用户组与 sudo 授权的关键逻辑
用户组的作用,是把一批用户放进同一个集合里,通过组权限统一管理文件访问,而不是逐个用户设置权限。比如搭内部开发环境,可以先建一个dev组,把团队成员都加进去,共享目录的组权限一配,大家就都能访问,成员变化时只改组成员,不用碰文件权限。
sudo 的本质是让普通用户临时以其他身份(默认 root)执行命令。允许谁执行哪些命令,配置写在/etc/sudoers里。改这个文件请务必用visudo命令打开,不要直接用vi /etc/sudoers,因为visudo会做语法校验,防止你把整个 sudo 搞坏。
配置行里最宽松的写法是:
username ALL=(ALL:ALL) ALL意思是“任意主机、以任意用户、执行任意命令”。这是全量放权。生产环境里应该尽量收紧,比如:
username ALL=(ALL) NOPASSWD: /usr/bin/systemctl restart nginx意思是该用户执行systemctl restart nginx时不需要输密码,但其他需要提权的命令仍然正常走密码验证。还有一点,RHEL 系用wheel组做管理员组,Ubuntu 默认用sudo组,两者机制类似但名称不同。在 Ubuntu 上把用户加进wheel组没意义,正确做法是加进sudo组。
3. 从零到一的完整实操流程
3.1 现实场景与动手前的检查
假设公司新来了一个同事小刘,需要在 Ubuntu 服务器上给他建一个普通账号,能登录、能用 sudo,并通过 SSH 密钥登录,避免每天输密码。我们把这个流程完整走一遍。
前提是你已经有管理员身份,并且能执行 sudo。动手前先确认环境基本信息:
cat /etc/os-release cut -d: -f1 /etc/passwd第一条查看 Ubuntu 版本,第二条列出当前机器上已有的所有用户名。知道自己在什么环境里操作,再开始建号,这是基本功,不丢人。
3.2 建号、设密码与默认文件处理
执行:
sudo adduser liu交互过程让你输入密码、确认密码,然后依次填写姓名、房间、电话、备注等信息。不想填的可以直接回车跳过,最后输入y确认。
这一步完成后,系统会自动创建/home/liu,并复制/etc/skel下默认的.bashrc、.profile等文件到家目录,默认 shell 一般是 bash。可以用id liu看到类似uid=1001(liu) gid=1001(liu) groups=1001(liu)的输出,当前用户只有自己的主组。
3.3 配置 sudo 和用户级环境变量
只建账号不加组,小刘目前没有管理员权限。这一步执行:
sudo usermod -aG sudo liu然后切换验证:
sudo su - liu sudo whoami如果输出root,说明 sudo 授权生效。第一次使用 sudo 时系统会提示输入当前用户密码,这是正常的校验流程。
接下来配置用户级环境变量。小刘之后要装软件、配环境,最常见的是往~/.bashrc里追加 PATH:
echo 'export PATH="$HOME/bin:$PATH"' >> ~/.bashrc source ~/.bashrc需要注意,很多人遇到的“ubuntu环境变量配置错误”,十有八九是改了/etc/environment或/etc/profile这种全局文件,语法写错导致所有用户的环境全挂了。改系统级环境变量前先备份,改完尽量在新终端里验证,不要关掉当前会话再去打开新窗口才发现问题。全局配置只有管理员能碰,普通用户平时用不着修改。
顺便提一句,有些朋友反馈“ubuntu安装gcc失败”,排查到最后往往不是 gcc 本身的问题,而是当前用户缺少写系统目录的权限,或者PATH里丢了/usr/bin。这类问题本质上都能扯到用户权限配置上,所以账号建好之后把 sudo 和 PATH 理清楚,很多后续麻烦可以提前规避。
3.4 SSH 密钥登录与权限细节
远程服务器上给新用户配置密钥登录是常规操作。先在本地生成密钥对,然后把公钥放到服务端。假设你本地已经有~/.ssh/id_rsa.pub,服务端执行:
sudo mkdir -p /home/liu/.ssh sudo chmod 700 /home/liu/.ssh echo "ssh-rsa AAAA......" | sudo tee /home/liu/.ssh/authorized_keys sudo chmod 600 /home/liu/.ssh/authorized_keys sudo chown -R liu:liu /home/liu/.ssh每一步都有讲究。.ssh目录权限必须是 700,authorized_keys文件必须是 600,属主必须是小刘自己。我看到过太多“ssh无法连接”的案例,根本不是密码或防火墙问题,而是.ssh目录权限太宽松,sshd 认为不安全直接拒绝读取密钥。日志里会显示类似Authentication refused: bad ownership or modes的信息。所以别小看权限配置。
如果本地 SSH 密钥已经配置好,其实可以用更省事的方式:
ssh-copy-id liu@服务器IP它会自动把公钥追加到对应用户的authorized_keys,并且自动设置好目录和文件权限。不过前提是该用户能通过密码登录,或者你有办法先把公钥传过去。
3.5 最后的验证与移交细节
流程收尾时,不要只跟小刘说“建好了”,至少过一遍下面几条:
id liu查看组成员是否包含 sudo;ls -ld /home/liu查看家目录属主和权限;- 用
sudo su - liu切换过去,感受一下登录后的 shell 环境; sudo tail -n 20 /var/log/auth.log看最近登录和提权记录,确认没有异常错误。
移交时把日常管理习惯写清楚,比如不要乱用 sudo、不要在/etc/下乱改文件、改全局配置先备份。用户管理不是建完号就结束了,后续的权限习惯才是关键。
4. 高频问题与排查技巧实录
4.1 忘记密码:应急恢复的两种思路
Ubuntu 忘记登录密码是搜索热门。如果你在本地机器前,最简单的方法是重启,在 GRUB 菜单里选择 Advanced options,进入 recovery mode,选 root shell,然后执行:
mount -o remount,rw / passwd username如果连用户名都不记得,可以先在 shell 里:
ls /home cat /etc/passwd确认要重置哪个账号。这里最容易被忽略的是 recovery 模式下根分区默认只读,所以mount -o remount,rw /这一步非常关键,不执行的话写操作会失败。
如果你是在远程服务器上忘了密码,而 ssh 也连不上,那走不了恢复模式,只能靠云控制台或其他带外入口,或者系统快照回滚。这也提醒了大家:云服务器密码不要等忘了才处理,最好一开始就配好管理员密钥,密码只是兜底方案。
4.2 sudo 报错的三种典型情况
第一种,username is not in the sudoers file。这是新手最常见的报错,意思是该用户不在 sudo 组里,也不在 sudoers 配置里。解决方法很简单:切到 root 或其他管理员账号,执行usermod -aG sudo username,或者用visudo加配置行。
第二种,用户密码过期,导致 sudo 怎么输密码都不对。优先检查 shadow 文件,确认账号没有过期、密码没有处于锁定状态。
第三种,/etc/sudoers被改坏,sudo 命令整个失效。这种情况需要死马当活马医,在还没断开的终端里用 root 执行pkexec visudo,或者直接通过恢复模式修复。所以平时改 sudoers 前先留备份,哪怕只是cp /etc/sudoers /etc/sudoers.bak,关键时刻能救命。
4.3 删除用户后留下的文件与 UID 冲突
删除用户时只执行了userdel username而没有加-r,家目录会留下来。之后如果系统创建了一个 UID 相同的新用户,这个新用户可能会“捡到”旧文件的归属权,变成安全隐患。运维里这种问题叫 UID reuse。
排查办法是:
find / -user oldusername找出所有还属于该用户的文件。如果确定不要了,直接删除或改为其他用户属主;如果要保留数据,用:
chown -R newuser:newgroup /home/oldusername把归属转给新用户。删除账号之前我还习惯跑一句:
pgrep -u username确认没有残留进程。删了号但进程还在跑,会留下一个无法归属的进程,比不删还难处理。
4.4 账号锁定、密码策略与审计日志
临时账号用完应该立刻锁定而不是删除,这样留有后悔药。方法:
sudo passwd -l username sudo chage -E 2026-01-01 usernamechage -E设定账号过期日期,适合给外包、实习生这类有时限的账号。如果要强制用户改密码,用:
sudo passwd -e username不然后很多用户会把初始密码用一辈子,安全隐患很大。
审计方面,Ubuntu 的用户管理日志集中在/var/log/auth.log。里面能看到登录成功/失败、sudo 调用、用户切换。遇到异常登录行为,先 grep 这个文件,经常能直接找到线索。日志不是摆设,是排查时最可靠的朋友。
5. 长期维护的一些个人心得
批量管理账号时,脚本化是个大趋势,但要注意交互命令和非交互命令的混用。写 shell 脚本批量建号时,用useradd加chpasswd组合更合适:
echo 'username:password' | sudo chpasswd比循环调passwd快得多,而且不会卡在交互提示上。如果有多台服务器,尽量用统一命名规范,比如dev-zhangsan、svc-nginx。不然过几个月再看,根本分不清这个账号是谁建的、是干嘛用的。
最后分享一个小习惯:每次改完用户或组配置,顺手把变更记录到本地笔记,或者至少保留 shell 历史。我见过太多团队,半年之后要查“这个账号当初为什么建”,全凭记忆,结果谁都说不清。用户管理不是安全部门一个人的事,每个用 Ubuntu 的人都该把账号当成自己家门口的锁一样,日常多看一眼,关键时候少折腾半天。