↑ 顶部/笔记 2026-10-25 · 约 14 分钟

特殊权限与提权(su / sudo)

一句话总结:rwx 管“能不能”,特殊权限管“以谁的身份、能否删别人的文件”,su/sudo 管“怎么换身份”。
适用:Rocky Linux / CentOS 9。基础 rwx 见 10_用户组与权限.md,本篇讲进阶部分。

更新于 2026-10-25 · 正文约 5430 字

一、先回顾:权限怎么生效

1.1 三组权限 + 匹配顺序

ls -l 的 9 位权限,3 位一组:

-rwxr-xr--. 1 root group1 31457280 4月 16 14:21 /tmp/a.txt
 │└┬┘└┬┘└┬┘
 │ │  │  └── o 其他人:r--
 │ │  └───── g 属组:r-x
 │ └──────── u 属主:rwx
 └────────── 文件类型

进程访问文件时,内核按 u → g → o 顺序匹配一次,命中即停,不取并集。

例:文件 rwx------ root root,用户 jack 在 root 组里,他仍然只能按“其他人”看(没有权限)。

1.2 权限对普通文件的意义

权限 含义 例子
r 读取文件内容 cat 1.txt
w 修改文件内容(不包含删除文件本身) echo 111 >> 1.txt
x 把文件当命令执行 ./script.sh

执行的两类文件:

  1. 二进制程序(/usr/bin/ls):只需要 x 权限就能跑;
  2. 脚本文件(内容是文本,靠解释器执行):需要 r + x,因为解释器要先读内容再执行。

能不能删除一个文件,不看文件自己的 w,而看所在目录的 w——这是最容易被忽略的一点。

1.3 权限对目录的意义

权限 对目录的含义 命令
r 能列出目录里的文件名 ls /dir
w 能在目录里创建、删除、移动、改名文件 touch /dir/a、rm /dir/a
x 能进入目录,访问里面的文件 cd /dir、cat /dir/a
  • 只有 r 没有 x:ls 看得到名字,但 cat 里面的文件会 Permission denied。
  • 只有 x 没有 r:能 cd 进去、能访问已知文件名的文件,但 ls 列不出来。
  • 有 w 没有 x:能建文件却进不去,实际很难用。

1.4 路径沿途的 x 权限(重点)

访问 /a/b/c/1.txt 时:

  1. 进程用户要对 /、/a、/a/b、/a/b/c 每一级目录都有 x;
  2. 再对 1.txt 本身有对应权限(读/写/执行)。

常见故障:文件权限明明是 777,但 cat /a/b/c/1.txt 还是 Permission denied——因为中间某个目录缺 x。

二、umask:新建文件的默认权限

2.1 计算规则

  • 文件系统默认上限:普通文件 666(默认不给执行位),目录 777;
  • 实际权限 = 默认上限 按位与上 umask 的取反,口算时用减法更直观:
  • 文件:666 - umask
  • 目录:777 - umask

root 默认 umask 是 022,所以:

文件 666 - 022 = 644  (rw-r--r--)
目录 777 - 022 = 755  (rwxr-xr-x)

2.2 对照表

umask 新建文件 新建目录
022 644 755
002 664 775
027 640 750
077 600 700
066 600 711
023 644 754

注意 umask 是八进制,且减法只对每一位有效;777 & ~066 = 711 这种用“按位与”算更保险。

2.3 查看与设置

umask                 # 查看当前值
umask -S              # 用 rwx 形式显示
umask 027             # 临时修改,只对当前 shell 生效

永久生效:

位置 作用范围
/etc/profile 全局,登录时
~/.bashrc 当前用户,每次开 shell
/etc/login.defs 的 UMASK 新建用户的默认 umask(useradd 时也会用)

三、特殊权限:SUID / SGID / Sticky

这三个权限占 ls -l 输出的第 4、7、10 位(原本是 x 的位置)。

特殊权限 数字 作用对象 效果
SUID 4 可执行文件 程序运行时以文件属主的身份运行
SGID 2 目录(也可执行文件) 目录里新建的文件/目录继承目录的属组;可执行文件以文件属组身份运行
Sticky 1 目录 目录里的文件只有属主和 root 能删除/改名

3.1 SUID(Set User ID)

chmod u+s /usr/bin/passwd
chmod 4755 /usr/bin/passwd
ls -l /usr/bin/passwd
# -rwsr-xr-x. 1 root root ... /usr/bin/passwd

典型例子:passwd 的属主是 root,普通用户执行它时临时获得 root 身份,才能去改 /etc/shadow。

  • 显示为 s(原位置有 x)或 S(原位置没有 x,说明配置有误);
  • 只对可执行文件有意义,给普通文本加 SUID 没用;
  • 风险最高:如果给 bash、vim 这类程序加 SUID,等于给了所有人 root shell。
find / -perm -4000 -type f 2>/dev/null    # 排查系统里所有 SUID 程序

3.2 SGID(Set Group ID)

对目录(最常用):目录里新建的文件和子目录,属组自动继承该目录的属组,而不是创建者的主组。

chmod g+s /aaa
chmod 2775 /aaa
ls -ld /aaa
# drwxrwsr-x. root it ... /aaa

部门共享目录的标准做法:chgrp it /share + chmod 2770 /share,这样组员新建的文件都自动属于 it 组,其他人也能按组权限访问。

对可执行文件:程序运行时以文件属组的身份运行(用得少)。

3.3 Sticky(粘滞位)

chmod o+t /share
chmod 1777 /share
ls -ld /tmp
# drwxrwxrwt. 20 root root ... /tmp

效果:目录里人人可写,但只有文件属主和 root 能删除或改名。

/tmp 就是典型:所有人能建文件,但删不了别人的文件。

3.4 数字表示与识别

chmod 4755 file      # SUID + 755
chmod 2755 dir       # SGID + 755
chmod 1777 dir       # Sticky + 777
chmod 7755 file      # 同时有 SUID+SGID+Sticky(几乎不用)
显示 含义
rws 有 x,且设置了 SUID
rwS 没有 x,却设置了 SUID(无效配置)
rws(属组位) 有 x,且设置了 SGID
rwt(其他人位) 有 x,且设置了 Sticky
rwT 没有 x,却设置了 Sticky

3.5 安全提醒

  • SUID 程序越少越安全,定期用 find / -perm -4000 审计;
  • 不要给 shell、编辑器、解释器加 SUID;
  • 共享目录优先用 SGID + 组权限,而不是 777。

四、su:切换用户

4.1 两种写法

命令 类型 环境变量
su - egon(或 su -l) 登录 shell 重新加载目标用户完整环境,家目录切到 /home/egon
su egon 非登录 shell 只切换身份,环境变量、当前目录大多保留
su - egon              # 推荐:完整切换
su egon                # 临时切身份,环境还是原来的
su - egon -c "id"      # 切换后执行一条命令再退出
su -c "systemctl restart nginx"   # root 用,切到 root 执行

su 默认切到 root,需要目标用户的密码;root 切到普通用户不需要密码。

4.2 登录 / 非登录 shell 加载哪些配置文件

登录 shell(su - user、ssh user@host、tty 登录)依次加载:

/etc/profile
  └─ /etc/profile.d/*.sh
~/.bash_profile
  └─ ~/.bashrc
       └─ /etc/bashrc
            └─ /etc/profile.d/*.sh(RHEL 的 /etc/bashrc 会再跑一遍)

非登录 shell(su user、在已有 shell 里再开一个 bash):

~/.bashrc
  └─ /etc/bashrc
       └─ /etc/profile.d/*.sh

结论:想在登录时就生效的(PATH、LANG)写 /etc/profile 或 ~/.bash_profile;想每次开 shell 都生效的(别名、函数、提示符)写 ~/.bashrc。
CentOS 9 里登录流程中 /etc/bashrc 可能被执行两次,所以脚本里别写有副作用的命令。

4.3 把命令加进 PATH

# 临时
export PATH="$PATH:/usr/local/nginx/sbin"

# 永久:写进 ~/.bash_profile 或 /etc/profile.d/nginx.sh
echo 'export PATH=$PATH:/usr/local/nginx/sbin' > /etc/profile.d/nginx.sh
source /etc/profile.d/nginx.sh

五、sudo:临时提权

5.1 它解决什么问题

  • 不用知道 root 密码:普通用户用自己的密码认证;
  • 按命令授权:只允许执行指定的几条命令;
  • 有审计:执行记录写进 /var/log/secure;
  • 可撤销:改配置立即生效,不用改 root 密码。
sudo systemctl restart nginx     # 用普通用户身份,临时以 root 执行这一条
sudo -l                          # 查看自己被授权了哪些命令
sudo -u www-data whoami          # 以指定用户身份执行
sudo -i                          # 相当于 su -,进入 root 的登录 shell

5.2 /etc/sudoers 语法

用户  主机=(运行身份)  命令
字段 说明 例子
用户 用户名或用 %组名 egon、%wheel、%it
主机 允许从哪台机器执行,ALL 表示任意 ALL
运行身份 以谁的身份执行,ALL 或 (root) (ALL)
命令 允许执行的命令,写绝对路径,可带参数 /usr/bin/systemctl restart nginx
root    ALL=(ALL)       ALL
%wheel  ALL=(ALL)       ALL
egon    ALL=(ALL)       ALL
lisi    ALL=(root)      /usr/bin/systemctl restart nginx
wangwu  ALL=(ALL)       NOPASSWD: /usr/bin/systemctl status nginx
  • NOPASSWD: 表示执行时不再输密码;
  • 命令可以用通配符,但授权越具体越安全;
  • 多个命令用逗号分隔;
  • 还支持别名:
User_Alias  ADMINS = egon, lisi
Cmnd_Alias  WEB    = /usr/bin/systemctl restart nginx, /usr/bin/systemctl reload nginx
ADMINS      ALL=(root) WEB

5.3 两种修改方式

方式 说明
visudo 推荐:编辑 /etc/sudoers,保存时自动检查语法,语法错不让你保存
vi /etc/sudoers 直接改,容易写错;改完必须 visudo -c 检查
visudo            # 打开编辑器
visudo -c         # 只检查语法
EDITOR=vim visudo # 指定用 vim 编辑

visudo 默认调起 vi。vi 有两种模式:命令模式(按键当命令)和编辑模式(i/a/o 进入,可以输入文字),保存退出是 Esc → :wq。不熟悉的话先把 EDITOR 设成 nano 或 vim。

图:vi 的命令模式与编辑模式切换

5.4 企业里的推荐做法

  1. 用组授权:%wheel ALL=(ALL) ALL,需要提权的人加进 wheel 组: bash usermod -aG wheel egon
  2. 细分权限:运维只给重启服务的命令,DBA 只给数据库相关命令;
  3. 用 drop-in 文件:不直接改主配置,新建 /etc/sudoers.d/web: text %web ALL=(root) NOPASSWD: /usr/bin/systemctl restart nginx 文件权限必须 440,否则 sudo 会忽略或报错;
  4. 改完检查:visudo -c;
  5. 定期审计:sudo -l -U 用户名、查 /var/log/secure 里的 sudo 记录。

5.5 常见报错

报错 原因
xxx is not in the sudoers file 没授权,或组没写对
sorry, you must have a tty to run sudo 配置了 Defaults requiretty
sudo: parse error in /etc/sudoers 语法错误,用 visudo -c 定位
输入密码后仍拒绝 命令路径写错(必须绝对路径),或参数不匹配

速查表

# 特殊权限
chmod u+s file; chmod 4755 file          # SUID
chmod g+s dir;  chmod 2775 dir           # SGID
chmod o+t dir;  chmod 1777 dir           # Sticky
find / -perm -4000 -type f 2>/dev/null   # 审计 SUID

# umask
umask; umask -S; umask 027
umask 022  # 文件 644 / 目录 755

# su
su - egon; su egon; su -c "id"
# 登录 shell:/etc/profile -> profile.d -> ~/.bash_profile -> ~/.bashrc -> /etc/bashrc
# 非登录:~/.bashrc -> /etc/bashrc -> profile.d

# sudo
visudo; visudo -c
sudo -l; sudo -u user cmd; sudo -i
usermod -aG wheel egon

常见坑

  1. 以为文件有 w 就能删——删除看的是目录的 w。
  2. 文件权限 777 却打不开——路径沿途目录缺 x。
  3. 给脚本只加 x 不加 r,执行报错,因为解释器读不了内容。
  4. chmod 4755 和 chmod 755 只差一个数字,安全等级差很多,别手滑。
  5. SGID 加在目录上才有“继承属组”的效果,加在普通文件上没意义。
  6. umask 是八进制减法,027 不是 27,写错会得到奇怪权限。
  7. su egon 不加载目标用户环境,PATH 还是原来的,容易“命令找不到”。
  8. sudo 授权命令必须写绝对路径,写 systemctl 会不生效。
  9. /etc/sudoers.d/ 下的文件权限要 440,否则 sudo 拒绝加载。
  10. 改 sudoers 不用 visudo,语法错了可能导致所有人都无法 sudo。

练习(16 题)

先自己做,再点开答案核对 0 / 16 已查看

01

只允许 lisi 重启 nginx 且不用输密码,写出配置行。

查看答案

属主 rwx(读写执行),属组 r-x(读和执行),其他人 r--(只读)。

02

修改 sudoers 的推荐命令是什么?改完如何检查语法?

查看答案

需要所在目录的 w 和 x。文件名是目录里的一条记录,删除就是删记录,和文件自身的 w 无关。

03

为什么 cat /a/b/c/1.txt 会要求 /a、/a/b、/a/b/c 都有 x?

查看答案

目录的 x 是“进入/穿越”权限;路径每一级都要能穿过,才能到达最终文件,再判断文件本身的权限。

04

二进制程序和 shell 脚本执行时对权限的要求有什么不同?

查看答案

二进制程序只需要 x;脚本文件需要 r + x,因为解释器要先读取脚本内容才能执行。

05

umask 为 027 时,新建文件和目录的默认权限分别是多少?

查看答案

文件 666-027=640(rw-r-----),目录 777-027=750(rwxr-x---)。

06

写出查看和临时设置 umask 的命令。

查看答案
umask
umask 027
07

SUID、SGID、Sticky 的数字代号分别是什么?

查看答案

SUID=4,SGID=2,Sticky=1。

08

给 /usr/bin/passwd 加 SUID,写出两条等价命令。

查看答案
chmod u+s /usr/bin/passwd
chmod 4755 /usr/bin/passwd
09

为什么 passwd 需要 SUID?不加会怎样?

查看答案

passwd 要改 /etc/shadow,普通用户没有写权限。加 SUID 后,执行 passwd 的进程临时以文件属主 root 的身份运行,才能改 shadow。不加 SUID,普通用户改密码会失败。

10

SGID 加在目录上有什么效果?举一个企业场景。

查看答案

目录里新建的文件和子目录自动继承该目录的属组。场景:部门共享目录 chgrp it /share + chmod 2770 /share,组员新建的文件都属于 it 组,方便组内协作。

11

Sticky 位的作用是什么?/tmp 的权限是多少?

查看答案

目录里的文件只有属主和 root 能删除或改名,其他人即使有 w 也不能删别人的文件。/tmp 是 1777(drwxrwxrwt)。

12

ls -l 权限位出现 rws、rwS、rwt 分别代表什么?

查看答案

rws:有 x,且设置了 SUID;rwS:没有 x 却设置了 SUID(无效);rwt:有 x,且设置了 Sticky。

13

登录 shell 和非登录 shell 加载的配置文件有什么不同?

查看答案

登录 shell 依次读 /etc/profile、/etc/profile.d/*.sh、~/.bash_profile、~/.bashrc、/etc/bashrc;非登录 shell 只读 ~/.bashrc、/etc/bashrc(RHEL 的 bashrc 会再跑 profile.d)。所以 PATH 类配置写 profile,别名写 bashrc。

14

su - egon 和 su egon 的区别是什么?

查看答案

su - egon 是登录 shell,重新加载目标用户完整环境、切到家目录;su egon 是非登录 shell,只换身份,环境和当前目录大多保留。

15

把 /usr/local/nginx/sbin 永久加入 PATH,写出一种做法。

查看答案
echo 'export PATH=$PATH:/usr/local/nginx/sbin' > /etc/profile.d/nginx.sh
source /etc/profile.d/nginx.sh
> 写到 `~/.bash_profile` 也可以,但只对单个用户生效。

**16.**
> 用户 egon 在任意主机上,可以以任意身份(含 root)执行任意命令。

**17.**
```text
lisi ALL=(root) NOPASSWD: /usr/bin/systemctl restart nginx

18.

visudo
visudo -c

visudo 保存时自动校验,-c 只检查不修改;也可以写到 /etc/sudoers.d/ 下,权限设为 440。

16

/etc/sudoers 中一行 egon ALL=(ALL) ALL 表示什么?

查看答案

(暂无答案)

特殊权限与提权(su / sudo) · 生成于 2026-10-26 00:46