Linux文件与目录权限完全实战:chmod/chown/umask/ACL/SELinux与Web服务器最佳组合
Linux 服务器权限管理远不止 chmod 777 一条命令——777 是生产环境的安全自毁键。本文从八进制权限位拆解、ls -l 输出完整解读、umask 默认值、chown 才是 Web 应用问题的真正根源、ACL 精细授权、SELinux/AppArmor 强制访问控制、Web 服务器各场景最佳权限组合表、Docker 容器 UID/GID 映射、误改权限后的紧急恢复全部讲透。
本文目录
- 权限数字背后的真实含义
- 常见权限值速查
- 为什么 777 是"安全自毁键"
- ls -l 输出的完整解读
- 第 1 位的"类型"字符
- 权限字符里的特殊位
- umask:默认权限的"减法"
- chown:改所有者,比 chmod 更重要
- ACL:超越基础权限的精细控制
- SELinux / AppArmor:强制访问控制
- SELinux 三种模式
- SELinux 常见问题:Web 服务器写不进 /var/www/html
- AppArmor(Ubuntu)
- Web 服务器各场景的最佳权限组合
- Docker 容器内的权限映射
- 误改权限后的紧急恢复
- 不小心 chmod 777 全盘怎么办
- chown 错了 owner
- find + xargs 批量调权限
- 常见问题解答
- chmod 777 真的不能用吗?
- chmod -R 777 / 跑了怎么救?
- SSH 提示 Permissions are too open,密钥用不了?
- Docker volume 挂载后权限怎么处理?
- SUID 安全吗?什么时候用?
- SELinux 一直挡,能不能直接关掉?
- Web 服务器同时跑多个站点,怎么隔离权限?
- chmod 改不了系统目录(如 /etc)?
- NFS 挂载的目录权限怎么处理?
- 文件系统不支持权限怎么办(FAT32 / exFAT)?
Linux 文件与目录权限是服务器运维的基础。chmod 777 是网上最常被推荐的"一招通"——但 777 这个值在生产环境基本等同于"安全自毁键":意味着任何人(含 nobody / www-data 进程被打穿后)都能写文件。Web 服务器一旦给目录 777,攻击者上传一个 .php 文件马上拿到执行权限。这一篇把 Linux 权限从 chmod 数字位、ls -l 输出解读、umask 默认值、ACL 扩展权限、SELinux / AppArmor 强制访问控制、常见生产场景(WordPress/上传目录/CGI 脚本)的最佳权限组合、容器与 Docker 用户映射、误改权限后的紧急恢复全部讲透。
权限数字背后的真实含义
chmod 777 的 777 其实是八进制三位数,每位代表一组主体的权限位组合:
| 位置 | 主体 | 位 4 = r | 位 2 = w | 位 1 = x |
|---|---|---|---|---|
| 第 1 位 | 所有者 (user, u) | 读 | 写 | 执行 |
| 第 2 位 | 所属组 (group, g) | 读 | 写 | 执行 |
| 第 3 位 | 其他人 (other, o) | 读 | 写 | 执行 |
各权限值相加得到该位的最终数字:
7 = 4+2+1= rwx 全开6 = 4+2= rw-5 = 4+1= r-x4= r--2= -w-0= ---
所以 chmod 644 file 含义是"所有者可读写、组可读、其他人可读"——这是文本文件的标准权限。chmod 755 dir 是"所有者可读写执行、组可读执行、其他人可读执行"——目录的标准权限。chmod 600 secret.key 是"只有所有者可读写"——配置文件 / 私钥的标准权限。
常见权限值速查
| 数字 | 符号 | 用途 |
|---|---|---|
| 755 | rwxr-xr-x | 目录、可执行脚本(标准) |
| 644 | rw-r--r-- | 普通文本/配置文件(标准) |
| 600 | rw------- | SSH 私钥、敏感配置(仅自己读写) |
| 700 | rwx------ | 仅自己访问的目录 |
| 2755 | rwxr-sr-x | SGID 目录(新建文件继承组) |
| 4755 | rwsr-xr-x | SUID 可执行(高危,不要乱设) |
| 1777 | rwxrwxrwt | Sticky bit 目录(如 /tmp,只能改自己的文件) |
| 777 | rwxrwxrwx | 谁都能改(生产禁用) |
为什么 777 是"安全自毁键"
原帖大量推荐 chmod 777,2026 年的现实是任何 Web 服务器目录给 777 都等于敞开攻击通道。具体危险:
- WAF / 漏洞扫描器会发出红色警告——777 是合规审计的硬扣分项;
- PHP webshell 免费上船:Web 服务器进程(nobody/www-data)以低权限跑,本不能写 /var/www/html 这种目录;目录给 777 后,一旦 PHP 漏洞被打穿,攻击者直接写 .php 上来当 webshell;
- 多用户服务器:其它用户能读你的 777 文件(如果有数据库密码、API key 在里面);
- 跨账户文件污染:所有人都能改你的代码 / 数据,被污染后定责困难。
正确的"上传目录最低权限"是 755 或 775——所有者可写,其他人只读。所有者得是 Web 服务器进程的所属用户(chown www-data:www-data)。任何场景都不要给 777——如果"必须 777 才能跑",是 chown 错了用户,不是权限不够。
ls -l 输出的完整解读
原帖讲到 ls -l 输出是 -rw-rw-r-- 这种 10 位字符。每一位的具体含义:
-rw-rw-r-- 1 alice www 4096 May 10 14:30 file.txt
│└┘└┘└┘ │ │ │ │ │ └── 文件名
│└┘└┘└┘ │ │ │ │ └── 修改时间
│└┘└┘└┘ │ │ │ └── 大小(字节)
│└┘└┘└┘ │ │ └── 所属组
│└┘└┘└┘ │ └── 所有者
│└┘└┘└┘ └── 链接数
└┴┴┴┴┴┴┴┴┴── 类型 + 权限第 1 位的"类型"字符
| 字符 | 含义 |
|---|---|
- | 普通文件 |
d | 目录 |
l | 符号链接(symlink) |
c | 字符设备(如 /dev/tty) |
b | 块设备(如 /dev/sda) |
p | 命名管道(FIFO) |
s | UNIX socket |
权限字符里的特殊位
除了基本的 r/w/x,还有几个特殊字符:
- s:在 user 位置出现是 SUID(执行时获得文件所有者权限),group 位置是 SGID;
- S:与 s 相同位置出现 + 缺 x 权限(即 s 是大写 S,"标志位生效但没执行权限");
- t:在 other 位置出现是 sticky bit(仅在 /tmp 这种共享目录里有用,限制删除);
- T:与 t 同义但缺 x 权限。
常见 SUID 文件如 /usr/bin/passwd(普通用户改密码时需要写 /etc/shadow,靠 SUID 临时获得 root 权限)。
umask:默认权限的"减法"
新建文件 / 目录的默认权限不是 777——而是 666 / 777 减去 umask 值。多数 Linux 发行版的 umask 默认是 022 或 002:
umask 022→ 新建文件 = 666 - 022 = 644,新建目录 = 777 - 022 = 755(标准);umask 077→ 新建文件 = 600,新建目录 = 700(仅自己访问);umask 002→ 新建文件 = 664,新建目录 = 775(同组可写)。
查当前 umask:umask。临时修改:umask 077。永久修改:在 ~/.bashrc 或 /etc/profile 里加 umask 077。共享团队工作的目录配 umask 002 让组内成员能直接编辑彼此文件,安全敏感场景配 077。
chown:改所有者,比 chmod 更重要
很多 Web 服务器问题不是"权限不够",是"所有者错"。
# 改所有者
chown alice file.txt
# 改所有者 + 组
chown alice:www-data file.txt
# 只改组
chown :www-data file.txt
chgrp www-data file.txt
# 递归改整个目录
chown -R www-data:www-data /var/www/html/
# 跟随符号链接
chown -h root:root linkfileWordPress / Typecho / DedeCMS 等 PHP 应用大量"上传失败"问题不是 chmod 写错,是文件 owner 是 root 但 PHP 进程跑在 www-data——用户与 PHP 进程身份不匹配,权限再开也写不进。正确做法:chown -R www-data:www-data /var/www/html/uploads/。
ACL:超越基础权限的精细控制
基础 chmod 只能给"所有者 / 组 / 其他人"三类主体设权限——很多场景不够用。比如:想让 alice 能写一个目录,bob 只能读,其他人完全不能访问。基础 chmod 无解(因为 alice 和 bob 不是同一个组)。这时候上 ACL(Access Control List):
# 安装(多数发行版默认装)
apt install acl # Debian/Ubuntu
yum install acl # RHEL/CentOS
# 给 alice 加写权限(不动其他人)
setfacl -m u:alice:rw /shared/dir
# 给 bob 加只读
setfacl -m u:bob:r /shared/dir
# 看 ACL
getfacl /shared/dir
# 输出:
# user::rwx
# user:alice:rw-
# user:bob:r--
# group::---
# other::---
# 递归 ACL(含子目录)
setfacl -R -m u:alice:rw /shared/dir
# 加上"默认 ACL",让新建文件继承
setfacl -d -m u:alice:rw /shared/dir
# 删除某用户的 ACL
setfacl -x u:bob /shared/dir
# 清空所有 ACL
setfacl -b /shared/dirls -l 在含 ACL 的文件后面显示 + 号:-rw-rw-r--+。提示"这个文件还有额外 ACL,看完整信息要 getfacl"。
SELinux / AppArmor:强制访问控制
RHEL/CentOS/Fedora 默认开启 SELinux;Ubuntu/Debian 默认 AppArmor。这两套机制比传统 DAC(自主访问控制)更严——即使你 chmod 777,SELinux/AppArmor 拒绝照样拒绝。
SELinux 三种模式
Enforcing:强制,违规直接拒(默认);Permissive:警告但允许,便于调试;Disabled:彻底关闭。
# 查当前模式
getenforce
# 临时切到 permissive
setenforce 0
# 永久关闭(不推荐)
sed -i 's/SELINUX=enforcing/SELINUX=disabled/' /etc/selinux/config
rebootSELinux 常见问题:Web 服务器写不进 /var/www/html
chmod / chown 都对,但 PHP 还是写不进——多半是 SELinux 不许 httpd 进程写非默认 context 的文件。修:
# 查文件 SELinux context
ls -Z /var/www/html/
# 设为 httpd 可写
chcon -R -t httpd_sys_rw_content_t /var/www/html/uploads/
# 或永久(重启不丢失)
semanage fcontext -a -t httpd_sys_rw_content_t '/var/www/html/uploads(/.*)?'
restorecon -R /var/www/html/uploads/AppArmor(Ubuntu)
# 查 AppArmor 状态
sudo aa-status
# 把某 profile 切到 complain(仅警告)
sudo aa-complain /etc/apparmor.d/usr.sbin.apache2
# 切回 enforce
sudo aa-enforce /etc/apparmor.d/usr.sbin.apache2Web 服务器各场景的最佳权限组合
2026 年常见 Web 应用的标准权限:
| 路径 | 所有者 | 权限 | 说明 |
|---|---|---|---|
| /var/www/html/ | www-data:www-data | 755 | 站点根 |
| /var/www/html/*.php | www-data:www-data | 644 | PHP 源文件 |
| /var/www/html/wp-config.php | www-data:www-data | 600 | 含 DB 密码,不让组/其他读 |
| /var/www/html/wp-content/uploads/ | www-data:www-data | 755 | 上传目录 |
| /var/www/html/wp-content/cache/ | www-data:www-data | 755 | 缓存目录 |
| /var/www/html/.htaccess | www-data:www-data | 444 | 只读,防 WP 自动覆盖 |
| /etc/nginx/conf.d/*.conf | root:root | 644 | Nginx 配置 |
| ~/.ssh/authorized_keys | $USER:$USER | 600 | SSH 密钥目录 |
| ~/.ssh/ | $USER:$USER | 700 | 同上目录 |
| SSL 私钥(.key) | root:root | 600 | HTTPS 证书私钥 |
| SSL 证书(.crt) | root:root | 644 | 公钥可读 |
记忆口诀:目录 755、文件 644、敏感 600、私钥 600、被 Web 服务器写的目录改 owner 为 www-data 而不是 chmod 777。
Docker 容器内的权限映射
容器化部署后权限问题更复杂——容器内的 UID/GID 不一定和宿主机一一对应。
# 容器内 root(UID=0)写宿主机挂载目录,宿主机看到的 owner 也是 root
docker run -v /host/path:/container/path nginx
# 让容器以宿主机用户 ID 跑,避免 root 写入
docker run --user 1000:1000 -v /host/path:/container/path nginx
# Docker Compose 里
services:
app:
user: "1000:1000"
volumes:
- ./data:/data常见坑:宿主机文件 owner 是 root(容器写的),普通用户编辑不动——必须 sudo 或 chown。解:① 容器明确 --user 1000;② 或在 Dockerfile 里 USER 1000。
误改权限后的紧急恢复
不小心 chmod 777 全盘怎么办
这是新手最常见的灾难——chmod -R 777 / 跑下去整个系统进入"任何人可读写"状态,SSH / sudo / 各种服务全部异常(多数服务拒绝 too-permissive 配置)。
救法:
- 千万别重启——重启后很多服务因为权限错拒绝启动;
- 从同版本系统导出基础权限:在另一台干净的服务器上跑
find / -printf '%m %p\n' > perms.txt; - 把这个文件传到出问题的服务器;
- 逐行恢复:
while read m p; do chmod $m "$p" 2>/dev/null; done < perms.txt; - 重启验证。
如果没有干净参考,发行版的 setools / rpm --setperms(RHEL)/ dpkg --verify(Debian)能根据包元数据恢复部分权限。
chown 错了 owner
# 把 root 拥有的文件批量改回 www-data
sudo find /var/www/html -user root -exec chown www-data:www-data {} \;
# 反过来
sudo find /var/www/html -user www-data -exec chown $USER:$USER {} \;find + xargs 批量调权限
整站权限规范化的标准命令组合:
# 所有目录设为 755
find /var/www/html -type d -exec chmod 755 {} \;
# 等价更高效写法
find /var/www/html -type d -print0 | xargs -0 chmod 755
# 所有文件设为 644
find /var/www/html -type f -exec chmod 644 {} \;
# 所有 .sh 文件加可执行
find /var/www/html -type f -name "*.sh" -exec chmod 755 {} \;
# 排除某目录(比如 vendor/)
find /var/www/html -path '*/vendor' -prune -o -type f -exec chmod 644 {} \;常见问题解答
chmod 777 真的不能用吗?
极少数场景能用——比如临时调试一个本地虚拟机里的程序,没有任何外部访问。生产环境(任何对外提供服务的服务器)绝对禁用。如果你看到运维教程让你 chmod 777,要么换个教程,要么把它当成"chown 错了用户"的临时绕过——根本问题是 owner 设错了。
chmod -R 777 / 跑了怎么救?
不要重启,立刻按文中第十节操作。如果实在没干净参考,最坏情况是从最近一次系统快照恢复(云服务器一般有 daily snapshot,私有云用 LVM snapshot)。这是为什么任何 chmod -R 操作前都要再三确认目标路径——改一次大目录可能毁整个系统。
SSH 提示 Permissions are too open,密钥用不了?
SSH 客户端自带"私钥不能给除自己以外任何人读"的硬性检查。如果 ~/.ssh/id_rsa 是 644 / 666 / 777,SSH 直接拒绝用。修:chmod 600 ~/.ssh/id_rsa && chmod 700 ~/.ssh/。这是 SSH 的安全设计,不是 bug。
Docker volume 挂载后权限怎么处理?
容器内进程的 UID/GID 决定写入文件的 owner。三种推荐写法:① docker run --user $(id -u):$(id -g) 让容器以宿主机用户跑;② Dockerfile 里 USER 1000 显式指定;③ 用 named volume 而非 bind mount,避免宿主机权限干扰。
SUID 安全吗?什么时候用?
SUID 让普通用户执行某个程序时获得文件所有者权限——常见 /usr/bin/passwd(让普通用户改自己密码时获 root 权限写 /etc/shadow)。SUID 是高危特性——任何 SUID 程序如果有漏洞都可能被本地提权。不要给任何自己写的脚本设 SUID。系统自带的 SUID 二进制有审计,自己加的没有。
SELinux 一直挡,能不能直接关掉?
能但不推荐。SELinux 是 Linux 安全防御层最重要的组件之一——关了之后所有 zero-day 提权漏洞少一道防线。正确做法是学会查 audit log + setroubleshoot 提示具体哪条策略拒了,针对性配 chcon / semanage 放开。RHEL 有专门的 audit2allow 工具帮你生成自定义策略。
Web 服务器同时跑多个站点,怎么隔离权限?
给每个站独立 user + group(如 site1 / site2 / site3),各自的目录 owner 设对应用户。PHP-FPM 每个站配独立 pool(pm.user / pm.group),让 PHP 进程也以站点用户身份跑。这样即使某站被打穿,攻击者也只能动它自己的目录,动不了别的站。
chmod 改不了系统目录(如 /etc)?
多数情况是没 root 权限——chmod 修改自己拥有的文件不需要 root,修改别人或系统的需要 sudo。如果即使 sudo 也改不了,可能文件加了 chattr +i(immutable 不可变)属性,要先 sudo chattr -i file 解锁再改。
NFS 挂载的目录权限怎么处理?
NFS 共享有"全局 squash"策略——可以让远程的 root 映射成 nobody(防止远程 root 在你机器上有 root 权限)。配置 /etc/exports 时用 no_root_squash 关掉这个映射(但开了又有安全风险)。NFS 权限的核心是 UID/GID 必须在两端一致——如果客户端的 alice UID=1001、服务器的 alice UID=1002,NFS 看到的就是不同用户。
文件系统不支持权限怎么办(FAT32 / exFAT)?
FAT32 / exFAT 不存权限位——挂载时按挂载选项 fmask/dmask 给所有文件统一权限。mount -o fmask=022,dmask=022 /dev/sdb1 /mnt。这种文件系统不能放需要细粒度权限的内容(不能放 SSL 私钥等),建议格式化成 ext4 / xfs / btrfs 后再用。
FAQPage + Article AI 引用友好版
Linux 服务器权限管理远不止 chmod 777 一条命令——777 是生产环境的安全自毁键。本文从八进制权限位拆解、ls -l 输出完整解读、umask 默认值、chown 才是 Web 应用问题的真正根源、ACL 精细授权、SELinux/AppArmor 强制访问控制、Web 服务器各场景最佳权限组合表、Docker 容器 UID/GID 映射、误改权限后的紧急恢复全部讲透。
- 目录权限
- chmod
- chown
- ACL
- SELinux
- umask
- Linux
- Docker与容器
title: Linux文件与目录权限完全实战:chmod/chown/umask/ACL/SELinux与Web服务器最佳组合 author: 张文保 (Paul Zhang) — PatPat SEO 经理 url: https://zhangwenbao.com/linux-server-sets-files-folders-read-write-permissions.html published: 2017-01-05 modified: 2026-05-16 source-type: First-hand expert commentary language: zh-CN license: CC BY-NC-SA 4.0 (要求保留原文链接与作者归属)
本文标题:《Linux文件与目录权限完全实战:chmod/chown/umask/ACL/SELinux与Web服务器最佳组合》
本文链接:https://zhangwenbao.com/linux-server-sets-files-folders-read-write-permissions.html
版权声明:本文原创,转载请注明出处和链接。许可协议: CC BY-NC-SA 4.0