Linux 文件权限
Chen Kai BOSS

文件权限是 Linux 运维里最"基础但最容易踩坑"的部分:一边是权限不足导致服务起不来、脚本跑不动、 Web 应用 403 报错;另一边是权限给大了带来安全风险(任何人都能改配置、删日志、写 crontab)。要把它用对,需要的不只是记住 chmod 755,而是理解权限位在文件与目录上的语义差异( r/w/x 对目录的含义与文件完全不同)、属主/属组/其他人的边界、以及 umask、 SUID/SGID 、 Sticky Bit 这些机制为什么会存在、什么场景下才该用。本篇会从最小概念集出发,系统讲清 rwx 的语义、数字/符号写法、chmod/chown 的典型用法与排错思路,并用常见场景(共享目录、可执行脚本、临时目录、安全加固)解释"该怎么给权限、给到什么程度",再补上 ACL 、chattr 这些扩展机制与实战排障清单,让你能把权限问题一次性定位并修正确。

Linux 权限模型: owner/group/others 三层架构

基本概念

Linux 是多用户系统,每个文件/目录都有三个身份属性:

  • 属主( Owner, u):创建或被指定为文件/目录拥有者的用户( UID)
  • 属组( Group, g):多个用户可以同属一个组,在组内具有共享权限( GID)
  • 其他用户( Others, o):不属于该文件属主或属组的所有人

为什么要这么设计?

  • 属主:文件的"所有者",通常有最高权限(如读写执行)
  • 属组:适用于团队协作(如开发组、运维组),组内成员共享权限
  • 其他用户:防止文件被任意用户访问(安全隔离)

三种权限位( rwx)

每个身份( u/g/o)都有三个权限位:

  • r( read):读权限
  • w( write):写权限
  • x( execute):执行权限

示例rwxr-xr-x

  • 属主:rwx(可读可写可执行)
  • 属组:r-x(可读可执行,不可写)
  • 其他:r-x(可读可执行,不可写)

转换为数字

  • rwx = 4+2+1 = 7
  • r-x = 4+0+1 = 5
  • r-x = 4+0+1 = 5
  • 所以 rwxr-xr-x = 755

rwx 在文件和目录上的语义差异(最容易踩的坑)

这是最容易混淆的点: rwx 在文件和目录上的含义完全不同。

对文件(普通文件)

权限 含义 示例
r 可读取文件内容 cat file.txt
w 可修改文件内容 echo "new" > file.txt
x 可执行文件(脚本需要有 shebang 如 #!/bin/bash ./script.sh

对目录

权限 含义 示例
r 可列出目录内容(看到文件名) ls dir
w 可在目录内创建、删除、重命名文件(通常需要 x touch dir/newfile
x 可进入目录(cd)、访问目录内的文件(如果知道文件名) cd dircat dir/file.txt

实际例子

情况 1:目录有 r 但没有 x

1
2
3
4
chmod 644 mydir  # mydir 权限变成 rw-r--r--(没有 x)
ls mydir # ✅ 可以列出文件名
cd mydir # ❌ Permission denied(不能进入)
cat mydir/file.txt # ❌ Permission denied(不能访问文件)

原因:没有 x 就不能进入目录,也不能访问目录内的文件。

情况 2:目录有 x 但没有 r

1
2
3
4
chmod 311 mydir  # mydir 权限变成 -wx--x--x(有 x 但没有 r)
ls mydir # ❌ Permission denied(不能列出文件名)
cd mydir # ✅ 可以进入
cat mydir/file.txt # ✅ 可以访问(如果知道文件名)

原因:有 x 就能进入和访问文件,但没有 r 就不能列出目录内容。

情况 3:目录有 w 但没有 x

1
2
chmod 622 mydir  # mydir 权限变成 rw--w--w-(有 w 但没有 x)
touch mydir/newfile # ❌ Permission denied(不能创建文件)

原因:虽然有 w,但没有 x 就不能进入目录,也就不能在目录内操作。

结论:对目录来说,x 是最基本的权限(没有 x 就什么都干不了);w 通常需要配合 x 使用。


chmod:修改权限(数字和符号两种写法)

数字写法(快速且常用)

每个权限位对应一个数字:

  • r = 4
  • w = 2
  • x = 1

相加得到一个 3 位数( owner/group/others):

  • 7 = rwx( 4+2+1)
  • 6 = rw-( 4+2)
  • 5 = r-x( 4+1)
  • 4 = r--( 4)
  • 0 = ---(无权限)

常见示例

1
2
3
4
chmod 755 script.sh  # owner=rwx, group=r-x, others=r-x(可执行脚本)
chmod 644 file.txt # owner=rw-, group=r--, others=r--(普通文件)
chmod 600 secret.key # owner=rw-, group=---, others=---(私钥文件)
chmod 777 shared # owner=rwx, group=rwx, others=rwx(完全开放,不推荐)

符号写法(更安全,适合增量修改)

1
2
3
4
5
chmod u+x script.sh  # 给 owner 加上执行权限
chmod g-w file.txt # 去掉 group 的写权限
chmod o=r file.txt # 设置 others 只有读权限
chmod a+r notes.md # 给所有人加上读权限( a=all)
chmod u+rwx,g+rx,o-rwx dir # 组合修改(逗号分隔)

递归修改

1
2
chmod -R 755 dir  # 递归修改目录及其内容
chmod -R u+rwX,g+rX,o-rwx dir # 大写 X 只给目录和已有执行权限的文件加 x(避免所有文件都变成可执行)

什么时候用数字、什么时候用符号?

  • 数字:适合"一次性设置到目标值"(如 chmod 644 file
  • 符号:适合"增量修改"(如 chmod u+x script.sh),更安全(不会误改其他权限位)

chown:修改文件所有权

chown 用于修改文件的属主和属组。

基本用法

1
2
3
4
sudo chown newowner file  # 只改属主
sudo chown newowner:newgroup file # 同时改属主和属组
sudo chown :newgroup file # 只改属组
sudo chown -R user:group dir # 递归修改目录及其内容

注意

  • 只有 root 或文件的当前属主可以修改所有权
  • 普通用户不能把文件"送给"别人(防止恶意占用别人的配额)

常见场景

  • Web 服务器目录:sudo chown -R www-data:www-data /var/www/html
  • 共享项目目录:sudo chown -R :developers /srv/project

umask:新建文件的默认权限

什么是 umask

umaskUser File Creation Mask(用户文件创建掩码),决定新建文件/目录的默认权限。

计算方法: 1. 默认权限(系统预设):

  • 文件:666( rw-rw-rw-,不包括执行权限,防止误执行)
  • 目录:777( rwxrwxrwx,目录需要 x 才能进入)
  1. 实际权限 = 默认权限 - umask 值

示例( umask = 022):

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

查看和设置 umask

查看当前 umask

1
umask  # 输出: 0022(第一位是特殊权限位,通常忽略)

临时设置 umask

1
2
umask 027  # 设置为 027
# 之后新建的文件权限是 640( 666-027),目录权限是 750( 777-027)

永久设置 umask(对当前用户): 编辑 ~/.bashrc~/.zshrc,添加:

1
umask 027

常见 umask 值

umask 文件权限 目录权限 适用场景
022 644 755 默认值(文件不被其他用户修改)
027 640 750 更严格(仅允许同组用户访问),生产环境推荐
002 664 775 共享环境(允许同组用户修改),开发环境
077 600 700 极度严格(只有属主能访问),适合个人私密文件

特殊权限: SUID/SGID/Sticky Bit

这三种特殊权限位用于特定的运维需求,理解它们的原理和使用场景很重要。

SUID( Set User ID)

原理

当可执行文件被赋予 SUID 权限后,普通用户执行该文件时,会以该文件的属主身份运行,而不是调用者自身的身份。

常见示例/usr/bin/passwd

  • ls -l /usr/bin/passwd 显示:-rwsr-xr-x root root(注意 owner 的 x 变成了 s)
  • 普通用户执行 passwd 时,以 root 身份运行,才能修改 /etc/shadow(只有 root 能写)

为什么需要 SUID?

  • 允许普通用户执行特定的需要高权限的操作(如修改自己的密码)
  • 不需要给用户 sudo 权限(更安全)

查看和设置

查看

1
ls -l file  # 如果属主的 x 位显示为 s(小写)或 S(大写),说明有 SUID

  • s(小写): SUID 且有执行权限
  • S(大写): SUID 但没有执行权限(通常是配置错误)

设置 SUID

1
2
chmod u+s myprog  # 符号写法
chmod 4755 myprog # 数字写法( 4 表示 SUID, 755 是基础权限)

去除 SUID

1
chmod u-s myprog

实战示例

假设你有一个 C 程序 myprog.c

1
2
3
4
5
6
7
8
9
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

int main() {
printf("Real UID=%d, Effective UID=%d\n", getuid(), geteuid());
system("id");
return 0;
}

编译并设置 SUID:

1
2
3
gcc -o myprog myprog.c
sudo chown root myprog # 属主改为 root
sudo chmod 4755 myprog # 设置 SUID + 755

普通用户执行:

1
./myprog

输出示例:

1
2
Real UID=1000, Effective UID=0
uid=1000(user) gid=1000(user) euid=0(root) groups=1000(user)

  • Real UID 是当前用户( 1000)
  • Effective UID 是文件属主( 0=root)
  • 所以程序以 root 权限运行

安全注意事项

SUID 是高风险的

  • SUID 程序一旦有漏洞(如缓冲区溢出、命令注入),攻击者可以获得 root 权限
  • 避免对不可信的程序设置 SUID
  • 定期审计系统中的 SUID 程序

查找系统中所有 SUID 程序

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

常见的 SUID 程序(这些是合理的):

  • /usr/bin/passwd:修改密码
  • /usr/bin/sudo:临时提权
  • /usr/bin/mount:挂载文件系统
  • /usr/bin/ping:发送 ICMP 包(需要 raw socket 权限)

SGID( Set Group ID)

应用场景

SGID 有两种用法:

1. 对可执行文件

进程运行时,其有效组 ID( GID)替换为文件的属组。这在需要访问特定组资源的工具中很常见。

2. 对目录(更常用)

当目录设置 SGID 后,在此目录中新建的文件或子目录会继承该目录的组,而非创建者的默认组。这非常适合团队共享目录。

示例

1
2
3
sudo mkdir /srv/project
sudo chown :developers /srv/project # 属组改为 developers
sudo chmod 2775 /srv/project # 设置 SGID + 775( 2 表示 SGID)

现在,任何 developers 组的成员在 /srv/project 里创建的文件,属组都自动是 developers,组内其他成员也能访问。

查看和设置

查看

1
ls -l file  # 如果属组的 x 位显示为 s(小写)或 S(大写),说明有 SGID

设置 SGID

1
2
chmod g+s shared_dir  # 符号写法
chmod 2775 shared_dir # 数字写法( 2 表示 SGID)

去除 SGID

1
chmod g-s shared_dir


Sticky Bit(粘滞位)

作用与原理

Sticky Bit 最常见于多用户可写的公共目录,如 /tmp当目录设置 Sticky Bit 后,该目录中的文件只能被其属主或 root 删除或改名,即使其他人对该目录也有写权限。

为什么需要 Sticky Bit?

  • /tmp 是所有用户共享的临时目录,权限是 1777( rwxrwxrwt)
  • 如果没有 Sticky Bit,用户 A 可以删除用户 B 的临时文件(安全风险)
  • 有了 Sticky Bit,用户 A 只能删除自己的文件,不能删除用户 B 的文件

查看和设置

查看

1
ls -ld /tmp  # 输出: drwxrwxrwt(最后一位是 t)

设置 Sticky Bit

1
2
chmod o+t dirname  # 符号写法
chmod 1777 /tmp # 数字写法( 1 表示 Sticky Bit)

去除 Sticky Bit

1
chmod o-t dirname


常见场景与最佳实践

场景 1:可执行脚本

问题./script.sh: Permission denied

排查

1
ls -l script.sh  # 查看权限

如果显示 -rw-r--r--(没有 x),说明没有执行权限。

解决

1
2
3
chmod +x script.sh  # 给所有人加上执行权限
# 或
chmod 755 script.sh # owner=rwx, group=r-x, others=r-x

注意:脚本还需要有 shebang(如 #!/bin/bash),否则需要用 bash script.sh 运行。

场景 2: Web 服务器目录

需求: Nginx/Apache 需要读取 /var/www/html 里的文件。

排查

1
2
ls -ld /var/www /var/www/html
ls -l /var/www/html/index.html

常见问题

  • 目录权限不足( Nginx 用户没有 x 权限,不能进入)
  • 文件权限不足( Nginx 用户没有 r 权限,不能读取)

解决

1
2
3
4
5
sudo chown -R www-data:www-data /var/www/html  # 属主改为 www-data
sudo chmod -R 755 /var/www/html # 目录和文件都设为 755
# 或者更严格
sudo find /var/www/html -type d -exec chmod 755 {} \; # 目录 755
sudo find /var/www/html -type f -exec chmod 644 {} \; # 文件 644

场景 3:共享目录(团队协作)

需求/srv/project 目录, developers 组的成员都能读写,其他人不能访问。

方案

1
2
3
sudo mkdir /srv/project
sudo chown :developers /srv/project # 属组改为 developers
sudo chmod 2770 /srv/project # SGID + 770(只有 owner 和 group 能访问)

  • 2: SGID(新建文件自动继承 developers 组)
  • 770: owner 和 group 都是 rwx, others 无权限

验证

1
2
3
# 用户 A( developers 组成员)创建文件
touch /srv/project/fileA
ls -l /srv/project/fileA # 输出:-rw-r--r-- userA developers

文件属组自动是 developers,组内其他成员也能访问。

场景 4:临时目录(防止互删文件)

需求/tmp 目录,所有用户都能创建文件,但不能删除别人的文件。

方案

1
sudo chmod 1777 /tmp  # Sticky Bit + 777

  • 1: Sticky Bit(只有属主和 root 能删除文件)
  • 777:所有用户都能读写执行

扩展机制: ACL 和 chattr

ACL( Access Control Lists)

为什么需要 ACL?

  • 传统权限只能设置 owner/group/others 三层,不够灵活
  • ACL 可以为特定用户或特定组设置权限(如"用户 A 有读权限,用户 B 有写权限")

查看 ACL

1
getfacl file.txt

设置 ACL

1
2
3
4
setfacl -m u:alice:rw file.txt  # 给用户 alice 读写权限
setfacl -m g:dev:rx dir # 给组 dev 读执行权限
setfacl -x u:alice file.txt # 移除用户 alice 的 ACL
setfacl -b file.txt # 移除所有 ACL

递归设置

1
setfacl -R -m u:alice:rwx dir  # 递归设置

chattr:文件属性(防止误删/误改)

chattr 可以设置文件的特殊属性( ext4 文件系统支持)。

常用属性

  • i( immutable):文件不可修改、删除、重命名(连 root 也不行,除非先去掉 i 属性)
  • a( append-only):文件只能追加写入,不能修改已有内容(适合日志文件)

设置不可修改

1
2
3
sudo chattr +i important.conf  # 文件变成不可修改
rm important.conf # ❌ Operation not permitted(连 root 也删不掉)
sudo chattr -i important.conf # 去掉 i 属性后才能删

设置只能追加

1
2
3
sudo chattr +a logfile.txt  # 只能追加
echo "new line" >> logfile.txt # ✅ 可以追加
echo "overwrite" > logfile.txt # ❌ Operation not permitted(不能覆盖)

查看属性

1
lsattr file.txt

使用场景

  • 保护重要配置文件(/etc/fstab/etc/passwd
  • 防止日志文件被清空

chattr 的其他属性

  • d( no dump):备份时忽略该文件
  • s( secure deletion):删除时用 0 填充数据(安全删除)
  • u( undeletable):删除后内容可恢复

示例:保护 /etc/fstab 不被误删

1
2
3
sudo chattr +i /etc/fstab
rm /etc/fstab # ❌ Operation not permitted
sudo chattr -i /etc/fstab # 需要先解除保护


权限排障清单:出问题了怎么办

问题 1:Permission denied

排查步骤: 1. 确认执行用户:whoami(或查看服务的运行用户,如 systemd unit 文件) 2. 查看文件权限:ls -l file 3. 查看所有父目录权限:namei -l /full/path/to/file(需要安装 util-linux 包) 4. 检查组成员:id(看当前用户属于哪些组) 5. 检查特殊属性:lsattr file(是否有 ia 属性)

常见原因

  • 文件没有读/写/执行权限
  • 父目录没有 x 权限(不能进入)
  • 用户不在文件的属组里

解决

1
2
3
4
sudo chmod 644 file  # 给读权限
sudo chmod +x script.sh # 给执行权限
sudo chmod 755 /path/to/parent/dir # 给父目录 x 权限
sudo chown user:group file # 修改所有权

问题 2: Web 服务器 403 Forbidden

原因: Nginx/Apache 用户(如 www-datanginx)没有权限读取文件。

排查

1
2
3
ps aux | grep nginx  # 查看 nginx 运行用户
ls -l /var/www/html/index.html # 查看文件权限
namei -l /var/www/html/index.html # 查看所有父目录权限

解决

1
2
3
sudo chown -R www-data:www-data /var/www/html
sudo chmod -R 755 /var/www/html # 目录 755
sudo find /var/www/html -type f -exec chmod 644 {} \; # 文件 644

问题 3:脚本执行失败

原因:脚本没有执行权限或 shebang 错误。

排查

1
2
ls -l script.sh  # 查看权限
head -1 script.sh # 查看 shebang

解决

1
2
chmod +x script.sh  # 加执行权限
# 确保 shebang 正确(如 #!/bin/bash)

问题 4:rm: cannot remove 'file': Operation not permitted

原因:文件可能有 i 属性(不可修改/删除)。

排查

1
lsattr file

如果输出包含 i(如 ----i--------),说明文件有 immutable 属性。

解决

1
2
sudo chattr -i file  # 去掉 i 属性
rm file # 现在可以删除了


总结与扩展阅读

这篇文章涵盖了 Linux 文件权限的核心内容: 1. ✅ Linux 权限模型( owner/group/others 、 rwx 语义) 2. ✅ rwx 在文件和目录上的差异(最容易踩的坑) 3. ✅ chmod 和 chown 的使用(数字/符号写法) 4. ✅ umask 的原理和常见值(新建文件的默认权限) 5. ✅ 特殊权限( SUID/SGID/Sticky Bit 的原理和使用场景) 6. ✅ 扩展机制( ACL 、 chattr) 7. ✅ 权限排障清单( Permission denied 、 403 、脚本执行失败等)

扩展阅读

  • man chmod:查看 chmod 的详细手册
  • man chown:查看 chown 的详细手册
  • man 5 acl:查看 ACL 的详细说明
  • SELinux / AppArmor:更高级的安全模型(强制访问控制 MAC)

下一步

  • 《 Linux 用户管理》:学习如何管理用户/组、/etc/passwd/etc/shadow、 sudo 配置
  • 《 Linux 文件操作深入解析》:学习管道、重定向、 stdin/stdout/stderr 、xargstee

到这里,建议已经从"会用 chmod 755"升级到"理解权限语义、能设计共享目录权限方案、能排查权限问题"。文件权限是 Linux 安全的基石,掌握了它,你就能更好地保护系统和数据。

  • 本文标题:Linux 文件权限
  • 本文作者:Chen Kai
  • 创建时间:2019-11-20 09:45:00
  • 本文链接:https://www.chenk.top/Linux-%E6%96%87%E4%BB%B6%E6%9D%83%E9%99%90/
  • 版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
 评论