第21章 其他文件系统
附录 D. OpenPGP 密钥
3.4.权限
在 FreeBSD 中,每个文件和目录都有一组相关的权限,有几个工具可以用来查看和修改这些权限。为了确保用户能够访问他们需要的文件,并且不能非法访问操作系统使用的或其他用户拥有的文件,了解权限的工作方式是必要的。
这一节讨论了 FreeBSD 中使用的传统 UNIX® 权限。对于更细化的文件系统访问控制,请参考“访问控制列表”。
在 UNIX® 中,基本权限是用三种访问类型分配的:读、写和执行。这些访问类型用于确定文件所有者、组和其他人(其他所有人)对文件的访问。读、写和执行权限可以用字母rwx表示,也可以用二进制数字表示,因为每个权限都是开或关(0)。当用数字表示时,顺序总是读作rwx,其中r的开启值为4w的开启值为2x的开启值为1
表 4.1 总结了可能的数字和字母的可能性。在阅读“目录列表”一栏时,-被用来代表一个被设置为关闭的权限。
表 2. UNIX® 权限
权限
参数
0
不可读,不可写,不可执行
---
1
不可读,不可写,可执行
--x
2
不可读、可写、不可执行
-w-
3
不可读、可写、可执行
-wx
4
可以读,不可写,不可执行
r--
5
可读,不可写,可执行
r-x
6
可读、可写,不可执行
rw-
7
可读、可写、可执行
rwx
使用ls(1)的-l参数可以查看一个长的目录列表,其中包括一列关于文件的所有者、组和其他人的权限的信息。例如,在一个任意的目录中,ls -l可能显示:
1
% ls -l
2
total 530
3
-rw-r--r-- 1 root wheel 512 Sep 5 12:31 myfile
4
-rw-r--r-- 1 root wheel 512 Sep 5 12:31 otherfile
5
-rw-r--r-- 1 root wheel 7680 Sep 5 12:31 email.txt
Copied!
第一列中的第一个(最左边)字符表示这个文件是一个普通文件、一个目录、一个特殊字符设备、一个套接字或任何其他特殊的伪文件设备。在这个例子中,-表示一个普通文件。接下来的三个字符,即本例中的rw-,给出了文件所有者的权限。接下来的三个字符,r--,给出了文件所属组的权限。最后三个字符,r--,给世界其他地方的人以权限。一个破折号意味着该权限被关闭。在这个例子中,权限被设置为所有者可以读写文件,组可以读取文件,而世界上的其他人只能读取文件。根据上表,这个文件的权限是644,其中每个数字代表文件权限的三个部分。
系统是如何控制设备的权限的?FreeBSD 将大多数硬件设备视为一个程序可以打开、读取和写入数据的文件。这些特殊的设备文件被存放在/dev/
目录也被当作文件对待。它们有读、写和执行的权限。目录的可执行位与文件的意义略有不同。当一个目录被标记为可执行时,它意味着可以使用cd(1)改变到该目录。这也意味着可以访问该目录中的文件,但要取决于文件本身的权限。
为了执行目录列表,必须在目录上设置读取权限。为了删除一个知道名字的文件,必须对包含该文件的目录有写和执行的权限。
还有更多的权限位,但它们主要是在特殊情况下使用,如setuid二进制文件和粘性目录。关于文件权限的更多信息以及如何设置它们,请参考chmod(1)。

3.4.1. 符号化的权限

符号权限使用字符而不是八进制值来给文件或目录分配权限。符号权限使用的语法是(who)(action)(permissions),其中有下列数值。
选项
参数
意义
(who)
u
用户
(who)
g
(who)
o
其他
(who)
a
All (“所有”)
(action)
+
增加权限
(action)
-
移除权限
(action)
=
显式设置权限
(permissions)
r
(permissions)
w
(permissions)
x
执行
(permissions)
t
黏滞位
(permissions)
s
设置 UID 或 GID
这些值与chmod(1)一起使用,但用字母而不是数字。例如,下面的命令可以阻止其他用户访问FILE
1
% chmod go= FILE
Copied!
当必须对一个文件进行多组修改时,可以提供一个逗号分隔的列表。例如,下面的命令删除了FILE上的组和world的写入权限,并为每个人增加了执行权限:
1
% chmod go-w,a+x FILE
Copied!

3.4.2.FreeBSD 的文件标志

除了文件权限之外,FreeBSD 还支持使用“文件标志”。这些标志为文件,但不是目录,增加了额外的安全和控制水平。通过文件标志,甚至可以阻止 root 删除或更改文件。
文件标志是用chflags(1)修改的。例如,要在文件file1上启用系统不可删除的标志,发出以下命令:
1
# chflags sunlink file1
Copied!
要禁用系统不可删除标志,请在sunlink前面加一个no
1
# chflags nosunlink file1
Copied!
要查看一个文件的标志,可以使用ls(1)中的-l
1
# ls -lo file1
Copied!
1
-rw-r-r-- 1 trhodes trhodes sunlnk 0 Mar 1 05:54 file1
Copied!
一些文件标志只能由 root 用户添加或删除。在其他情况下,文件所有者可以设置其文件标志。更多信息请参考chflags(1)和chflags(2)。

3.4.3. setuid、setgid 和 sticky 权限

除了已经讨论过的权限之外,所有管理员都应该知道还有三个特定的设置:它们是setuidsetgidsticky权限。
这些设置对某些 UNIX® 操作很重要,因为它们提供了通常不授予普通用户的功能。为了理解它们,必须注意真实用户 ID 和有效用户 ID 之间的区别。
真正的用户 ID 是拥有或启动该进程的 UID。有效 UID 是进程运行的用户 ID。举个例子,当用户修改密码时,passwd(1)以真实用户 ID 运行。然而,为了更新密码数据库,该命令以根用户的有效 ID 运行。这使得用户在修改密码时不会看到“拒绝许可”的错误。
setuid权限可以通过在权限集前加上数字四(4)来设置,如下例所示:
1
# chmod 4755 suidexample.sh
Copied!
suidexample.sh 的权限现在看起来如下:
1
-rwsr-xr-x 1 trhodes trhodes 63 Aug 29 06:36 suidexample.sh
Copied!
请注意,s现在是为文件所有者指定的权限集的一部分,取代了可执行位。他允许实用程序提高权限,如passwd(1)。
注意: **nosuid mount(8)选项将导致这种二进制文件默默地失败而不提醒用户。这个选项并不完全可靠,因为nosuid包装器可能会规避它。
要实时查看这个,请打开两个终端。在一个终端上,以普通用户的身份输入passwd。在它等待新密码的时候,检查进程表并查看passwd(1)的用户信息。
在终端A:
1
Changing local password for trhodes
Copied!
Old Password:
1
Copied!
在终端B:
1
# ps aux | grep passwd
Copied!
1
trhodes 5232 0.0 0.2 3420 1608 0 R+ 2:10AM 0:00.00 grep passwd
2
root 5211 0.0 0.2 3620 1724 2 I+ 2:09AM 0:00.01 passwd
Copied!
尽管passwd(1)是以普通用户的身份运行的,但它使用的是有效 UID,即root
setgid权限的功能与setuid权限的功能相同;只是它改变了组的设置。当一个应用程序或实用程序以这种设置执行时,它将被授予基于拥有文件的组的权限,而不是启动该进程的用户。
要在一个文件上设置setgid权限,请为chmod(1)提供前导 two(2):
1
# chmod 2755 sgidexample.sh
Copied!
在下面的列表中,注意到s现在是在指定给组权限设置的区域:
1
-rwxr-sr-x 1 trhodes trhodes 44 Aug 31 01:49 sgidexample.sh
Copied!
注意: 在这些例子中,即使有关的 shell 脚本是一个可执行文件,它也不会以不同的 EUID 或有效用户 ID 运行。这是因为 shell 脚本不能访问 setuid(2) 系统调用。
setuidsetgid权限位可能会降低系统的安全性,因为允许提升权限。第三个特殊权限,粘性位,可以加强系统的安全性。
当一个目录上的粘性位被设置时,它只允许文件所有者删除文件。这对于防止不拥有文件的用户在公共目录(如/tmp)中删除文件很有用。要利用这个权限,请在权限设置前加一个1(1)
1
# chmod 1777 /tmp
Copied!
粘性位权限将在权限集的最末端显示为t
1
# ls -al / | grep tmp
Copied!
1
drwxrwxrwt 10 root wheel 512 Aug 31 01:49 tmp
Copied!