首页 › 博客 › 文章

WordPress 目录权限怎么设:为什么 777 会出事

WordPress 目录权限怎么设:为什么 777 会出事

WordPress 的目录权限问题有个共同特点:配错了往往不报错,而是以一种完全不像权限问题的形式表现出来——插件莫名消失、图片传不上去、更新卡在 FTP 凭据。这篇把权限位的读法、常见组合的含义、以及几类典型故障的排查命令讲清楚。

WordPress 目录权限设置 配图

权限位怎么读:三组数字分别管谁

在 Linux 里,每个文件和目录都带着一组权限,用三组数字表示,比如 755。拆开看是:第一位管属主,第二位管属组,第三位管其他所有人。

数字 读(r) 写(w) 执行(x) 计算方式
7 ✓ ✓ ✓ 4 + 2 + 1
6 ✓ ✓ ✗ 4 + 2
5 ✓ ✗ ✓ 4 + 1
4 ✓ ✗ ✗ 4
0 ✗ ✗ ✗ 0

关键在于:执行位对文件和目录的含义完全不同。对文件来说,执行位表示「能不能当程序运行」;对目录来说,执行位表示「能不能进入这个目录」。

这一点是后面所有故障的根源。一个目录只有读权限(r)而没有执行权限(x)时,你能列出目录里的文件名,但打不开里面的任何一个文件——就像你能看到信封上的名字,却拆不开信。反映到程序上,就是「目录看起来存在,但里面的一切都取不到」。

755、644、777:常见组合各意味着什么

组合 属主 属组 其他 适用场景
755 读写执行 读 + 执行 读 + 执行 目录的标准值
644 读写 只读 只读 普通文件的标准值
600 读写 无权限 无权限 含敏感信息的文件
750 读写执行 读 + 执行 无权限 要求更严的目录
777 读写执行 读写执行 读写执行 不应用于生产环境

WordPress 站点的基线就是「目录 755、文件 644」。这个组合的含义是:文件的属主(也就是 Web 服务进程)可以读写,其他任何用户只能看不能改。

需要特别说明 wp-config.php。这个文件里存着数据库名、用户名和密码,标准做法是设成 600 或 640,让只有属主和属组能读。设成 644 时,同一台服务器上其他用户的程序都能读到你的数据库口令——在共享主机或一台服务器跑多个站点的环境下,这是实打实的风险。

属主与 Web 用户:真正决定能不能写的是它

权限位只对三类身份生效,所以在看权限之前,得先确认「文件归谁」。用 ls 就能看到:

ls -ld /www/wwwroot/你的域名/wp-content
# 输出类似:drwxr-xr-x 8 www www 4096 Oct 14 09:00 wp-content
#                        ↑   ↑
#                      属主 属组

判断标准只有一条:PHP 进程以哪个用户运行,站点文件就该归哪个用户。宝塔环境下通常是 www,部分环境是 nginx 或 www-data。

这里有个常被误解的细节:如果 PHP 进程用户恰好就是文件的属主,那系统只检查「属主」那一位的权限,属组和其他那两位设成什么都不影响写入。所以有时把权限改成 777 后问题依旧,原因就是属主不对——此时正确的做法是改属主,而不是继续放宽权限。

反过来,如果属主是 root 而 PHP 是 www,那么无论怎么放宽后两位,都不如执行一次 chown 来得干净。这也解释了为什么「图省事设 777」往往无效:它掩盖了真正的属主问题,还额外引入了风险。

为什么 777 会出事

777 的意思是:任何人对这个文件都可读、可写、可执行。放到生产环境上有三层问题。

第一层,任何本地用户都能篡改你的代码。服务器上跑的进程不止 WordPress 一个,只要其中任何一个被攻破,攻击者就能往你的主题或插件目录里写文件。写入一个 PHP 文件就等于拿到了 Web 权限,后面的事就与权限无关了。

第二层,对目录而言,可写意味着能删能改名。很多人以为「可写」只是能新建文件,实际上对目录有写权限就能删除或重命名目录内的任何文件,哪怕那个文件的属主是别人。

第三层,执行位让上传的文件可能被执行。如果上传目录同时具备写和执行权限,攻击者传上去的脚本就有机会被直接运行。这也是为什么上传目录通常只给写、不给执行(通过 PHP-FPM 或 Nginx 禁止解析该目录下的 PHP 文件)。

获取报价

邮箱 + 需求 + 预算区间,24 小时内回复报价。

还有一个容易被忽略的副作用:设成 777 之后,很多主机面板的安全扫描会把站点标记为高风险,部分托管商甚至会直接暂停站点。用一个长期的安全隐患去换一次临时的便利,通常不划算。

正确的解法从来不是放宽权限,而是把属主改对。「上传失败 → chmod 777 → 还是失败」这个循环,几乎总是属主问题,退出循环的方式是 chown。

目录缺执行位:最有迷惑性的那种故障

这一节讲一类真实发生过的故障,它的表现完全不像权限问题。

故障现象是这样的:某次维护后,站点前台一切正常,但某个插件的功能消失了。后台「已安装插件」列表里,这些插件仍显示已启用,而且没有任何报错,日志也是干净的。更奇怪的是,用命令行以 root 身份执行同样的检查脚本,结果显示一切正常。

排查到最后发现:wp-content 下的某个目录权限被设成了 644(文件权限值被误用到目录上)。目录有读权限但没有执行权限,于是:

  • 命令行用 root 执行时一切正常——root 不受权限位约束;
  • Web 进程访问时,PHP 的目录遍历函数直接失败,WordPress 判定「这个目录不存在」;
  • 于是插件不被加载,但后台的启用状态是从数据库里读的,所以列表仍然显示「已启用」;
  • 页面不白屏,因为 WordPress 只是跳过了这些插件,继续执行。

这类故障有三个特征,遇到时可以优先往权限方向想:命令行正常但 Web 端失效、没有任何报错、状态显示与实际行为矛盾。

值得注意的是,这类问题的排查难点在于「root 能看到的和 Web 看到的不一样」。所以排查时不要用 root 直接测试,要用 Web 进程的身份去验证:

# 以 Web 用户身份测试能否进入并列出目录
su -s /bin/sh www -c 'ls /www/wwwroot/你的域名/wp-content/plugins/'

# 逐级查看完整路径上每一级的权限(这条最有用)
namei -l /www/wwwroot/你的域名/wp-content/plugins/

namei 会沿着路径逐级打印权限与属主,任何一级缺 x 都一目了然。这是排查此类问题时性价比最高的一条命令。

批量修正:正确的执行顺序与命令

修正权限时顺序很重要,反了会让站点直接不可用。按下面的顺序执行:

  1. 先备份。至少记录当前的权限分布,便于对比:find 站点根 -printf ‘%m %u:%g %pn’ > perm-backup.txt
  2. 先改目录:find 站点根 -type d -exec chmod 755 {} ;
  3. 再改文件:find 站点根 -type f -exec chmod 644 {} ;
  4. 统一属主:chown -R www:www 站点根
  5. 收紧敏感文件:chmod 600 站点根/wp-config.php
  6. 验证:用 Web 用户身份访问关键目录,回前台刷新页面确认功能恢复。

第 2、3 步的顺序不能颠倒。如果先执行「文件设为 644」,目录也会被设成 644,站点立刻变成 404 或白屏。真发生了也不用慌,重新按正确顺序执行一遍即可恢复。

第 4 步的 www:www 要替换成实际的 Web 用户与属组。不确定就先用 ps 命令确认 PHP 进程的运行用户,不要照抄。

执行完之后,务必再检查一遍是否有目录被漏掉:

# 找出所有属主缺少执行位的目录(正常应无输出)
find /www/wwwroot/你的域名 -type d ! -perm -u+x

wp-config.php 与上传目录的特殊处理

有几个路径不遵循「755 / 644」的通用基线:

路径 建议权限 原因
wp-config.php 600 或 640 含数据库口令,应禁止其他用户读取
wp-content/uploads 755(属主正确即可) 需要由 PHP 进程写入
wp-content 缓存目录 755 缓存插件需要写入
根目录 .htaccess 644 部分插件需要改写它
站点根目录 755 目录基线

上传目录还要注意一点:给它写权限的同时,要确保该目录下的 PHP 文件不会被执行。这一条是在 Web 服务器层配置的(Nginx 里禁止解析该目录的 PHP,Apache 里放 .htaccess 规则),单靠权限位做不到。权限位只能控制「谁能写」,控制不了「写进去的东西能不能被运行」。

另外,如果站点启用了自动更新,根目录也需要可写;如果出于安全考虑把根目录设成只读,那就要接受无法在线更新,改用命令行或部署流程来更新代码。两种做法都合理,重要的是保持一致,别让系统处于「一半可写一半不可写」的中间状态。

排查命令速查

想确认什么 命令
完整路径上各级的权限 namei -l 完整路径
某目录的权限与属主 ls -ld 目录路径
PHP 进程以谁运行 ps aux | grep php-fpm
找出缺执行位的目录 find 站点根 -type d ! -perm -u+x
批量看权限分布 find 站点根 -printf ‘%m %u:%g %pn’
以 Web 用户身份测试访问 su -s /bin/sh www -c ‘ls 路径’

排查的顺序建议是:先确认属主,再看权限位,最后用 Web 用户身份验证。跳过前两步直接改权限,是把症状压下去而不是解决问题。

完整的部署环境里还有别的地方会用到这些命令,可以参考宝塔 LNMP 部署里的环境检查部分,以及上线前的上线检查清单。

权限与安全加固的关系

权限是整个安全体系的最底层,它决定了攻击面有多大,但也不能指望它解决所有问题。合理的做法是让权限保持「够用但不多余」的状态:

Web 进程能写的地方越少越好。理想情况下,只有上传目录和缓存目录需要可写,代码目录(主题、插件、核心)保持只读。这样即使应用层出现漏洞,攻击者也没法落盘。

把代码目录设为只读的代价是不能在线更新。对有部署流程的站点来说这是划算的;对需要后台一键更新的站点,就要接受这个便利带来的风险,并用其他手段(比如文件完整性监控)来弥补。

敏感文件要单独收紧。除了 wp-config.php,备份文件、.env、数据库导出文件都不应放在 Web 可访问的目录里,或者至少禁止通过 HTTP 访问。这类文件的泄漏往往不是被攻破,而是被直接下载。

最后,权限检查值得放进定期巡检。用上面的 find 命令定期扫一遍,把「哪些地方可写」作为一项已知状态维护起来,比出事后临时排查要省事得多。

常见问题

设成 777 之后问题解决了,为什么还要改回来?
因为 777 只是掩盖了真正的原因——属主不对。它让任何用户都能改写你的代码,一旦服务器上其他进程被攻破,攻击者就能直接往插件目录里写文件。正确做法是改属主,权限保持 755 / 644。

上传图片时提示无法创建目录,怎么排查?
先看 wp-content/uploads 的属主是不是 Web 用户,再看权限位。属主对的情况下 755 就够用,不需要 777。如果属主是 root,改权限到 777 也只是一次性的假象。

改完权限后站点打不开了,怎么恢复?
多半是执行顺序反了,把目录也设成了 644。重新按「先目录 755、后文件 644」的顺序执行一遍即可恢复。

wp-config.php 设成 600 后站点无法访问?
600 意味着只有属主能读。如果 Web 进程不是该文件的属主,就读不到配置。解决办法是把属主改成 Web 用户,或者设成 640 并把属组改成 Web 用户所在组。

命令行执行正常,网页上却报目录不存在?
典型的用户身份差异:命令行用的是 root(不受权限约束),网页用的是 Web 用户。用 su 切换到 Web 用户再执行一次同样的操作,就能复现问题。

需要专业团队?

如果站点反复出现权限相关的故障,或者需要对生产环境做一次完整的安全基线检查,我们可以协助排查并给出适配当前服务器环境的权限方案。

更多 WordPress 技术文章,见技术文章栏目。

参考资料与延伸阅读

WPDaiwei

WPDaiwei-专业Wordpress网站定制开发提供商

需要 WordPress 开发服务?

24 小时内免费出方案与报价,国内国外都接单。

QQ