使用Cloudflared隧道转发本地WordPress站点时的证书验证问题
问题背景
我使用XAMPP(基于Apache)在本地运行WordPress网站,通过Cloudflared隧道将服务转发至Cloudflare托管的域名example.com。已将Cloudflare颁发的example.com域名证书安装到XAMPP证书目录,确认HTTPS响应会携带该证书,且Cloudflare的SSL/TLS加密模式设置为「Full (Strict)」。
错误信息
通过浏览器访问域名时出现502 Bad Gateway错误,Cloudflared日志打印如下报错:
error="Unable to reach the origin service. The service may be down or it may not be responding to traffic from cloudflared: x509: certificate is valid for *.example.com, example.com, not localhost
不同访问场景结果
- 访问
http://example.com或https://example.com:触发上述502错误 - 访问
http://localhost:网站主体可加载,但资源加载失败(WordPress通过https://example.com/path/to/resource路径拉取资源) - 访问
https://localhost:资源加载失败问题同上,且Chrome提示证书无效
当前Cloudflared配置(config.yml)
ingress: - hostname: ssh.example.com # 此规则暂未调试完成 service: ssh://localhost:22 - hostname: example.com # 出现问题的规则 service: https://localhost - service: https://localhost
核心疑问
Cloudflared执行入口规则访问https://localhost时,本地Apache返回的是example.com域名证书,但该证书对localhost无效,导致验证失败。不想申请同时包含localhost和example.com的证书,是否需要让Apache对http(s)://localhost请求返回localhost证书,对example.com入口请求返回Cloudflare验证的证书?如果是,该如何操作?
方案1:简化配置,改用HTTP连接本地服务
Cloudflared与本地Apache的通信属于本地环路,不存在传输安全风险,可直接将入口规则中的HTTPS改为HTTP,跳过本地证书验证。Cloudflare与用户浏览器之间依然通过HTTPS加密,符合「Full (Strict)」模式要求。
修改后的config.yml:
ingress: - hostname: ssh.example.com service: ssh://localhost:22 - hostname: example.com service: http://localhost:80 # 明确指定HTTP默认端口80 - service: http://localhost:80
方案2:配置Apache虚拟主机,按Host头返回对应证书
若坚持使用HTTPS连接本地服务,需给Apache配置双虚拟主机,根据请求的Host头返回对应证书:
步骤1:生成localhost自签证书
用OpenSSL生成仅针对localhost的自签证书:
openssl req -x509 -sha256 -nodes -newkey rsa:2048 -days 365 -keyout localhost.key -out localhost.crt
生成时Common Name填写localhost,将生成的localhost.key和localhost.crt放入XAMPP证书目录(如xampp/apache/conf/ssl.crt/和xampp/apache/conf/ssl.key/)。
步骤2:修改Apache虚拟主机配置(httpd-vhosts.conf)
打开xampp/apache/conf/extra/httpd-vhosts.conf,添加两个虚拟主机规则:
# 处理localhost请求的虚拟主机 <VirtualHost *:443> ServerName localhost DocumentRoot "C:/xampp/htdocs" # 替换为你的WordPress根目录路径 SSLEngine on SSLCertificateFile "conf/ssl.crt/localhost.crt" SSLCertificateKeyFile "conf/ssl.key/localhost.key" <Directory "C:/xampp/htdocs"> AllowOverride All Require all granted </Directory> </VirtualHost> # 处理example.com请求的虚拟主机 <VirtualHost *:443> ServerName example.com ServerAlias *.example.com DocumentRoot "C:/xampp/htdocs" SSLEngine on SSLCertificateFile "conf/ssl.crt/example.com.crt" # 你的Cloudflare证书文件 SSLCertificateKeyFile "conf/ssl.key/example.com.key" # 你的Cloudflare证书私钥 <Directory "C:/xampp/htdocs"> AllowOverride All Require all granted </Directory> </VirtualHost>
步骤3:修改Cloudflared配置,指定请求Host头
在config.yml的example.com入口规则中添加originRequest配置,让Cloudflared请求本地服务时携带example.com的Host头:
ingress: - hostname: ssh.example.com service: ssh://localhost:22 - hostname: example.com service: https://localhost:443 originRequest: originServerName: example.com # 指定请求Host头为example.com - service: https://localhost:443
方案3:修复WordPress资源加载问题
访问localhost时资源加载失败,是因为WordPress站点URL固定为https://example.com。可修改wp-config.php添加以下代码,让WordPress根据请求Host头动态生成资源URL:
define('WP_HOME', 'https://' . $_SERVER['HTTP_HOST']); define('WP_SITEURL', 'https://' . $_SERVER['HTTP_HOST']);
内容的提问来源于stack exchange,提问作者Brian Smith

