通过 F5 代理的子域流量未得到正确处理
Subdomain traffic through F5 proxy not being handled correctly
我们服务器上的第二个域名 ws.example.org 的流量没有得到正确处理。不是从第二个域名目录传送内容,而是错误地从第一个域名条目 www.example.org.
传送内容
详情:
服务器是 运行 Apache 2.2.31,位于 F5 负载 balancer/proxy 后面,其中包含相关域名的 SSL 证书。我们的服务器从 F5 获得的流量 未 加密,但仍通过端口 443 传送。
default:443 虚拟主机的 Apache 配置条目已被注释掉。服务器没有安装或可用的任何证书,并且不加密任何流量。
httpd.conf的相关内容是:
Listen 80
Listen 443
NameVirtualHost *:80
<VirtualHost *:80>
ServerName www.example.org
ServerAlias example.org
DocumentRoot /Apache/htdocs
<Directory "/Apache/htdocs">
Options FollowSymLinks MultiViews
AllowOverride All
Order allow,deny
Allow from all
</Directory>
</VirtualHost>
<VirtualHost *:80>
ServerName ws.example.org
DocumentRoot "/Apache/htdocs/WebServices"
<Directory "/Apache/htdocs/WebServices">
AllowOverride All
</Directory>
</VirtualHost>
由于我们想要强制使用 www example.org 并且我们想要强制对流量进行加密,因此正在使用驻留在 /Apache/htdocs 中的 .htaccess 中的以下规则:
RewriteEngine On
# force www
RewriteCond %{HTTP_HOST} ^example.org [NC]
RewriteRule ^(.*)$ https://www.example.org/ [L,R=301]
# force HTTPS for everything
RewriteCond %{HTTP:X-Forwarded-Proto} !https
RewriteCond %{HTTPS} off
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
我看不到 F5,但我确信 F5 上没有与我们的域相关的 iRule。我们已经尝试将来自 F5 的流量传送到端口 80 上的服务器,尽管这部分适用于第二个域名 ws.example.org,但它破坏了主域 www.example.org(本例中的错误是无限重定向循环)。
事实证明,解决方案是需要在 F5 和 Apache 服务器上进行更改的组合。在 Apache 上,我们在确保 F5 仅在端口 80 上发送流量后关闭所有对端口 443 的监听。
在 F5 上,需要添加一个 iRule 以包含 header,它告诉 Apache 协议是什么,以便确定我们是否需要重写为 httpS 的重写规则可以工作。添加到 F5 的 iRule 是:
when CLIENT_ACCEPTED {
if { [PROFILE::exists clientssl] } then {
set client_protocol "https"
} else {
set client_protocol "http"
}
}
when HTTP_REQUEST {
HTTP::header insert "X-Forwarded-For" [IP::client_addr]
HTTP::header insert "X-Forwarded-Proto" $client_protocol
HTTP::header insert "X-Forwarded-Port" [TCP::client_port]
}
我们需要从上面的 3 人组中获得的唯一规则是 X-Forwarded-Proto
添加 F5 的规则后,一切都开始正常工作,今天仍然如此。
我们服务器上的第二个域名 ws.example.org 的流量没有得到正确处理。不是从第二个域名目录传送内容,而是错误地从第一个域名条目 www.example.org.
传送内容详情:
服务器是 运行 Apache 2.2.31,位于 F5 负载 balancer/proxy 后面,其中包含相关域名的 SSL 证书。我们的服务器从 F5 获得的流量 未 加密,但仍通过端口 443 传送。
default:443 虚拟主机的 Apache 配置条目已被注释掉。服务器没有安装或可用的任何证书,并且不加密任何流量。
httpd.conf的相关内容是:
Listen 80
Listen 443
NameVirtualHost *:80
<VirtualHost *:80>
ServerName www.example.org
ServerAlias example.org
DocumentRoot /Apache/htdocs
<Directory "/Apache/htdocs">
Options FollowSymLinks MultiViews
AllowOverride All
Order allow,deny
Allow from all
</Directory>
</VirtualHost>
<VirtualHost *:80>
ServerName ws.example.org
DocumentRoot "/Apache/htdocs/WebServices"
<Directory "/Apache/htdocs/WebServices">
AllowOverride All
</Directory>
</VirtualHost>
由于我们想要强制使用 www example.org 并且我们想要强制对流量进行加密,因此正在使用驻留在 /Apache/htdocs 中的 .htaccess 中的以下规则:
RewriteEngine On
# force www
RewriteCond %{HTTP_HOST} ^example.org [NC]
RewriteRule ^(.*)$ https://www.example.org/ [L,R=301]
# force HTTPS for everything
RewriteCond %{HTTP:X-Forwarded-Proto} !https
RewriteCond %{HTTPS} off
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
我看不到 F5,但我确信 F5 上没有与我们的域相关的 iRule。我们已经尝试将来自 F5 的流量传送到端口 80 上的服务器,尽管这部分适用于第二个域名 ws.example.org,但它破坏了主域 www.example.org(本例中的错误是无限重定向循环)。
事实证明,解决方案是需要在 F5 和 Apache 服务器上进行更改的组合。在 Apache 上,我们在确保 F5 仅在端口 80 上发送流量后关闭所有对端口 443 的监听。
在 F5 上,需要添加一个 iRule 以包含 header,它告诉 Apache 协议是什么,以便确定我们是否需要重写为 httpS 的重写规则可以工作。添加到 F5 的 iRule 是:
when CLIENT_ACCEPTED {
if { [PROFILE::exists clientssl] } then {
set client_protocol "https"
} else {
set client_protocol "http"
}
}
when HTTP_REQUEST {
HTTP::header insert "X-Forwarded-For" [IP::client_addr]
HTTP::header insert "X-Forwarded-Proto" $client_protocol
HTTP::header insert "X-Forwarded-Port" [TCP::client_port]
}
我们需要从上面的 3 人组中获得的唯一规则是 X-Forwarded-Proto
添加 F5 的规则后,一切都开始正常工作,今天仍然如此。