D6:学习Shell之六
权限
本章涉及的命令有:
- id —— 显示用户ID(identity)
- chmod —— 更改文件的模式
- umask —— 设置默认的文件权限
- su —— 以其他用户的身份运行shell
- sudo —— 以其他用户的身份执行一个命令
- chown —— 更改文件的所有者
- chgrp —— 更改文件的群组所有权
- passwd —— 更改一个用户的密码
目录
所有者、群组成员和其他所有人
当我们要查看某些文件(例如/etc/shadow)时,可能会遇到一些问题:
[me@linuxbox ~]$ file /etc/shadow
/etc/shadow: regular file, no read permission
[me@linuxbox ~]$ less /etc/shadow
/etc/shadow: Permission denied
这是由于普通用户没有读取此文件的权限。
使用以下命令可以查看当前用户的身份信息:
[me@linuxbox ~]$ id
udi=500(me) gid=500(me) groups=500(me),24(cdrom),25(floppy)
当创建用户账户时,系统会为用户分配一个名为user ID(uid)的号码,为了便于阅读,该号码会映射到一个用户名。
同时,系统会为该用户分配一个primary group ID(gid),并可以属于其他组。
groups是该用户同时属于的组,以逗号分隔各个组。
每种系统内建的组和组ID可能都不同。比如在FreeBSD中,没有root组,debian有root组,其gid为0;FreeBSD中mail组的gid是6,而debian中mail组的gid是8
FreeBSD中新建的用户,其uid和gid从1001开始,而debian从1000开始
每种系统里的用户所属的组会有不同,跟系统管理设备和服务权限的方式有关
在类Unix系统中,用户账户在/etc/passwd文件中定义,组在/etc/group文件中定义,保存用户密码信息的文件为/etc/shadow。
/etc/passwd文件中定义用户登录名称、uid、gid、账户的真实姓名、主目录和登录shell。
现代的类Unix系统通常会为用户创建一个同名的唯一、单一成员组,便于权限分配。
读、写、运行
对文件和目录的访问权限定义为读访问、写访问、运行访问。
使用ls -l命令列出文件时,第一段(前10个字符)表示文件属性(file attributes)。而第一个字符表示文件类型(file type)。下表列出各文件类型的说明:
属性 |
文件类型 |
- |
普通文件 |
d |
目录 |
l |
符号链接
需要注意,对于符号链接,其余的文件属性始终是"rwxrwxrwx",并且为伪值(dummy values)。真正的文件属性是符号链接指向的文件的属性。 |
c |
字符特殊文件(character special file) 此类文件类型指的是以字节流形式处理数据的设备,类如终端或/dev/null |
b |
特殊的文件块(block special file) 此类文件类型指的是以块形式处理数据的设备,例如硬盘驱动器或DVD驱动器 |
文件属性的其余9个字符称为文件模式(file mode),代表文件所有者、文件组所有者和其他所有人的读(r)、写(w)、运行(x)权限。下表说明权限属性:
属性 |
文件 |
目录 |
r |
允许打开并读取其中内容 |
如果还设置了运行(x)属性,则允许列出目录中的内容 |
w |
允许写入或截断文件,但此属性不允许重命名或删除文件。 删除或重命名文件的权限由目录属性决定。 |
如果还设置了运行(x)属性,则允许创建、删除和重命名目录中的文件。 |
x |
允许将文件作为程序处理并执行。 用脚本语言编写的程序文件也必须设置为可读(r)才能执行。 |
允许进入此目录,比如,cd directory |
下表是一些示例:
文件属性 |
含义 |
-rwx------ |
常规文件,文件所有者可读、可写、可运行;其他人不能访问。 |
-rw------- |
常规文件,文件所有者可读、可写;其他人不能访问。 |
-rw-r--r-- |
常规文件,文件所有者可读、可写;文件所有者组成员可读;文件是全世界可读(world-readable)。 |
-rwxr-xr-x |
常规文件,文件所有者可读、可写、可运行;所有人可读、可运行 |
-rw-rw---- |
常规文件,只有文件所有者和文件所有者组成员可读、可写。 |
lrwxrwxrwx |
符号链接,所有符号链接的权限都是虚拟的(dummy) |
drwxrwx--- |
目录,所有者和所有者组成员可以进入该目录,并在目录中创建、重命名、删除文件 |
drwxr-x--- |
目录,所有者可以进入该目录,并在目录中创建、重命名、删除文件;所有者组成员可以进入该目录,但不能创建、重命名、删除文件 |
chmod —— 更改文件模式
使用chmod命令可以更改文件或目录的模式(权限)。
只有文件所有者或超级用户才能更改文件或目录的模式。
chmod支持两种不同方式来指定模式更改:八进制(octal)数表示法或符号表示法。
下表是文件模式的八进制、二进制对应关系:
文件模式 |
八进制 |
二进制 |
--- |
0 |
000 |
--x |
1 |
001 |
-w- |
2 |
010 |
-wx |
3 |
011 |
r-- |
4 |
100 |
r-x |
5 |
101 |
rw- |
6 |
110 |
rwx |
7 |
111 |
使用三位八进制数,可以为所有者、组所有者和所有人设置文件模式。
[me@linuxbox ~]$ > foo.txt
[me@linuxbox ~]$ ls -l foo.txt
-rw-rw-r-- 1 me me 0 2016-03-06 14:52 foo.txt
[me@linuxbox ~]$ chmod 600 foo.txt
[me@linuxbox ~]$ ls -l foo.txt
-rw------- 1 me me 0 2016-03-06 14:52 foo.txt
通过传递参数“600”,可以设置所有者的读写权限,同时删除组所有者和其他人的所有权限。
通常使用的映射有:7(rwx)、6(rw-)、5(r-x)、4(r--)、0(---)。
chomd还支持用于指定文件模式的符号标记(symbolic notation)。符号标记分为三部分:
符号标记使用四个字符来表示谁会受影响:
符号 |
含义 |
u |
“user”的简写,但是表示文件或目录的所有者 |
g |
组所有者 |
o |
“other”的简写,但表示所有人 |
a |
“all”的简写,是以上所有的“u”、“g”、“o” |
如果未指定任何字符,则假定为“all”。
该操作可以用一个“+”表示添加权限、一个“-”表示删除权限,或者一个“=”表示只应用指定的权限,并删除其他权限。
符号标记模式设置权限,由“r”、“w”、“x”来表示,下表为示例:
标记 |
含义 |
u+x |
为所有者添加运行权限 |
u-x |
删除所有者的运行权限 |
+x |
为所有人添加运行权限,相当于a+x |
o-rw |
从所有者和组所有者之外的任何人删除读写权限 |
go=rw |
设置组所有者和其他人读写权限,且删除他们的其他权限 |
u+x,go=rx |
为所有者添加运行权限,并设置组所有者和其他人读和运行权限。逗号分隔多个设置 |
符号标记可以设置单个属性,而不干扰其他任何属性。
有些系统提供了图形界面的方式设置文件或目录的属性,此处略。
umask —— 设置默认权限
umask命令控制新建文件时赋予它的默认权限。它使用八进制表示法来表示模式属性中删除的位掩码。
对于FreeBSD和debian,默认的掩码为22(FreeBSD为22,debian为0022)。
掩码与文件模式的对应关系:
初始文件模式 |
--- rw- rw- rw- |
掩码(以22为例) |
000 000 010 010 |
结果 |
--- rw- r-- r-- |
可以看到,当掩码出现1的时候,结果中的一个属性被删除了。
(发行版默认的umaks值一般就可以了,只在需要高度安全的时候才需要特别控制它。)
特殊权限
通常使用三位八进制数来控制权限,但从技术上讲,应该是四位八进制数。因为除了读、写、运行权限外,还有一些使用较少的权限设置。
第一个是setuid位(八进制4000)。当应用于可执行文件时,它会将实际用户(实际运行程序的用户)的有效用户ID(effective user ID)设置为程序所有者的有效用户ID。
当普通用户运行“setuid root”程序时,该程序以超级用户的有效权限运行。这允许程序访问普通用户通常无法访问的文件和目录。显然,这会带来安全问题,所以setuid程序的数量必须保持在绝对最小。
第二个使用较少的设置时setgid位(八进制的2000),它与setuid位一样,将有效组ID从实际用户的实际组ID更改为文件所有者的组ID。
当公共组成员需要访问目录中的所有文件时,无论文件所有者的主组是什么。这在共享目录中很有用。
第三个称为stick位(八进制的1000)。粘性位。可以将可执行文件标记为“不可交换”(not swappable)。对于文件,Linux会忽略粘性位,对于目录,它会阻止用户删除或重命名文件,除非用户是目录所有者、文件所有者或超级用户。
用法示例:
chmod u+s program为程序分配setuid。文件的属性为 -rwsr-xr-x
chmod g+s dir为目录分配setgid。目录的属性为 drwxrwsr-x
chmod +t dir为目录分配stick位。目录的属性为 drwxrwxrwt
更改ID
有以下三种方法可以使用替代身份:
- 注销当前账户并用另外的账户登录
- 使用su命令
- 使用sudo命令
su —— 使用替换用户和组ID运行shell
su命令用于使用其他用户启动shell。使用格式为:
su [-[l] [user]
如果包含-l选项(可缩写成-),则生成的shell会话是指定用户的登录shell。这意味着将加载用户的环境,并将工作目录更改为用户的主目录。
如果不使用-l选项,将无法执行一些超级用户常用的命令,比如reboot等。
如果未指定用户,则假定为超级用户。
使用exit命令退出当前用户shell。
也可以执行单个命令,比如:
su -l -c 'reboot'
使用以上方式可以将命令传递给新shell执行。将命令用引号(单引号或双引号都可以)括起来很重要,以避免在当前shell中扩展。
但在FreeBSD下运行以上命令时会收到提示:su: only root may use -c
sudo —— 像其他用户一样运行命令
sudo命令在很多方面与su类似,管理员可以将sudo配置为允许普通用户以不同用户(通常是超级用户)的身份以受控的方式执行命令。
另一个重要的区别是,使用sudo不需要提供超级用户的密码,而是使用该用户自己的密码。
sudo不会启动新的shell,也不会加载其他用户的环境。sudo可以通过使用-i选项来启动交互式超级用户会话(像su -一样)。
使用以下命令可以查看当前用户的权限:
[me@linuxbox ~]$ sudo -l
User me may run the following commands on this host:
(ALL) ALL
chown —— 更改文件的所有者和群组
chown命令用来更改文件或目录的所有者和群组。
此命令需要超级用户权限。语法如下:
chown [owner] [:[group]] file ...
参数举例:
参数 |
结果 |
bob |
将文件的所有权从当前所有者更改为用户bob |
bob:users |
将文件的所有权从当前所有者更改为用户bob,并且将所有者群组改为组users |
:admins |
将文件的所有者群组改为组admins。不改变文件的所有者 |
bob: |
将文件所有者从当前所有者更改为用户bob,并将组所有者更改为用户bob的登录组 |
实例
用户janet有超级用户权限,tony没有。janet从自己的主目录复制了一份文件到tony的主目录。jent想要tony可以编辑这个文件,于是janet将该文件的所有权从janet变更为tony:
[janet@linuxbox ~]$ sudo cp myfile.txt ~tony
Password:
[janet@linuxbox ~]$ sudo ls -l ~tony/myfile.txt
-rw-r--r-- 1 root root root 2018-03-20 14:30 /home/tony/myfile.txt
[janet@linuxbox ~]$ sudo chown tony: ~tony/myfile.txt 此处使用了冒号,说明janet还将文件的组所有权也变更到了tony所在的组。
[janet@linuxbox ~]$ sudo ls -l ~tony/myfile.txt
-rw-r--r-- 1 tony tony tony 2018-03-20 14:30 /home/tony/myfile.txt
sudo默认的信任时间是5分钟
chgrp —— 更改组所有权
工作原理与chown大致相同。
行使特权
使用sudo方式创建的目录或文件,其所有者是root,权限模式为755。
将目录共享给组使用时,需要先使用chown :music命令变更所有者组(示例中组名为music目录的拥有者并未改变,还是root);
然后使用chmod 775命令更改权限模式,使得music组中所有成员都可以完全控制目录中的文件。(其他人只能看到此目录中的文件列表,但不能在此目录中创建文件)
接下来,music组的成员如果在目录中创建文件或目录,则新建的文件和目录的所有者将是创建它们的那个账号。
由于系统上默认的umask是0022,它阻止组成员写入属于组中其他成员的文件。所以music中的其他成员将无法操作这些文件或文件夹(比如删除文件、进入文件夹)。
为解决上面这个问题,需要将music组成员使用的umask改为0002。
另外,由一个成员创建的每个文件和目录都将被设置为用户的主要组,而不是music组。这可以通过在目录上设置setgid位来解决:
[bill@linuxbox ~]$ sudo chmod g+s /usr/local/share/Music
[bill@linuxbox ~]$ ls -ld /usr/local/share/Music
drwxrwsr-x 2 root music 4096 2018-03-24 20:03 /usr/local/share/Music
[bill@linuxbox ~]$ umask 0002
[bill@linuxbox ~]$ > /usr/local/share/Music/test_file
[bill@linuxbox ~]$ mkdir /usr/local/share/Music/test_dir
[bill@linuxbox ~]$ ls -l /usr/local/share/Music
drwxrwsr-x 2 bill music 4096 2018-03-24 20:24 test_dir
-rw-rw-r-- 1 bill music 0 2018-03-24 20:22 test_file
[bill@linuxbox ~]$
umask只能持续到会话结束。后续会有章节讲如何永久更改umask。
更改密码
passwd可以设置或修改密码。此命令将试图强制使用强壮的密码。所谓强壮意味着:不能太短、不能与以前的密码太相似、不能是字典单词或太容易猜到。
超级用户可以使用passwd命令的其他选项锁定某个账号、设置密码过期等,参阅此命令的手册页。