我已经设置了一个 apache 配置来尝试重定向/login
和 ProxyPass 所有其他请求:
RewriteEngine on
RewriteCond "%{REQUEST_URI}" "^/login$"
RewriteRule "^/login$" "https://sub.example.org/$1" [L,R]
SSLProxyEngine on
ProxyRequests off
ProxyPassMatch ^/login ! # Prevent proxy on /login
ProxyPassReverse ^/login ! # Prevent proxy on /login
ProxyPassMatch ^/ https://sub.example.org/
ProxyPassReverse ^/ https://sub.example.org/
ProxyPreserveHost off
RequestHeader set Host sub.example.org
Header set Host alt.example.org
我检查过的大多数结果都符合我的预期:
- alt.example.org/login 重定向到 sub.example.org/login
- alt.example.org/users 显示 sub.example.org/users 的内容(无需重定向)
...但https://alt.example.org/(空路径)导致Location
标题具有值https://alt.example.org^/login
。 ^
哇!是什么导致了域中的重定向?为什么它引用的是alt
而不是sub
?
在 apache 上运行的 Rails 应用程序的日志表明,Rails 应用程序本身实际上正在重定向到https://sub.example.org/login,这更有意义,因为 ProxyPass 意味着 Rails 只能看到 sub.example.org 而看不到 alt.example.org。那么为什么 apache 会给出 https://alt.example.org^/login?
答案1
...但
https://alt.example.org/
(空路径) 导致Location
标头的值为https://alt.example.org^/login
。哇!是什么导致^
域中的重定向,为什么它引用 alt 而不是 sub?
该ProxyPassReverse
指令不接受正则表达式作为第一个参数,这似乎是发生冲突的地方。它也不能!
作为第二个参数。如果指令与响应不匹配,alt
子域将出现在标头中。Location
ProxyPassReverse
您似乎不需要ProxyPassReverse
与 相关的第一个指令/login
,因为此 URL 未被代理。
此外,这些ProxyPassMatch
指令似乎将所有内容都代理到根目录https://sub.example.org/
- 您不想代理到目标域中的相应 URL 路径吗?但奇怪的是,这似乎确实是您观察到的结果?如果您确实想代理到相同的 URL 路径,那么您可以使用更简单的ProxyPass
指令,并使用简单的前缀匹配而不是正则表达式。
alt.example.org/login
重定向至sub.example.org/login
虽然这不是由您在顶部发布的“重定向”执行的,它将重定向到文档根目录,因为$1
反向引用是空的,因为在RewriteRule
图案。正如您稍后所述,“Rails 应用程序本身实际上正在重定向到https://sub.example.org/login
”。
因此,为了重定向到sub.example.org/login
(这似乎是意图),那么您需要将指令更改为如下所示的内容:
RewriteRule ^/(login)$ https://sub.example.org/$1" [R,L]
RewriteCond
这里不需要前面的指令,因为它只是重复你在RewriteRule
图案。
RequestHeader set Host sub.example.org
此行是多余的,因为这是前一个指令的目的ProxyPreserveHost off
。
Header set Host alt.example.org
这一行似乎也是多余的,因为它Host
是一个请求头,而不是响应头。
ProxyPassMatch ^/login ! # Prevent proxy on /login
此外,Apache 不支持行尾注释。只是因为 Apache 指令处理方式的“怪癖”才阻止了此特定行尾注释破坏您的服务器!
因此,考虑到以上几点,请尝试以下操作:
RewriteEngine on
# Externally Redirect "/login" to other domain
RewriteRule ^/(login)$ https://sub.example.org/$1" [R,L]
SSLProxyEngine on
ProxyRequests off
ProxyPreserveHost off
# Prevent proxy on /login
ProxyPass /login !
# Proxy all other URLs
ProxyPass / https://sub.example.org/
ProxyPassReverse / https://sub.example.org/