Linux 用户与权限:多团队共用一台服务器怎么分

Linux 用户与权限:多团队共用一台服务器怎么分

一、一台服务器,三个团队,谁把谁的文件删了?

公司有台 64C/256G 的测试服务器,运维、开发、数据三个团队共用。某天开发小王 rm -rf /data/* 把数据组的 ETL 结果全清了------因为大家都在用 root,/data 谁都能写。

这不是段子,这是真实的生产事故。多团队共用一台服务器,权限不分=定时炸弹

今天把 Linux 用户与权限管理体系讲清楚:用户/组怎么建、目录权限怎么分、sudo 怎么收口、ACL 怎么补位,一套组合拳下来,各团队互不干扰,出问题可追溯。

二、核心概念:用户、组、权限三位一体

Linux 权限模型就三句话:

  1. 每个文件属于一个用户(owner)和一个组(group)
  2. 权限分三组:owner / group / others,每组有 read / write / execute
  3. 用户可以属于多个组,组是权限分配的基本单位
bash 复制代码
# 查看文件权限
ls -ld /data/backend
# drwxrwx--- 2 deploy backend 4096 Jun 17 10:00 /data/backend
# ││││││││││
# │┴─┬─┘│┴─┬─┘│┴─┬─┘
# type owner group others
# rwx  rwx   ---    → owner可读写执行,group可读写执行,others无权限

多团队共用服务器的核心思路:一个团队一个组,目录归属对应组,权限用 group 控制

三、实战:多团队权限划分方案

场景:运维组(ops)、后端组(backend)、数据组(data)共用一台服务器。

1. 创建团队组和用户

bash 复制代码
# 1. 创建三个团队组
groupadd ops
groupadd backend
groupadd data
# 2. 创建用户并加入对应组
useradd -m -g ops zhangsan        # 运维张三
useradd -m -g backend xiaowang    # 后端小王
useradd -m -g data lisi           # 数据李四
# 3. 验证
id zhangsan
# uid=1001(zhangsan) gid=1001(ops) groups=1001(ops)
id xiaowang
# uid=1002(xiaowang) gid=1002(backend) groups=1002(backend)

2. 创建团队目录并设置权限

bash 复制代码
# 1. 创建团队数据目录
mkdir -p /data/ops /data/backend /data/data

# 2. 设置目录归属(组 ownership)
chown root:ops /data/ops
chown root:backend /data/backend
chown root:data /data/data

# 3. 设置权限:owner=rwx, group=rwx, others=---
chmod 770 /data/ops
chmod 770 /data/backend
chmod 770 /data/data

# 4. 验证
ls -ld /data/*
# drwxrwx--- 2 root ops      4096 ... /data/ops
# drwxrwx--- 2 root backend   4096 ... /data/backend
# drwxrwx--- 2 root data      4096 ... /data/data

这样各团队只能进自己的目录,互不干扰。

3. SGID:新建文件自动继承组权限

上面有个问题:用户在 /data/backend 下新建的文件,默认组是用户的主组(backend),这没问题。但如果某个用户通过附加组访问其他目录,新建文件的组可能不对。SGID 解决这个问题

bash 复制代码
# 给目录设置 SGID
chmod g+s /data/backend

# 效果:在该目录下新建的文件/子目录,自动继承目录的组
su - xiaowang
touch /data/backend/test.txt
ls -l /data/backend/test.txt
# -rw-r--r-- 1 xiaowang backend ... test.txt  ← 组是 backend,不是 xiaowang 的主组

# 递归设置 SGID(含已有子目录)
find /data -type d -exec chmod g+s {} \;

4. Sticky Bit:防止互相删文件

770 权限下,同组用户可以互相删除对方的文件(因为组有 write 权限)。加 Sticky Bit 后,只有文件 owner 才能删自己的文件:

bash 复制代码
# 设置 Sticky Bit(同 /tmp 的机制)
chmod +t /data/backend

# 验证
ls -ld /data/backend
# drwxrwx--T 2 root backend ... /data/backend
#                ↑ T = Sticky Bit 生效

# 效果:小王能写 /data/backend,但删不了同组小李的文件

最佳实践组合:

bash 复制代码
# 目录权限 = 770 + SGID + Sticky Bit = 3770
chmod 3770 /data/backend
# 3 = SGID(2) + Sticky(1)
# 验证
ls -ld /data/backend
# drwxrws--T 2 root backend ... /data/backend

5. 附加组:跨团队协作

运维小张偶尔需要查看后端日志,但不需要写权限:

bash 复制代码
# 方案一:把小张加入 backend 附加组(给读写权限)
usermod -aG backend zhangsan
id zhangsan
# uid=1001(zhangsan) gid=1001(ops) groups=1001(ops),1002(backend)

# 方案二(推荐):用 ACL 精细控制,只给读权限
setfacl -m u:zhangsan:rx /data/backend
getfacl /data/backend
# user::rwx
# user:zhangsan:r-x    ← 小张只读
# group::rwx
# mask::rwx
# other::---

附加组 vs ACL 怎么选?

场景 方案
一个人需要另一个组的完整读写权限 附加组
一个人只需要读权限 ACL
临时授权,随时回收 ACL(setfacl -x 删除)
多人统一管理 附加组(改组就行)

四、sudo 收口:禁 root 直登,按团队授权

多人共用服务器,用 root 操作=无法追溯谁干了什么。必须做两件事:

1. 禁止 root SSH 直登

bash 复制代码
# /etc/ssh/sshd_config
PermitRootLogin no
systemctl restart sshd

2. 按团队配置 sudo 权限

bash 复制代码
# /etc/sudoers.d/ops(运维组:全部权限)
%ops ALL=(ALL) ALL

# /etc/sudoers.d/backend(后端组:只能重启自己的服务)
%backend ALL=(root) /usr/bin/systemctl restart backend-app, /usr/bin/systemctl status backend-app

# /etc/sudoers.d/data(数据组:只能操作自己的目录和脚本)
%data ALL=(root) /usr/bin/systemctl restart etl-*, /usr/local/bin/run_etl.sh

验证 sudo 配置:

bash 复制代码
# 查看用户能执行哪些 sudo 命令
sudo -lU xiaowang
# User xiaowang may run the following commands:
#     (root) /usr/bin/systemctl restart backend-app, /usr/bin/systemctl status backend-app

审计:谁用了 sudo 做了什么

bash 复制代码
# 查看 sudo 日志
grep sudo /var/log/secure    # CentOS
grep sudo /var/log/auth.log  # Ubuntu

# 或者 journalctl
journalctl -t sudo --since "today"

五、ACL 补位:传统权限搞不定的场景

传统权限只能设 owner/group/others 三级,ACL 可以给任意用户设权限:

1. ACL 基本操作

bash 复制代码
# 给用户设权限
setfacl -m u:zhangsan:rx /data/backend        # 小张只读
setfacl -m u:lisi:rwx /data/backend           # 李四读写执行

# 给组设权限
setfacl -m g:ops:rx /data/backend              # 运维组只读

# 删除某条 ACL
setfacl -x u:zhangsan /data/backend

# 清空所有 ACL
setfacl -b /data/backend

# 递归设置(目录+已有文件)
setfacl -R -m u:zhangsan:rx /data/backend/

# 默认 ACL(新建文件自动继承)
setfacl -d -m u:zhangsan:rx /data/backend/

2. mask:ACL 的天花板

bash 复制代码
# mask 限制了 ACL 能给的最大权限
setfacl -m u:zhangsan:rwx /data/backend
setfacl -m m::rx /data/backend    # 把 mask 设为 rx

getfacl /data/backend
# user:zhangsan:rwx          #effective:r-x   ← 实际只有 rx
# mask::r-x

# 改 mask 会影响所有 ACL 用户的实际权限,要小心

3. ACL 典型场景

场景:新人入职需要临时查看数据组目录

bash 复制代码
# 授权
setfacl -R -m u:newguy:rx /data/data/
setfacl -d -m u:newguy:rx /data/data/   # 新文件也继承

# 离职或权限到期,一键回收
setfacl -R -x u:newguy /data/data/

六、权限速查表

需求 命令
创建团队组 groupadd <组名>
创建用户并指定组 useradd -m -g <组> <用户>
用户加附加组 usermod -aG <组> <用户>
目录归属组 chown root:<组> <目录>
目录权限770 chmod 770 <目录>
SGID(新建文件继承组) chmod g+s <目录>
Sticky Bit(防删他人文件) chmod +t <目录>
组合 3770 chmod 3770 <目录>
ACL 授权 setfacl -m u:<用户>:<权限> <目录>
ACL 默认继承 setfacl -d -m u:<用户>:<权限> <目录>
ACL 查看 getfacl <目录>
ACL 删除 setfacl -x u:<用户> <目录>
查看 sudo 权限 sudo -lU <用户>
查看 sudo 日志 journalctl -t sudo --since "today"

七、总结

一句话总结: 多团队共用服务器,核心是"一组一目录、770+SGID+Sticky、sudo 按组收口、ACL 补位精细控制"。

落地清单:

  1. 每个团队建一个专用组(groupadd),用户主组对应团队
  2. 团队目录 chmod 3770(770 + SGID + Sticky Bit)
  3. 禁止 root SSH 直登,PermitRootLogin no
  4. sudo 按组授权(/etc/sudoers.d/ 按团队拆文件)
  5. 跨团队只读需求用 ACL(setfacl),不用附加组给读写
  6. 临时权限用 ACL + 默认继承,到期 setfacl -x 回收
  7. 定期审计:getfacl 检查目录权限、sudo -lU 检查 sudo 权限