心宇

FDF24DCED8C6738F8313A6D3B073C3F4

首页 管理

Linux 权限、安全上下文与特殊权限

Linux 的安全机制可以理解为多个层次。

最基础的一层是传统 Unix 权限模型:

User / Group / Other
        +
r / w / x

在此基础上还有:

SUID
SGID
Sticky Bit
ACL

更高级的安全机制还包括:

Capabilities
SELinux
AppArmor
seccomp
Namespaces

本章主要讨论:

传统 Linux 文件权限 + 特殊权限位 + ACL。


一、Linux 权限判断的基本对象

例如:

ls -l test.txt

得到:

-rw-r----- 1 userA group1 1024 Oct 1 10:00 test.txt

可以拆解为:

-  rw-  r--  ---
│   │    │    │
│   │    │    └── Other 权限
│   │    └─────── Group 权限
│   └──────────── Owner 权限
└──────────────── 文件类型

文件:

Owner = userA
Group = group1

权限:

Owner → rw-
Group → r--
Other → ---

二、Linux 判断权限时看的是进程身份

需要建立一个非常重要的概念:

真正访问文件的不是“登录用户”这个抽象概念,而是进程。

例如:

userA
  ↓
启动 bash
  ↓
bash 启动 cat
  ↓
cat 进程
  ↓
访问 test.txt

内核最终判断的是:

这个进程以什么 UID / GID 身份运行,它是否有权限访问这个文件?

因此 Linux 文件权限本质上是:

Process Credentials
        ↓
与
        ↓
File Owner / Group / Mode
        ↓
进行匹配

三、进程中的 UID

Linux 进程实际上存在多种 UID,其中最重要的是:

Real UID       RUID
Effective UID  EUID
Saved UID      SUID / Saved-set-user-ID

注意这里的:

Saved UID

也经常缩写为 SUID,但它和文件权限中的:

Set User ID

不是完全相同的概念。


Real UID

表示:

谁启动了这个进程。

例如:

userA
  ↓
执行 passwd

通常:

Real UID = userA

Effective UID

表示:

当前进程实际进行权限检查时使用的用户身份。

Linux 内核在进行传统文件权限判断时,重点使用的是:

Effective UID

因此可以简单记忆:

RUID → 谁启动了我

EUID → 我现在以谁的权限工作

SUID 程序的核心作用,就是可能让:

RUID ≠ EUID

四、Linux 文件权限匹配规则

假设:

-rw-r----- 1 userA group1 test.txt

某个进程准备访问 test.txt。

Linux 会按照一定顺序判断。


第一步:判断 Owner

如果进程的有效用户身份与文件 Owner 匹配:

Process EUID
      ==
File Owner UID

那么:

只使用 Owner 权限。

例如:

-rw-r----- userA group1 test.txt

如果:

EUID = userA

则检查:

rw-

五、Owner 匹配后不会继续检查 Group

这一点非常重要。

假设:

----rwx--- userA group1 test

userA 同时也是 group1 成员。

此时 userA 访问文件:

Owner 权限 = ---
Group 权限 = rwx

因为:

EUID == Owner

所以直接使用:

Owner = ---

不会因为 Group 有 rwx 就继续尝试 Group 权限。

因此权限判断不是:

“Owner 不够,再看看 Group 能不能补权限。”

而是:

身份匹配到哪一类,就使用哪一类权限。


六、第二步:判断 Group

只有 Owner 不匹配时,才判断 Group。

Linux 会检查进程的组身份是否匹配文件 Group。

这里不仅涉及:

Effective GID

还涉及:

Supplementary Groups

即用户的附加组。

例如:

id userB

可能得到:

uid=1001(userB)
gid=1001(userB)
groups=1001(userB),2000(group1)

虽然:

Primary Group = userB

但是:

Supplementary Group = group1

因此 userB 的进程仍然可以匹配:

File Group = group1

然后使用 Group 权限。


七、第三步:Other

如果:

Owner 不匹配
        &&
Group 不匹配

那么:

使用 Other 权限

因此传统 Unix 权限判断可以总结成:

        Process
           │
           ▼
EUID == File Owner?
     │
 ┌───┴───┐
YES      NO
 │        │
Owner     ▼
权限    Group 匹配?
          │
      ┌───┴───┐
     YES      NO
      │        │
    Group    Other
     权限      权限

一句话记忆:

Owner → Group → Other,匹配成功后立即使用对应权限,不会继续向后叠加权限。


八、root 的权限

root:

UID = 0

在传统 DAC 权限模型中拥有非常高的权限,并且可以绕过大量普通文件权限检查。

但是不能简单理解成:

root 永远拥有无限权限。

现代 Linux 还可能受到:

SELinux
AppArmor
Capabilities
Namespaces
只读文件系统
Immutable 属性

等机制影响。

因此:

rwx

只是 Linux 安全模型的一层。


九、SUID

SUID:

Set User ID

主要用于:

可执行文件。

假设:

-rwxr-xr-x 1 root root program

userA 执行:

./program

正常情况下:

RUID = userA
EUID = userA

也就是说:

普通用户执行一个属于 root 的程序,并不意味着程序自动获得 root 权限。


十、设置 SUID

执行:

chmod u+s program

文件权限可能变成:

-rwsr-xr-x root root program

此时 userA 执行:

./program

进程可能变成:

RUID = userA
EUID = root

因此程序在执行某些权限检查时具有:

root

的有效身份。

所以更准确地说:

SUID 使可执行程序运行时的 Effective UID 设置为该可执行文件 Owner 的 UID。

而不是简单地说:

“整个进程变成了文件所有者。”

因为:

RUID

通常仍然记录真正启动程序的用户。


十一、passwd 为什么需要 SUID?

经典例子:

/usr/bin/passwd

查看:

ls -l /usr/bin/passwd

可能看到:

-rwsr-xr-x 1 root root ... /usr/bin/passwd

普通用户执行:

passwd

需要修改系统保存密码信息的受保护资源。

普通用户本身没有直接修改这些系统文件的权限。

但是 passwd:

Owner = root
SUID = enabled

因此执行过程中可以获得完成特定受保护操作所需要的权限。

注意:

这并不意味着普通用户可以通过 passwd 任意修改系统文件。

因为程序自身的代码逻辑仍然会限制:

允许修改什么
允许修改谁的密码
需要进行什么认证

SUID 只是提供程序完成受保护操作所需要的权限基础。


十二、SUID 的 s 和 S

例如:

-rwsr-xr-x

Owner 权限中的:

s

实际上表示两个权限同时存在:

x
+
SUID

即:

Owner 有执行权限
SUID 已设置

如果:

-rwSr-xr-x

大写:

S

表示:

SUID 已设置
但是 Owner 没有 x 权限

因此:

s = SUID + x

S = SUID,但是没有 x

十三、设置 SUID

符号方式:

chmod u+s FILE

取消:

chmod u-s FILE

数字方式:

SUID = 4

例如:

chmod 4755 program

其中:

4 755
│  │
│  └── 普通 rwx 权限
│
└───── SUID

十四、SUID 主要针对可执行文件

不要随意给普通程序设置:

chmod u+s

尤其:

Shell
解释器
编辑器
脚本
用户可修改的程序

因为 SUID 程序可能形成严重的提权风险。

特别是:

Owner = root
+
SUID

意味着程序可能拥有非常高的系统权限。

因此 SUID 是 Linux 安全审计中的重点对象。

可以搜索:

find / -perm -4000 -type f 2>/dev/null

查找系统中的 SUID 文件。


十五、SGID

SGID:

Set Group ID

数值表示:

2

设置:

chmod g+s FILE

或者:

chmod 2755 FILE

SGID 有两种非常重要的用途:

SGID on Executable File
SGID on Directory

二者必须分开理解。


十六、SGID 用于可执行文件

如果:

-rwxr-sr-x root group1 program

那么执行这个程序时:

进程的 Effective GID 可以设置为该文件所属组的 GID。

也就是说:

SUID
→ 改变 Effective UID

SGID
→ 改变 Effective GID

十七、SGID 用于目录

SGID 更常见、更实用的场景是:

共享目录。

假设创建:

groupadd group1

useradd a1
useradd a2

usermod -aG group1 a1
usermod -aG group1 a2

创建共享目录:

mkdir /var/tmp3
chown root:group1 /var/tmp3
chmod 2775 /var/tmp3

查看:

ls -ld /var/tmp3

得到:

drwxrwsr-x root group1 /var/tmp3

这里:

s

表示目录设置了 SGID。


十八、目录 SGID 的作用

正常情况下,用户创建文件时,新文件的 Group 通常根据进程的文件创建规则决定,通常与创建进程的文件系统凭据有关。

但是:

如果父目录设置了 SGID,新创建的文件和子目录通常会继承父目录的 Group。

例如:

/var/tmp3

Owner = root
Group = group1
SGID = enabled

a1 创建:

touch /var/tmp3/a.txt

a2 创建:

touch /var/tmp3/b.txt

可能得到:

-rw-rw-r-- a1 group1 a.txt
-rw-rw-r-- a2 group1 b.txt

重点:

Owner 不同
Group 相同

这非常适合:

多人共享工作目录。


十九、SGID 不代表组成员一定可以修改文件

这是非常容易混淆的一点。

SGID 只保证:

新文件继承父目录的 Group。

至于 group1 是否真的能够修改文件,还要看:

文件的 Group 权限
+
umask
+
ACL

例如:

-rw-r--r-- a1 group1 test

即使:

a2 ∈ group1

a2 仍然没有写权限。

因为:

Group = r--

因此多人共享目录经常需要:

SGID
+
合适的 Group 权限
+
umask / Default ACL

一起使用。


二十、目录删除文件看什么权限?

这是理解 Sticky Bit 前最重要的知识。

很多人认为:

“我没有文件的写权限,所以我不能删除它。”

这并不准确。

Linux 中:

删除文件,本质上是在修改父目录中的目录项。

因此删除文件主要看:

父目录的权限

而不是文件本身的 w 权限。

假设:

drwxrwxrwx shared/

里面:

-rw------- a1 a1 secret.txt

即使 a2:

不能读取 secret.txt
不能修改 secret.txt

但如果 a2 对:

shared/

拥有足够的:

w + x

目录权限,那么在没有 Sticky Bit 等额外限制时,a2 可能仍然能够:

删除
重命名

这个文件的目录项。


二十一、Sticky Bit

Sticky Bit 主要用于:

共享可写目录。

设置:

chmod o+t /var/tmp3

或者数字方式:

chmod 1777 /var/tmp3

例如:

drwxrwxrwt root root /tmp

最后:

t

就是 Sticky Bit。


二十二、Sticky Bit 的作用

在一个所有人都可写的共享目录中,如果没有 Sticky Bit:

a1 创建 file1
a2 创建 file2

只要目录权限允许:

a1 可能删除 file2
a2 可能删除 file1

设置 Sticky Bit 后,会对删除和重命名增加额外限制。

通常只有:

文件所有者
目录所有者
或具有相应特权的进程

才能删除或重命名目录中的对应文件。

因此:

Sticky Bit
≈
共享目录中限制用户删除/重命名其他用户的文件

二十三、最经典的 Sticky Bit:/tmp

执行:

ls -ld /tmp

通常可以看到:

drwxrwxrwt root root /tmp

即:

777
+
Sticky Bit

为什么?

因为:

/tmp

需要允许大量用户和程序创建临时文件。

如果只有:

777

那么用户之间可能互相删除对方的文件。

因此使用:

1777

二十四、Sticky Bit 的 t 和 T

和 SUID/SGID 类似:

t

表示:

Sticky Bit
+
Other 有 x 权限

而:

T

表示:

Sticky Bit
+
Other 没有 x 权限

例如:

drwxrwxrwt
         ↑
         t

二十五、特殊权限位总结

三个特殊权限:

SUID       4
SGID       2
Sticky     1

因此:

chmod 4755 file
      ↑
      SUID

chmod 2755 directory
      ↑
      SGID

chmod 1777 directory
      ↑
      Sticky

可以记成:

4 → SUID
2 → SGID
1 → Sticky

二十六、三种特殊权限的核心区别

SUID
│
└─ 可执行文件
   → 影响 Effective UID


SGID
│
├─ 可执行文件
│  → 影响 Effective GID
│
└─ 目录
   → 新文件继承目录 Group


Sticky Bit
│
└─ 目录
   → 限制共享目录中删除/重命名他人文件

这是最值得记住的模型。


二十七、SGID + Sticky Bit

例如:

mkdir /shared
chown root:group1 /shared
chmod 3770 /shared

这里:

3
=
2 + 1
=
SGID + Sticky

因此:

SGID
↓
新文件继承 group1

Sticky
↓
限制成员删除/重命名其他成员拥有的文件

适用于某些共享目录场景。

但是:

不能简单地说“SGID + Sticky 通常用于 /var 日志目录”。

不同日志目录和服务有不同权限模型。现代 Linux 日志服务还可能使用:

systemd-journald
ACL
专用用户
专用组
logrotate
SELinux

因此 SGID + Sticky 更准确的典型场景是:

多人或多进程共享、需要统一 Group,同时又希望限制互相删除文件的目录。


二十八、ACL:Access Control List

传统 Linux 权限只有:

一个 Owner
一个 Group
一个 Other

有时不够灵活。

例如:

hello.c

Owner = userA
Group = userA

现在希望:

userB → rw
userC → r
groupDev → rw

如果只使用传统:

Owner / Group / Other

就比较麻烦。

因此 Linux 支持:

POSIX ACL

即:

Access Control List

二十九、查看 ACL

使用:

getfacl hello.c

例如:

# file: hello.c
# owner: userA
# group: userA

user::rw-
user:userB:rw-
group::r--
mask::rw-
other::---

三十、给指定用户授权

例如:

setfacl -m u:userB:rw hello.c

表示:

-m
=
modify ACL

然后:

u:userB:rw

表示:

userB
=
read + write

三十一、给指定组授权

例如:

setfacl -m g:groupDev:rw hello.c

表示:

groupDev
=
read + write

注意你原笔记这里写成了:

g:userB

如果 userB 是用户名而不是组名,就不应该这样写。


三十二、删除指定用户 ACL

删除 userB 的 ACL:

setfacl -x u:userB hello.c

注意:

-x

删除 ACL 项时一般不再写:

:rwx

所以正确形式:

setfacl -x u:userB hello.c

而不是:

setfacl -x u:userB:rwx hello.c

三十三、删除指定组 ACL

例如:

setfacl -x g:groupDev hello.c

三十四、删除所有扩展 ACL

可以:

setfacl -b hello.c

其中:

-b
=
remove all extended ACL entries

三十五、ACL 中非常重要的 mask

ACL 中经常看到:

mask::rw-

这是非常重要的一项。

例如:

user:userB:rwx
mask::rw-

虽然给 userB 配置:

rwx

但 mask:

rw-

会限制相关 ACL 条目的最大有效权限。

因此 userB 实际有效权限可能只有:

rw-

getfacl 有时会显示:

user:userB:rwx        #effective:rw-

因此 ACL 排错时一定要检查:

mask

三十六、ACL 与 ls -l

如果文件存在扩展 ACL:

ls -l hello.c

可能看到:

-rw-rw----+ 1 userA userA hello.c
          ↑
          +

最后的:

+

通常表示该文件存在扩展 ACL。

这时不能只看:

rwx

还应该:

getfacl hello.c

三十七、Default ACL

ACL 对目录还有一个非常实用的功能:

Default ACL

它可以让:

在目录中新创建的文件自动继承预设 ACL。

例如共享开发目录:

mkdir /project
chown root:groupDev /project
chmod 2770 /project

设置默认 ACL:

setfacl -m d:g:groupDev:rwx /project

这里:

d:
=
default

以后在 /project 中创建的新文件和子目录,就可以继承相应 ACL。

查看:

getfacl /project

可能看到:

default:user::rwx
default:group::rwx
default:group:groupDev:rwx
default:mask::rwx
default:other::---

三十八、SGID + Default ACL 是共享目录的常见组合

多人协作目录经常可以使用:

SGID
+
Default ACL

SGID 负责:

继承 Group

Default ACL 负责:

继承更精细的权限

例如:

chown root:developers /project
chmod 2770 /project

setfacl -m d:g:developers:rwx /project

形成:

/project
   │
   ├── SGID
   │      ↓
   │   新文件继承 developers 组
   │
   └── Default ACL
          ↓
       新文件继承指定 ACL

三十九、Linux 权限体系整体关系

到这里可以把 Linux 文件权限理解成:

                 Linux 文件访问
                       │
                       ▼
              Process Credentials
                       │
              ┌────────┴────────┐
              │                 │
             UID               GID
              │                 │
              └────────┬────────┘
                       ▼
                DAC 权限检查
                       │
        ┌──────────────┼──────────────┐
        ▼              ▼              ▼
      Owner           Group          Other
        │              │              │
        └──────────────┴──────────────┘
                       │
                    rwx 权限
                       │
              ┌────────┴────────┐
              ▼                 ▼
        特殊权限位             ACL
              │                 │
        ┌─────┼─────┐      精细用户/组权限
        ▼     ▼     ▼
      SUID   SGID  Sticky

在现代 Linux 中,上面这些还可能继续受到:

SELinux / AppArmor
Capabilities
seccomp
Namespaces
文件系统属性
Mount Options

等安全机制限制。


四十、最终记忆模型

传统 Linux 权限最核心的规则:

Owner 匹配
   ↓
使用 Owner 权限
   ↓
结束

否则
   ↓
Group 匹配
   ↓
使用 Group 权限
   ↓
结束

否则
   ↓
使用 Other 权限

特殊权限:

SUID
→ 执行程序时影响 Effective UID

SGID
→ 可执行程序:影响 Effective GID
→ 目录:新文件继承目录 Group

Sticky Bit
→ 共享目录中限制删除/重命名他人的文件

ACL:

传统 rwx 不够
       ↓
使用 ACL
       ↓
针对特定 User / Group 单独授权
       ↓
同时注意 ACL Mask

因此可以把这一章浓缩成一句话:

Linux 传统文件安全模型的核心,是内核根据进程的有效身份(UID/GID)与文件的 Owner、Group、Other 权限进行匹配;SUID/SGID 可以影响进程执行身份或目录的组继承,Sticky Bit 用于保护共享目录中的文件,而 ACL 则在传统 rwx 模型之上提供更加精细的用户和组权限控制。

posted on 2026-10-01 08:12  心宇16969  阅读(17)  评论(0)    收藏  举报