其实对于Linux的文件权限一直一知半解, 之前使用php尝试访问sqlite的时候就发生了文件权限的惨案, 至今也不知道为什么会这样.. 当时的情况是, 将博客的public文件夹放置在服务器的/usr/share/nginx/html
下就会G, 哪怕对数据库文件+该文件所在的目录都设置了777权限后php还是无法访问该目录下的sqlite DB; 修改放置位置到/srv/http/
下就可以了, 而且不需要设置777, 设置为755即可.. 但是其实之前也考虑到文件权限等等, 因而将nginx和php-fpm的用户全部设置为了rqdmap, 而public文件的用户和组也全部都是rqdmap… 为何放到/srv
下就可以了呢… 疑案未决…
因而准备稍微系统看一下Linux的文件权限管理.
文件属性
从ls -l
这一条耳熟能详的指令开始, 可以看到8个字段:
1|----------|------|-------------|--------|--------|----------|------|
2| 文件类型 | 权限 | 目录/链接数 | 拥有者 | 用户组 | 文件大小 | 日期 |
3|----------|------|-------------|--------|--------|----------|------|
单独先提一下目录/链接数
是什么. 对于一个文件来说, 其表示该文件的硬链接数; 对于一个目录来说, 其表示一级子目录的数量(包含了.
和..
, 因而实际的子目录数量需要减去2)
比如按照如下的命令创建一个硬链接一个软链接, 会显示文件的连接数为2, 而符号链接文件仅为1:
1$ touch in
2$ ln in in_hard
3$ ln -s in in_soft
结果如下:
1$ ls -l
2total 0
3-rw-r--r-- 2 rqdmap rqdmap 0 Jan 1 13:18 in
4-rw-r--r-- 2 rqdmap rqdmap 0 Jan 1 13:18 in_hard
5lrwxrwxrwx 1 rqdmap rqdmap 2 Jan 1 13:18 in_soft -> in
另外在测试时也遇到一个有关shell指令的问题(需要参考
trash:取代危险的rm, shell的-e
无法判断一个失效的符号链接, 必须要单独用-L
才能判断. 也就是说:
-
当先用
trash
删除in_soft, 再删除in, OK. -
当先删除in, 再删除in_soft, 就不行了. 因为shell的
-e
无法判断该符号链接.
至于软硬连接就不多说了, 硬链接与源文件共享同一个inode, 而软连接文件有自己的inode, 只是其block内容为源文件的路径信息, 之前在xv6的lab中也做过实现.(虽然当时没有整理博客导致忘记的差不多了)
下面再介绍一下ln -l
的前两个字段.
文件类型
linux文件分为5个类型:
1|------|------|------------|--------------------|------------------------------|
2| d | - | l | b | c |
3|------|------|------------|--------------------|------------------------------|
4| 目录 | 文件 | 符号连接等 | 可供储存的接口设备 | 串行端口设备,如键盘、鼠标等 |
5|------|------|------------|--------------------|------------------------------|
权限信息
权限信息共有9个字符, 也是耳熟能详了. 拥有者, 用户组和其他人对应着读写执行三个权限.
shell命令
修改拥有者和用户组
使用chown
和chgrp
即可:
1# 修改文件拥有者
2$ chown [-R] 账号名称 文件或目录
3$ chown [-R] 账号名称:组名 文件或目录
4
5# 修改文件所属用户组
6$ chgrp [-R] 用户组名称 文件或目录
修改文件权限
使用chmod
修改文件权限:
-
使用数字来修改权限, 比较麻烦.
-
使用符号类型修改权限, 但是需要遵循一定的语法规则. 通过这3个符号结合即可设定一组权限, 设定之间可以通过逗号(不能有空格)分隔.
1|--------|--------|--------|----------|
2| u | g | o | a |
3|--------|--------|--------|----------|
4| 拥有者 | 用户组 | 其他人 | 所有用户 |
5|--------|--------|--------|----------|
6
7|----------|----------|----------|
8| + | - | = |
9|----------|----------|----------|
10| 添加权限 | 去除权限 | 设定权限 |
11|----------|----------|----------|
12
13|----|----|------|
14| r | w | x |
15|----|----|------|
16| 读 | 写 | 执行 |
17|----|----|------|
事实上可以通过setfacl
实现更精细的访问控制, 不过这里不予深究了.
权限的作用
这一点是比较重要的, 却一直不太清楚. 目录和文件的权限有所差别, 展示如下:
1|------|------------------|------------------|
2| 权限 | 文件 | 目录 |
3|------|------------------|------------------|
4| r | 可以读取文件内容 | 可以读取目录结构 |
5| w | 可以编辑文件内容 | 可以改动目录结构 |
6| x | 可以被系统执行 | 用户可以cd进目录 |
7|------|------------------|------------------|
附加权限
Linux除了正常的rwx权限外, 还有一类附加权限: SET位权限(suid与sgid)以及粘滞位权限(sticky).
SET位权限s
set位权限(suid、sgid)是为了使“没有取得特权用户要完成一项必须要有特权才可以执行的任务”而产生的, 一般用于给可执行的文件设置. 设置了suid后, 任意用户执行文件时, 将获得该文件owner的身份; 设置了sgid后, 任意用户执行文件时, 将获得该文件group的身份.
例如:passwd命令就使用了suid, 用户执行passwd命令时, 以root用户的身份执行.
1-rwsr-xr-x 1 root root 51544 Nov 10 16:03 /usr/bin/passwd
SET位会体现在所有者或用户组的可执行位上.
通过以下的命令设置/去除SUID位或SGID位:
1chmod u+s filename # 设置SUID位
2chmod u-s filename # 去除SUID位
3chmod g+s filename # 设置SGID位
4chmod g-s filename # 去除SGID位
Sticky位权限t
第一次接触该权限是在网络实验的ftp服务器上?… 粘滞位权限一般用于目录. 目录设置了粘滞位权限后, 即使用户拥有对该目录的写权限, 也不可以删除目录下其他用户的文件. 例如:linux的/tmp目录就设置了粘滞位权限.
1drwxrwxrwt 12 root root 420 Jan 1 14:07 tmp
粘滞位体现了其他用户的可执行位上. 如果设置了粘滞位却没有可执行权限, 则粘滞位会表现为T而不是t.
通过chmod位目录设置或删除粘滞位:
1chmod +t directory
2chmod -t directory