适用:所有 Linux 耗时:约 30 分钟 前置:E1(懂权限)

E1 讲了"文件权限",这一篇讲"用户"——权限的另一半。

单位里共用一台机器、给同事开账号、装个服务要专用的运行用户——这些都是这一篇的内容。


一、Linux 用户的三个基本面

1. 每个用户有 UID

id
# uid=1000(zhangsan) gid=1000(zhangsan) groups=1000(zhangsan),27(sudo)
UID 范围用途
0root(超级管理员),只有一个
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         # 设密码

adduser vs useradd:

  • adduser(Debian 系)友好,自动建家目录、问密码、设 shell
  • useradd(底层命令)默认什么都不做,不加 -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 天过渡清单