Linux 文件权限
Linux 文件权限体系:chmod/chown、SUID/SGID/sticky bit、umask、ACL 的用法与区别。
#type / howto
#status / growing
#tech / ops
#resource / linux
#platform / linux
[!info] related notes
- 相关 MOC: Linux MOC
- 相关命令: Linux 文件管理命令
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可能破坏系统