黄鼠博客

Linux 权限管理的一些麻烦

2018-12-03

Linux权限管理的一些麻烦

sudo chmod -R 666 / 你真的了解linux权限管理吗 ?

  • 本文仅仅是罗列一些问题和麻烦,并没有深入分析一些问题,笔者暂时没有分析Linux代码的精力,如果你对文中提到的问题有更好的想法,欢迎留言
  • 本文在ubuntu上测试

问题

Q1: read write excute 权限对于文件文件夹分别意味着什么?文件夹的可执行权限是什么意思

Q2: 为什么other权限为0的文件还是被人重命名了?甚至被人删除了?

Q3: 根目录下这个tmp文件夹这个 t 是什么权限?
​ drwxrwxrwt 7115 root root 262144 Dec 2 22:28 tmp/

Q4: 这里原本应该是x, 这个s代表什么?有什么作用?
​ -rwsr-xr-x 1 root root 54256 May 17 2017 /usr/bin/passwd*

基础

  • 如果你不知道 drwxrwxrwx 表示权限777的文件夹
  • 如果你不知道 -rw-rw-r-- 表示权限664的普通文件
  • 如果你不知道第一个位置 l 代表链接文件,c代表character设备, p代表管道….
  • 如果你不知道这三个数字与 owner, group, other 权限的关联
  • 如果你不知道为什么需要权限管理
  • 如果你不知道修改权限并不能修改文件的拥有者(chown)

请,先查阅资料,本文假设这些你都知道: )

传统unix 权限管理系统

  • 对于文件
    r: 读文件内容 w:写文件内容 x: 执行文件
  • 对于文件夹
    r: 读文件夹中文件/文件夹的名字
    x: 搜索/访问权限,访问文件夹中的文件/文件夹
    w: 创建 、删除、遍历(如cd)、移动子文件/文件夹

看起来很简单,其实有很多坑,文件夹的x权限定义其实并不明确,我只观察到现象,但不是很明白原因。

正常的文件夹都有x权限

正常的文件夹都有x权限,如果你不想给你个文件夹x权限,绝大多数情况下你不需要给另外两种权限。例如,你不想让某个文件夹被访问,r=0,w=0,x=0就好

下面会讨论没有x权限的文件夹,却设置了r,w造成的奇怪现象

没有x的文件夹,w没有意义

搜索/访问权限被认为是创建、删除、遍历、移动的基础。没有x权限,w权限给定的一切都无从谈起。而且这样的文件夹它的子文件/文件夹的权限也没有意义,因为它们都不能被访问,管它有什么权限都无济于事。

(下面ls 一大堆问号不是编码错误,而是没有x权限导致无法访问到子文件/文件夹的meta-info)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
$ chmod 600 test
$ ll test
ls: cannot access 'test/b': Permission denied
ls: cannot access 'test/..': Permission denied
ls: cannot access 'test/m': Permission denied
ls: cannot access 'test/c2': Permission denied
ls: cannot access 'test/.': Permission denied
total 0
d????????? ? ? ? ? ? ./
d????????? ? ? ? ? ? ../
-????????? ? ? ? ? ? b
-????????? ? ? ? ? ? c2
d????????? ? ? ? ? ? m/
$ rm -f test/b
rm: cannot remove 'test/b': Permission denied
$ mv test/b test/c
mv: failed to access 'test/c': Permission denied

因此,不同于文件如果你想的是给一个文件夹开放所有读和写的权限,chmod 666 是不对的,而应该chomd 777

如果你一不小心sudo chmod -R 666 / 这将带来巨大的权限问题,没有x权限,所有非root运行的程序都因不能访问而无法执行…

没有x的文件夹,r有意义

1
2
3
4
5
6
7
8
9
10
11
12
$ ll test
ls: cannot access 'test/b': Permission denied
ls: cannot access 'test/..': Permission denied
ls: cannot access 'test/m': Permission denied
ls: cannot access 'test/c2': Permission denied
ls: cannot access 'test/.': Permission denied
total 0
d????????? ? ? ? ? ? ./
d????????? ? ? ? ? ? ../
-????????? ? ? ? ? ? b
-????????? ? ? ? ? ? c2
d????????? ? ? ? ? ? m/

没有x的文件夹,w无意义,但r却是有意义的。如以上所示,这样的文件夹能读到子文件/文件夹的名字,但仅限于此。更多的信息都不能读到(meta-info ,创建时间,权限、所有者等等)

有x没有r的文件夹,权限很高

你可能认为不给文件夹读的权限,ls都看不了,其它操作肯定也是寸步难行。但其实不是这样的, 拥有wx权限的文件夹几乎拥有所有权限

这样的文件夹,仅仅是不能读到目录中名字,如果你知道你要访问对象的名字,一切操作正常, 图谋不轨的人若想知道这个文件夹下的所有文件是可以爆破得到的。

1
2
3
4
5
6
7
8
9
10
11
12
13
$ chmod 100 test
$ cd test
$ pwd
/home/ubuntu/test
$ ls
ls: cannot open directory '.': Permission denied
$ ls a
-rwxrwxrwx 1 ubuntu ubuntu 0 Dec 2 23:46 a* ### 虽然没有r权限,但是指定名字后任然能读到它的所有信息
$ cat a
## 下面这两个还需要写权限 chmod 300
$ mv b a
$ cp a b

移动/重命名/删除/创建文件是上一级文件夹的权限

如果上一级文件夹有w和x权限,你自己的文件什么权限都没有,仍然可以被移动/重命名/删除

所以,即使你给other用户关闭了w权限(例如 chmod 700), other用户虽然不能修改你文件的内容,但却可以把它删掉,甚至是替换成另一个同名的文件。如果在你的发布的应用中没有注意这一点,将带来极大的安全隐患。

1
2
3
4
5
6
$ chmod 700 .
$ chmod 000 a
$ ls -l .
drwx------ 3 ubuntu ubuntu 4096 Dec 3 00:11 ./
drwxr-xr-x 23 ubuntu ubuntu 4096 Dec 2 23:46 ../
---------- 1 ubuntu ubuntu 0 Dec 2 23:46 a

对应地,拥有一个文件的所有权限,但如果上级文件夹没有wx权限(例如仅有rx),你任然无法对它重命名/移动/删除

1
2
3
4
5
$ chmod 500 test
$ cd test
$ chmod 777 b
$ rm -f b
rm: cannot remove 'b': Permission denied

这种情况时有发生,如果你不了解这个机制就会给你带来困惑。如果别的用户让你在他的目录下操作一个文件,他把这个文件全部权限都给你,chmod 777 ,甚至把owner 转移给你,你发现你还是不能对这个文件进行重命名/移动/删除,他没有考虑到外面那个文件夹在默认创建时的权限是775, 没有w权限。

默认权限

  • 在你创建(touch, mkdir 等),cp (不管它原来文件的权限怎么样),文件默认权限 664 文件夹默认权限 775
  • 不管cp前文件拥有者是谁,cp后的文件属于你
  • gcc 编译生成的可执行文件权限是775, 其它用户可执行,但不能修改

root

root用户拥有所有权限,哪怕它的权限是000。root 就是这么厉害,不要轻易使用root用户

更复杂的细粒度权限管理

sticky bit

根目录下这个tmp文件夹这个 t 是什么权限?

1
2
ll -d /tmp
drwxrwxrwt 7115 root root 262144 Dec 3 11:55 /tmp/

/tmp 文件夹是一个允许所有用户在其中存放临时文件的目录。它允许随意添加,删除,修改,移动自己创建的文件,但是不能动别人的东西,仅用rwx权限管理系统做不到这一点,它不能做到用户级的区分,只能粗略地区分owner、group、other。

这种共享的文件夹其实还是很实用的,你可能需要在多人共享的服务器上建立一个共享资源的文件夹,777的权限显然是不可取的,我们并不希望别人删除自己放的东西,这个时候你就需要sticky bit了

设置方法很简单:chmod 1777 xxxx,然后ls -l 可以看到权限最后一个x变为了t

需要注意的是在linux中,t权限对文件夹有效,对文件无意义

setuid

如果让一个程序在运行时拥有owner的权限呢? 甚至是root的权限呢?

例如sudo和passwd 这两个程序,执行它们显然需要root权限,我们可以看到它们都被设置了setuid

1
2
3
4
$ ll /usr/bin/sudo
-rwsr-xr-x 1 root root 136808 Jul 4 2017 /usr/bin/sudo*
ll /usr/bin/passwd
-rwsr-xr-x 1 root root 54256 May 17 2017 /usr/bin/passwd*

那,怎么给我们自己的程序设置setuid标记呢:

1
2
3
4
chmod u+x
chmod 4775
###设置过后原来的x会变为s
-rwsr-xr-x

除此之外还有setgid,它和setuid 类似,只不过是让程序运行时拥有group的权限。

这里需要注意的是如果文件没有可执行权限,setuid 和setgid 标记是没用的,s 会显示为S。

小结

传统的unix权限管理其实有很多的缺陷,不能细粒度地指定权限,不能指定某个用户对某个文件有哪些权限。这一套机制只能说基本够用,如果你有更复杂的权限管理需要,ACL对你可能有用。

参考文献

[1] Wikipedia, https://en.wikipedia.org/wiki/File_system_permissions#Traditional_Unix_permissions

Tags: 技术
使用支付宝打赏
使用微信打赏

喜欢这篇文章,可以小小地打个赏~