在不使用mod_rewrite的情况下将HTTP流量重定向到Apache中的https

时间:2016-10-26 13:32:56

标签: apache mod-rewrite url-rewriting mod-alias

我正在尝试一个非常简单的事情,我通常会使用RewriteRule(当我这样做时效果很好)。

我的目标: 强制某些(并非所有)URL使用https协议。

注意事项:

  • Apache是​​一个加密卸载器。我们希望有一个虚拟主机来处理未加密和解密的流量。卸载程序将所有流量转发到同一端口并设置X-Forwarded-Proto标头。 (它还为未来的兼容性设置了新的Forwarded标题,但为了简洁,我将在下面留下它。)
  • 我最近阅读的所有内容都建议使用RedirectRedirectMatch代替RewriteRule。因此,如果可能,我想避免RewriteRule
  • 我想强制使用的网址是我在虚拟主机的<LocationMatch>部分配置的反向代理。
  • 虚拟主机有多个Alias条目,这些条目都对应于TLS证书中包含的有效名称(即我不希望/需要强制用户使用规范名称)
  • 似乎RedirectRedirectMatch无法使用%{HTTP_HOST}服务器变量。这意味着我需要额外的逻辑才能拥有不同的RedirectMatch行,具体取决于客户端使用的主机(Messy)。
  • 如果我需要使用mod_rewrite,最好在RewriteRule部分中设置<LocationMatch>以保持该路径/代理的配置为一个地点。然而,这似乎也会引起问题。

一些示例代码的时间有助于解释这一点。以下所有示例都位于VirtualHost部分中,如下所示:

<VirtualHost 192.168.0.1:80>
    ServerName www.example.com
    ServerAlias example.com
    ServerAlias anothervalidalias.com

选项1 - 使用RedirectMatch。这有效,但会强制使用主机名。

<LocationMatch "/backendcontextroot">
    ProxyPreserveHost on
    ProxyPass "http://192.168.0.2:8080/backendcontextroot"
    <If "-z req('X-Forwarded-Proto')">
        RedirectMatch ^(.*) https://www.example.com/$1
    </If>
</LocationMatch>

选项2 - 使用RedirectMatch。这将是我的理想解决方案,但HTTP_HOST不起作用。 Apache不向客户端发送任何响应。

<LocationMatch "/backendcontextroot">
    ProxyPreserveHost on
    ProxyPass "http://192.168.0.2:8080/backendcontextroot"
    <If "-z req('X-Forwarded-Proto')">
        RedirectMatch ^(.*) https://%{HTTP_HOST}/$1
    </If>
</LocationMatch>

选项3 - 在RewriteRule块中使用LocationMatch。如果我真的无法使用Redirect而被迫使用RewriteRule,那么这将是我首选的方法,因为它将/backendcontextroot反向代理的配置保存在一个地方。然而,这会产生一些“时髦”的感觉。重定向...

<LocationMatch "/backendcontextroot">
    ProxyPreserveHost on
    ProxyPass "http://192.168.0.2:8080/backendcontextroot"
    RewriteEngine on
    RewriteCond %{HTTP:X-Forwarded-Proto} !https
    RewriteRule ^(.*)$ https://%{HTTP_HOST}/$1
</LocationMatch>

重定向到:     https://www.example.com/proxy:http://192.168.0.2:8080/backendcontextroot

选项4 - 在RewriteRule块之外使用LocationMatch 。这样可行,但此反向代理的配置随后会传播到&#39;。它也使用了RewriteRule,尽管我建议尽可能避免使用它。

RewriteEngine on
RewriteCond %{HTTP:X-Forwarded-Proto} !https
RewriteCond %{REQUEST_URI} ^/backendcontextroot
RewriteRule ^(.*)$ https://%{HTTP_HOST}/$1

<LocationMatch "/backendcontextroot">
    ProxyPreserveHost on
    ProxyPass "http://192.168.0.2:8080/backendcontextroot"
</LocationMatch>

我是否坚持使用选项4还是有更优雅的方式?

1 个答案:

答案 0 :(得分:0)

RedirectMatch仅适用于相对不加选择的重定向,这就是它满足大多数需求的原因。保持加密代理清洁,并在后端请求中添加标头,表示连接已加密(不确定如何操作),或连接到其他端口,例如您要添加到后端有8443的同一Listen<VirtualHost>的{​​{1}}。后端仍然不会使用加密连接,但会通过检查标头或端口来了解连接是否“安全”。这些检查可以通过8080通过RewriteCond%{HTTP:X-Your-Https-Header},或者通过网站的脚本语言,很容易地通过后端执行,并且具有从其发送的重定向,因为只有它知道哪些URL需要重定向。它可以使用%{SERVER_PORT}发送重定向完成,因为这是客户端需要请求的内容,并且您的后端将使用正确的标头/端口代理新请求。

编辑:加密服务器上的配置示例

https: