🔍搜索⌘K

Linux 权限进阶:一文读懂 SUID、SGID 与粘滞位

概述

Linux 的基础权限(读 r、写 w、执行 x)能满足绝大多数文件访问控制需求,但碰到系统管理(比如普通用户改密码)和多人协作(比如团队共享文件)这些场景,普通权限就有点「力不从心」了。

SUID、SGID 和粘滞位(Sticky Bit)是 Linux 给的特殊权限位,它们打破了「用户只能以自己身份操作文件」的限制,既能让普通用户执行高权限命令,又能在多人共享时保住文件安全。搞懂这三个特殊权限,是从「Linux 入门」跨到「系统运维进阶」的关键一步。

一、SUID:让普通用户以文件所有者身份执行命令

1. SUID 是什么?

SUID(Set User ID on Execution)是一种「执行时切换身份」的机制:一个文件设了 SUID 位之后,普通用户跑这个文件时会临时拿到文件所有者的权限(执行完权限自动收回),而不是以自己身份跑。

最典型的例子就是 /usr/bin/passwd 命令。这命令所有者是 root,普通用户改自己密码得往 /etc/shadow(只有 root 能写的密码文件)里写——正是 SUID 让普通用户能临时以 root 身份执行 passwd,才把密码改成功了。

2. SUID 的核心特点与限制

特点 / 限制说明
仅作用于可执行文件非可执行文件设 SUID 没意义(执行权限是 SUID 生效的前提)
仅支持二进制文件Shell 脚本没法设 SUID(Linux 为了安全,禁止脚本靠 SUID 提权)
执行时临时获所有者权限只在文件执行期间生效,执行完立即收回,避免权限泄露
对目录无效SUID 位设在目录上时,Linux 会忽略(目录的特殊权限归 SGID 管)

3. 如何查看与设置 SUID?

(1)查看 SUID 位

用 ls -l 看文件权限时,要是文件所有者的「执行位」(x)被换成了 s,就说明这个文件已经设了 SUID:

# 查看 passwd 命令的权限(所有者执行位为 s,即 SUID 已启用)
ls -l /usr/bin/passwd
# 输出示例:-rwsr-xr-x 1 root root 68232 5月  10 2023 /usr/bin/passwd
#        ↑ 所有者权限位的 x 变成 s,代表 SUID 生效

要是显示 S(大写),说明文件有 SUID 位但缺所有者执行权限(x),SUID 没法生效,得补上执行权限。

(2)设置 SUID 位

用 chmod 命令,通过 u+s(user + setuid)参数给文件加 SUID 位:

# 语法:chmod u+s 文件名
# 示例:为 test.bin(二进制文件)设置 SUID
chmod u+s /path/to/test.bin

# 验证设置结果
ls -l /path/to/test.bin
# 输出示例:-rwsr-xr-x 1 root user 12345 5月 31 2024 /path/to/test.bin

(3)取消 SUID 位

用 u-s 参数去掉 SUID 位:

chmod u-s /path/to/test.bin

4. SUID 的典型应用场景

  • 系统命令提权:除了 passwd,su、sudo、ping 这些命令都靠 SUID 实现「普通用户执行高权限操作」;
  • 自定义工具提权:要是你写了个需要访问系统级文件的二进制工具(比如读系统日志),可以给工具设 SUID(所有者设为 root),让普通用户不用 sudo 就能跑。

安全提醒:SUID 是把「双刃剑」——要是给某个恶意的二进制文件设了 SUID(所有者是 root),攻击者就能借这个文件拿到 root 权限。所以得定期用 find / -perm -4000 -type f 2>/dev/null 把系统里设了 SUID 的文件翻一遍,排查异常文件。

二、SGID:解决多用户共享文件的权限难题

1. SGID 是什么?

SGID(Set Group ID on Execution)有两种作用场景:作用在文件上和作用在目录上,其中「作用在目录上」最常用也最实在。

  • 作用在文件上:跟 SUID 类似,普通用户跑这个文件时会临时拿到文件所属组的权限(而不是自己默认的组权限);
  • 作用在目录上:这是 SGID 的核心用法——在设了 SGID 的目录里,所有新建的文件 / 子目录的所属组,会自动继承这个目录的所属组,而不是创建者自己的默认组。

拿团队协作举个例子:开发团队有个共享目录 /data/project,所属组是 dev。给这个目录设了 SGID 之后,不管团队成员(都属于 dev 组)用自己的账号在里面建文件还是子目录,新文件的所属组都会是 dev,而不是成员个人的默认组,于是「团队成员自动就有文件的访问权限」了。

2. SGID 的核心特点

作用对象核心效果
可执行文件执行文件时,临时获得文件所属组的权限(类似 SUID,但切换的是组权限)
目录目录内新建的文件 / 子目录,自动继承目录的所属组(解决多用户共享的权限继承问题)
依赖组执行权限作用在文件时,文件所属组需有执行权限(x);作用在目录时,目录所属组需有执行权限(x,目录的执行权限代表 “进入目录”)

3. 如何查看与设置 SGID?

(1)查看 SGID 位

用 ls -l 看时,文件 / 目录的「所属组执行位」(x)被换成 s,就说明已经设了 SGID:

# 查看一个设置了 SGID 的共享目录
ls -l /data/
# 输出示例:drwxr-sr-x 2 root dev 4096 5月 31 2024 project/
#        ↑ 所属组权限位的 x 变成 s,代表 SGID 生效
  • 要是显示 S(大写),说明有 SGID 位但缺所属组执行权限,SGID 没法生效。

(2)设置 SGID 位

用 chmod 命令,通过 g+s(group + setgid)参数给文件 / 目录加 SGID 位:

# 场景1:为共享目录设置 SGID(最常用)
# 1. 创建共享组 dev
groupadd dev
# 2. 创建共享目录 /data/project
mkdir -p /data/project
# 3. 修改目录所属组为 dev(确保团队成员属于该组)
chgrp dev /data/project
# 4. 为目录设置 SGID,并开放组写权限(允许成员修改文件)
chmod g+s,g+w /data/project

# 验证设置结果
ls -l /data/
# 输出示例:drwxrwsr-x 2 root dev 4096 5月 31 2024 project/

# 场景2:为可执行文件设置 SGID(较少用)
chmod g+s /path/to/test.bin

(3)取消 SGID 位

用 g-s 参数去掉 SGID 位:

chmod g-s /data/project

4. SGID 的实战配置:搭建团队共享目录

拿「开发团队共享代码目录」为例,完整配置流程如下:

# 1. 创建共享组 dev,添加团队成员(如 user1、user2)
groupadd dev
usermod -aG dev user1
usermod -aG dev user2

# 2. 创建共享目录,设置所属组和 SGID
mkdir -p /data/dev_code
chgrp dev /data/dev_code
chmod g+s,g+w /data/dev_code  # g+s 设 SGID,g+w 允许组内成员写

# 3. 配置成员的 umask(确保新建文件对组可写)
# umask 002 表示:新建文件权限为 664(rw-rw-r--),目录为 775(rwxrwxr-x)
echo "umask 002" >> /home/user1/.bashrc
echo "umask 002" >> /home/user2/.bashrc
source /home/user1/.bashrc
source /home/user2/.bashrc

# 4. 测试:user1 在共享目录新建文件
su - user1
cd /data/dev_code
touch test_code.py

# 查看文件权限:所属组为 dev,组有读写权限
ls -l test_code.py
# 输出示例:-rw-rw-r-- 1 user1 dev 0 5月 31 2024 test_code.py

到这步,user2 就能直接编辑 test_code.py(因为文件所属组是 dev,而且组有写权限),不用手动改文件权限,实现「无缝共享」。

三、粘滞位(Sticky Bit):保护多用户共享目录的文件安全

1. 粘滞位是什么?

粘滞位(Sticky Bit)只作用在目录上,是一种「防删除保护」机制:在设了粘滞位的目录里,只有文件的所有者、目录的所有者,以及 root 用户,才能删除或重命名这个目录下的文件——就算别的用户对目录有「写权限」,也删不了别人建的文件。

最典型的例子就是系统的 /tmp 目录(所有用户都能读写的临时目录):

ls -l /
# 输出示例:drwxrwxrwt 14 root root 4096 5月 31 2024 tmp/
#        ↑ 其他用户权限位的 x 变成 t,代表粘滞位生效

要是 /tmp 没粘滞位,谁都能删别人的临时文件,会出大安全问题。

2. 粘滞位的核心特点

  • 只作用在目录:文件设粘滞位没意义(Linux 会忽略);
  • 限制「删除 / 重命名」操作:只允许 3 类角色动文件:文件所有者、目录所有者、root;
  • 不影响「读写执行」:别的用户照样能对文件读、写、执行(只要有对应权限),只是限制删除和重命名。

3. 如何查看与设置粘滞位?

(1)查看粘滞位

用 ls -l 看目录权限时,要是「其他用户执行位」(x)被换成 t(小写),就说明设了粘滞位:

ls -l /tmp
# 输出示例:drwxrwxrwt 14 root root 4096 5月 31 2024 tmp/
#        ↑ 其他用户权限位的 x 变成 t,代表粘滞位生效
  • 要是显示 T(大写),说明有粘滞位但缺其他用户执行权限(x),粘滞位没法生效(目录的执行权限是「进目录」的前提)。

(2)设置粘滞位

用 chmod 命令,通过 o+t(other + sticky)参数给目录加粘滞位:

# 语法:chmod o+t 目录名
# 示例:为团队共享目录 /data/share 设置粘滞位(防止成员删别人的文件)
chmod o+t /data/share

# 验证设置结果
ls -l /data/
# 输出示例:drwxrwxr-t 2 root dev 4096 5月 31 2024 share/

(3)取消粘滞位

用 o-t 参数去掉粘滞位:

chmod o-t /data/share

4. 粘滞位的应用场景

  • 公共临时目录:比如 /tmp、/var/tmp,保证所有用户能建临时文件,但删不了别人的;
  • 团队共享目录:就算给目录开了「其他用户写权限」,靠粘滞位也能防误删别人的文件(比如设计团队的素材共享目录)。

四、总结:特殊权限位对比与使用建议

权限位作用对象核心效果典型应用场景安全注意事项
SUID可执行文件执行文件时,临时获文件所有者权限passwd、sudo 等系统命令禁止给 Shell 脚本设 SUID;定期排查异常 SUID 文件
SGID目录(主要)目录内新建文件 / 子目录,自动继承目录所属组团队共享目录(如代码、素材目录)确保共享组只包含需要访问的用户,避免权限泄露
粘滞位目录仅文件所有者、目录所有者、root 可删除 / 重命名目录内文件/tmp、公共共享目录仅给 “多用户可写” 的目录设粘滞位,避免过度限制

实用命令速查

需求命令示例
查找系统中所有 SUID 文件find / -perm -4000 -type f 2>/dev/null
查找系统中所有 SGID 目录find / -perm -2000 -type d 2>/dev/null
查找系统中所有粘滞位目录find / -perm -1000 -type d 2>/dev/null
同时设置 SGID 和粘滞位chmod g+s,o+t /data/share

搞懂 SUID、SGID 和粘滞位,不光能解决 Linux 里实际的权限难题,更能帮你体会「Linux 权限设计的安全思路」——既要满足灵活的操作需求,又得用机制限制权限滥用,这也是 Linux 能成为服务器主流系统的核心原因之一。