如何在 Amazon Load Balancer 后面修复 WordPress HTTPS 问题?
How to fix WordPress HTTPS issues when behind an Amazon Load Balancer?
我以前遇到过这个问题。当 运行 WordPress(或其他 PHP 脚本)在 Amazon 的 EC2 负载均衡器后面时,脚本没有意识到它们在 https:// 协议上 运行 并导致诸如无休止的问题重定向循环和 HTTPS 警告 ("Some content on this page is being requested in a non-secure way...")。
我在这里找到了解决方案,但需要修改 WordPress 核心,这不利于可更新性:
https://wordpress.org/support/topic/when-behind-amazon-web-services-elastic-load-balancer-causes-endless-redirect
有没有办法在不修改 WordPress 核心的情况下解决这个问题?我正在使用 Apache 2.2。
与 link 一样,您给出了建议,对于 WordPress,问题出在 is_ssl()
函数上,该函数与大多数 PHP 软件一样显式检查 $_SERVER['HTTPS']
和 $_SERVER['SERVER_PORT']
检查当前页面是否在https://上下文中被访问。
当您的页面通过 HTTPS 访问时,但 Amazon 负载均衡器正在执行 SSL 卸载并实际在 non-SSL 端口 80、网络服务器 PHP 或任何其他内容上请求您的内容没关系,不明白或看不到它是通过 https:// 访问的。
解决这个问题的方法是 Amazon 的 ELB 发送 de-facto 标准 X-Forwarded-Proto
HTTP header,我们可以使用它来确定客户端是哪个协议 实际上 在负载均衡器的另一端使用。
对于 Apache 2.2,您可以使用以下内容:
<IfModule mod_setenvif.c>
SetEnvIf X-Forwarded-Proto "^https$" HTTPS
</IfModule>
这只是读取X-Forwarded-Proto
header。如果此值等于 https
,则 HTTPS
环境变量设置为 1
。 PHP 会看到这个环境变量,最终,它将变成 $_SERVER['HTTPS']
等于 1
—— 就像“真正的”本机 SSL 请求一样。
WordPress documentation 的另一个选项是将其添加到您的 wp-config。php:
if (strpos($_SERVER['HTTP_X_FORWARDED_PROTO'], 'https') !== false)
$_SERVER['HTTPS']='on';
不幸的是,以上都没有为我解决混合内容错误。然而,起作用的是将协议添加到 wp-config.php 中的 WP_HOME && WP_SITEURL 变量,例如
define( 'WP_HOME', 'https://' . $_SERVER['HTTP_HOST']);
define( 'WP_SITEURL', WP_HOME );
之后,源中的所有 URL 都以 https 开头,所有混合内容错误都消失了。
在 WordPress 中使用 ssl 时,使用这 4 步方法消除重定向循环和混合内容问题。
1) 在数据库中将 'http://' 替换为 '//' - 这将创建图像和其他资产的所有相关 url
2) 在 wp-config 中,定义通用 wp_home 和 wp_siteurl 变量。
define('WP_HOME','//'. $_SERVER['SERVER_NAME']);
define('WP_SITEURL','//'. $_SERVER['SERVER_NAME']);
3) 如果您正在使用负载平衡器,请使用 'HTTP_X_FORWARDED_PROTO' 服务器变量来确定使用的协议。为此,请在 wp-config
中添加此行
if (strpos($_SERVER['HTTP_X_FORWARDED_PROTO'], 'https') !== false)
$_SERVER['HTTPS']='on';
4) 最后在 .htaccess 中,如果您在负载均衡器后面,请使用此行将所有流量重定向到 https。
# http to https
RewriteCond %{HTTP:X-Forwarded-Proto} =http
RewriteRule . https://%{HTTP:Host}%{REQUEST_URI} [L,R=permanent]
如果其他人正在寻找与此等效的 Nginx,您需要执行以下操作:
对于重写设置,您应该在 server
块下添加以下内容:
if ($http_x_forwarded_proto != 'https') {
rewrite ^ https://$host$request_uri? permanent;
}
为了设置 HTTPS 参数,您应该在 location ~ \.php$
块下添加以下内容:
if ($http_x_forwarded_proto = 'https') {
set $fe_https 'on';
}
fastcgi_param HTTPS $fe_https;
记得删除任何其他 fastcgi_param HTTPS
命令(如果有)(我的 fastcgi_params
文件中有)。
我的服务器环境是:
Ubuntu 20.04.3 LTS, PHP 8.0.11, nginx/1.18.0
/etc/nginx/sites-available/default
中的以下设置对我有用:
server {
listen 80;
listen [::]:80;
root /var/www/html;
index index.php index.html index.htm;
server_name ChangeDomainName.com www.ChangeDomainName.com;
if ($http_x_forwarded_proto != 'https') {
rewrite ^ https://$host$request_uri? permanent;
}
location / {
try_files $uri $uri/ /index.php?$args;
}
location ~ \.php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/run/php/php8.0-fpm.sock;
if ($http_x_forwarded_proto = 'https') {
set $fe_https 'on';
}
fastcgi_param HTTPS $fe_https;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
}
}
我以前遇到过这个问题。当 运行 WordPress(或其他 PHP 脚本)在 Amazon 的 EC2 负载均衡器后面时,脚本没有意识到它们在 https:// 协议上 运行 并导致诸如无休止的问题重定向循环和 HTTPS 警告 ("Some content on this page is being requested in a non-secure way...")。
我在这里找到了解决方案,但需要修改 WordPress 核心,这不利于可更新性: https://wordpress.org/support/topic/when-behind-amazon-web-services-elastic-load-balancer-causes-endless-redirect
有没有办法在不修改 WordPress 核心的情况下解决这个问题?我正在使用 Apache 2.2。
与 link 一样,您给出了建议,对于 WordPress,问题出在 is_ssl()
函数上,该函数与大多数 PHP 软件一样显式检查 $_SERVER['HTTPS']
和 $_SERVER['SERVER_PORT']
检查当前页面是否在https://上下文中被访问。
当您的页面通过 HTTPS 访问时,但 Amazon 负载均衡器正在执行 SSL 卸载并实际在 non-SSL 端口 80、网络服务器 PHP 或任何其他内容上请求您的内容没关系,不明白或看不到它是通过 https:// 访问的。
解决这个问题的方法是 Amazon 的 ELB 发送 de-facto 标准 X-Forwarded-Proto
HTTP header,我们可以使用它来确定客户端是哪个协议 实际上 在负载均衡器的另一端使用。
对于 Apache 2.2,您可以使用以下内容:
<IfModule mod_setenvif.c>
SetEnvIf X-Forwarded-Proto "^https$" HTTPS
</IfModule>
这只是读取X-Forwarded-Proto
header。如果此值等于 https
,则 HTTPS
环境变量设置为 1
。 PHP 会看到这个环境变量,最终,它将变成 $_SERVER['HTTPS']
等于 1
—— 就像“真正的”本机 SSL 请求一样。
WordPress documentation 的另一个选项是将其添加到您的 wp-config。php:
if (strpos($_SERVER['HTTP_X_FORWARDED_PROTO'], 'https') !== false)
$_SERVER['HTTPS']='on';
不幸的是,以上都没有为我解决混合内容错误。然而,起作用的是将协议添加到 wp-config.php 中的 WP_HOME && WP_SITEURL 变量,例如
define( 'WP_HOME', 'https://' . $_SERVER['HTTP_HOST']);
define( 'WP_SITEURL', WP_HOME );
之后,源中的所有 URL 都以 https 开头,所有混合内容错误都消失了。
在 WordPress 中使用 ssl 时,使用这 4 步方法消除重定向循环和混合内容问题。
1) 在数据库中将 'http://' 替换为 '//' - 这将创建图像和其他资产的所有相关 url
2) 在 wp-config 中,定义通用 wp_home 和 wp_siteurl 变量。
define('WP_HOME','//'. $_SERVER['SERVER_NAME']);
define('WP_SITEURL','//'. $_SERVER['SERVER_NAME']);
3) 如果您正在使用负载平衡器,请使用 'HTTP_X_FORWARDED_PROTO' 服务器变量来确定使用的协议。为此,请在 wp-config
中添加此行if (strpos($_SERVER['HTTP_X_FORWARDED_PROTO'], 'https') !== false)
$_SERVER['HTTPS']='on';
4) 最后在 .htaccess 中,如果您在负载均衡器后面,请使用此行将所有流量重定向到 https。
# http to https
RewriteCond %{HTTP:X-Forwarded-Proto} =http
RewriteRule . https://%{HTTP:Host}%{REQUEST_URI} [L,R=permanent]
如果其他人正在寻找与此等效的 Nginx,您需要执行以下操作:
对于重写设置,您应该在 server
块下添加以下内容:
if ($http_x_forwarded_proto != 'https') {
rewrite ^ https://$host$request_uri? permanent;
}
为了设置 HTTPS 参数,您应该在 location ~ \.php$
块下添加以下内容:
if ($http_x_forwarded_proto = 'https') {
set $fe_https 'on';
}
fastcgi_param HTTPS $fe_https;
记得删除任何其他 fastcgi_param HTTPS
命令(如果有)(我的 fastcgi_params
文件中有)。
我的服务器环境是:
Ubuntu 20.04.3 LTS, PHP 8.0.11, nginx/1.18.0
/etc/nginx/sites-available/default
中的以下设置对我有用:
server {
listen 80;
listen [::]:80;
root /var/www/html;
index index.php index.html index.htm;
server_name ChangeDomainName.com www.ChangeDomainName.com;
if ($http_x_forwarded_proto != 'https') {
rewrite ^ https://$host$request_uri? permanent;
}
location / {
try_files $uri $uri/ /index.php?$args;
}
location ~ \.php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/run/php/php8.0-fpm.sock;
if ($http_x_forwarded_proto = 'https') {
set $fe_https 'on';
}
fastcgi_param HTTPS $fe_https;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
}
}