Apache ProxyPass + RewriteRule?

Apache ProxyPass + RewriteRule?

我已经设置了一个 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子域将出现在标头中。LocationProxyPassReverse

您似乎不需要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/

相关内容