适用:所有 Linux 耗时:约 30 分钟 前置:E1(懂权限)
E1 讲了"文件权限",这一篇讲"用户"——权限的另一半。
单位里共用一台机器、给同事开账号、装个服务要专用的运行用户——这些都是这一篇的内容。
一、Linux 用户的三个基本面
1. 每个用户有 UID
id
# uid=1000(zhangsan) gid=1000(zhangsan) groups=1000(zhangsan),27(sudo)
| UID 范围 | 用途 |
|---|---|
| 0 | root(超级管理员),只有一个 |
| 1-999 | 系统用户(服务用,比如 www-data、mysql) |
| 1000+ | 普通用户(你) |
UID 0 就是 root。 有人把某个普通账号的 UID 改成 0,等于造了第二个 root——这是后门手法。检查方法:
awk -F: '$3==0 {print $1}' /etc/passwd,应该只有root一个。
2. 用户信息存在两个文件
| 文件 | 内容 |
|---|---|
/etc/passwd | 用户名、UID、GID、家目录、shell(所有人可读) |
/etc/shadow | 密码哈希(只有 root 可读) |
看一行 /etc/passwd:
zhangsan:x:1000:1000:张三:/home/zhangsan:/bin/bash
│ │ │ │ │ │ └─ 登录 shell
│ │ │ │ │ └────────────── 家目录
│ │ │ │ └─────────────────────── 描述
│ │ │ └──────────────────────────── 主组 GID
│ │ └───────────────────────────────── UID
│ └──────────────────────────────────── 密码占位(真实哈希在 shadow)
└────────────────────────────────────────── 用户名
3. 每个用户有一个主组,可以属于多个附加组
groups # 我属于哪些组
id -nG # 同上
组的意义:权限可以按组给,不用一个一个用户给。
单位场景:developers 组的成员都能读写 /srv/project,新人入组就自动有权限——不用改文件权限。
二、加人、删人、改人
加一个用户
sudo adduser zhangsan # Debian 系:交互式,会问密码、全名
sudo useradd -m -s /bin/bash zhangsan # 通用:-m 建家目录,-s 指定 shell
sudo passwd zhangsan # 设密码
adduservsuseradd:
adduser(Debian 系)友好,自动建家目录、问密码、设 shelluseradd(底层命令)默认什么都不做,不加-m就没家目录 新手建议用adduser(如果系统有)。
删除用户
sudo deluser zhangsan # 删用户,保留家目录
sudo deluser --remove-home zhangsan # 连家目录一起删(⚠️ 数据没了)
⚠️ 删用户前先确认家目录里有没有重要文件。 生产环境建议先禁用再删:
sudo usermod -L zhangsan # 锁定密码(-L = Lock) sudo usermod -s /usr/sbin/nologin zhangsan # 禁止登录 # 观察一段时间没问题,再真删
改用户
sudo usermod -aG sudo zhangsan # 加入 sudo 组(获得管理员权限)
sudo usermod -aG developers zhangsan # 加入 developers 组
sudo usermod -s /bin/bash zhangsan # 改 shell
sudo usermod -L zhangsan # 锁定账号
sudo usermod -U zhangsan # 解锁
sudo usermod -l 新名 旧名 # 改用户名
⚠️
-aG的a千万不能漏!usermod -G sudo zhangsan(没有a)= 把用户的附加组直接设成只有 sudo,其他组全被踢掉。 正确写法永远是-aG(append + groups,追加)。
改密码
sudo passwd zhangsan # 管理员改别人的
passwd # 改自己的
sudo passwd -e zhangsan # 强制下次登录必须改密码
三、组管理
sudo addgroup developers # 建组(Debian 系)
sudo groupadd developers # 建组(通用)
sudo delgroup developers # 删组
sudo gpasswd -a zhangsan developers # 加人进组(另一种写法)
sudo gpasswd -d zhangsan developers # 从组里移除
看组里有哪些人:
getent group developers
# developers:x:1001:zhangsan,lisi,wangwu
四、sudo:怎么给"有限的管理员权限"
直接把 root 密码告诉同事是最糟的做法。(没法追责、没法限制、改密码要通知所有人)
正确做法:用 sudo 给特定权限。
最简单:加进 sudo 组
sudo usermod -aG sudo zhangsan # Debian 系
sudo usermod -aG wheel zhangsan # RPM 系
效果:这个用户能 sudo 执行任何命令。适合"副管理员",不适合普通同事。
更精细:只允许特定命令
用 visudo 编辑(必须用 visudo,不要直接编辑 sudoers 文件——它会做语法检查,写错了不至于把 sudo 锁死):
sudo visudo -f /etc/sudoers.d/zhangsan
内容:
# 允许 zhangsan 只重启 nginx
zhangsan ALL=(ALL) NOPASSWD: /bin/systemctl restart nginx, /bin/systemctl status nginx
这样他能重启 nginx,但删不了你的文件。
常用 sudoers 写法
# 免密码执行特定命令
zhangsan ALL=(ALL) NOPASSWD: /usr/bin/systemctl restart nginx
# 免密码执行某个目录下所有命令
%developers ALL=(ALL) NOPASSWD: /usr/bin/docker
# 组内所有人可以执行任何命令(要密码)
%wheel ALL=(ALL) ALL
⚠️
visudo写错会导致 sudo 完全不可用,可能把自己锁在外面。 安全做法:改之前另开一个 root 终端备用,或者先备份/etc/sudoers。
五、服务专用用户(好习惯)
为什么服务不该用 root 跑:服务被攻破 = 攻击者拿到 root = 整台机器沦陷。
正确做法:给每个服务建一个不能登录的专用用户。
sudo useradd -r -s /usr/sbin/nologin -d /var/lib/myapp myapp
参数含义:
-r= 系统用户(UID < 1000)-s /usr/sbin/nologin= 不能登录(只能被服务用)-d /var/lib/myapp= 家目录位置
然后让服务以这个身份跑(systemd 里):
[Service]
User=myapp
Group=myapp
看某个服务用什么用户跑:
ps aux | grep nginx
# www-data 是 nginx 的工作进程用户
六、审计:谁在什么时候干了什么
谁登录过
last # 登录历史
last -n 20 # 最近 20 条
lastb # 登录失败记录(需要 root)
who # 当前谁在线
w # 当前谁在线 + 在干什么
谁用了 sudo
sudo grep sudo /var/log/auth.log | tail -20 # Debian 系
sudo grep sudo /var/log/secure | tail -20 # RPM 系
输出会显示:谁、在什么时间、执行了什么命令。
谁在改文件
默认没有。要开审计:
sudo apt install auditd
sudo systemctl enable --now auditd
然后配置监控某个文件:
sudo auditctl -w /etc/passwd -p wa -k passwd_change
# -w 监控文件,-p wa 监控写和属性变更,-k 关键字
查记录:
sudo ausearch -k passwd_change | tail -20
这个偏专业,日常用得少。但单位环境"谁动了配置文件"这种问题,只有它能回答。
七、动手:四个练习
练习 1:看清自己是谁
id
groups
whoami
echo $HOME
echo $SHELL
练习 2:建一个测试用户
sudo adduser testuser # 按提示设密码
id testuser
ls -ld /home/testuser
验证:用 su - testuser 切换过去看看(退出用 exit)。
练习 3:建组并验证权限隔离
# 建组和目录
sudo addgroup testgroup
sudo mkdir -p /srv/testshare
sudo chgrp testgroup /srv/testshare
sudo chmod 2775 /srv/testshare # 2775 = SGID + 组可写
# 把人加进组
sudo usermod -aG testgroup testuser
# 验证
ls -ld /srv/testshare
getent group testgroup
2775的2是 SGID:在这个目录里新建的文件,组自动继承testgroup,组里所有人都能改。这是"团队共享目录"的标准做法。
练习 4:查有没有隐藏的 root 账号
awk -F: '$3==0 {print $1}' /etc/passwd
正常只应该输出 root。 多出来就是有问题。
练习 5(收尾):删掉测试用户
sudo deluser --remove-home testuser
sudo delgroup testgroup
sudo rmdir /srv/testshare 2>/dev/null || sudo rm -rf /srv/testshare
八、验证:你过关了吗
- 会看
id/groups//etc/passwd - 会用
adduser加人、deluser删人 - 知道
usermod -aG的a不能漏 - 会建组、把人加进组
- 知道
sudo组和wheel组的区别(不同发行版) - 知道服务该用专用用户跑,不该用 root
- 会用
last/who/w查登录情况 - 会用
awk -F: '$3==0'查隐藏 root
九、不行怎么办
Q1:adduser 不存在
RPM 系没有这个命令,用:
sudo useradd -m -s /bin/bash zhangsan
sudo passwd zhangsan
Q2:新用户登录后是 $ 提示符,没有家目录
建用户时没加 -m:
sudo mkhomedir_helper zhangsan # Debian 系
# 或
sudo cp -r /etc/skel/. /home/zhangsan/
sudo chown -R zhangsan:zhangsan /home/zhangsan
Q3:加了 sudo 组还是不生效 必须重新登录(组信息在登录时加载)。当前会话不会更新。
# 验证
groups # 有没有 sudo
sudo -l # 能执行什么
Q4:su 和 sudo -i 有什么区别
su - 用户:切换到那个用户,需要那个用户的密码sudo -i:以 root 身份开一个 shell,需要你自己的密码(前提是你在 sudo 组) 日常用sudo,不要习惯性su。
Q5:visudo 报语法错误,sudo 用不了了
用 root 直接登录(或单用户模式),恢复备份:
cp /etc/sudoers.bak /etc/sudoers
这就是为什么改之前要备份。
Q6:同事离职了,怎么彻底清理
# 1. 先禁用(保留数据)
sudo usermod -L zhangsan
sudo usermod -s /usr/sbin/nologin zhangsan
# 2. 找出他建的定时任务
sudo crontab -u zhangsan -l
sudo crontab -u zhangsan -r # 删除
# 3. 找他的进程
ps -u zhangsan
# 4. 备份家目录后删除
sudo tar czf /backup/zhangsan-home-$(date +%Y%m%d).tgz /home/zhangsan
sudo deluser --remove-home zhangsan
# 5. 检查他有没有遗留的 sudo 权限
sudo grep zhangsan /etc/sudoers /etc/sudoers.d/*
十、一句话总结
用户有 UID,root 是 0。权限按"组"给,不按"人"给。
加人:
adduser;加组:usermod -aG(那个a不能漏);给管理权:加进sudo组。服务用
nologin专用用户跑,绝不用 root。
← 上一篇 E6|Shell 脚本 返回 7 天进阶清单 第一季 从 Windows 迁到 Linux:7 天过渡清单