在GKE GLB使用HTTPS时静态资源链接为何为HTTP协议?
问题分析与解决:WordPress静态资源HTTP协议加载失败
场景与配置
架构:Global External Application LB(HTTPS 443端口)→ Caddy Web服务器(80端口)→ WordPress
GKE Gateway与HTTPRoute配置
kind: Gateway apiVersion: gateway.networking.k8s.io/v1beta1 metadata: name: mydomain-external-https namespace: my-ns annotations: networking.gke.io/certmap: mydomain-space-certmap spec: gatewayClassName: gke-l7-global-external-managed listeners: - name: https protocol: HTTPS port: 443 addresses: - type: NamedAddress value: caddy-static-ip --- kind: HTTPRoute apiVersion: gateway.networking.k8s.io/v1beta1 metadata: name: mydomain-space-external-http-route namespace: my-ns labels: gateway: mydomain-external-https spec: parentRefs: - name: mydomain-external-https hostnames: - "v1.mydomain.space" - "v2.mydomain.space" rules: - backendRefs: - name: caddy-app-service port: 80
Caddy配置
v1.mydomain.space:80 { root * /var/www/html/v1.mydomain.space php_fastcgi localhost:9000 file_server encode gzip log { output file /var/log/caddy/v1.mydomain.space.access.log } @static { file path *.ico *.css *.js *.gif *.jpg *.jpeg *.png *.svg *.woff *.pdf *.webp } header @static Cache-Control max-age=5184000 } v2.mydomain.space:80 { root * /var/www/html/v2.mydomain.space php_fastcgi localhost:9000 file_server encode gzip log { output file /var/log/caddy/v2.mydomain.space.access.log } @static { file path *.ico *.css *.js *.gif *.jpg *.jpeg *.png *.svg *.woff *.pdf *.webp } header @static Cache-Control max-age=5184000 }
问题现象
访问https://v1.mydomain.space/wp-admin/setup-config.php等页面时,页面本身能通过HTTPS正常加载(HTTP 200),但页面内的静态资源链接全部是HTTP协议,导致加载失败,例如:
http://v1.mydomain.space/wp-includes/css/dashicons.min.css?ver=6.4.1 http://v1.mydomain.space/wp-admin/css/l10n.min.css?ver=6.4.1 http://v1.mydomain.space/wp-includes/js/jquery/jquery-migrate.min.js?ver=3.4.1
问题原因
GKE的Global External LB负责终止HTTPS连接,之后以HTTP协议将请求转发给后端的Caddy服务。WordPress无法感知到原始请求是HTTPS的,因此生成静态资源链接时默认使用了当前通信的HTTP协议,导致资源链接为HTTP。
解决办法
方法1:修改Caddy配置,传递HTTPS相关头信息
在Caddy的php_fastcgi指令前添加头信息,告诉WordPress原始请求是HTTPS的:
v1.mydomain.space:80 { root * /var/www/html/v1.mydomain.space # 添加以下两行,传递HTTPS标识和原始协议头 header X-Forwarded-Proto https header X-Forwarded-Port 443 php_fastcgi localhost:9000 file_server encode gzip log { output file /var/log/caddy/v1.mydomain.space.access.log } @static { file path *.ico *.css *.js *.gif *.jpg *.jpeg *.png *.svg *.woff *.pdf *.webp } header @static Cache-Control max-age=5184000 }
对v2.mydomain.space:80的配置做同样修改。
方法2:在WordPress中强制HTTPS
如果方法1不生效,可以直接在WordPress的wp-config.php中添加以下配置,强制所有链接使用HTTPS:
define('WP_HOME', 'https://v1.mydomain.space'); define('WP_SITEURL', 'https://v1.mydomain.space'); define('FORCE_SSL_ADMIN', true); define('FORCE_SSL_LOGIN', true); // 处理内容中的HTTP链接 add_filter('content_url', function($url) { return str_replace('http://', 'https://', $url); }); add_filter('site_url', function($url) { return str_replace('http://', 'https://', $url); });
注意:如果是多站点(v1和v2),需要分别对应各自的域名配置,或者通过动态判断域名来适配。
补充说明
GKE的LB会自动传递X-Forwarded-Proto头,但在某些场景下可能没有正确传递,或者Caddy没有将这些头传递给PHP-FPM。通过Caddy显式设置这些头,可以确保WordPress正确识别原始请求的协议。
内容的提问来源于stack exchange,提问作者Nagri
相关产品推荐
相关产品推荐

