记一次 Linux “多人等权”共享目录的问题及解决
记一次 Linux “多人等权”共享目录的问题及解决
在实验室公用 Linux 服务器的多用户环境下,经常需要一个由多人平行读写执行的共享目录;兼顾可维护与最小化权限暴露。但遇到一些问题,探索后发现与 umask、sgid、目录可穿越 (x)、ACL继承都有关,暴露出自己在 Linux 运维功底方面的缺陷。特此记录,以供参考。
问题介绍
服务器:Linux(Debian 系)
需求:
/proj/shared下由多位成员协同读写代码与数据现状:已创建用户组
projgrp,将成员 A、B 都加入了该组问题现象:
- 成员 A 能在
/proj/shared写入,但成员 B 无法修改 A 创建的文件 - A 在
/proj/shared创建的新文件属组落在自己的主组,而不是projgrp - 成员 B 登录后
cd /home/A/.../shared报“权限不够”
- 成员 A 能在
经过研究,发现这些现象背后牵涉 目录执行位(x)、umask、SGID、ACL 以及 登录会话的组缓存 等机制。逐个解决后完成了需求,特此记录,以便有类似需求的读者参考。
知识回顾
umask:仅影响新建文件/目录的权限位(如
rw-rw-r--),并不决定属组归属。- 常用:
umask 0002→ 新文件664,新目录775
- 常用:
目录执行位(x):对目录意味着“可穿越”。路径上的每一层目录都需要对访问者有
x,才能cd进去。SGID(setgid):目录位设置
g+s后,新建子目录一定继承父目录组;新建文件在多数本地文件系统上也会继承父目录组(更标准做法是配合 ACL 保证)。ACL(访问控制列表):
setfacl -m ...设置访问 ACL(立即作用于当前对象)setfacl -d -m ...设置默认 ACL(仅对将来新建的内容生效)mask条目会裁剪“命名用户/组”的有效权限(常见坑点)
根因剖析
路径上某层目录缺少执行位
x
例:成员 B 需要穿越/home/A才能进入共享子目录,若/home/A对组没有x,即使目标目录权限正确也进不去。仅设置了组与权限,未设置 SGID
结果:在共享目录中新建的文件仍归属用户的主组,而非协作组。只在顶层目录设置了默认 ACL,子目录未继承
结果:深层子目录中新建的文件不带默认 ACL,仍不可写。ACL 的
mask把有效权限裁剪掉
看到#effective: r--/rw-等提示,说明默认/访问 ACL 被mask限制。用户会话未刷新组列表
刚把用户加入协作组,当前 TTY/SSH 会话仍在用旧组缓存;需要重新登录或用newgrp。文件系统或挂载选项未启用 ACL
某些发行版或挂载方式需要显式acl选项。
解决方案
1) 组与顶层权限初始化
1 | # 创建协作组 |
2775的2即 SGID;s确保目录树中的新建内容倾向继承协作组。
2) 仅允许“穿越”上层私有目录
若共享目录位于某个私有家目录下(如 /home/userA/shared),给协作组一个最小的穿越权限:
1 | # 仅允许组穿越(不可列目录),保护家目录隐私 |
不用把
/home/userA改成 755;--x足以穿过而看不到其他文件。
3) 递归设置 SGID + 访问 ACL + 默认 ACL
关键:对子目录也必须生效,因此做递归设置:
1 | DIR=/proj/shared |
m::rwx是 ACL 的 mask,不放开会“剪掉”有效权限,导致组写权限实测无效。
4) 成员 umask 设置
协作成员的 umask 设为 0002(常见 shell 的 ~/.zshrc、~/.bashrc):
1 | umask 0002 |
这确保新建文件是
664,目录是775,符合“组可写”的协作预期。
注意:umask 不控制属组;属组继承依赖 SGID/ACL。
5) 刷新用户会话的组上下文
将成员加入协作组后,需要重新登录或临时执行:
1 | newgrp projgrp |
newgrp会以该组为有效组启动一个子 shell,退出即可回到原会话。
验证
顶层目录必须具备 s 权限位
1 | ls -ld /proj/shared |
ACL 应包含默认与 mask
1 | getfacl /proj/shared |
新建文件/目录测试
1 | # 模拟成员 B 的新会话测试 |
总结
| 现象 | 排查点 | 处理 |
|---|---|---|
cd 报权限不够 |
路径某层目录缺 x |
给协作组添加最小穿越 ACL:setfacl -m g:projgrp:--x /path/that/blocks |
| 新文件属组不是协作组 | 目录/子目录没 SGID | 递归:find DIR -type d -exec chmod g+s {} + |
| 组无写权限(但 ACL 好像给了) | mask 裁剪了有效权限 |
同时设置 m::rwx:访问与默认 ACL 都要设 |
| 只在顶层有效,子目录无效 | 只在顶层设了默认 ACL | 用 -R 递归设置访问与默认 ACL |
| 成员刚加组仍不生效 | 会话组缓存 | 重登录或 newgrp projgrp |
| ACL 设置后无效果 | 文件系统未启用 ACL | mount 检查;/etc/fstab 增加 acl,重挂载 |
在多人协作的公用服务器上,实现“等权共享目录”并不复杂,但需要系统性处理:
- 路径可穿越(x)
- SGID 保证组继承
- ACL(含 mask)保证权限一致性
- umask 做默认位的兜底
- 会话刷新确保新组即时生效
记一次 Linux “多人等权”共享目录的问题及解决