我正在尝试一个非常简单的事情,我通常会使用RewriteRule(当我这样做时效果很好)。
我的目标:
强制某些(并非所有)URL使用https
协议。
注意事项:
X-Forwarded-Proto
标头。 (它还为未来的兼容性设置了新的Forwarded
标题,但为了简洁,我将在下面留下它。)Redirect
或RedirectMatch
代替RewriteRule
。因此,如果可能,我想避免RewriteRule
。<LocationMatch>
部分配置的反向代理。Alias
条目,这些条目都对应于TLS证书中包含的有效名称(即我不希望/需要强制用户使用规范名称)Redirect
和RedirectMatch
无法使用%{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还是有更优雅的方式?
答案 0 :(得分:0)
RedirectMatch
仅适用于相对不加选择的重定向,这就是它满足大多数需求的原因。保持加密代理清洁,并在后端请求中添加标头,表示连接已加密(不确定如何操作),或连接到其他端口,例如您要添加到后端有8443
的同一Listen
或<VirtualHost>
的{{1}}。后端仍然不会使用加密连接,但会通过检查标头或端口来了解连接是否“安全”。这些检查可以通过8080
通过RewriteCond
或%{HTTP:X-Your-Https-Header}
,或者通过网站的脚本语言,很容易地通过后端执行,并且具有从其发送的重定向,因为只有它知道哪些URL需要重定向。它可以使用%{SERVER_PORT}
发送重定向完成,因为这是客户端需要请求的内容,并且您的后端将使用正确的标头/端口代理新请求。
编辑:加密服务器上的配置示例
https: