Apache ProxyPass + RewriteRule?

Apache ProxyPass + RewriteRule?

我已經設定了一個 apache 配置來嘗試重定向/login並代理傳遞所有其他請求:

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/

相關內容