最近遇到一个比较搞的问题,有关 linux 下的文件权限。因为发现解决问题之后的答案是我们很多工作多年的攻城狮以前都没有重视过的,所以特别写下来,帮助加深记忆。

【背景】

同事学习 lnmp,搭好 CentOS 6.5 的环境之后,新建了一个用户组 test,在该组别下新建了一个用户 test,然后准备用这个用户模拟 nginxphp-fpm 进程的启动用户,跟着手册上做实践。

【关键信息】

  • 用户:test:test
  • 目录:/www/test
  • 目录权限:drwxrwxrwx. 2 root root 40 Oct 21 16:43 test
  • 文件:/www/test/index.html
  • 文件权限:-rw-r--r--. 1 root root 0 Oct 22 10:04 index.html

【现象】

  1. 先用 root 的身份 touch 了一个空文件 index.html
  2. su test,然后以 test 用户的身份去删除这个空文件;
  3. WTF!!! 竟然删除文件成功了???!!!

普通用户删除了 root 用户的文件,我保证,刚看到这个现象的时候,我内心绝对是崩溃的。

【解决的途径】

首先,检查了 test 用户的用户组,确认的确是 test 组。

其次,检查文件和目录的权限,除了 test 目录没有按照惯例,被设置成 0777 之外,没有什么特别的。不可能一个 0777 还能捣蛋吧?!

再次,visudo 命令检查有没有给 test 做高规格的授权。结论是:否。默认配置,没有可疑的配置。

接下来检查 rm 命令有没有被动过手脚。考虑到这是一台从 min 发行版正常安装起来的测试机,到这里我觉得已经有点儿过了。不过没关系,面对系统『问题』,谨慎一些总是好的。

之后又检查了 uidgid,确保 test:test 没有占用一些有特殊作用的保留 id。

最后,还找不到问题,已经过去了半个多小时。猛然想起什么,试了一下除开 test 的其它用户,发现都能重现这个问题。至此发现问题的源头不在 test 这个用户身上。

【答案】

发现源头不在 test 用户身上之后,就走上了正路。如果不是用户或者用户组本身拥有超级权限,那么多半的多半,是权限本身的设计问题。

按经验,对客观存在的东西,不是 bug,就是一个 feature

于是开始谷歌 Linux 文件权限相关的手册,终于终于找到了鸟哥 Linux 私房菜——第六章、Linux 的文件权限及目录配置(很奇怪,鸟哥的文档以简体形式放在宝岛学校的官网上),以及 Sticky bit 的维基页。算是为这件事情做了一个注解。

鸟哥说:

  • 权限对目录的重要性
    • r (read contents in directory): ……
    • w (modify contents of directory): 这个可写入的权限对目录来说,是很了不起的! 因为他表示你具有异动该目录结构列表的权限,也就是底下这些权限:
      • 建立新的文件与目录;
      • 删除已经存在的文件与目录(不论该文件的权限为何!)
      • 将已存在的文件或目录进行更名;
      • 搬移该目录内的文件、目录位置。 总之,目录的w权限就与该目录底下的文件名异动有关就对了啦!
    • x (access directory): ……

维基说:

… When a directory’s sticky bit is set, the filesystem treats the files in such directories in a special way so only the file’s owner, the directory’s owner, or root can rename or delete the file. Without the sticky bit set, any user with write and execute permissions for the directory can rename or delete contained files, regardless of the file’s owner.

【解决办法】

  1. 一定不要给多余的权限。这件事要养成习惯!任何可能接触到系统的人都要培养出来。
  2. 对于共用目录,一定要对这个目录激活 sticky bit。比如 /tmp 目录就默认激活了 sticky bit 的,这样大家共用这个目录也不会混乱。
  3. sticky bit 的限制不能继承,也就是说只对激活了 sticky bit 的当前目录有用。