通过 Nginx 反向代理将 Apache http 站点转换为安全的 https 站点

通过 Nginx 反向代理将 Apache http 站点转换为安全的 https 站点

我必须支持在 Apache Web 服务器上运行的旧 WordPress 网站。为了更安全,此 Apache 服务器位于 Docker 容器中,并且可以通过 Nginx 反向代理配置供全世界访问。此网站目前通过 http 提供服务,我想将其移至 https。

我想我有两个选择:

  1. 为 Nginx 站点安装了 SSL 证书,并且它对proxy_passApache 容器上的普通 http 站点也执行此操作:

    server {
        listen      443 ssl;
        server_name www.example.com;
    
        ssl_certificate /etc/nginx/ssl/letsencrypt/live/www.example.com/fullchain.pem;
        ssl_certificate_key /etc/nginx/ssl/letsencrypt/live/www.example.com/privkey.pem;
    
        access_log  /var/log/nginx/example.com.access.log;
    
        location /  {
            proxy_pass       http://Apache2-PHP5.6:80;
            proxy_set_header Host            $host;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
         }
    }
    

    在这种情况下,从 Apache 服务器的角度来看,它仍然通过 http 为网站提供服务

  2. 这个比较麻烦:网关 Nginx 服务器和代理 Apache 站点都需要安装 SSL 证书,然后需要在配置值中http改为。httpsproxy_pass

我希望第一种情况一切顺利。但 Apache 认为它通过 http 提供服务,这带来了一些问题:有一些隐藏的 URL 重定向,我真的不想重新配置/调试它们。这些 URL 重定向会执行如下操作:如果请求的 URL 是http://www.example.com,则将其重写(http 状态 301)为http://www.example.com/main。浏览器会收到此重定向,因此,即使第一个请求是通过 https 发出的,现在重定向的 URL 也是 http 请求。此外,站点 html 包含指向其自身资源(JavaScript 和 CSS 文件)的多个完整路径 href,其中还包括协议引用。目前尚不清楚这些 href 是否采用了请求发出时的协议,还是硬编码的。无论如何,不​​幸的是,如果不进行认真的挖掘,这将无法奏效。

所以,我只剩下选项 2。我试过了,它有效,我可以在 Nginx 和容器化的 Apache 上设置相同的 SSL 证书。但我想知道这是否真的应该继续运行。因为虽然 Apache 服务器现在知道内容是通过 https 提供的,但现在每个请求都会发生双重 SSL。感觉不对劲。

答案1

你可以通过在你的 nginx 配置中设置 HTTP_X_FORWARDED_PROTO 来解决选项 1 中的问题(正如你所说,这是一个更好的方法)

proxy_set_header X-Forwarded-Proto $scheme;

并通过将此行附加到 wp-config.php 来配置 WordPress 以识别它

if (isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] === 'https') {
    $_SERVER['HTTPS'] = 'on';
}

也可以看看Wordpress 支持文章作为该解决方案的变体。

答案2

您应该能够告诉 Apache,传入请求是通过proxy_set_header X-Forwarded-Proto "https";第一个设置中的声明从 HTTPS 请求代理的

答案3

通常我更愿意在反向代理上完成所有繁重的工作,并尽可能保持暴露的后端站点的原始性。

您的问题似乎本质上是(WordPress)后端生成和使用的(绝对)URI 与您希望访问者使用的URI 不同。

你可以通过以下方式解决这个问题重写(HTML)内容WordPress 在 nginx 中生成的ngx_http_sub_module。这还允许您使用类似以下内容重写绝对 URL:

    location / {    
         sub_filter 'http://example.com/' 'https://www.example.com/' ;
         sub_filter 'http://www.example.com/' 'https://www.example.com/' ;
         sub_filter_once off;
         proxy_pass       http://Apache2-PHP5.6:80;
         proxy_set_header Host            $host;
         proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;                
    }

相关内容