Linux文件系统上的特殊权限


纸上得来终觉浅,绝知此事要躬行。

Linux 的文件权限,远不止 rwx 那么简单,还有一些特殊权限是用来打破限制和默认的安全上下文规则的,除了之前介绍过的隐藏属性,还有几个显式的特殊权限。下面就来说说 Linux 文件系统上的 SUIDSGIDSticky 权限。

Linux文件系统上的特殊权限


1. 权限分类

Linux 系统上面关于用户、组、其他的人的权限的基本分类

  • user
    • r
    • w
    • x
  • group
    • r
    • w
    • x
  • other
    • r
    • w
    • x

  • 目录 - rwx - 说明
    • r
      • 有读取目录内容列表的权限
      • 即可以使用 ls 命令查看该目录的内容列表
    • w
      • 有更改目录的权限
      • 即可以在此目录下新建文件或子目录等
    • x
      • 可以进入该目录
      • 即可以使用 cd 命令进入该目录
  • 文件 - rwx - 说明
    • r
      • 可读取此文件的内容
      • 即可以读取文件
    • w
      • 可编辑此文件的内容
      • 即可以增加、删除、更改文件内容
    • x
      • 可以执行此文件

2. 安全上下文

前提:进程有属主和属组;文件有属主和属组

  • (1) 任何一个可执行程序文件能不能启动为进程,取决发起者对程序文件是否拥有执行权限
  • (2) 启动为进程之后,其进程的属主为发起者,进程的属组为发起者所属的组
  • (3) 进程访问文件时的权限,取决于进程的发起者
    • (a) 进程的发起者,同文件的属主,则应用文件属主权限
    • (b) 进程的发起者,属于文件的属组,则应用文件属组权限
    • (c) 应用文件“其它”权限

3. 特殊权限

3.1 SUID

  • 含义解释
    • 任何一个可执行程序文件能不能启动为进程,取决发起者对程序文件是否拥有执行权限
    • 启动为进程之后,其进程的属主为原程序文件的属主
  • 权限设定
$ chmod u+s FILE...
$ chmod u-s FILE...

3.2 SGID

  • 含义解释
    • 默认情况下,用户创建文件时,其属组为此用户所属的基本组
    • 一旦某目录被设定了 SGID,则对此目录有写权限的用户在此目录中创建的文件所属的组为此目录的属组
  • 权限设定
$ chmod g+s DIR...
$ chmod g-s DIR...

3.3 Sticky

  • 含义解释
    • 对于一个多人可写的目录,如果设置了 sticky,则每个用户仅能删除自己的文件
  • 权限设定
$ chmod o+t DIR...
$ chmod o-t DIR...

$ chmod 4777 /tmp/a.txt
| NUM | SUID | SGID | STICKY |
| --- | ---- | ---- | ------ |
| 0   | 0    | 0    | 0      |
| 1   | 0    | 0    | 1      |
| 2   | 0    | 1    | 0      |
| 3   | 0    | 1    | 1      |
| 4   | 1    | 0    | 0      |
| 5   | 1    | 0    | 1      |
| 6   | 1    | 1    | 0      |
| 7   | 1    | 1    | 1      |

3.4 三个权限位映射

请注意,在权限位上可能会出现 sS,其意义实际上不一样。

  • SUID: user - 占据属主的执行权限位

    • s: 属主拥有 x 权限
    • S:属主没有 x 权限
  • SGID: group - 占据 group 的执行权限位

    • s: group 拥有 x 权限
    • Sgroup 没有 x 权限
  • Sticky: other - 占据 ohter 的执行权限位

    • t: other 拥有 x 权限
    • Tother 没有 x 权限

3.5 chattr 命令

注释: ls 是看不到 attr 属性的,可以用 lsattr 显示特定属性。

  • chattr +i xxx 锁定该文件 ,不允许修改/删除/重命名/重定向方式清空也不可以
  • chattr -i xxx 去掉锁定
  • chattr +a xxx 只能 >> 追加内容,不能删除和减少
  • chattr -a xxx 去掉只能追加这种锁定
$ touch file1
$ chattr +i file1
$ lsattr file1
----i----------- file1

$ echo "escape" > file1
-bash: file1: Permission denied

$ echo "escape" >> file1
-bash: file1: Permission denied

$ mv file1 /tmp
mv: cannot remove ‘file1’: Operation not permitted

$ rm file1
rm: remove regular empty file ‘file1’? y
rm: cannot remove ‘file1’: Operation not permitted
$ touch file2
$ chattr +a file2
$ lsattr file2
-----a---------- file2

$ echo "escape" > file2
-bash: file2: Operation not permitted

$ echo "escape" >> file2
$ cat file2
escape

$ rm file2
rm: remove regular file ‘file2’? y
rm: cannot remove ‘file2’: Operation not permitted

4. ACL 访问控制列表

ACL:Access Control List 访问控制列表。除了文件原本的权限位设置,可以自定义用户访问控制。

  • CentOS 7 默认创建的 xfsext4 文件系统具有 ACL 功能
  • CentOS 7 之前版本,系统安装时候创建的文件系统有 ACL 功能,默认手工创建的 ext4 文件系统无 ACL 功 能,需手动增加。
# 比如在CentOS6上新加一块磁盘,创建了sdb1分区,可以用下面命令使其支持ACL
$ tune2fs –o acl /dev/sdb1
$ mount –o acl /dev/sdb1 /mnt/test

4.1 getfacl XXX

  • 获取文件或文件夹的权限
# 默认的从上到下的权限依次是:
# owner:文件的拥有者
# group:文件的拥有组
> user:自定义的用户(可多个)
> group:自定义的组(可多个)
> other:自定义的其它用户(可多个)

# 如果一个用户属于多个自定义的组,权限是这几个组的权限的累加。
$ touch a
$ getfacl a
# file: a
# owner: root
# group: root
user::rw-
group::r--
other::r--

$ mkdir dir1
$ getfacl dir1
# file: dir1
# owner: root
# group: root
user::rwx
group::r-x
other::r-x

4.2 setfacl 基础命令

  • 给一个文件加了facl的话,整个权限位后面会有个+号,表示设置了facl权限。
  • -m 参数,表示modify修改的意思
# 禁止escape用户访问file1
$ setfacl -m u:escape:000 file1

$ getfacl file1
# file: file1
# owner: root
# group: root
user::rw-
user:escape:---
group::r--
mask::r--
other::r--
# 禁止escape组访问file2
$ setfacl -m g:escape:rw- file2

$ getfacl file2
# file: file2
# owner: root
# group: root
user::rw-
group::r--
group:escape:rw-
mask::r--
other::r--
# 禁止其它用户访问file1
$ setfacl -m o:0 file3

$ getfacl file3
# file: file3
# owner: root
# group: root
user::rw-
group::r--
other::---

4.3 setfacl 的其他用法

  • setfacl -Rb *:清除所有acl
  • setfacl -M TEXT:利用列表来批量设置权限
$ cat file.acl
u:escape:-
g:escape:rwx

$ setfacl -M file.acl xxx

$ getfacl xxx
# file: xxx
# owner: root
# group: root
user::rw-
user:escape:---
group::rw-
group:escape:rwx
mask::rwx
other::rw-
  • -d 参数,表示默认在facl权限下的目录,新创建的文件和文件夹继承上一级目录的权限。
# 那么在dir2下新创建的目录就默认继承dir2的acl权限
setfacl -md d:u:yu:rwx /app/dir2
  • -x表示删除某个权限
setfacl -x u:yu:rwx /app/dir2
  • -X按照文件里的内容来批量删除权限
setfacl -X file.acl xxx

4.4 ACL 中的 mask

  • faclmask是高压线,是影响自定义用户和自定义组的权限,有了mask后,会与自定义的用户和组的权限做逻辑与,这之后是自定义用户和组的真实权限。
  • 默认是没有高压线的,默认值一般都是所有自定义用户和组的最高权限累加。
  • 如果设置了,就相当于设定了高压线,高于这个高压线的权限,会降低到高压线之下。
# 设置了高压线后,自定义用户和自定义组的有效值是不超过mask的r--
$ touch file4
$ setfacl -m u:yu:rwx file4
$ setfacl -m g:yu:rw- file4
$ getfacl file4
# file: file4
# owner: root
# group: root
user::rw-
user:yu:rwx
group::r--
group:yu:rw-
mask::rwx
other::r--

$ setfacl -m m:r-- file4

$ getfacl file4
# file: file4
# owner: root
# group: root
user::rw-
user:yu:rwx #effective:r--
group::r--
group:yu:rw- #effective:r--
mask::r--
other::r--

4.5 facl 权限的复制、备份和恢复

  • 复制acl权限
  • getfacl file1 | setfacl --set-file=- file2
  • 主要的文件操作命令cpmv都支持ACL,只是cp命令需要加上-p 参数。但是tar等常见的备份工具是不会保留目录和文件的ACL信息。
# 得到app目录及其目录里所有文件的acl权限(-R参数),写入到/root/app.acl文件里
$ getfacl -R /app >/root/app.acl

# 去掉/app目录及其目录里所有文件的acl权限(-b去除)
$ setfacl -R -b /app
# 恢复权限

# 绝对路径法
$ setfacl --set-file=/root/app.acl /app

# 相对路径法(需要在要恢复的文件夹或文件的上一级目录运行)
$ setfacl --restore /root/app.acl

5. 实例演示

SUID

  • 普通用户通过passwd命令修改自己的密码

setfacl

# 修改的密码最终会存储在/etc/shadow文件中,虽然用户有passwd命令的执行权限,但是shadow文件的权限为000
# 参考上文所说的进程的安全上下文,是没有权限修改密码的,那么为何我们能修改密码成功呢?
$ sudo ll /etc/shadow
----------. 1 root root 823 Nov  2 15:36 /etc/shadow

# 查看一下passwd这个可执行程序文件的权限,竟然是rws,出现了s权限,这就是SUID权限
# 这里A用户执行passwd实际上进程属主不再是A而是root所以能修改密码了
$ ll /usr/bin/passwd
-rwsr-xr-x. 1 root root 30768 Feb 22  2012 /usr/bin/passwd

# 使用chmod命令就可以实现
$ sudo chmod u+s /usr/bin/passwd

SGID

  • 大家创建各自的文件实现协同工作
# 默认情况下,用户A创建一个文件其属主是A,属组是A的基本组这没有问题。
# 如果在一个公共目录中,大家创建各自的文件想实现协同工作,但是由于系统的这种默认机制显然A用户访问B用户的文件会被禁止,因为不在一个组呀!
# 当某个目录设定为SGID权限后,则对此目录拥有写权限的用户在此目录中创建的文件属组为目录的属组,而非用户的基本组
$ sudo chmod g+s /tmp/public

Sticky

  • 在一个协同工作目录中,用户可以互相编辑文件但是不允许删除别人的文件
$ sudo chmod o+t /tmp/public

ACL

# 在/testdir/dir里创建的新文件自动属于g1组
# 组g2的成员如alice能对这些新文件有读写权限
# 组g3的成员如tom只能对新文件有读权限
# 其它用户(不属于g1,g2,g3)不能访问这个文件夹。

# 前期准备
$ echo g{1,2,3} | xargs -n 1 groupadd
$ tail -n 3 /etc/group
g1:x:1002:
g2:x:1003:
g3:x:1004:
$ useradd alice -g g2
$ useradd tom -g g3

# 题目解答
$ chgrp g1 /testdir/dir
$ chmod g+s /testdir/dir
$ setfacl -Rm d:g:g2:rw /testdir/dir
$ setfacl -Rm d:g:g3:r /testdir/dir
$ chmod o= /testdir/dir
# 2、备份`/testdir/dir`里所有文件的ACL权限到`/root/acl.txt`中,清除`/testdir/dir`中所有ACL权限 ,最后还原ACL权限。

# 备份权限
$ getfacl -R /testdir/dir > /root/acl.txt

# 清除/testdir/dir权限
$ testdir/dir

# 还原ACL权限,两种方法。
# 第一种绝对路径法:
$ setfacl --set-file=/root/acl.txt /testdir/dir

# 第二种相对路径法(查看acl.txt看是相对路径testdir/dir,是相对于/的,所以先cd到/,这步不能省)
$ cd /
$ setfacl --restore /root/acl.txt

文章作者: Escape
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 Escape !
  目录