Apache 位于 nginx 反向代理后面,设置正确的 Host 标头

Apache 位于 nginx 反向代理后面,设置正确的 Host 标头

我在 Docker 容器中使用 Apache 运行我的应用程序。我让 nginx 充当反向代理,在另一个以 Apache 为上游的 Docker 容器中运行。我proxy_pass为此使用了指令。

Apache 在 URL 中运行https://example-8gnm1aqrns-lz.a.run.app Nginx 在 URL 中运行http://example.com

整个过程都在 Google Cloud Run 上运行,问题是 Google Cloud Run 为每个服务分配一个 URL,并使用标Host头来区分应用程序,因此Host: example-8gnm1aqrns-lz.a.run.app当使用 nginx 连接到上游时,我不得不发送标头,以便请求正确路由。

这导致我的应用程序出现问题,因为它认为它在 URL 中运行https://example-8gnm1aqrns-lz.a.run.app,而不是http://example.com

是否可以使用一些 Apache .htaccess 配置来Host根据X-Forwarded-Hostnginx 发送的内容覆盖标头?

答案1

不要让 Apache 做这些实际工作,而是让 NGINX 在将数据交给 Apache 之前就完成这些工作,方法是使用额外的配置选项设置 Apache 期望作为 proxy_pass 交接的一部分的 Host 标头。

NGINX 具有以下用于 proxy_set_header 的变量,用于扩充传递给后端代理的内容。因此,您将获得类似以下内容:

...

location / {
    proxy_pass http://10.20.30.40;
    proxy_set_header Host example.com;
}
...

在您的 NGINX 配置中为反向代理。然后,Apache 不会关心 X-Forwarded-Host,因为您会设置 Host 标头,而不是 Apache应该优先服务。

应该修复问题 - 当浏览器访问的域与后端的响应主机不同时,我会以这种方式使用多个 NGINX 系统 - 到目前为止,它可以与 Django 后端、PHP 后端、Apache 甚至我用于测试的 Python HTTP 服务器配合使用。我对 Apache 的理解是,它会优先考虑 Host 标头,而不是 X-Forwarded-Host。

答案2

APP_HOST我通过在 Google Cloud Run 控制面板中定义一个名为 的新环境变量并将其设置为 来解决了这个问题example.com

.htaccess然后我在文档根目录中的文件中添加了以下配置:

<IfModule mod_env.c>
    PassEnv APP_HOST
</IfModule>

<IfModule mod_headers.c>
    RequestHeader set Host %{APP_HOST}e env=APP_HOST
</IfModule>

这使得我能够根据环境变量覆盖Hostexample-8gnm1aqrns-lz.a.run.app到的标题。example.comAPP_HOST

我当然可以对主机名进行硬编码,但我认为,如果您想.htaccess在不同的上下文中使用同一个文件(例如在暂存服务器上),使用环境变量可以为您提供更大的灵活性。

编辑

您可以使用以下方法解决这个问题X-Forwarded-Host,例如,如果您运行虚拟主机,并且需要站点可从多个域访问

<IfModule mod_setenvif.c>
    SetEnvIf X-Forwarded-Host (.*) REAL_HOST_HEADER=$1
    <IfModule mod_headers.c>
        RequestHeader set Host "%{REAL_HOST_HEADER}e"
    </IfModule>
</IfModule>

这将从中抓取标题并根据值X-Forwarded-Host设置标题。Host

相关内容