13 10 月 2026

一台服务器如果只有你一个人用 root,怎么折腾都行。但只要出现第二个使用者——同事、朋友、开服合伙人——问题就来了:谁改了配置?谁删了存档?为什么这个人的程序能读别人的文件?

这篇讲 Linux 多用户体系的实际用法:建用户、给 sudo、分组协作、限制权限、审计操作,以及服务该用什么账号跑。

财富云计算 的云服务器支持完整的 root 权限与多用户管理;如果只是做内网服务或游戏服务端,选 NAT 型云服务器(无独立公网 IP)价格比独立 IP 机型省一半以上。

一、先理解三个概念:用户、组、UID

Linux 里识别身份靠的是 UID(用户 ID),不是用户名。用户名只是给人看的别名。

id ops
# uid=1001(ops) gid=1001(ops) groups=1001(ops),27(sudo)

UID 约定:

UID 范围用途
0root,超级管理员
1–999系统用户(nginx、mysql、www-data 等)
1000+普通用户

组(GID) 解决的是"批量授权":把若干人放一个组,给组授权即可,不用一个个配。每个用户有一个主组,还能加入多个附加组。

相关文件:

cat /etc/passwd      # 用户账号信息(含 UID/GID/家目录/shell)
cat /etc/group       # 组信息
cat /etc/shadow      # 密码哈希(只有 root 可读)
cat /etc/sudoers     # sudo 授权配置

passwd 每行格式:

ops:x:1001:1001:运维账号:/home/ops:/bin/bash
│   │  │    │     │        │         └─ 登录 shell
│   │  │    │     │        └─ 家目录
│   │  │    │     └─ 备注(GECOS)
│   │  │    └─ 主组 GID
│   │  └─ UID
│   └─ 密码占位(x 表示在 shadow 里)
└─ 用户名

二、创建用户

# 交互式(推荐,Debian/Ubuntu)
adduser ops

# 非交互式(CentOS 也用这个)
useradd -m -s /bin/bash ops      # -m 建家目录,-s 指定 shell
passwd ops                       # 设密码

# 常用参数
useradd -m -s /bin/bash -c "张三" -G sudo,www-data zhangsan
#                          └ 备注      └ 附加组

创建完检查:

id ops
ls -ld /home/ops

创建服务专用账号(跑 nginx/mysql/游戏服务端用,不允许登录):

useradd -r -s /sbin/nologin gamesrv
# -r 系统用户(UID<1000),-s /sbin/nologin 禁止交互登录

这是很重要的安全实践:每个服务用自己的低权限账号跑,服务被攻破时只能拿到这个账号的权限。


三、修改和删除用户

usermod -aG sudo ops             # 追加附加组(⚠️ 必须带 -a,否则会覆盖原有组)
usermod -g devs ops              # 改主组
usermod -s /bin/zsh ops          # 改 shell
usermod -d /data/ops -m ops      # 改家目录并迁移文件
usermod -L ops                   # 锁定账号(禁用登录,保留数据)
usermod -U ops                   # 解锁
usermod -e 2026-12-31 ops        # 设置账号过期时间(临时账号很有用)

userdel ops                      # 删账号(保留家目录)
userdel -r ops                   # 连家目录一起删(⚠️ 数据没了)
⚠️ usermod -G 不带 -a 是新手常踩的坑:会把用户从其他所有附加组里踢出去,sudo 权限瞬间丢失。

四、组管理

groupadd devs                    # 建组
groupdel devs                    # 删组
groupmod -n developers devs      # 改组名
gpasswd -a ops devs              # 把用户加入组
gpasswd -d ops devs              # 从组移除
groups ops                       # 查看用户属于哪些组
newgrp devs                      # 临时切换主组(新建文件会用这个组)

协作目录的标准做法:

# 1. 建共享目录,组设为 devs
mkdir -p /data/shared
chgrp devs /data/shared
chmod 2775 /data/shared          # 2 = SGID,新建文件自动继承 devs 组

# 2. 把相关人员加进 devs
gpasswd -a alice devs
gpasswd -a bob devs

# 3. 用户重新登录后生效,验证
touch /data/shared/test && ls -l /data/shared/test
# 应该看到组是 devs

五、sudo:给普通用户临时的管理员权限

基本用法

sudo apt update                  # 单条命令提权
sudo -u www-data whoami          # 以指定用户身份执行
sudo -i                          # 切到 root 环境(加载 root 的环境变量)
sudo su -                        # 同上,另一种写法
sudo -l                          # 查看自己有哪些 sudo 权限
sudo !!                          # 上一条命令忘了加 sudo,这样补

授权方式

方式一:加入 sudo/wheel 组(简单,全权限)

usermod -aG sudo ops             # Debian/Ubuntu
usermod -aG wheel ops            # CentOS/Rocky(需确认 sudoers 里 %wheel 已启用)

方式二:在 /etc/sudoers 里精细授权(推荐)

永远用 visudo 编辑,它会做语法检查,写错了不会把自己锁死:

sudo visudo
# 或者更安全:在 /etc/sudoers.d/ 下建独立文件
sudo visudo -f /etc/sudoers.d/ops

配置示例:

# 允许 ops 执行所有命令(等同于 sudo 组)
ops  ALL=(ALL:ALL) ALL

# 免密码执行所有命令(自动化脚本用,注意风险)
ops  ALL=(ALL) NOPASSWD:ALL

# 只允许管理服务,不许改别的
ops  ALL=(ALL) /usr/bin/systemctl restart nginx, /usr/bin/systemctl restart php-fpm

# 只允许以 www-data 身份执行,且免密
deploy  ALL=(www-data) NOPASSWD: /usr/bin/git

# 禁止某用户使用 sudo
baduser  ALL=(ALL) !ALL

语法格式:用户 主机=(可切换的身份) [选项:]命令列表

别名简化(人多时很有用):

User_Alias  ADMINS = ops, alice, bob
Cmnd_Alias  SERVICES = /usr/bin/systemctl start *, /usr/bin/systemctl stop *, /usr/bin/systemctl restart *
ADMINS  ALL=(ALL) SERVICES

sudo 安全建议

  • 尽量用 NOPASSWD 的白名单,而不是全局 NOPASSWD。
  • 命令路径写绝对路径(防止 PATH 劫持)。
  • 定期审计 sudo -l 和 /etc/sudoers.d/ 下的文件。
  • sudo 日志默认在 /var/log/auth.log,出问题可追溯。

六、切换用户与环境

su ops                           # 切换用户,保留原环境变量
su - ops                         # 切换并加载 ops 的完整环境(推荐)
sudo -u nginx nginx -t           # 以 nginx 身份测试配置
exit                             # 退回

su - 和 su 的区别常导致"命令找不到",因为 PATH 不同。切换后执行 echo $PATH 对比一下就明白了。


七、登录审计:谁在什么时候干了什么

who                              # 当前登录的用户
w                                # 更详细(含在干什么)
last                             # 历史登录记录
lastb                            # 失败的登录尝试(需 root)
lastlog                          # 每个用户最近一次登录
whoami / id                      # 当前身份

命令审计(记录所有 sudo 执行的命令):

# 在 /etc/sudoers 加一行
Defaults logfile="/var/log/sudo.log"
Defaults log_input, log_output
Defaults iolog_dir="/var/log/sudo-io/%{user}"

之后:

cat /var/log/sudo.log

团队共用服务器时强烈建议开启,出事后能还原是谁敲的哪条命令。


八、服务该用什么账号跑

原则:绝不用 root 跑对外服务。

查看服务跑在什么账号下:

systemctl show -p User,Group nginx
ps aux | grep nginx | head

常见服务的默认账号:

服务Ubuntu/DebianCentOS/Rocky
nginxwww-datanginx
Apachewww-dataapache
PHP-FPMwww-dataapache/nginx
MySQLmysqlmysql
Redisredisredis

自建服务(比如游戏服务端)的做法:

# 1. 建专用账号,禁止登录
useradd -r -m -s /sbin/nologin steam

# 2. 数据目录归属给它
chown -R steam:steam /opt/steam

# 3. systemd 里指定运行用户
[Service]
User=steam
Group=steam
WorkingDirectory=/opt/steam
ExecStart=/opt/steam/start.sh

这样即使游戏服务端有漏洞被利用,攻击者拿到的也只是 steam 这个无权登录、家目录受限的账号。


九、账号安全加固清单

# 1. 检查有没有空密码账号
awk -F: '($2 == "") {print $1}' /etc/shadow

# 2. 检查除了 root 还有没有 UID=0 的账号
awk -F: '($3 == 0) {print $1}' /etc/passwd

# 3. 设置密码复杂度策略
apt install libpam-pwquality -y     # Debian/Ubuntu
nano /etc/security/pwquality.conf
# minlen = 12
# dcredit = -1  (至少1个数字)
# ucredit = -1  (至少1个大写)
# lcredit = -1  (至少1个小写)
# ocredit = -1  (至少1个特殊字符)

# 4. 设置密码有效期
chage -M 90 ops                  # 90 天必须改密码
chage -l ops                     # 查看策略

# 5. 锁定长期不用的账号
usermod -L olduser

# 6. 禁止 root 通过 SSH 登录
# /etc/ssh/sshd_config: PermitRootLogin no

十、实战:给团队配一台共享服务器

场景:3 个人共用一台服务器,都做网站运维,各自有家目录,共享一个项目目录。

# 1. 建组
groupadd webops

# 2. 建用户并加入组
for u in alice bob carol; do
  useradd -m -s /bin/bash -G webops,sudo $u
  passwd $u
done

# 3. 共享项目目录
mkdir -p /data/project
chgrp webops /data/project
chmod 2775 /data/project
chmod +t /data/project          # sticky,防止互删

# 4. 各自家目录私密
chmod 750 /home/alice /home/bob /home/carol

# 5. Web 目录授权(让 nginx 也能读)
chown -R www-data:webops /var/www/html
chmod -R 775 /var/www/html
chmod -R 2775 /var/www/html/uploads

# 6. 开启 sudo 审计
echo 'Defaults logfile="/var/log/sudo.log"' > /etc/sudoers.d/audit
chmod 440 /etc/sudoers.d/audit

# 7. 验证
su - alice
touch /data/project/a.txt && ls -l /data/project/a.txt
sudo -l

十一、常见故障

问题原因解决
xxx is not in the sudoers file没授权用 root 执行 usermod -aG sudo xxx
加了组但 sudo 还是不行需要重新登录才生效退出 SSH 重连,或 newgrp sudo
visudo 报错不敢保存语法错误直接退出不保存(:q!),配置不会损坏
误改 sudoers 被锁死语法错误导致 sudo 全废走云控制台 VNC/单用户模式修复
用户删不掉有进程在跑pkill -u 用户名 后再 userdel
家目录权限乱了手动 chmod 过chown -R 用户:组 /home/用户,chmod 750

十二、小结

  1. 别用 root 干活:建普通用户 + sudo,出事能追溯。
  2. 服务用独立低权限账号:useradd -r -s /sbin/nologin。
  3. 协作用组 + SGID:共享目录 2775。
  4. sudo 授权尽量白名单:visudo 编辑,命令写绝对路径。
  5. 开启审计:Defaults logfile + fail2ban。
想实操这套多用户方案,可以开一台 财富云计算 的云服务器。练手、内网服务、游戏服务端推荐 NAT 型(无独立公网 IP,价格比独立 IP 机型省一半以上);需要对外提供网站访问再选独立 IP 机型。

相关阅读:

  • 《SSH 密钥登录与账号安全配置》
  • 《Linux 文件权限与用户组详解》
  • 《fail2ban 防暴力破解实战配置》
延伸阅读
  1. 网站环境怎么选:LNMP 手动 / 宝塔面板 / Docker / 云开发
  2. 问卷表单系统搭建:SurveyKing / Formbricks,数据自己收
  3. 图床搭建:Lsky Pro / Lychee,自托管图片托管方案
  4. 邮件列表搭建:listmonk 自托管 Newsletter,把读者握在自己手里
  5. 文档站点搭建:MkDocs / VuePress / Docsify,产品文档与技术手册方案
  6. RSS 阅读器搭建:FreshRSS 自托管,把信息流拿回自己手里
  7. 短链接服务搭建:Shlink 自托管,链接数据自己掌握
  8. 网站状态监控页搭建:Uptime Kuma,服务器挂了第一时间知道
更多阅读
  1. 上一篇:网站常见漏洞与基础防护:SQL 注入、XSS、文件上传、越权
  2. 下一篇:systemd 服务编写与开机自启实战:让程序开机自动跑、崩了自动重启
发表评论 1

取消回复