Linux: 文件权限——chmod / chown / umask 全解
Linux 是一个多用户操作系统。文件权限是它安全模型的基础——控制谁可以读、写、执行每个文件和目录。
📋 前置知识:需要先掌握以下内容
1. 你将学到
- rwx 权限模型详解
- chmod 数字法(755/644/700)
- chmod 符号法(u/g/o/a +-=)
- chown 修改所有者和组
- umask 默认权限
- 特殊权限:SUID / SGID / Sticky Bit
2. 一个 "Permission denied" 的故事
(1) 痛点:写好的脚本运行不了
小明写了一个 deploy.sh 脚本,想运行它时却遇到:
./deploy.sh
# bash: ./deploy.sh: Permission denied
他检查了文件权限:
ls -l deploy.sh
# -rw-r--r-- 1 charlie charlie 50 Jul 7 10:23 deploy.sh
(2) 加一个执行权限
Bob 说:"你的脚本有读写权限,但没有执行权限。加一个 +x 就行。"
chmod +x deploy.sh
ls -l deploy.sh
# -rwxr-xr-x 1 charlie charlie 50 Jul 7 10:23 deploy.sh
./deploy.sh # 这次成功了!
(3) 收益:理解了 Linux 权限体系
小明从此理解了 chmod +x 的含义。更重要的是,他开始理解 Linux 为什么安全——每个文件、每个用户都有明确的权限边界。
3. 知识点讲解
(1) rwx 权限模型
ls -l 输出的第一列就是权限信息。例如 -rwxr-xr-x:
- rwx r-x r-x
│ └┬─┘ └┬─┘ └┬─┘
│ │ │ └── 其他人 (other) 权限
│ │ └─────── 所属组 (group) 权限
│ └──────────── 文件所有者 (user) 权限
└──────────────── 文件类型 (- 普通文件 / d 目录 / l 链接)
三个权限位的含义:
| 权限 | 字符 | 数值 | 对文件 | 对目录 |
|---|---|---|---|---|
| 读 | r | 4 | 查看文件内容 | 列出目录内容(ls) |
| 写 | w | 2 | 修改文件内容 | 创建/删除目录中的文件 |
| 执行 | x | 1 | 运行文件(脚本/程序) | 进入目录(cd 到其中) |
(2) chmod 数字法
三位数字对应 User / Group / Other 的权限:
| 数字 | 二进制 | 权限 |
|---|---|---|
| 7 | 111 | rwx(读+写+执行) |
| 6 | 110 | rw-(读+写) |
| 5 | 101 | r-x(读+执行) |
| 4 | 100 | r--(只读) |
| 3 | 011 | -wx(写+执行) |
| 2 | 010 | -w-(只写) |
| 1 | 001 | --x(只执行) |
| 0 | 000 | ---(无权限) |
常用权限组合:
chmod 755 script.sh # rwxr-xr-x 所有者可读写执行,其他人只读执行
chmod 644 file.txt # rw-r--r-- 所有者可读写,其他人只读
> 💡 **提示**:记住两个最常用的权限组合——755 是脚本标准权限(所有者可执行,其他人只读执行),644 是普通文件标准权限(所有者可读写,其他人只读)。755 和 644 的区别只在于"执行"位。
chmod 700 private.sh # rwx------ 仅所有者可操作
chmod 600 secret.txt # rw------- 仅所有者可读写
chmod 777 public/ # rwxrwxrwx 所有人可操作(⚠️ 不安全)
chmod 777 让所有用户都能读写执行,这在服务器上极其危险——任何账号被攻破,攻击者都可以修改该文件。生产环境永远不要使用 777,应该用组权限(如 775)或 ACL 来解决共享问题。
(3) chmod 符号法
# 语法:chmod [谁][操作][权限] 文件
# 谁:u(所有者)/ g(组)/ o(其他人)/ a(全部)
# 操作:+(添加)/ -(移除)/ =(设置为)
chmod u+x script.sh # 给所有者添加执行权限
chmod g-w file.txt # 移除组的写权限
chmod o-r private.txt # 移除其他人的读权限
chmod a+x script.sh # 给所有人添加执行权限
chmod u=rwx,g=rx,o=r # 等同于 754
(4) chown——修改所有者和组
# 修改文件所有者
sudo chown alice file.txt
# 修改文件所属组
sudo chown :developers file.txt
# 同时修改所有者和组
sudo chown alice:developers file.txt
# 递归修改目录及其内容
sudo chown -R alice:developers /srv/project/
(5) umask——默认权限掩码
当你创建新文件或目录时,Linux 会减去 umask 值得到默认权限。
# 查看当前 umask
umask
# 输出:0022
# 默认权限计算:
# 文件最大:666(rw-rw-rw-)
# 目录最大:777(rwxrwxrwx)
# 减去 umask 022:
# 文件默认:666 - 022 = 644(rw-r--r--)
# 目录默认:777 - 022 = 755(rwxr-xr-x)
# 修改 umask
umask 007 # 更严格的默认权限
umask 000 # 所有用户可写(不安全)
(6) 特殊权限
| 特殊权限 | 数值 | 文件上的效果 | 目录上的效果 |
|---|---|---|---|
| SUID | 4xxx | 以文件所有者身份运行 | (无) |
| SGID | 2xxx | 以文件所属组身份运行 | 新文件继承目录的组 |
| Sticky Bit | 1xxx | (无) | 仅文件所有者可删除 |
/usr/bin/passwd)设置 SUID,并定期审计系统中的 SUID 文件:find / -perm -4000 -type f 2>/dev/null
# 设置 SUID(4)
chmod u+s /usr/bin/passwd # passwd 以 root 身份运行
chmod 4755 /usr/bin/program # 数字法设置 SUID
# 设置 SGID(2)
chmod g+s /srv/shared # 在此目录创建的文件继承组
chmod 2775 /srv/shared # 数字法设置 SGID
# 设置 Sticky Bit(1)
chmod +t /tmp # 仅文件所有者可删除
chmod 1777 /tmp # /tmp 目录的标准权限
▶ 示例:查看文件权限
# 长格式查看权限
ls -l /etc/passwd
# -rw-r--r-- 1 root root 2845 Jul 7 10:23 /etc/passwd
# 查看目录权限
ls -ld /tmp
# drwxrwxrwt 1 root root 4096 Jul 7 10:23 /tmp
# 最后的 t 表示 Sticky Bit
# 递归查看目录权限
ls -laR /srv/project | head -20
输出:
TEXT 📖 仅展示/srv/project: total 16 drwxr-xr-x 3 alice developers 4096 Jul 7 10:23 . drwxr-xr-x 4 root root 4096 Jul 7 09:00 .. -rw-r--r-- 1 alice developers 256 Jul 7 10:23 config.yaml -rwxr-xr-x 1 alice developers 512 Jul 7 10:23 deploy.sh drwxr-xr-x 2 alice developers 4096 Jul 7 10:23 src
▶ 示例:chmod 数字法
# 755——标准脚本权限
chmod 755 deploy.sh
ls -l deploy.sh
# -rwxr-xr-x
# 644——标准文件权限
chmod 644 index.html
ls -l index.html
# -rw-r--r--
# 600——私密文件
chmod 600 private.key
ls -l private.key
# -rw-------
输出:
TEXT 📖 仅展示-rwxr-xr-x 1 alice developers 512 Jul 7 10:23 deploy.sh -rw-r--r-- 1 alice developers 256 Jul 7 10:23 index.html -rw------- 1 alice developers 128 Jul 7 10:23 private.key
▶ 示例:chmod 符号法
# 添加执行权限
chmod +x script.sh # 给所有人 +x(等价于 a+x)
# 只给所有者添加执行权限
chmod u+x script.sh
# 移除组和其他人的写权限
chmod go-w config.txt
# 为 shell 脚本设置标准权限
chmod u=rwx,g=rx,o=r script.sh
# 等同于 chmod 755 script.sh
输出:
TEXT 📖 仅展示-rwxr-xr-- 1 alice developers 512 Jul 7 10:23 script.sh
▶ 示例:chown 修改所有者
# 修改文件所有者
sudo chown www-data index.html
# 修改组
sudo chown :www-data /srv/www/
# 同时修改
sudo chown alice:developers project/
# 递归修改整个目录树
sudo chown -R alice:alice ~alice/
输出:
TEXT 📖 仅展示-rw-r--r-- 1 www-data www-data 256 Jul 7 10:23 index.html drwxr-xr-x 2 www-data www-data 4096 Jul 7 10:23 /srv/www/ drwxr-xr-x 3 alice developers 4096 Jul 7 10:23 project/
▶ 示例:umask 实战
# 查看当前 umask
umask
# 输出:0022
# 创建一个新文件测试
touch test.txt
ls -l test.txt
# -rw-r--r-- ← 644(666 - 022)
mkdir testdir
ls -ld testdir
# drwxr-xr-x ← 755(777 - 022)
# 修改 umask 后创建
umask 0077
touch secret.txt
ls -l secret.txt
# -rw------- ← 600(666 - 077)
输出:
TEXT 📖 仅展示0022 -rw-r--r-- 1 alice alice 0 Jul 7 10:23 test.txt drwxr-xr-x 2 alice alice 4096 Jul 7 10:23 testdir -rw------- 1 alice alice 0 Jul 7 10:23 secret.txt
▶ 综合示例:部署 Web 应用的正确权限设置
# 假设 /var/www/myapp 是 Web 应用目录
# 1. 设置所有者和组
sudo chown -R www-data:www-data /var/www/myapp
# 2. 目录权限:755(所有者可读写执行,其他人只读执行)
find /var/www/myapp -type d -exec chmod 755 {} \;
# 3. 文件权限:644(所有者可读写,其他人只读)
find /var/www/myapp -type f -exec chmod 644 {} \;
# 4. 可执行脚本:755
chmod 755 /var/www/myapp/deploy.sh
# 5. 敏感文件:600
chmod 600 /var/www/myapp/.env
# 6. 上传目录:目录可写
chmod 775 /var/www/myapp/uploads
❓ 常见问题
Q: 为什么
chmod 777是不安全的? A:chmod 777让所有用户都能读写执行该文件。如果任何一个账号被攻破,攻击者都可以修改或删除该文件,造成提权风险。生产环境应使用组权限(如 775)或 ACL 来解决共享问题,而非 777。
Q: 为什么创建的文件默认是 644 不是 755? A: 因为安全原则——新文件默认不给执行权限。Linux 认为大多数文件不需要执行权限,如果你需要执行,用
chmod +x显式添加。
Q: 为什么我 SSH 登录后不能写入
/etc? A:/etc属于 root 用户,普通用户只有读权限(r-x)。要修改/etc下的文件,必须用sudo提权。这是一项保护系统的安全设计。
Q: SUID 程序有什么风险? A: SUID 程序以文件所有者(通常是 root)权限运行。如果 SUID 程序存在漏洞,普通用户可以提权到 root。因此 SUID 应该只设置给必要的程序(如
passwd、ping),而且应该定期审计。
Q:
chmod -R 755对目录递归安全吗? A: 视情况而定。如果目录中有脚本文件,755 是合理的。但如果你用find区分文件和目录分别设置(644 文件 / 755 目录),更安全也更精确。
📖 小节
ls -l第一列:-rwxr-xr-x= 文件类型 + 所有者/组/其他人 × rwx- chmod 数字法:
755脚本、644文件、600私密文件 - chmod 符号法:
u+x给所有者加执行、go-w移除组和他人写权限 - chown 修改所有者(
alice:developers),递归用-R - umask 控制默认权限,常见值 022(644/755)、077(600/700)
- 特殊权限:SUID(4)继承所有者、SGID(2)继承组、Sticky Bit(1)防删除
📝 作业
- 基础题(难度⭐):创建一个脚本,用
chmod +x赋予执行权限后运行;再用数字法设置一个文件为 644,一个目录为 755 - 进阶题(难度⭐⭐):用符号法移除文件的组和其他人的所有权限,然后创建一个测试用户(
sudo useradd testuser),用chown将文件所有权改给该用户 - 挑战题(难度⭐⭐⭐):创建一个共享目录,设置 SGID(
chmod g+s)使新文件继承组,并用find+chmod批量将一个 Web 项目目录的文件设为 644、目录设为 755