Linux 文件权限

Linux 文件权限体系:chmod/chown、SUID/SGID/sticky bit、umask、ACL 的用法与区别。

#type / howto #status / growing #tech / ops #resource / linux #platform / linux

[!info] related notes

Linux 文件权限

一句话定义

Linux 通过权限位控制”谁能对文件做什么操作”,包括基本权限、特殊权限位和 ACL。

权限基础

ls -la
# -rwxr-xr-- 1 user group 4096 May 27 10:00 app.sh
# │││││││││
# ││││││││└─ 其他人权限
# │││││││└── 所属组权限
# ││││││└─── 所有者权限
# │││││└──── 其他人执行
# ││││└───── 其他人写入
# │││└────── 其他人读取
# ││└─────── 组执行
# │└──────── 组写入
# ────────── 组读取
# ─────────── 所有者执行
# ──────────── 所有者写入
# ───────────── 所有者读取
# ────────────── 文件类型 (- 普通文件, d 目录, l 链接)

权限对照表:

权限文件目录
r (4)读取内容列出目录内容
w (2)修改内容创建/删除文件
x (1)执行进入目录

chmod:修改权限

# 数字模式
chmod 755 app.sh    # rwxr-xr-x
chmod 644 config.txt # rw-r--r--
chmod 700 secret.sh  # rwx------

# 符号模式
chmod u+x app.sh    # 给所有者添加执行权限
chmod g-w file.txt  # 移除组的写权限
chmod o=r file.txt  # 设置其他人只读
chmod a+r file.txt  # 所有人添加读权限

# 递归修改目录
chmod -R 755 /var/www

# 常用权限组合
# 644 = 普通文件(所有者读写,其他人只读)
# 755 = 可执行文件/目录(所有者全权限,其他人读+执行)
# 600 = 私密文件(只有所有者读写)
# 700 = 私密目录(只有所有者全权限)

chown:修改所有者

# 修改所有者
chown user file.txt

# 修改所有者和组
chown user:group file.txt

# 只修改组
chown :group file.txt

# 递归修改
chown -R user:group /var/www

# 常用场景
chown -R www-data:www-data /var/www  # Web 服务器目录
chown -R postgres:postgres /var/lib/postgresql  # 数据库目录

特殊权限位

SUID (Set User ID)

# 设置 SUID:执行时以文件所有者身份运行
chmod u+s /usr/bin/passwd
chmod 4755 /usr/bin/passwd  # 4 = SUID

# 查看
ls -la /usr/bin/passwd
# -rwsr-xr-x 1 root root ... /usr/bin/passwd
#    ^ s 表示 SUID 已设置

# 典型应用:passwd 命令需要 root 权限修改 /etc/shadow
# 但普通用户也能执行,因为 SUID 让它以 root 身份运行

# 安全风险:SUID 程序如果被利用,攻击者获得所有者权限

SGID (Set Group ID)

# 设置 SGID
chmod g+s /shared/dir
chmod 2775 /shared/dir  # 2 = SGID

# 对文件:执行时以文件所属组身份运行
# 对目录:新建文件继承目录的组(而不是创建者的主组)

# 典型应用:共享目录
mkdir /shared
chown :developers /shared
chmod 2775 /shared
# 现在 developers 组的任何人在 /shared 创建的文件
# 都自动属于 developers 组

Sticky Bit

# 设置 Sticky Bit
chmod +t /tmp
chmod 1777 /tmp  # 1 = sticky bit

# 效果:目录中的文件只有所有者能删除
# 即使其他人有写权限也不能删除别人的文件

# 典型应用:/tmp 目录
# 所有人都能写入,但不能删除别人的临时文件
ls -ld /tmp
# drwxrwxrwt 1 root root ... /tmp
#         ^ t 表示 sticky bit 已设置

umask:默认权限掩码

# 查看当前 umask
umask
# 0022

# umask 计算:
# 文件默认权限 = 666 - umask = 666 - 022 = 644 (rw-r--r--)
# 目录默认权限 = 777 - umask = 777 - 022 = 755 (rwxr-xr-x)

# 设置 umask
umask 027  # 新文件 640,新目录 750

# 永久设置:写入 ~/.bashrc 或 /etc/profile
echo 'umask 027' >> ~/.bashrc

ACL:访问控制列表

ACL 提供比基本权限更细粒度的控制:

# 查看 ACL
getfacl file.txt

# 设置 ACL
# 给特定用户权限
setfacl -m u:bob:rw file.txt

# 给特定组权限
setfacl -m g:developers:r file.txt

# 设置默认 ACL(目录新建文件自动继承)
setfacl -d -m g:developers:rw /shared

# 递归设置
setfacl -R -m g:developers:rw /shared

# 删除 ACL
setfacl -x u:bob file.txt  # 删除特定条目
setfacl -b file.txt         # 删除所有 ACL

# ACL 与 ls
ls -la file.txt
# -rw-rw-r--+ 1 user group ... file.txt
#           ^ + 表示有 ACL 扩展

权限排查流程

# 1. 检查基本权限
ls -la /path/to/file

# 2. 检查 ACL
getfacl /path/to/file

# 3. 检查特殊权限位
stat -c '%a %U %G' /path/to/file

# 4. 检查父目录权限(目录需要 x 权限才能进入)
ls -ld /path/to/
ls -ld /path/

# 5. 检查 SELinux/AppArmor(如果系统启用了)
ls -Z /path/to/file  # SELinux 上下文
getenforce            # SELinux 状态

常见误区

  • 目录必须有 x 权限:没有 x 就不能进入目录
  • chmod 777 危险:所有人都能读写执行,生产环境禁用
  • SUID 有安全风险:只对可信程序设置
  • umask 是”减法”:不是设置权限,是屏蔽权限
  • ACL 优先级高于基本权限:ACL 更细粒度
  • 递归修改权限要谨慎:chmod -R 777 可能破坏系统
创建于 2026/5/27 更新于 2026/5/27