文件权限管理

权限基础概念

Linux 使用三种权限控制文件访问:读取(r)写入(w)执行(x)
这三种权限分别应用于三类用户:文件所有者(u)所属群组(g)其他用户(o)

权限类型详解

读取权限 (r)

  • 文件:可读取文件内容
  • 目录:可列出目录内容(ls

写入权限 (w)

  • 文件:可修改文件内容
  • 目录:可在目录中创建、删除、重命名文件

执行权限 (x)

  • 文件:可作为程序执行
  • 目录:可进入目录(cd

查看文件权限

使用 ls -l 命令

1
2
ls -l filename
ls -la /path/to/directory

输出示例解析

1
2
3
4
5
6
7
8
9
10
11
12
$ ls -l test.txt
-rw-r--r-- 1 alice developers 1234 Jan 15 10:30 test.txt
│└┬┘└┬┘└┬┘│ │ │ │ │
│ │ │ │ │ │ │ │ └── 文件名
│ │ │ │ │ │ │ └──────────── 修改时间
│ │ │ │ │ │ └─────────────────── 所属群组
│ │ │ │ │ └────────────────────────── 文件所有者
│ │ │ │ └─────────────────────────────── 硬链接数
│ │ │ └───────────────────────────────── 其他用户权限
│ │ └───────────────────────────────────── 群组权限
│ └───────────────────────────────────────── 所有者权限
└─────────────────────────────────────────── 文件类型

文件类型标识

标识 类型 说明
- 普通文件 文本、数据、可执行文件等
d 目录 包含文件和其他目录
l 符号链接 指向其他文件的引用
c 字符设备 按字符流访问的设备(如终端)
b 块设备 按块访问的设备(如硬盘)
s 套接字 进程间通信端点
p 命名管道 进程间通信

修改文件权限

chmod 命令详解

1
chmod [who][operator][permission] file...

参数说明

类别 选项 含义
Who u 用户(所有者)
g 群组
o 其他用户
a 所有用户(等同于 ugo)
Operator + 添加权限
- 移除权限
= 设置精确权限
Permission r 读取权限
w 写入权限
x 执行权限
X 仅当文件是目录或已有执行权限时添加执行权限
s 设置 SUID 或 SGID
t 设置粘滞位

示例

1
2
3
4
5
6
7
8
9
10
11
12
13
# 添加执行权限
chmod +x script.sh # 给所有用户添加执行权限
chmod u+x program # 仅给所有者添加执行权限

# 移除权限
chmod o-w file.txt # 移除其他用户的写入权限
chmod go-rwx secret.txt # 移除群组和其他用户的所有权限

# 设置精确权限
chmod u=rwx,g=rx,o=r file # 所有者读写执行,群组读执行,其他只读

# 递归修改目录
chmod -R 755 /path/to/dir # 递归修改目录及其内容
1
chmod [mode] file...

权限数字对应表

权限 二进制 数字
--- 000 0
--x 001 1
-w- 010 2
-wx 011 3
r-- 100 4
r-x 101 5
rw- 110 6
rwx 111 7

常用权限组合

Mode 权限 用途
777 rwxrwxrwx 完全开放(不推荐)
755 rwxr-xr-x 标准可执行文件/目录
750 rwxr-x— 私有可执行文件/目录
700 rwx—— 完全私有
644 rw-r–r– 标准普通文件
640 rw-r—– 群组可读
600 rw——- 私有文件

示例

1
2
3
4
5
chmod 755 script.sh         # 可执行脚本
chmod 644 document.txt # 普通文档
chmod 600 ~/.ssh/id_rsa # 私钥文件
chmod 700 ~/private_dir # 私有目录
chmod -R 755 ~/bin # 递归设置

常用文件权限设置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# Web 服务器目录
find /var/www -type d -exec chmod 755 {} \;
find /var/www -type f -exec chmod 644 {} \;

# SSH 密钥
chmod 700 ~/.ssh
chmod 600 ~/.ssh/id_rsa
chmod 644 ~/.ssh/id_rsa.pub
chmod 644 ~/.ssh/authorized_keys
chmod 644 ~/.ssh/known_hosts

# 脚本文件
chmod +x script.sh # 添加执行权限
chmod u+s program # 设置 SUID

修改文件所有者和群组

chown 命令

1
chown [选项] [所有者][:群组] 文件...

常用选项

  • -R : 递归修改目录及其内容
  • -c : 只在发生改变时报告
  • -v : 显示详细处理过程
  • --reference=RFILE : 使用参考文件的属主

示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# 修改所有者
chown alice file.txt

# 修改群组
chown :developers file.txt
chgrp developers file.txt # 等效命令

# 同时修改所有者和群组
chown alice:developers file.txt

# 递归修改目录
chown -R alice:alice /home/alice/project

# 使用参考文件
chown --reference=template.txt newfile.txt

# 仅修改符号链接本身(而非目标)
chown -h alice symlink

chgrp 命令

专门用于修改群组:

1
chgrp [选项] 群组 文件...

示例

1
2
chgrp developers project/
chgrp -R www-data /var/www

特殊权限

SUID (Set User ID)

当可执行文件设置了 SUID 位,用户执行该文件时,进程的有效用户ID会变成文件所有者的ID,而不是执行者的ID。

应用场景:passwd 命令

1
2
3
4
$ ls -l /usr/bin/passwd
-rwsr-xr-x 1 root root 68208 Jul 15 2021 /usr/bin/passwd

SUID 位(所有者的 x 位置)

普通用户可以通过 passwd 修改自己的密码(需要写入 /etc/shadow),就是因为 passwd 有 SUID 位,执行时临时获得了 root 权限。

设置 SUID

1
2
chmod u+s /path/to/program    # 符号模式
chmod 4755 /path/to/program # 数字模式(4 表示 SUID)

注意

  • 大写 S 表示没有执行权限但设置了 SUID
  • SUID 对目录无效(在某些 BSD 系统上有特殊用途)
  • 不当使用 SUID 可能带来安全风险

SGID (Set Group ID)

对可执行文件

类似于 SUID,但继承的是文件所属群组的权限。

1
2
3
4
$ ls -l /usr/bin/wall
-rwxr-sr-x 1 root tty 30800 Feb 28 2022 /usr/bin/wall

SGID 位(群组的 x 位置)

对目录

在设置了 SGID 的目录中创建的新文件,其所属群组会自动继承目录的群组,而不是创建者的主群组。

应用场景:共享项目目录

1
2
3
4
5
6
# 创建项目目录
mkdir /srv/project
chgrp developers /srv/project
chmod 2770 /srv/project # 设置 SGID

# 现在任何在此目录创建的文件都属于 developers 群组

设置 SGID

1
2
chmod g+s /path/to/directory    # 符号模式
chmod 2775 /path/to/directory # 数字模式(2 表示 SGID)

注意:大写 S 表示没有执行权限但设置了 SGID。

Sticky Bit (粘滞位)

粘滞位只对目录有效。设置了粘滞位的目录,只有文件所有者目录所有者root 才能删除或重命名该目录中的文件,即使其他用户有写权限也不行。

典型应用/tmp 目录

1
2
3
4
$ ls -ld /tmp
drwxrwxrwt 15 root root 4096 Jan 15 10:30 /tmp

粘滞位(其他人的 x 位置)

所有用户都可以在 /tmp 创建文件,但只能删除自己的文件,防止恶意删除他人的临时文件。

设置粘滞位

1
2
chmod +t /path/to/directory    # 符号模式
chmod 1777 /path/to/directory # 数字模式(1 表示粘滞位)

注意:大写 T 表示没有执行权限但设置了粘滞位。

特殊权限速查表

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
┌─────────────────────────────────────────────────────┐
│ 权限位布局 │
├─────────────────────────────────────────────────────┤
│ SUID │ SGID │ Sticky │ User │ Group │ Other │
│ (4) │ (2) │ (1) │ (rwx) │ (rwx) │ (rwx) │
└─────────────────────────────────────────────────────┘

常用组合:
├── 4755 (rwsr-xr-x) = SUID + 755
├── 2755 (rwxr-sr-x) = SGID + 755
├── 1777 (rwxrwxrwt) = Sticky + 777 (如 /tmp)
└── 6755 (rwsr-sr-x) = SUID + SGID + 755

符号模式:
├── u+s = 设置 SUID
├── g+s = 设置 SGID
├── o+t = 设置粘滞位
└── a = 所有用户 (u+g+o)

实践练习

练习:设置共享开发目录

场景:团队共享的项目目录 /srv/webapp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
# 1. 创建目录并设置正确的群组
sudo mkdir -p /srv/webapp
sudo groupadd webdev
sudo chown root:webdev /srv/webapp

# 2. 设置 SGID,使新文件继承目录群组
sudo chmod 2770 /srv/webapp

# 3. 设置目录权限
# 2 = SGID, 7 = rwx (所有者), 7 = rwx (群组), 0 = --- (其他)
sudo chmod 2770 /srv/webapp

# 4. 将开发用户添加到群组
sudo usermod -aG webdev alice
sudo usermod -aG webdev bob

# 5. 验证设置
ls -ld /srv/webapp
# 预期输出:drwxrws--- 2 root webdev ...

# 6. 测试(切换到开发用户)
su - alice
touch /srv/webapp/test.txt
ls -l /srv/webapp/test.txt
# 预期:文件群组应该是 webdev,而不是 alice 的主群组

练习:SUID 安全分析

任务:分析系统中的 SUID 文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
# 1. 查找所有 SUID 文件
find / -perm -4000 -type f 2>/dev/null

# 2. 查找所有 SGID 文件
find / -perm -2000 -type f 2>/dev/null

# 3. 详细查看 SUID 文件
find /usr/bin -perm -4000 -ls 2>/dev/null

# 4. 检查可疑的自定义 SUID 程序
# 正常的 SUID 程序通常在标准位置
# /usr/bin/passwd
# /usr/bin/sudo
# /usr/bin/su
# /usr/bin/mount
# /usr/bin/umount
# /usr/bin/ping
# ...

# 5. 安全审计脚本
echo "=== SUID 文件安全审计 ==="
echo "系统 SUID 文件数量:"
find / -perm -4000 -type f 2>/dev/null | wc -l

echo ""
echo "非标准位置的 SUID 文件:"
find / -perm -4000 -type f 2>/dev/null | grep -v -E "^/(usr/|bin/|sbin/|usr/sbin/)"

echo ""
echo "最近修改的 SUID 文件:"
find / -perm -4000 -type f -mtime -7 2>/dev/null

常见问题 FAQ

为什么无法访问文件,即使我是 root?

可能原因:文件位于挂载为 noexecnodevnosuid 的文件系统上。

1
2
3
4
5
6
7
8
9
10
# 查看挂载选项
mount | grep /path/to/mount

# 示例输出:
# /dev/sda1 on /home type ext4 (rw,nosuid,nodev,noexec,relatime)

# 解决方案:重新挂载(临时)
sudo mount -o remount,exec,suid /home

# 或编辑 /etc/fstab 永久修改

如何恢复误删的权限?

场景:不小心执行了 chmod -R 777 /

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# 1. 立即停止系统写入(避免更多损坏)
# 2. 使用 Live CD/USB 启动

# 3. 挂载根分区
sudo mount /dev/sda1 /mnt

# 4. 使用包管理器恢复默认权限(推荐)
# Debian/Ubuntu:
sudo dpkg --root=/mnt --configure -a

# CentOS/RHEL/Fedora:
# 使用 rpm 恢复或重新安装关键包

# 5. 手动修复关键目录
sudo chmod 755 /mnt/bin /mnt/lib /mnt/lib64 /mnt/sbin /mnt/usr
sudo chmod 555 /mnt/boot
sudo chmod 1777 /mnt/tmp
sudo chmod 755 /mnt/var

# 6. 验证并重启

预防措施

  • 使用 chmod --reference 代替手动设置
  • 重要操作前使用 getfacl -R /path > permissions_backup.acl 备份权限

ACL 与基本权限的区别?

基本权限的局限

  • 只能设置一个所有者
  • 只能设置一个群组
  • 其他人的权限是统一的

ACL (Access Control List) 的优势

  • 可以为多个用户设置不同权限
  • 可以为多个群组设置不同权限
  • 支持默认 ACL(新文件自动继承)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# 检查文件系统是否支持 ACL
mount | grep acl

# 安装 ACL 工具
sudo apt-get install acl # Debian/Ubuntu
sudo yum install acl # CentOS/RHEL

# 查看 ACL
getfacl filename

# 设置 ACL
setfacl -m u:alice:rwx filename # 给用户 alice 设置 rwx
setfacl -m g:developers:rw filename # 给群组 developers 设置 rw
setfacl -x u:alice filename # 移除 alice 的 ACL
setfacl -b filename # 移除所有 ACL

# 设置默认 ACL(目录)
setfacl -d -m u:alice:rwx /shared/dir
setfacl -R -m u:alice:rwx /shared/dir # 递归设置

延伸阅读

权限管理是 Linux 安全的基石


© 2025 Rl. 使用 Stellar 创建
站点访问量 Loading... 站点访客数 Loading... 页面访问量 Loading...