我已经设置了一个 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 呢?
该
ProxyPassReverse
指令不采用正则表达式作为第一个参数,这似乎是发生冲突的地方。这也不能!
作为第二个论点。如果指令与响应不匹配,子alt
域将出现在标头中。Location
ProxyPassReverse
您似乎不需要与
ProxyPassReverse
相关的第一个指令/login
,因为该 URL 没有被代理。此外,这些
ProxyPassMatch
指令似乎将所有内容都代理到https://sub.example.org/
- 您不想代理到目标域中的相应 URL 路径吗?虽然奇怪的是,这似乎是你观察到的结果中发生的事情?如果您确实想代理到相同的 URL 路径,那么您可以使用更简单的ProxyPass
指令,并使用简单的前缀匹配而不是正则表达式。虽然这不是由您在顶部发布的“重定向”执行的,它会重定向到文档根目录,因为
$1
反向引用是空的,因为模式中没有捕获子RewriteRule
模式。正如您稍后所说,“Rails 应用程序本身实际上正在重定向到https://sub.example.org/login
”。因此,为了重定向到
sub.example.org/login
(这似乎是意图),您需要更改指令以改为阅读以下内容:RewriteCond
此处不需要前面的指令,因为它只是重复您已经在RewriteRule
模式中执行的相同检查。该行是多余的,因为这是前面
ProxyPreserveHost off
指令的目的。这一行似乎也是多余的,因为
Host
它是请求标头,而不是响应标头。此外,Apache 不支持行尾注释。只是因为处理 Apache 指令的方式有一个“怪癖”,才能防止这个特定的行尾注释破坏你的服务器!
因此,考虑到上述几点,请尝试以下操作: