Posted in

个人电脑部署博客站,无需公网IP,无需端口映射

————–系列②

Cloudflare Tunnel部署WordPress时的一个经典故障。”发布失败”问题。根本原因是Cloudflare Tunnel与WordPress的REST API通信冲突,我们将从底层原理开始修复:问题根源深度分析

  1. Tunnel的请求头传递:Cloudflare Tunnel默认会修改Host头,导致WordPress无法识别自身
  2. HTTPS混合内容:Tunnel强制HTTPS,但WordPress内部仍使用HTTP地址
  3. REST API验证失败:WordPress后台操作依赖/wp-json接口,隧道配置错误导致阻断
  4. IP地址不一致:Tunnel使用Cloudflare IP,但Nginx看到的是127.0.0.1

🛠️ 终极解决方案(分步执行)

第一步:修复WordPress地址设置

# 1. 编辑wp-config.php (在define('WP_DEBUG')上方添加)
sudo nano /var/www/html/blog/wp-config.php
/** 强制HTTPS和正确主机头 */
define('WP_HOME', 'https://' . $_SERVER['HTTP_HOST']);
define('WP_SITEURL', 'https://' . $_SERVER['HTTP_HOST']);
define('FORCE_SSL_ADMIN', true);

// 处理Cloudflare代理IP
if (isset($_SERVER['HTTP_CF_CONNECTING_IP'])) {
    $_SERVER['REMOTE_ADDR'] = $_SERVER['HTTP_CF_CONNECTING_IP'];
}

第二步:修正Cloudflare Tunnel配置

# 1. 编辑Tunnel配置文件
sudo nano /etc/cloudflared/config.yml
tunnel: YOUR_TUNNEL_ID
credentials-file: /root/.cloudflared/YOUR_TUNNEL_ID.json
ingress:
  - hostname: yourdomain.com
    service: http://localhost:80
    originRequest:
      noTLSVerify: true  # 关键参数!
      originServerName: yourdomain.com # 传递真实域名
      httpHostHeader: yourdomain.com # 修复Host头
  - hostname: www.yourdomain.com
    service: http://localhost:80
    originRequest:
      noTLSVerify: true
      originServerName: www.yourdomain.com
      httpHostHeader: www.yourdomain.com
  - service: http_status:404

第三步:修复Nginx配置(关键!)

sudo nano /etc/nginx/sites-available/blog
server {
    # ... 原有配置保持不变 ...

    location / {
        # 添加代理头识别
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header Host $http_host; # 传递原始Host头

        # WordPress重写规则
        try_files $uri $uri/ /index.php?$args;
    }

    # 在PHP处理块添加:
    location ~ \.php$ {
        # ... 原有配置 ...

        # 修复REST API通信
        fastcgi_param HTTPS "on";
        fastcgi_param HTTP_X_FORWARDED_PROTO "https";
        fastcgi_param HTTP_X_FORWARDED_FOR $proxy_add_x_forwarded_for;
    }
}

第四步:重启所有服务

sudo systemctl restart nginx php-fpm cloudflared
sudo systemctl status cloudflared  # 确保状态正常

第五步:修复WordPress数据库

-- 登录MySQL
sudo mysql -u root -p

-- 执行修复命令
USE wordpress;
UPDATE wp_options SET option_value = 'https://yourdomain.com' WHERE option_name IN ('siteurl', 'home');
EXIT;

🧪 验证修复效果

  1. 测试REST API
   curl -I https://yourdomain.com/wp-json/
   # 应返回HTTP/2 200
  1. 手动触发发布测试
   # 在服务器执行内部API测试
   sudo -u www-data php -r "require '/var/www/html/blog/wp-load.php'; wp_remote_post( get_rest_url(null, 'wp/v2/posts') );"
  1. 检查调试日志
   tail -f /var/www/html/blog/wp-content/debug.log
   # 观察发布时的错误信息

⚠️ 若问题依然存在:终极核武器方案

# 1. 禁用所有插件(通过数据库)
sudo mysql -u root -p wordpress -e "UPDATE wp_options SET option_value = 'a:0:{}' WHERE option_name = 'active_plugins';"

# 2. 重置.htaccess规则
cd /var/www/html/blog
sudo -u www-data cp -f wp-includes/default-constants.php .htaccess

# 3. 修复文件所有权
sudo chown -R www-data:www-data /var/www/html/blog
sudo find /var/www/html/blog -type d -exec chmod 755 {} \;
sudo find /var/www/html/blog -type f -exec chmod 644 {} \;

# 4. 重建Nginx缓存
sudo rm -rf /var/cache/nginx/*
sudo systemctl restart nginx

🔧 预防措施(部署后必做)

  1. 安装Must-Use插件
   sudo mkdir /var/www/html/blog/wp-content/mu-plugins
   sudo nano /var/www/html/blog/wp-content/mu-plugins/cloudflare_fix.php
   <?php
   // 强制信任Cloudflare代理
   if (isset($_SERVER['HTTP_CF_CONNECTING_IP'])) {
       $_SERVER['REMOTE_ADDR'] = $_SERVER['HTTP_CF_CONNECTING_IP'];
   }

   // 修复REST API认证
   add_filter('rest_authentication_errors', function($result) {
       if (!empty($result)) return $result;
       if (defined('REST_REQUEST') && REST_REQUEST ) {
           if (isset($_SERVER['HTTP_CF_RAY'])) {
               return true; // 信任Cloudflare请求
           }
       }
       return $result;
   });
  1. 配置Cloudflare页面规则
   URL: yourdomain.com/wp-admin/*
   设置:SSL → 完全(严格)
   设置:缓存级别 → 绕过
  1. 启用WordPress调试日志
   // 在wp-config.php中添加
   define('WP_DEBUG', true);
   define('WP_DEBUG_LOG', true);
   define('WP_DEBUG_DISPLAY', false);

通过这套组合拳,99%的”发布失败”问题都能解决。如果仍有问题,请执行以下命令收集诊断数据:

# 生成诊断报告
sudo cloudflared tunnel info YOUR_TUNNEL_ID > tunnel.log
sudo nginx -T > nginx_config.log
sudo tail -n 100 /var/log/nginx/error.log > nginx_error.log
sudo tail -n 100 /var/log/cloudflared.log > cloudflared.log

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注