Linux系统中的权限详解

404 阅读10分钟

 【Linux】Linux系统中的权限详解

我们linux服务器上有严格的权限等级,如果权限过高导致误操作会增加服务器的风险。所以对于了解linux系统中的各种权限及要给用户,服务等分配合理的权限十分重要。

一.文件基本权限


  首先看下linux下的文件权限,可以使用ll命令或者是带-l(长列表选项)的ls命令。

  

   文件列表信息分为:文件类型、权限、链接数、所属用户、所属用户组、文件大小、最后修改时间、文件名。

   linux一共有7种文件类型,分别如下:

            -:普通文件

           d:目录文件

           l: 软链接(类似Windows的快捷方式)

          (下面四种是特殊文件)

           b:块设备文件(例如硬盘、光驱等)

           p:管道文件

           c:字符设备文件(例如猫等串口设备)

           s:套接口文件/数据接口文件(例如启动一个MySql服务器时会产生一个mysql.sock文件)

文件权限对应关系

       

  我们看上面截图第一个文件权限信息,每三位为一组

rwxr-xr-x  5 root root  94 Jun 27 2017 xdg

**rwx: **代表文件所有者(u表示)权限,这里是root,root对该文件拥有读写执行权限。

r-x : 代表所属组(g表示)的权限,这里所属组拥有对该文件读和执行的权限。

r-x : 代表其他人(o表示)的权限,这里和上面权限一样。

   当然我们也可以修改文件的权限。

   linux中chmod命令就可以用来变更文件或目录的权限。

   语法:  chmod (选项) 模式  文件名

   用法如下:

       先创建一个文件a.txt,此时a.txt文件拥有者是没有执行权限,我们可以给它加上执行权限(x),u就是代表文件拥有者。

  

   如果想给a.txt的用户组和其他用户也加上执行权限,可以加上多个。

  

  既然可以加权限,也可以减权限,加号改成减号就行。

  

  还有更简单的方式,直接用等于号赋予相应的权限

  

  或者用a=的方式赋予,a就是代表all。

   

   也可以给多个文件赋予权限,我们在创建一个文件b.txt

  

   总结下,权限对文件及目录的作用

    对于文件:

      r : 可以读取文件内容(比如命令 cat more head tail)。

     w : 可以编辑文件(比如命令 vim echo ),但是不能删除文件,因为文件名没有放在自己的文件空间,而是放在了上一级的目录空间下。

     x : 可以执行。

   对于目录:

              r:可以查询目录下的文件(比如命令ls  ll)。

             w:具有修改目录结构的权限,比如新建文件和目录,删除此目录下文件和目录,重命名此目录下文件和目录,剪切和复制(比如命令cp mv touch rm)。

        x:目录有执行权限但是不能运行,可以进入目录(cd命令)。

     对文件来说最高权限是x,对于目录来说最高权限是w,一般给目录赋予权限0 ,5(rx),7(rxw),赋予4 ,1, 6都是没有意义的。对于文件能否删除,首先要对目录具有执行权限,同时对文件也具有执行权限。

chown命令:用来改变文件或目录的所有者和所属用户组。

chgrp命令 : 用来改变文件或目录的所属的用户组。

示例:

复制代码

[root@localhost test123]# ll
总用量 0
drwxr-x--- 2 root root 20 55 11:38 abc
[root@localhost test123]# chown test123:test123 abc      将abc用户组和所属者都改成test123    中间用:分割
[root@localhost test123]# ll
总用量 0
drwxr-x--- 2 test123 test123 20 55 11:38 abc

复制代码

二.默认权限


    我们在linux系统中新建一个文件或者目录,那么这个文件或目录会有一个权限,这个权限就是默认权限。这个权限就是靠umask的值来定义的。那么什么是umask?

    umask(权限掩码) 就是指定当前用户在建立文件或目录时候的权限默认值。当新文件被创建时,其最初的权限由文件创建掩码决定。用户每次登录系统时,umask命令都被执行, 并自动设置掩码mode来限制新文件的权限。用户可以通过再次执行umask命令来改变默认值,新的权限将会把旧的覆盖掉。

我们可以执行umask命令来查看系统中文件默认权限。

[root@localhost local]# umask
0022

解释下0022

第一位0:文件特殊权限。

022:文件默认权限。 

下面创建一个文件和一个目录。

复制代码

[root@localhost tmp]# touch a.txt
[root@localhost tmp]# mkdir dir
[root@localhost tmp]# ll
总用量 54768
-rw-r--r--  1 root root        0 55 14:31 a.txt
drwxr-xr-x  2 root root        6 55 14:31 dir

复制代码

我们看文件默认权限是644,而目录的权限是755,那么是如何依靠umask来设定权限的呢。

我们先看下文件默认权限的特点:

    1.文件默认不能建立为执行权限,必须手工赋予执行权限。所以文件的默认权限最大为666。这样能保护系统安全。

    2.默认权限要换算成对应的字母权限在相减而不是数字。

    3.建立文件或目录之后的默认权限,为666减去umask的值。

计算方式如下:

   1. 文件默认最大权限666,umask=022

      -rw-rw-rw-   减去  -----w--w-   等于 -rw-r--r--   (644)

  2. 文件默认最大权限666,umask=033

     -rw-rw-rw-   减去   -----wx-wx  等于 -rw-r--r--    (644)

 其实是做了一个逻辑与的运算。

目录的默认权限:

****1.目录默认权限最大是777。

    2.目录默认权限换算成字符在相减。

    3.建立目录之后的默认权限,是777减去umask的值。

修改umask的值:

****使用umask + 值,比如umask 0000;

   不过这样只是临时生效,要永久修改就要修改环境变量配置文件/etc/profile

三.ACL(Access Control List )权限


    linux系统中一个文件只有一个所属组,一个所有者,acl权限是解决用户对文件权限不足,也就是用户身份不够的情况下。打算让某个用户对这个文件有权限,不用考虑这个用户是哪个所有组
还是其他人。用acl给这个用户赋予权限。ACL权限 是解决用户对文件身份不足的问题(该用户不属于 拥有者 所属组 其他人)。系统是否支持ACL是与文件系统有关的。

 
首先查看系统分区中ACL权限是否开启,命令如下:

复制代码

先看下分区情况
[root@localhost tmp]# df
文件系统                    1K-块      已用     可用 已用% 挂载点
/dev/mapper/centos-root  39134548  29770328  9364220   77% /
devtmpfs                   923152         0   923152    0% /dev
tmpfs                      933636        80   933556    1% /dev/shm
tmpfs                      933636      9128   924508    1% /run
tmpfs                      933636         0   933636    0% /sys/fs/cgroup
/dev/mapper/centos-home  19105792     33080 19072712    1% /home
/dev/sda1                  508588    177692   330896   35% /boot
.host:/                 127927292 118371212  9556080   93% /mnt/hgfs
tmpfs                      186728        12   186716    1% /run/user/42
tmpfs                      186728         0   186728    0% /run/user/0

因为我安装的是centos7,所以我的系统文件系统是xfs类型,用xfs_growfs命令查看,如果文件系统是ext2/ext3/ext4可以用dumpe2fs命令查看指定分区详细文件系统信息。
[root@localhost tmp]# xfs_growfs /dev/sda1
meta-data=/dev/sda1              isize=256    agcount=4, agsize=32000 blks
         =                       sectsz=512   attr=2, projid32bit=1
         =                       crc=0        finobt=0 spinodes=0
data     =                       bsize=4096   blocks=128000, imaxpct=25
         =                       sunit=0      swidth=0 blks
naming   =version 2              bsize=4096   ascii-ci=0 ftype=0
log      =internal               bsize=4096   blocks=853, version=2
         =                       sectsz=512   sunit=0 blks, lazy-count=1
realtime =none                   extsz=4096   blocks=0, rtextents=0

复制代码

 查看系统是否支持ACL,使用dmesg命令(可以帮助用户了解系统的启动信息,可以查看ACL信息)查看,发现xfs文件系统是默认支持ACL权限的。

查看ACL权限:

设定ACL权限:

    setfacl   选项 文件名

    选项:

       -m:设定ACL权限。

       -x:删除指定的ACL权限。

       -b:删除所有的ACL权限。

      -d:设定默认的ACL权限。

      -k:删除默认的ACL权限。

      -R:递归设定ACL权限。

四.sudo权限


    sudo是linux系统管理指令,操作对象是系统命令。是允许让普通用户执行部分或者全部的系统管理员才能执行的命令的一个工具,限制某个普通用户有限的命令有root权限(比如说重启,备份,添加用户,ifconfig命令等)。sudo 执行时候不需要知道超级管理员的密码。

   sudo是超级用户赋予普通用户权限才能使用,sudo为系统管理员提供配置文件,使用visudo命令(这个命令可以防止两个用户同时修改它,也能进行有限的语法检查)可以打开该配置文件:

复制代码

[root@localhost ~]# visudo    这个命令实际是打开了/etc/sudoers文件
## Sudoers allows particular users to run various commands as
## the root user, without needing the root password.
##
## Examples are provided at the bottom of the file for collections
## of related commands, which can then be delegated out to particular
## users or groups.
... ...

复制代码

 在文件98行有个例子

格式解释: 用户名(给哪个用户赋予权限,这里是root)  被管理的主机地址(第一个ALL)= (可使用身份(第二个ALL),这个可以省略直接跟授权的命令)    授权的命令(要写绝对路径,命令写的越简单权限就越大,越详细普通用户获得权限就越小)

使用  man 5 sudoers  命令查看配置文件详细解释

 普通用户没有关闭系统的权限,如下提示。

复制代码

[song@localhost ~]$ shutdown -r now
==== AUTHENTICATING FOR org.freedesktop.login1.reboot ===
Authentication is required for rebooting the system.
Authenticating as: root
Password: Failed to execute operation: 连接超时
Must be root.
polkit-agent-helper-1: pam_authenticate failed: Authentication failure

复制代码

 在配置文件中最后一行给song用户添加shutdown权限并保存

 用song账号登录并用sudo -l 命令显示出自己(执行 sudo 的使用者)的权限。

复制代码

[song@localhost ~]$ sudo -l
[sudo] password for song:
匹配此主机上 song 的默认条目:
    requiretty, !visiblepw, always_set_home, env_reset, env_keep="COLORS
    DISPLAY HOSTNAME HISTSIZE INPUTRC KDEDIR LS_COLORS", env_keep+="MAIL PS1
    PS2 QTDIR USERNAME LANG LC_ADDRESS LC_CTYPE", env_keep+="LC_COLLATE
    LC_IDENTIFICATION LC_MEASUREMENT LC_MESSAGES", env_keep+="LC_MONETARY
    LC_NAME LC_NUMERIC LC_PAPER LC_TELEPHONE", env_keep+="LC_TIME LC_ALL
    LANGUAGE LINGUAS _XKB_CHARSET XAUTHORITY",
    secure_path=/sbin:/bin:/usr/sbin:/usr/bin

用户 song 可以在该主机上运行以下命令:
    (ALL) /sbin/shutdown -r now       这里song身份就被切换成ALL

复制代码

这里用sudo命令后面加配置文件赋予的命令去执行,不能写错,不然会执行不了,如下。

[song@localhost ~]$ sudo /sbin/shutdown -h now
对不起,用户 song 无权以 root 的身份在 localhost.localdomain 上执行 /sbin/shutdown -h now。

所以写成配置文件里一模一样的就可以执行

[song@localhost ~]$ sudo /sbin/shutdown -r now

 如果写多个可以用逗号分开

再看下

复制代码

[song@localhost ~]$ sudo -l
匹配此主机上 song 的默认条目:
    requiretty, !visiblepw, always_set_home, env_reset, env_keep="COLORS DISPLAY HOSTNAME HISTSIZE INPUTRC KDEDIR LS_COLORS", env_keep+="MAIL PS1 PS2 QTDIR USERNAME
    LANG LC_ADDRESS LC_CTYPE", env_keep+="LC_COLLATE LC_IDENTIFICATION LC_MEASUREMENT LC_MESSAGES", env_keep+="LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER LC_TELEPHONE",
    env_keep+="LC_TIME LC_ALL LANGUAGE LINGUAS _XKB_CHARSET XAUTHORITY", secure_path=/sbin:/bin:/usr/sbin:/usr/bin

用户 song 可以在该主机上运行以下命令:
    (ALL) /sbin/shutdown -r now, (ALL) /sbin/ls

复制代码

上面的例子是给某个用户赋予权限,当然我们也可以给一组用户赋予权限。也是在配置文件中

## Same thing without a password
# %wheel        ALL=(ALL)       NOPASSWD: ALL

上面wheel是组名,前面要加上%号,其它设置和用户一样。

sudo命令主要参数说明:

参数含义
-V显示版本编号及设置信息,下图。
-l显示出自己(执行 sudo 的使用者)的权限。
-uusername(用户名) 不加此参数,代表要以 root 的身份执行指令,否则是以 username 的身份执行指令。
-v```
延长密码有效期限。

 ![](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/298eb31ed31e41669b29cf3324848ecc~tplv-k3u1fbpfcp-zoom-1.image)![](<> "点击并拖拽以移动")​

### 五.文件的特殊权限SetUid & SetGid & Sticky BIT

***

###

     linux系统文件中除了读(r),写(w),执行(x)权限外,还有s和t这两个特殊的权限。当s这个标志出现在文件所有者的x权限上时,此时就被称为SetUid(简称SUID),当s出现在用户组(g)上就是SetGid,当s出现在其他用户(o)上就是Sticky Bit(简称SBIT)。

     SetUid的功能:

-    只有可执行的二进制程序才能设定SUID权限,就是这个文件可以执行才可以设定,否则不起作用。
-    命令执行者要对该程序拥有x(执行)权限。
-    命令执行者在执行该程序是获得该程序文件属主身份,打个比方,user1用户没有passwd文件的读取权限,那么user1用户希望能看见passwd文件内容,只能将自己的身份添加到passwd文件所属的用户组,或 者是用root用户登录,或者就是修改passwd的文件权限,也就是setuid这个特殊的文件权限。
-    SetUid权限只在该程序执行过程中有效,也就是说身份改变只在程序执行过程中有效。

赋SUID权限方式:

     数字赋予法:chmod **4**755 文件名。

     字母赋予法: chmod u+**s** 文件名  这里s就是SUID的意思,取消可以用chmod u-s 文件名。

普通用户不能设置SUID权限。要用root用户执行。

[song@localhost ~]$ chmod 4755 /bin/vi chmod: 更改"/bin/vi" 的权限: 不允许的操作


下面有个文件aaa,并且用户对该文件拥有执行权限,我们去给该文件添加SUID权限。

![](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/0bcc7dd171f94a4f85191de5418851b1~tplv-k3u1fbpfcp-zoom-1.image)![](<> "点击并拖拽以移动")​

 红色箭头那里之前x变成了s,表示aaa文件拥有了s权限,同时aaa文件也变成了红色,表示不安全。

 如果要是用户对aaa没有执行权限呢。我们创建一个新文件bbb,并修改其权限不包含执行权限。然后在赋予SUID。

![](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/a5a032139686484085963ec0bca5d3c4~tplv-k3u1fbpfcp-zoom-1.image)![](<> "点击并拖拽以移动")​

这里变成了大S,这里大S表示不能正确使用的。

我们知道用户的密码是保存在/etc/shadow文件中,我们看下这个文件的权限

[root@localhost tmp]# ll /etc/shadow ---------- 1 root root 1696 5月 27 18:58 /etc/shadow


发现这个文件的权限是000,用户属主是root,那么除了root用户能修改密码外,用户自己同样也能修改密码,为什么没有写入这个文件的权限去修改密码,这是因为这个SUID功能。我们看下passwd这个命令就知道原因了。

[root@localhost tmp]# which passwd /usr/bin/passwd [root@localhost tmp]# ll /usr/bin/passwd -rwsr-xr-x. 1 root root 27832 6月 10 2014 /usr/bin/passwd


首先passwd命令是可执行的,同时发现passwd命令默认就有SUID权限,而且任何用户对这个命令也有执行权限(最后有x),所以普通用户在执行这个命令的时候就会拥有这个命令所属主的身份,变成了root,命令执行完后这个身份就消失了又变成普通用户。

系统还有其他的命令也包含SUID权限,比如su命令。

![](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/d2127884d9204463bd2ab84aae44da50~tplv-k3u1fbpfcp-zoom-1.image)![](<> "点击并拖拽以移动")​

 SUID权限比较灵活,所以不能随意设置,不然会对系统造成潜在的危害。比如vi命令,如果添加SUID权限,那么普通用户获取root身份就可以修改所有的文件。

 所以SUID(也包括SGID)权限原则:

-   关键的目录要严格控制写权限,比如根目录“/”,“/usr”目录等。
-   用户的密码设置要严格遵守密码三原则(复杂性,易记性,时效性)。
-   对系统中默认应该具有SUID,SGID权限的文件列表出来,定时检查有没有之外的文件被设置SUID,SGID权限。可以通过find命令查找。

[![复制代码](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/8f48f5cfb07241e0b7652086406ed9a9~tplv-k3u1fbpfcp-zoom-1.image)]()![](<> "点击并拖拽以移动")​

[root@localhost tmp]# find / -type f ( -perm -04000 -o -perm -02000 ) -exec ls -lg {} ; 04000表示SUID 02000表示SGID -o表示或者的意思 find: ‘/proc/26739/task/26739/fdinfo/6’: 没有那个文件或目录 find: ‘/proc/26739/fdinfo/6’: 没有那个文件或目录 -rwsr-xr-x 1 root 0 5月 28 14:19 /root/tmp/aaa -rwSr--r-- 1 root 0 5月 28 14:30 /root/tmp/bbb -rwsr-xr-x. 1 root 32584 6月 10 2014 /usr/bin/fusermount -r-xr-sr-x. 1 tty 15344 6月 10 2014 /usr/bin/wall -rwsr-xr-x. 1 root 64200 3月 6 2015 /usr/bin/chage -rws--x--x. 1 root 23960 3月 6 2015 /usr/bin/chfn -rws--x--x. 1 root 23856 3月 6 2015 /usr/bin/chsh -rwsr-xr-x. 1 root 44232 3月 6 2015 /usr/bin/mount -rwsr-xr-x. 1 root 32064 3月 6 2015 /usr/bin/su -rwxr-sr-x. 1 tty 19536 3月 6 2015 /usr/bin/write -rwsr-xr-x. 1 root 78168 3月 6 2015 /usr/bin/gpasswd -rwsr-xr-x. 1 root 41752 3月 6 2015 /usr/bin/newgrp


[![复制代码](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/d32db0a2f5534e83a66e4c4b3cf17afc~tplv-k3u1fbpfcp-zoom-1.image)]()![](<> "点击并拖拽以移动")​

在上面我们新创建一个文件系统会根据umask的设置赋予新文件一个权限,那么umask的值是四位,如下:

[root@localhost ~]# umask 0022


可是我们通过chmod命令给文件赋予权限一般都是三位数字,比如755,644等,那么这个umask后三位022是基本默认权限,第一位0就是特殊权限。

### 六.chattr权限(不可改变位权限)

***

###

      chattr命令用于改变文件属性,只针对root用户有效。

      格式:chattr [ + - = ] [选项]  文件或目录,这里的[ + - = ]是控制文件的属性。

                + : 增加权限。

                - :  删除权限。

               = : 赋予/等于某权限。

     常用选项:

           i: 即insert,不得任意更动文件或目录。

                如果对文件设置i属性,那么不允许对文件进行删除,重命名,添加和修改数据,相当于锁定这个文件。如果对目录设置i属性,那么只能修改目录下的文件数据(文件数据保存在文件自己的数据块中),不允许建立和删除文件。

           a:即append,让文件或目录仅供附加用途。

                如果对文件设置a属性,只能在文件中添加数据(因为vi被禁用了,所以用echo  >> 输出重定向追加的方式),不能删除也不能修改数据。如果对目录设置a属性,那么只允许在目录中新建和修改文件,不允许删除文件,可以适用于各种日志文件。

 案例:

给文件添加i属性

[root@localhost tmp]# chattr +i aa.txt [root@localhost tmp]# lsattr aa.txt 用lsattr命令查看 ----i----------- aa.txt


不允许删除

[root@localhost tmp]# rm -rf aa.txt rm: 无法删除"aa.txt": 不允许的操作


 给目录添加i属性

[![复制代码](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/f20427f97428407fb67810e637700f4c~tplv-k3u1fbpfcp-zoom-1.image)]()![](<> "点击并拖拽以移动")​

[root@localhost tmp]# chattr +i dir [root@localhost tmp]# lsattr -d dir ----i----------- dir [root@localhost tmp]# cd dir [root@localhost dir]# touch a.txt touch: 无法创建"a.txt": 权限不够


[![复制代码](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/66b47ae7683a44a7b7d25401cfa51ed3~tplv-k3u1fbpfcp-zoom-1.image)]()![](<> "点击并拖拽以移动")​

### 七.Linux常用权限

  1.600(rw------):只有root有读写权限。

  2.644(rw-r--r--):只有root有读写权限;group用户和other用户只有读权限。

  3.755(rwxr-xr-x):root有读、写、执行权限;group用户和other用户只有读、执行权限。

​