解决WordPress迁移后403错误:权限、索引与安全策略
wordpress整站迁移出现403

首页 2025-09-02 01:38:20

正文(以 Pony-style 专业口吻,约 680 字):
昨晚 23:47,技术群里弹出一张截图——整站迁移完毕,首页却赫然 403。那一瞬间,我仿佛回到二十年前,看着 OICQ 第一次跑通却登不上服务器的凌晨。今天,把这段踩坑笔记公开,希望后来者少走一步弯路。
整站迁移从来不是把文件从 A 拖到 B 那么简单。它像一次城市搬迁:数据库是居民,文件系统是街道,Nginx 是交警,而 403 就是交警突然把主干道封死。问题的根因往往只有三类:文件权限错位、目录索引失配、安全策略误杀。听上去简单,但魔鬼藏在细节。
第一步,SSH 登录新服务器,敲下 ls -la。如果看到目录清一色 640、文件 600,那恭喜你,权限矩阵已经“社恐”——别人连看都不让看。WordPress 的推荐姿势是目录 755、文件 644;若你启用了 FTP 或 sftp 更新,还得把属主改回 www-datanginx。一行命令搞定:chown -R www-data:www-data /var/www/html && find /var/www/html -type d -exec chmod 755 {} \; && find /var/www/html -type f -exec chmod 644 {} \;。执行完,别急着刷新浏览器,先看第二步。
第二步,确认 Nginx 的 index 指令。很多迁移脚本只拷数据,不拷配置。新机器若缺少 index.php,Nginx 找不到默认入口,直接甩 403。在 /etc/nginx/sites-available/your-site 里加一行:index index.php index.html index.htm;,再 nginx -t && systemctl reload nginx
第三步,也是最隐蔽的——SELinux 或云厂商安全组。阿里云、腾讯云默认开 SELinux enforcing,文件即便 777,也可能被安全上下文拦截。两条命令验证:getenforce 结果是 Enforcing?那就执行 setsebool -P httpd_can_network_connect on 并给 WordPress 目录打标签:restorecon -Rv /var/www/html。云安全组里,确认 80、443 端口放行对象包含你当前 IP。
做完三步,再按 F5,如果仍是 403,打开 Nginx 错误日志:tail -f /var/log/nginx/error.log。看到 access forbidden by rule 就是某个 location 正则误伤;看到 Permission denied 就回到权限和 SELinux。凌晨 00:31,我们群里的那台服务器终于吐出 200 OK,迁移正式宣告闭环。
记住,技术人最怕的不是报错,而是报错的沉默。把日志当雷达,把权限当门禁,把防火墙当保险丝,403 就不再是黑洞,而是系统给你的精准坐标。

教程:WordPress 整站迁移后出现 403 的完整排障流程
(面向零基础,命令可直接复制)
  1. 前置条件
    • 已拥有新服务器 root 权限
    • 已安装 Nginx + PHP-FPM(或 Apache)
    • 域名已解析到新服务器 IP
  2. 检查文件权限
    1.1 SSH 登录:ssh root@新服务器IP
    1.2 统一权限:
    bash
    复制
    chown -R www-data:www-data /var/www/html
    find /var/www/html -type d -exec chmod 755 {} \;
    find /var/www/html -type f -exec chmod 644 {} \;
    1.3 验证:
    bash
    复制
    ls -la /var/www/html/wp-admin/index.php
    若看到 -rw-r--r-- 1 www-data www-data,则正常。
  3. 检查 Nginx 站点配置
    2.1 编辑配置文件:
    bash
    复制
    nano /etc/nginx/sites-available/your-site
    2.2 确保包含:
    复制
    index index.php index.html index.htm;
    location / {
        try_files $uri $uri/ /index.php?$args;
    }
    2.3 测试并重载:
    bash
    复制
    nginx -t && systemctl reload nginx
  4. 检查 SELinux(仅 CentOS/RHEL)
    3.1 查看状态:
    bash
    复制
    getenforce   # Enforcing 说明开启
    3.2 设置布尔值:
    bash
    复制
    setsebool -P httpd_can_network_connect on
    3.3 恢复上下文:
    bash
    复制
    restorecon -Rv /var/www/html
  5. 检查云安全组 / 防火墙
    4.1 确认入方向已放行 TCP 80、443。
    4.2 UFW 用户:
    bash
    复制
    ufw allow 80,443/tcp
  6. 实时查看错误日志定位终极原因
    bash
    复制
    tail -f /var/log/nginx/error.log
    出现 Permission denied 返回第 1、3 步;出现 access forbidden by rule 检查 Nginx location 正则。
  7. 最终验证
    浏览器无痕模式访问域名,返回 200 即完成。若仍 403,把日志最后 20 行贴到社区,别闷头熬夜。
至此,整站迁移出现的 403 问题,从现象到根因、再到一次性修复,全部闭环。
MySQL连接就这么简单!本地远程、编程语言连接方法一网打尽
还在为MySQL日期计算头疼?这份加一天操作指南能解决90%问题
MySQL日志到底在哪里?Linux/Windows/macOS全平台查找方法在此
MySQL数据库管理工具全景评测:从Workbench到DBeaver的技术选型指南
MySQL密码忘了怎么办?这份重置指南能救急,Windows/Linux/Mac都适用
你的MySQL为什么经常卡死?可能是锁表在作怪!快速排查方法在此
MySQL单表卡爆怎么办?从策略到实战,一文掌握「分表」救命技巧
清空MySQL数据表千万别用错!DELETE和TRUNCATE这个区别可能导致重大事故
你的MySQL中文排序一团糟?记住这几点,轻松实现准确拼音排序!
别再混淆Hive和MySQL了!读懂它们的天壤之别,才算摸到大数据的门道