Linux 权限管理
所有者
要修改文件或目录的所属组,使用 chgrp
命令:
而修改文件或目录的所属组,使用 chown
命令:
访问权限
Linux 系统中,每个文件都明确规定了不同身份用户的访问权限,使用 ls -l
命令可以看到。
$ ls -l ~
total 99
drwxrwxr-x 2 jiamin jiamin 4096 May 25 16:44 Download
-rwxrwxr-x 1 jiamin jiamin 79 Aug 22 18:42 connect.sh
-rw-r--r-- 1 jiamin jiamin 79 Aug 22 20:11 test.txt
...
ls -l
命令输出内容的第一列即是各文件对不同用户设定的权限,一共有 11 位:
-
第 1 位表示文件类型。- 表示普通文件,d 表示目录,l 表示连接文件,b 表示设备文件,等等。
-
第 2~10 位为三种不同的用户身份设定权限,每三位为一组,三组分别代表所有者、所属组和其他人三种身份的权限。每组权限的三位分别规定了是否对文件有读(r)、写(w)、执行(x) 权限。除此之外,我们还可以在 x 权限的位置,看到 s 或者 t 权限。
s 针对可执行文件或目录,使文件在执行阶段,临时拥有文件所有者的权限。t 针对目录,任何用户都可以在此目录中创建文件,但只能删除自己的文件
-
第 11 位受 SELinux 的安全规则管理(不在此进行讨论)。
文件 | 目录 | |
---|---|---|
r | 可读文件内容 | 可查看目录下文件/子目录列表 |
w | 可更改文件内容 | 可新建/删除/移动该目录中文件/子目录,可对该目录下的文件/子目录做更名操作 |
x | 可执行该文件 | 可进入该目录 |
例:若用户要执行
cp /dir1/file /dir2/
命令,需要:
- 对
/dir1/
拥有 x 权限- 对
/dir1/file
拥有 r 权限- 对
/dir2/
拥有 w,x 权限
权限修改
可用 chmod
命令修改文件权限。
-
可用数字修改文件权限
代表权限的 9 个字符,视为 3 个 3 位的二进制数,如
rwxrw-r-x
即视为 111 110 101 三个二进制数,用十进制表示即为 765,故可用chmod 765 test_file
将test_file
的权限改为rwxrw-r-x
。 -
使用数字修改文件权限
使用
u
、g
、o
分别代表所有者、所属组和其他人三种身份,也可使用a
代表全部的身份。使用r
、w
、x
分别代表读、写、执行权限。使用+
添加权限、-
删除权限、=
设定权限。如:
默认权限
Linux 系统中,创建新的文件和目录时,通过使用 umask
默认权限来给所有新建的文件和目录赋予初始权限。
默认权限由 4 个八进制数组成,第一个数代表文件所具有的特殊权限(SetUID、SetGID、Sticky BIT),后三个数字分别代表创建的新文件/目录需要从最大默认权限中减去的数值。使用 umask
命令变可查看默认权限,默认 root 用户是 0022,而普通用户是 0002。
对文件来说,最大默认权限是 666,而目录最大权限是 777,因此,在不修改 umask
的情况下,root 用户创建的文件与目录权限分别为 644 和 755。
若要修改默认权限,使用 umask [mode]
修改,修改后只临时有效,若要永久设置,可写入 /etc/profile
文件中
ACL 访问控制权限
在实际使用时,光靠所有者、所属组和其他人三种身份,并不能完全满足更精细的权限管理,因此就需要使用 ACL 访问控制权限。ACL 全称是 Access Control List(访问控制列表),它可以对单一用户设定访问文件的权限。
要开启 ACL:
- 使用
mount -o remount,acl 分区
重新挂载需要开启 ACL 的分区,该方法临时生效 - 修改
/etc/fstab
文件,在需要开启 ACL 的分区的对应行的第 4 列挂载参数中添加,acl
,以永久生效
若要设置 ACL 权限,使用 setfacl
命令,查看使用 getfacl
命令。
setfacl
命令使用基本格式为 setfacl 参数 file
,其常用参数为:
功能 | 参数 | 例子 |
---|---|---|
设定 ACL 权限 | -m u/g:用户/组名:权限 |
setfacl -m u:user0:rx test/ |
设定目录中新建文件的默认权限 | -m d:u/g:用户/组名:权限 |
setfacl -m d:u:user0:rx test/ |
删除指定用户/组的 ACL 权限 | -x u/g:用户名 |
setfacl -x u:user0 test/ |
删除所有 ACL 权限 | -b |
setfacl -b test/ |
设置 ACL 权限后,使用 ls -l
查看文件时,便会发现对应条目的第一列的第 11 个字符变为了 +
,可通过 getfacl 文件名/目录名
来查看 ACL 权限细节。
可以看到,
getfacl
的输出中还有mask
这一项。设定的 ACL 权限还需与 mask 按位与,才是最终权限,其作用即规定了 ACL 最大能设定的权限。mask
权限可通过setfact -m m:权限 目录/文件
来修改。
Linux 文件特殊权限
SetUID(SUID)
前面提到过,在所有者执行(x)权限的位置,有时候还能看到 s 权限,这种权限针对可执行文件,使文件在执行阶段,临时拥有文件所有者的权限。这种权限通常称为 SetUID,或 SUID 特殊权限。
$ which passwd
/usr/bin/passwd
$ ls -l /usr/bin/passwd
-rwsr-xr-x 1 root root 68208 Mar 14 2022 /usr/bin/passwd
在 Linux 系统中,用户的密码数据记录在 /etc/shadow
整个文件中
但可以看到,除 root 外其他用户对该文件没有写权限,那么 Linux 如何让普通用户修改自己的密码呢?答案就在 passwd
命令的 SetUID 权限上了,普通用户在使用 passwd
命令修改自己密码时,会临时拥有所有者 root 的权限来执行这个命令,从而修改 /etc/shadow
文件,命令执行完毕,普通用户所拥有的 root 身份也会失效。
SUID 作用于可执行文件,要求执行命令的用户对文件拥有 x 权限,这样 SUID 才会生效。使用 chmod u+s 文件名
可为文件设置 SUID 权限。
SetGID(SGID)
当 s 权限在所属组的 x 权限位上时,此时的权限称为 SetGID,或 SGID 特殊权限。同 SUID 权限,SGID 会使得执行该文件的用户的组身份临时变为文件所属者。
plocate
命令在执行过程中,用户会临时获得 plocate
这个组的权限,从而可以在 /var/lib/plocate/plocate.db
这个数据库中查看信息。
$ ls -l /var/lib/plocate/plocate.db
-rw-r----- 1 root plocate 30541707 Sep 3 17:04 /var/lib/plocate/plocate.db
SGID 也可作用于目录,作用于目录时,用户要对该目录拥有 rwx 权限,SGID 命令才能生效,这样若其他用户在设置了 SGID 的目录下新建文件,新文件所属组为父目录所属组,而所有者还是该用户。
# su - user0
$ ls -ld /tmp/dtest/
drwxr-srwx 2 root root 4096 Sep 3 17:33 /tmp/dtest/
$ touch /tmp/dtest/testfile
$ ls -l /tmp/dtest/
total 0
-rw-rw-r-- 1 user0 root 0 Sep 3 17:41 testfile
Stick BIT(SBIT)
Stick BIT,即 SBIT 特殊权限。SBIT 权限仅对目录有效,一旦目录设定了 SBIT,那么用户在此目录下创建的文件或目录,就只有用户自己和 root 拥有修改以及删除权限。如 Linux 系统中的 /tmp
目录就设定了 SBIT 权限:
所有用户都可以在 /tmp
文件夹中新建文件/目录,一旦创建,就只有该用户以及 root 可以修改或删除,而除此之外的其他用户就只有读权限。
特殊权限的设置
我们知道,使用 chmod
命令可以设置文件的权限,777 是 rwxrwxrwx
,755
是 rwxr-xr-x
,那么特殊权限 SUID、SGID、SBIT 应该如何设置呢?
在 Linux 中 SUID、SGID、SBIT 分别使用 4、2、1 来指示,在原先三位权限的前面添加特殊权限对应的数字之和便能使用 chmod 权限 文件名
来设置特殊权限了。
# su - user0
$ cd /tmp
$ mkdir test
$ ll -d test
drwxrwxr-x 2 user0 user0 4096 9月 3 18:09 test/
$ chmod 5755 test
$ ll -d test
drwsr-xr-t 2 user0 user0 4096 9月 3 18:09 test/
也可通过 u+s
g+s
o+t
的方式分别赋予文件特殊权限。
若对没有 x 权限的权限的文件设置 SUID、SGID 或 SBIT 权限,权限将不会生效,并且,使用
ls -l
命令查看的时候,对应位将显示为大写的S
或T
。
隐藏属性
除普通权限和特殊权限外,Linux 系统中还有一些隐藏权限,隐藏权限通过 chattr
命令进行修改,基本格式为:
下表列出常用属性,及其功能
属性 | 功能 |
---|---|
i | 不可做任何修改(即使是 root): 1. 拥有 i 属性的普通文件,不可删除、改名、修改内容、添加内容; 2. 拥有 i 属性的目录,内部不可建立、删除、重命名文件 |
a | 仅可以 append 模式打开: 1. 拥有 a 属性的普通文件,只能在文件中增加内容,而不可删除文件、改名、修改内容 2. 拥有 a 属性的目录,只能在内部新建文件,不能删除、更名内部文件 |
s | 拥有 s 属性的目录或普通文件,删除时,会彻底删除,用 0 填充所占区域 |
使用 lsattr
命令查看文件隐藏属性,常用选项有 -a
-d
-R
选项,这些选项功能和 ls
命令的相同。
sudo 命令
通过 sudo
命令,用户可以使用其他用户的身份去执行命令。该命令基本格式为:
常用参数为:
-u user
:欲使用用户的用户名或 ID,若不指定,默认使用 root 用户-l
:显示出自己的权限-k
:强制使用者在下一次执行sudo
时询问密码(默认 5 分钟不使用sudo
会再次询问密码)
为普通用户添加 sudo 权限
sudo
命令运行时,系统会先通过 /etc/sudoers
文件验证用户是否有 sudo
命令的权限,如果有,用户需输入自己的密码进行确认,密码正确后才会以指定的身份执行 sudo
后的命令。默认情况下,系统只有 root 用户拥有 sudo
命令的权限。要让普通用户获得 sudo
权限,一种方法是直接修改 /etc/sudoers
文件,另一种方法后文会介绍。
我们通常会使用 visudo
命令修改 /etc/sudoers
文件,这是因为 visudo
会自行检测 /etc/sudoers
文件的语法。大多 Linux 系统默认使用 vi
编辑器(Ubuntu 默认使用的是 nano
,若要修改默认编辑器,使用 update-alternatives --config editor
命令)。可以看到,/etc/sudoers
文件中包含有如下的内容(在 Ubuntu 系统中是 sudo
组,在 CentOS 系统中是 wheel
组):
- 每行开头使用
username
或者%groupname
指定这行规则所适用的用户或用户组; - 其后的第一个
ALL
意味着这条规则适用于所有 host; - 括号内的两个
ALL
指示了适用于这条规则的用户使用sudo
命令时,可以使用所有的用户(user)以及所有的用户组(group)身份; - 最后一个
ALL
表明适用于这条规则的用户可以用sudo
执行所有的命令。
因此要给某一用户,如 user0
,添加 sudo
命令的权限,有两种方法:
-
(不推荐)修改
/etc/sudoers
文件,在其中添加: -
将
user0
用户加入sudo
组(或wheel
组)- 修改
/etc/groups
文件,找到sudo
组所在的行,在最后添加user0
(若要添加多个用户,使用,
分隔):
- 或者直接执行如下命令:
- 修改