Linux系统的权限管理,整体上可分为:普通权限、默认权限、ACL权限、文件特殊权限、文件系统属性chattr权限、系统命令sudo权限等,下面介绍和说明下这些权限。
我们知道,用户对文件只有三种身份:所属主、所属组、其他人;每种用户身份拥有读(read)、写(write)和执行(execute)三种权限,这就是普通权限了。
- [weixiangxiang@localhost /]$ ll
- 总用量 36
- lrwxrwxrwx. 1 root root 7 7月 22 02:37 bin -> usr/bin
- drwxr-xr-x. 3 root root 21 8月 1 10:28 data
- drwxr-xr-x. 138 root root 8192 8月 1 19:35 etc
- drwxr-xr-x. 6 root root 65 7月 31 17:33 home
- drwxr-xr-x. 8 root root 182 7月 31 19:28 opt
- dr-xr-x---. 17 root root 4096 8月 1 19:36 root
- drwxr-xr-x. 14 root root 167 7月 12 2017 usr
- .....(后面显示省略)
权限位的说明,如下图所示:
其中,第0位表示的是文件类型:
类型 | 含义 | 解释 |
- | 普通文件 | |
b | 块设备文件 | 是一种特殊设备文件,存储设备都是这种文件,如分区文件/dev/sda1就是这种文件。 |
c | 字符设备文件 | 是特殊设备文件,输入设备一般都是这种文件,如鼠标、键盘等。 |
d | 目录文件 | |
l | 软链接文件 | |
p | 管道符文件 | 是一种非常少见的特殊设备文件。 |
s | 套接字文件 | 是一种特殊设备文件,一些服务支持Socket访问,就会产生这样的文件。 |
第1~3位表示属主权限(user):表示文件的所有者权限,即当前用户拥有的权限~
第4~6位表示属组权限(group):表示当前用户的用户组,除了当前用户外其他用户拥有的权限~
第7~9位表示其他人权限(others):表示其他人拥有的权限~
类型 | 含义 |
-:none | 无读写执行权限 |
r:read | 可读权限 |
w:write | 可写权限 |
x:execute | 可执行权限 |
权限模式:
格式为“[ugoa][[+-=][perms]]”,即“[用户身份][[赋予方式][权限]]”的格式。其中,用户身份有所属主(user)、所属组(group)、其他人(others)可分别简写为u、g、o,而a表示全部身份;赋予权限有+、-、=分别表示增加权限、减掉权限、设置权限;权限则指的是可读可写可执行了。
举例:创建一个test.txt文件,并查看权限,修改权限。
- # 创建测试文件
- [weixiangxiang@localhost ~]$ touch test.txt
- [weixiangxiang@localhost ~]$ ll
- 总用量 8
- -rw-rw-r--. 1 weixiangxiang weixiangxiang 0 7月 25 21:25 test.txt
-
- # 属主添加x权限,属组减掉w权限,其他人增加w权限
- [weixiangxiang@localhost ~]$ chmod u+x,g-w,o+w test.txt
- [weixiangxiang@localhost ~]$ ll
- 总用量 8
- -rwxr--rw-. 1 weixiangxiang weixiangxiang 0 7月 25 21:25 test.txt
-
- # 不需要关心原来权限是什么,直接通过=设置权限需要的权限
- [weixiangxiang@localhost ~]$ chmod u=rwx,g=rw,o=rw test.txt
- [weixiangxiang@localhost ~]$ ll
- 总用量 8
- -rwxrw-rw-. 1 weixiangxiang weixiangxiang 0 7月 25 21:25 test.txt
数字权限:
简化字母赋予权限的方式,使用数字表示,比如属主权限中:r表示4,w表示2,x表示1,组合的话进行相加即可,即7=4+2+1表示可读可写可执行,同理5=4+1表示可读可执行。
- [weixiangxiang@localhost ~]$ mkdir test_20220725
- [weixiangxiang@localhost ~]$ ll
- 总用量 8
- drwxrwxr-x. 2 weixiangxiang weixiangxiang 6 7月 25 21:47 test_20220725
- -rwxrw-rw-. 1 weixiangxiang weixiangxiang 0 7月 25 21:25 test.txt
-
- # -R表示递归设置权限
- [weixiangxiang@localhost ~]$ chmod -R 777 test_20220725
- 总用量 8
- drwxrwxrwx. 2 weixiangxiang weixiangxiang 6 7月 25 21:47 test_20220725
- -rwxrw-rw-. 1 weixiangxiang weixiangxiang 0 7月 25 21:25 test.txt
请注意,666,777都是最高的权限,为了安全性实际上不建议这么设置!!!
举例:使用root用户创建一个日志文件,通过ll命令显示对用户组及其他用户只读,修改文件的所属主 或 所属主和所属组。
- [root@localhost home]# touch test001.log
- [root@localhost home]# ll
- 总用量 2
- drwx------. 3 mysql mysql 78 7月 22 17:33 mysql
- -rw-r--r--. 1 root root 0 7月 25 22:04 test001.log
- drwx------. 17 weixiangxiang weixiangxiang 4096 7月 25 22:04 weixiangxiang
-
- # 将该文件的属主权限修改为 weixiangxiang, 该用户则具有了 rw 权限
- [root@localhost home]# chown weixiangxiang test001.log
- 总用量 2
- drwx------. 3 mysql mysql 78 7月 22 17:33 mysql
- -rw-r--r--. 1 weixiangxiang root 0 7月 25 22:04 test001.log
- drwx------. 17 weixiangxiang weixiangxiang 4096 7月 25 22:04 weixiangxiang
-
- # 将该文件的属主权限修改为 weixiangxiang, 所属组也修改为 weixiangxiang
- [root@localhost home]# chown weixiangxiang:weixiangxiang test001.log
- 总用量 2
- drwx------. 3 mysql mysql 78 7月 22 17:33 mysql
- -rw-r--r--. 1 weixiangxiang weixiangxiang 0 7月 25 22:04 test001.log
- drwx------. 17 weixiangxiang weixiangxiang 4096 7月 25 22:04 weixiangxiang
请注意:root用户拥有超级管理员的权限,可以修改任意文件的权限,但普通用户只能修改自己目录下的文件权限,否则报权限不足!!!
举例:接着修改所属组为mysql
- # 将该文件的所属组修改为 mysql
- [root@localhost home]# chown weixiangxiang:weixiangxiang test001.log
- 总用量 2
- drwx------. 3 mysql mysql 78 7月 22 17:33 mysql
- -rw-r--r--. 1 weixiangxiang mysql 0 7月 25 22:04 test001.log
- drwx------. 17 weixiangxiang weixiangxiang 4096 7月 25 22:04 weixiangxiang
Linux 是一个比较安全的操作系统,而安全的基础就是权限,因此,在 Linux 中所有的文件和目录都要有基本的权限,新建的文件和目录当然也要有默认的权限。在 Linux 系统中,通过 umask 默认权限来给所有新建立的文件和目录赋予初始权限。
- [root@localhost /]# umask
- 0022
- # 八进制显示
- [root@localhost /]# umask -S
- u=rwx,g=rx,o=rx
很明显,八进制更能清晰的辨别所属主、所属组及其他人的权限类型。0022,第一位0代表文件的特殊权限(这个后面再说吧),022表示的才是 umask 默认权限。那么,默认权限是如何计算得到的呢?
umask默认权限一定不是直接使用权限数字相减得到的,而是通过二进制逻辑与和逻辑非联合运算得到的,最简单的办法还是使用权限字母来计算,比如:
以weixiangxiang用户为例:
- [root@localhost weixiangxiang]# su weixiangxiang
- [weixiangxiang@localhost ~]$ umask
- 0002
-
- [weixiangxiang@localhost ~]$ touch 1.log
- [weixiangxiang@localhost ~]$ ll
- -rw-rw-r--. 1 weixiangxiang weixiangxiang 0 7月 25 22:48 1.log
-
- [weixiangxiang@localhost ~]$ mkdir ttt/
- [weixiangxiang@localhost ~]$ ll
- drwxrwxr-x. 2 weixiangxiang weixiangxiang 6 7月 25 22:51 ttt
当 umask=0002 时,按照上面的计算规则,新建文件默认的权限为:-rw-rw-r-- ;新建目录默认的权限为:drwxrwxr-x 。
临时性的修改:(重启机器或重新登录时,该修改会失效)
[weixiangxiang@localhost ~]$ umask 0022
永久性的修改:
vi /etc/profile
在实际工作中,普通权限是不够用的,比如有一个场景:一个公司的A部门存在一个该部门文件目录./deptA,对该目录权限的规划应该为:部门主管使用root用户,且作为属主拥有rwx权限,而该部门的员工加入的是groupA,groupA作为属组并赋予rwx权限,其他人则没有权限,这样是符合实际情况的!
但是,有一天需要从其他部门调过来一个同事支撑该部门的日常工作,由于这位同事不熟悉该部门的业务,不能随意修改该部门的文档,只能给他赋予rx的权限。这样的话,是把他加入groupA组?还是赋予他其他人的权限?这些都明显不符合要求,这时候普通权限就不够用了!
Windows系统中,可以单独指定用户并单独进行分配权限的方式,就能很好的解决用户身份不足的情况。那么,Linux系统使用的ACL(访问控制列表)设置用户对文件的权限,CentOS系统是默认开启ACL的。
<1>. 查看ACL状态:getfacl 文件/目录名
- # 查看 mysql安装目录的 ACL权限
- [root@localhost /]# getfacl /opt/mysql-8.0.26-el7-x86_64/
- getfacl: Removing leading '/' from absolute path names
- # file: opt/mysql-8.0.26-el7-x86_64/
- # owner: root
- # group: root
- user::rwx
- group::r-x
- other::r-x
-
- # 查看 test001.log文件的 ACL权限
- [root@localhost /]# getfacl /home/test001.log
- getfacl: Removing leading '/' from absolute path names
- # file: home/test001.log
- # owner: weixiangxiang
- # group: mysql
- user::rw-
- group::r--
- other::r--
<2>. 设置ACL状态:setfacl [参数选项] 文件/目录名
参数选项:
- [root@localhost /]# setfacl --help
- setfacl 2.2.51 -- set file access control lists
- Usage: setfacl [-bkndRLP] { -m|-M|-x|-X ... } file ...
- -m, --modify=acl modify the current ACL(s) of file(s)
- -M, --modify-file=file read ACL entries to modify from file
- -x, --remove=acl remove entries from the ACL(s) of file(s)
- -X, --remove-file=file read ACL entries to remove from file
- -b, --remove-all remove all extended ACL entries
- -k, --remove-default remove the default ACL
- --set=acl set the ACL of file(s), replacing the current ACL
- --set-file=file read ACL entries to set from file
- --mask do recalculate the effective rights mask
- -n, --no-mask don't recalculate the effective rights mask
- -d, --default operations apply to the default ACL
- -R, --recursive recurse into subdirectories
- -L, --logical logical walk, follow symbolic links
- -P, --physical physical walk, do not follow symbolic links
- --restore=file restore ACLs (inverse of `getfacl -R')
- --test test mode (ACLs are not modified)
- -v, --version print version and exit
- -h, --help this help text
实现上面的场景需求:
- # 创建部门目录
- [root@localhost /]# mkdir deptA
- # 创建分组groupA
- [root@localhost /]# groupadd groupA
-
- # 设置deptA目录的属主和属组,并赋予770权限
- [root@localhost /]# chown root:groupA /deptA
- [root@localhost /]# chmod 770 /deptA
- [root@localhost /]# ll -d /deptA/
- drwxrwx---. 2 root groupA 6 7月 14 19:04 /deptA/
-
- # 再创建一个其他部门调动过来的员工,但只能赋予操作deptA目录的rx权限
- [root@localhost /]# useradd xiaoxiao
- [root@localhost /]# setfacl -m u:xiaoxiao:rx /deptA/
-
- [root@localhost /]# getfacl deptA/
- # file: deptA/
- # owner: root
- # group: groupA
- user::rwx # 用户root的权限,属主
- user:xiaoxiao:r-x # 用户xiaoxiao的权限
- group::rwx # 用户组groupA的权限,属组
- mask::rwx # mask默认权限
- other::--- # 其他人权限,其他人
从结果可以看到,用户xiaoxiao既不是deptA目录的属主,也不是属组,也不是其他人,而是单独被分配了rx权限。通过 setfacl -m u:指定用户:指定权限 指定目录 方式很便捷的实现了单独为指定用户分配指定的权限!!同理,通过 setfacl -m g:指定用户组:指定权限 指定目录 方式也可以实现单独为指定用户组分配指定的权限~~
除了通过-m实现新增ACL权限操作外,使用参数选项中的-R可以递归设置ACL权限;使用参数选项中的-d可以设置默认ACL权限;使用参数选项中的-x/-b/-k可分别删除单个/删除所有/删除默认的ACL权限;
是否想过一个问题,为什么普通用户可以通过 passwd 命令修改自己的密码?我们知道,普通用户的信息保存在/etc/passwd文件中,用户的密码实际保存在/etc/shadow文件中的加密密码,看下这两个文件:
- [root@localhost /]# ll /etc/passwd
- -rw-r--r--. 1 root root 2658 7月 14 19:26 /etc/passwd
- [root@localhost /]# ll /etc/shadow
- ----------. 1 root root 1729 7月 14 19:27 /etc/shadow
这两个文件,一个是644(普通用户只具有可读权限)、一个是000(普通用户无权限),也就是说普通用户对这两个文件其实都是没有写权限的,那为什么普通用户可以修改自己的权限呢?
其实,普通用户可以修改自己的密码的秘密不在于这两个文件,而在于passwd命令,看下这个命令:
- [root@localhost /]# ll /usr/bin/passwd
- -rwsr-xr-x. 1 root root 27856 4月 1 2022 /usr/bin/passwd
关键的奥秘在于,在属主应该写x(执行)权限的位置出现了一个小写s,这种权限称作SetUID权限。
因此,当一个具有执行权限的文件设置SetUID权限后,用户在执行这个文件时将以文件所有者的身份来执行。也就是说,当普通用户使用passwd命令更改自己的密码的时候,实际上是在用passwd命令所有者root的身份在执行passwd命令,root当然可以将密码写入/etc/shadow文件,所以普通用户也可以修改/etc/shadow文件,命令执行完成后,该身份也随之消失。
当然,可以验证SetUID权限的作用,比如,通过以下命令取消root用户的SetUID权限,普通用户修改密码则会报错:
- [root@localhost /]# chmod u-s /usr/bin/passwd
- [root@localhost /]# su xiaoxiao
- [xiaoxiao@localhost /]$ passwd
- 更改用户 test_0814 的密码 。
- 新的 密码:
- 重新输入新的 密码:
- passwd:身份验证令牌错误。
实际上我们不能随便设置SetUID权限,同时要防止黑客的恶意修改,有几点安全建议:
参考SetUID,就好理解SetGID了,在属组应该写x(执行)权限的位置出现了一个小写s,这种权限称作SetGID权限。比如 locate 命令:
- [root@localhost /]# ll /usr/bin/locate
- -rwx--s--x. 1 root slocate 40520 4月 11 2018 /usr/bin/locate
SetGID权限可作用于文件,也可作用于目录。
当是文件:
和passwd命令类似,普通用户在执行locate命令的时候,会获取locate属组的组身份。locate命令是在系统中按照文件名查找符合条件的文件的,不过它不是直接搜索系统的,而是搜索/var/lib/mlocate/mlocate.db这个数据库的。
当是目录:
Sticky BIT意为粘着位,也简称为SBIT,作用如下:
如果没有SBIT的话,因为普通用户拥有w权限,可以删除此目录下的所有文件,包括其他用户建立的文件。一旦被赋予了粘着位,除了root用户可以删除所有文件,普通用户就算拥有w权限,也只能删除自己建立的文件,而不能删除其他用户建立的文件。
默认系统中/tmp/目录拥有SBIT权限,其他人的x权限位被t占用了:
- [root@localhost /]# ll -d /tmp/
- drwxrwxrwt. 35 root root 8192 8月 14 20:51 /tmp/
因此,具有SBIT权限的目录是不允许删除的!
我们知道,“755”代表属主拥有读、写、执行权限;属组拥有读、执行权限;其他人拥有读、执行权限。如果把特殊权限也考虑在内,那么权限就应该写成“4755”,其中“4”就是特殊权限SetUID了,“755”还是代表属主、属组和其他人的权限。这几个特殊权限这样来表示:
另外,需要注意:这几个特殊权限操作的对象是不同的,SetUID只对二进制程序文件有效,SetGID可以对二进制程序文件和目录有效,但是SBIT只对目录有效。特殊权限只针对具有可执行权限的文件有效,不具有x权限的文件被赋予了SetUID和SetGID权限会被标记为S, SBIT权限会被标记为T。所以,如果需要设置特殊权限,则还是需要分开设定的。
charrt权限的特点:
chattr 命令格式:chattr [-RVf] [+-=参数选项] 文件/目录名
通过--help看下有哪些参数选项:
- [root@localhost /]# chattr --help
- Usage: chattr [-RVf] [-+=aAcCdDeijsStTu] [-v version] files...
特别注意以下参数:
因此,charrt命令是一种凌驾于rwx权限上的命令,通常需要谨慎使用!此外,通过 lsattr 命令可以查看文件系统属性:
- # -a 列出目录下所有de文件属性,-d只显示目录
- [root@localhost /]# lsattr -d /opt/---------------- /opt/
root 超级用户作为管理员,拥有着 Linux 系统的最高级权限,实际上所有的大小事情都交给 root 超级用户去做是不现实的,健康的管理方法是在 Linux 服务架构好后,可授权普通用户协助管理员完成日常管理,通过 sudo 工具实现,几乎所有的 Linux 是默认安装了 sudo。值得注意的是,sudo的操作对象是系统命令,即 root 把本来只能由超级用户执行的命令赋予普通用户执行。
root 用户通过 visudo 命令可以编辑其配置文件/etc/sudoers进行授权,配置文件部分内容如下,注释也解释的很清楚:
- [root@localhost /]# visudo
- ......
- ## Next comes the main part: which users can run what software on
- ## which machines (the sudoers file can be shared between multiple
- ## systems).
- ## Syntax:
- ##
- ## user MACHINE=COMMANDS
- ##
- ## The COMMANDS section may have other options added to it.
- ##
- ## Allow root to run any commands anywhere
- root ALL=(ALL) ALL
-
- ## Allows members of the 'sys' group to run networking, software,
- ## service management apps and more.
- # %sys ALL = NETWORKING, SOFTWARE, SERVICES, STORAGE, DELEGATING, PROCESSES, LOCATE, DRIVERS
-
- ## Allows people in group wheel to run all commands
- %wheel ALL=(ALL) ALL
-
- ## Same thing without a password
- # %wheel ALL=(ALL) NOPASSWD: ALL
-
- ## Allows members of the users group to mount and unmount the
- ## cdrom as root
- # %users ALL=/sbin/mount /mnt
- rom, /sbin/umount /mnt
- rom
-
- ## Allows members of the users group to shutdown this system
- # %users localhost=/sbin
- utdown -h now
-
- ## Read drop-in files from /etc/sudoers.d (the # here does not mean a comment)
- #includedir /etc/sudoers.d
文件格式说明:
- # 用户名 被管理的主机IP地址=(可使用的身份) 授权命令(绝对路径)
- root ALL=(ALL) ALL
- # %组名 被管理的主机IP地址=(可使用的身份) 授权命令(绝对路径)
- %wheel ALL=(ALL) ALL
举例:给新建用户赋予服务器关机重启的权限
- [root@localhost /]# useradd test_0814
- [root@localhost /]# passwd test_0814
- 更改用户 test_0814 的密码 。
- 新的 密码:
- 重新输入新的 密码:
- passwd:所有的身份验证令牌已经成功更新。
- [root@localhost /]# su test_0814
- [test_0814@localhost /]$ sudo /sbin
- utdown -r now
-
- 我们信任您已经从系统管理员那里了解了日常注意事项。
- 总结起来无外乎这三点:
-
- #1) 尊重别人的隐私。
- #2) 输入前要先考虑(后果和风险)。
- #3) 权力越大,责任越大。
-
- [sudo] test_0814 的密码:
- test_0814 不在 sudoers 文件中。此事将被报告。
- [test_0814@localhost /]$ su root
- 密码:
- [root@localhost /]# visudo
- ......
- # 在文件中加入内容:
- test_0814 ALL=(ALL) /sbin
- utdown -h now
-
- [root@localhost /]# su test_0814
- [test_0814@localhost /]$ sudo /sbin
- utdown -r now
- [sudo] test_0814 的密码:
- 对不起,用户 test_0814 无权以 root 的身份在 localhost.localdomain 上执行 /sbin
- utdown -r now。
额,这下尴尬了,用户 test_0814 无法执行关机重启的命令,这是咋回事呢?看一下该用户授权列表:卧槽,仔细检查一番之后发现,-r写成-h,哈哈哈!
- [test_0814@localhost /]$ sudo -l
- [sudo] test_0814 的密码:
- ......
- 用户 test_0814 可以在 localhost 上运行以下命令:
- (ALL) /sbin/shutdown -h now
- [test_0814@localhost /]$
最后,科普下 shutdown 关机命令各参数的区别:
很明显,要用-r重启,而不是-h!