Apache ProxyPass + RewriteRule?

Apache ProxyPass + RewriteRule?

/login他のすべてのリクエストをリダイレクトして ProxyPass するように Apache 構成を設定しました。

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/ログイン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の によるリダイレクトの原因は何ですか? また、なぜ sub ではなく alt を参照するのですか?^

ディレクティブProxyPassReverseは最初の引数として正規表現を取らないため、競合が発生していると思われます。また、!2 番目の引数として正規表現を取ることもできません。ディレクティブが応答と一致しない場合、altサブドメインがヘッダーに表示されます。LocationProxyPassReverse

この URL はプロキシされていないため、ProxyPassReverseに関連する最初のディレクティブは必要ないようです。/login

また、これらの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/

関連情報