如何在 Apache 虚拟主机中使用来自 CloudFront 的自定义 headers

How to can I use custom headers from CloudFront in Apache virtualhost

我接到了一项我不太确定如何处理的任务。我被要求做的是向 CloudFront 添加自定义 header 并使 Apache 使用此自定义 header 为站点提供服务。当 header 未设置时,我还需要回退到正常使用。

我有我的主要网站:www.domain.com,它是在 CloudFront 上设置的,原点设置为 prod.domain.com.该站点在服务器上设置为 www.domain.com(无法更改)

我想做的是在 CloudFront 中设置一个自定义 header 来定义站点名称,并在我的虚拟主机中使用此 header 来加载正确的站点。

例如,我添加了 header:company-host-name 并将值设置为 www.domain.com 。 CloudFront 来源是 prod.domain.com 并已更新 DNS 以指向此新域的服务器 IP。到目前为止一切顺利,但现在正在尝试从服务器加载 prod.domain.com

我想要做的是使用自定义 header 来加载站点,而不是 Apache 处理此问题的默认方式。尽管如果没有设置 header 我仍然需要回退。我认为只需将此 header 设置为主机 header 就足够了。

我的服务器规格:

# cat /etc/centos-release
CentOS release 6.8 (Final)

# httpd -v 
Server version: Apache/2.2.15 (Unix)
Server built:   May 11 2016 19:28:33

我还需要知道如何在 Apache 2.4 中执行此操作,但目前 2.2 是必不可少的。

我试过玩 headers 并将其添加到我的 http.conf

<IfModule mod_headers.c>
<IfDefine company_host_name>
    Header set Host "%{company_host_name}e"
</IfDefine>
</ifModule>

我希望用自定义 header 值覆盖主机 header。我认为这应该足够了,但我似乎无法让它发挥作用。

也许我就是over-complicating,需要退一步。所以我在这里寻求一些我认为不会太困难的帮助。

感谢您提供的任何帮助。

虚拟主机

<VirtualHost *:80>
    ServerName www.domain.com
    ServerAlias prod.domain.com

    RequestHeader set Host "www.domain.com"

    DocumentRoot /var/www/vhosts/domain.com/public_html

    <Directory /var/www/vhosts/domain.com/public_html>
    Options -Indexes +FollowSymLinks -MultiViews
    AllowOverride All
    </Directory>

    ErrorLog /var/www/vhosts/domain.com/logs/error.log

    # Possible values include: debug, info, notice, warn, error, crit,
    # alert, emerg.
    LogLevel warn

    CustomLog /var/www/vhosts/domain.com/logs/access.log combined

    <IfModule mod_php5.c>
    php_value error_log /var/www/vhosts/domain.com/logs/php_error.log
    php_value newrelic.appname "domain.com - PHP"
    </IfModule>

    <IfModule mod_headers.c>
        Header set Access-Control-Allow-Origin "*"
    </IfModule>


    #INCLUDES

</VirtualHost>

根据您的问题描述,我了解到您希望源服务器 prod.domain.com 能够为 www.domain.com.
提供内容 Apache select 通过比较每个 VirtualHost 块中的 ServerName/ServerAlias 值与客户端在请求中发送的 "Host" 请求 Header 来传递内容的正确 DocumentRoot。 CloudFront 将始终充当原始服务器的最终用户,并将始终将 prod.domain.com 作为主机 header 发送到原始服务器。

Host: CloudFront sets the value to the domain name of the origin that is associated with the requested object.

http://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/RequestAndResponseBehaviorCustomOrigin.html#request-custom-headers-behavior

因此,prod.domain.com 在源服务器上应该有 1 个 VirtualHost 块可以处理来自 Cloudfront 的请求。 但是,正如您所说,该网站只能 运行 作为 www.domain.com,这两个域应该由同一个 VirtualHost 块提供服务。在这里,我假设应用程序使用 "Host" header 值 "www.domain.com" 来生成内容。

因此,在 www.domain.com 的现有 VirtualHost 中,添加一个 ServerAlias 和 RequestHeader set 指令,如下所示:

<VirtualHost *:80>

   ServerName www.domain.com
   ServerAlias prod.domain.com

   RequestHeader set Host "www.domain.com"

   DocumentRoot /path/to/webserver
   ..
</VirtualHost>

现在,由于 ServerAlias 是 prod.domain.com,来自 Cloudfront 的请求将从此 DocumentRoot 提供服务。 此外,由于主机请求 header 将始终被覆盖为 www.domain.com,您的应用程序应该能够生成内容。

您不必使用 Cloudfront 添加自定义 header,但只是因为您在问题中提出,可以按如下方式完成:

在 AWS 控制台中,select CloudFront,然后 select 有问题的 "Web Distribution"。从顶部的选项卡,select "Distribution Settings"。 下一个 Select "Origins" 选项卡并单击 "Edit"。 在字段 Origin Custom Headers, Header Name 中添加自定义 header company-host-name,在 "Header Value" 字段中添加值 www.domain.com。它将随每个请求发送到源。