System Security and Permissions
用户
计算机启动时的密码输入界面就是通常的用户登录界面。以什么用户登录计算机,我们就只能以该用户的身份创建文件、访问该用户能访问文件。每个Linux操作系统都会有一个超级用户root
,root
用户拥有对所有文件的访问权限,并且能够执行普通用户无法执行的“特权”命令。不过,Linux也为我们提供了除重新登陆外的切换用户身份的方式。
su
:Switch User,以其他用户身份运行shell
1 | su [options] [-] [USER [arg]...] |
su
命令允许我们在正确输入目标用户的登录密码的情况下以该用户的身份启动shell。若su
后面的用户选项为空,则会默认切换为root
用户:
1 | [meme@localhost Playground]$ su |
输入
exit
后我们将退出目标用户并恢复原用户身份。
若我们只是想以其他用户的身份执行一个命令,我们也可以使用su -c 'command'
来传递命令:
1 | [meme@localhost Playground]$ su -c 'ls' |
执行完命令后,我们将立马返回原用户。需要注意的是,传递的命令必须用引号括起。
sudo
:以另一个用户身份执行命令
1 | sudo [command] |
sudo
在一定程度上很像su -c 'command'
,都是使得我们能以其他用户的身份执行命令。但是sudo
通常只用于执行root
用户的命令,且能够执行的命令也只能由root
用户配置,因而是一种比su
更加安全可控的方式:
1 | [meme@localhost Playground]$ sudo ls |
可用
sudo -l
查看所有sudo
能够执行的命令(的库地址)。一次sudo
后,系统会信任用户几分钟,使得后续的sudo
不用再输入密码。
拥有者,组成员,其他人
在Linux的安全架构下,用户对文件的访问权限分为三个层次:拥有者(owner)、组成员(groups)、其他人(others)。一般来说,文件拥有者的访问权限最高,它不仅可以更改不同层次的用户对本文件的访问范围,也可以以更改文件所属组的形式授予新的用户以组成员访问权限。
1 | [meme@localhost Playground]$ ls -l ./foo.txt |
对于上面的foo.txt
文件,其拥有者和访问组依次为meme
、meme
。
除了以组成员的形式赋予其他用户权限,文件拥有者还可以单独为某个用户赋予权限。
组
Linux用一串数字来标记不同的用户和组。使用id
命令可以查看当前用户的用户标识和组标识:
1 | [meme@localhost Playground]$ id |
其中,uid
是当前用户的用户标识,gid
是组标识,此处显示的gid
是当前用户所在组(即当前用户创建文件时文件所属的组)的标识,最后的groups
则是所有包含了当前用户的组及其标识。使用groups
同样可以查询所有包含当前用户的组:
1 | [meme@localhost Playground]$ groups |
使用newgrp [-] [group]
可以切换当前用户的工作组为指定组:
1 | [meme@localhost Playground]$ newgrp wheel |
为了方便权限分配,Linux会为每个用户创建一个独一无二的组作为默认工作组,如上面的
10001(meme)
。所有的用户信息被保持在了文件/etc/passwd
中,组信息则被保持在了/etc/group
中,这两个文件随着/etc/shadow
的变动而修改,/etc/shadow
包含了前面两个文件没有的用户信息,如用户密码的信息等。
常用组命令
只有root
用户能够创建和管理组,因此对于组的管理都要在root
用户下进行。
groupadd
:新建组
1 | groupadd [options] GROUP |
groupadd
允许我们创建指定名称的组:
1 | [meme@localhost Playground]$ sudo groupadd photo |
组一旦被创建,其信息就会被加入到/etc/group
中。
gpasswd
:Group Password,组管理
1 | gpasswd [options] groupname |
gpasswd
命令是Linux下/etc/group
和/etc/shadow
的管理工具,实际上起着管理组的作用。其常用选项-a
用于为指定组增加用户,-d
用于为指定组删减用户:
1 | [meme@localhost Playground]$ sudo gpasswd -a bob photo |
权限
Linux系统的文件通常有三种基本访问权限:读r
、写w
和执行x
。
对于普通文件,这些权限很清晰明了地定义了不同用户能对其进行的操作,但是对于目录文件,则有些许不同:
r
表示可以用ls
列出该目录下的文件,即可以读取目录列表;w
表示可以在目录中增加或者删减文件;x
表示允许用户在目录中查找,且可以以cd
命令切换到该目录。说白了,
rwx
都表示的是对文件内容的使用权力。
当我们用ls -l
列出文件的详细元数据时,前面的10个字符是文件的属性,后面的2个字符串分别是文件的拥有者和访问组,然后是文件的大小、文件的修改时间以及文件名称。
1 | [meme@localhost Playground]$ ls -l foo.txt |
- 第1个字符表文件的类型,
-
表普通文件,d
表目录文件; - 第2~10个字符的每三个字符依次表明文件拥有组、访问组和其他用户对该文件的访问权限,顺序为
rwx
。
chmod
:Change Mode,更改文件权限
1 | chmod [OPTION]... MODE[,MODE]... FILE... |
chmod
以3个八进制数字来分别代表文件拥有者、访问组和其他用户的目标访问权限,如6
表示110
,权限为rw-
;4
表示100
,权限为r--
;0
表示000
,权限为---
:
1 | [meme@localhost Playground]$ chmod 600 foo.txt |
除了以数字来直接代表目标权限,chmod
也支持符号形式的表示:
u
、g
、o
分别表示文件拥有者、访问组和其他用户;+
,-
,=
分别表示添加、减少和指定权限;r
、w
、x
分别表示3种权限。- 如:
1 | [meme@localhost Playground]$ chmod u-r,go=rw foo.txt |
umask
:User File-Creation Mode Mask,设置默认权限
1 | umask [-p] [-S] [mode] |
umask
让我们能够设置在当前用户下创建文件时,各用户的初始权限:
1 | [meme@localhost Playground]$ umask 002 |
其中每位数字(依次代表文件拥有者、访问组和其他用户)都代表一个二进制形式的掩码,即2
等价于010
,表示遮盖rwx
中的第二位w
。
此处
x
也被遮盖的原因是.txt
文件无法被执行,也就是说它没有x
操作。umask
设置的掩码不是永久的,它只在当前的shell上生效。
chown
:Change Owner,更改文件所有者和访问组
1 | chown [options] owner[:group] file... |
如:
1 | [meme@localhost Playground]$ sudo chown bob:photo foo.txt |
其中,若文件的所有者是自己且要将该文件的访问组改回自己,则无需root
权限,如最后一个命令所示。
特殊权限
除了上面的3种权限rwx
,Linux还提供另外3种特殊权限setuid
、setgid
和sticky
。
setuid
& setgid
setuid
和setgid
的符号均为s
,只不过前者只存在于文件拥有者,而后者只存在于文件的访问组。它们的作用相似:当拥有s
权限的可执行文件被运行时,该可执行文件会以拥有s
权限的文件拥有者或者拥有s
权限的访问组的身份运行,即,若文件夹dir
(文件夹是一种特殊的可执行文件)的访问组photo
没有s
权限,meme
用户在dir
下创建文件的访问组仍然是meme
:
1 | [meme@localhost dir]$ touch foo.txt |
反之,若赋予dir
的访问组以s
权限(要在root
下才能赋予成功),则meme
用户在dir
下创建的文件的访问组仍然是photo
:
1 | [meme@localhost dir]$ sudo chmod g+s . |
在上面的代码框中,当前文件夹dir
的访问组权限由r-x
变为了r-s
。之后新创建的ff.txt
的访问组也相应地变成了dir
的访问组。
sticky
为文件附加sticky
(标识t
)位的操作为:
1 | chmod +t FILE |
这个权限用处不大,一般只用于目录文件,它能阻止用户删除或重命名该目录下的文件,除非用户是这个目录的所有者,或者是文件所有者,或是是超级用户root
。
passwd
:修改用户密码
1 | passwd [user] |
我们可以使用该命令修改指定用户的登陆密码