リバースプロキシ経由でアクセスしたときにリダイレクトでおかしくなるケースって、だいたいリバプロの設定と社会が悪いです。
リバースプロキシを導入する理由というのは多々あります。セキュリティだったらい、SSL オフロードであったり、負荷分散、圧縮もそう。
トラフィックを受けつけるポイントでもあるので、それを利用した様々な処理を埋め込むこともできます。認証や認可もそう。
- フロントエンジニアに知ってもらいたいリバースプロキシの重要性 | RickyNews
- Reverse Proxy がなぜ必要か - naoyaのはてなダイアリー
- GitHub - bitly/oauth2_proxy: A reverse proxy that provides authentication with Google, Github or other provider
それでですね、こういうリバプロを経由したときに、ちょっとしたところで「あれ」って挙動をするときがあります。例えば、
- リダイレクトしたときにエラーになるんだけど
- 一部の画面遷移で 404 になるんだけど
といった場合。こういう場合は、リバプロ設定がおかしいことが多いです。
リバースプロキシって、基本的にはバックエンドのサーバを隠して「代理」(Proxy) になることが前提になります。そういう意味で、リバプロは必死にバックエンドのサーバを隠蔽しなければなりませんし、ネットワーク設計もそれが前提になることが多い。
例えば外部からバックエンドへ直接繋がるトラフィックは遮断されますし、バックエンドサーバの名前解決は外部からできなくても良いでしょう。
一方で、バックエンドから外部に、バックエンド自身の情報を出力しちゃうケースがあります。バックエンドサーバが生成する HTTP ヘッダとかですね。
Location
ヘッダContent-Location
ヘッダ- Cookie
バックエンドは、普通、リバプロの情報の存在を前提に実装しません(X-Forwarded-For
とかは見ることはある)し、自身が「バックエンド」であり自身の情報を「隠さないといけない」ということは意識しないのではないでしょうか。
だからこそ、バックエンドサーバの返却するリダイレクトレスポンスの Location
ヘッダが バックエンドサーバのホスト名/IPアドレスになっている のは当然で、これを外部から隠すのは、リバプロの責務だとぼくは思っています。
例えば、Apache の mod_proxy では、ProxyPassReverseディレクティブ がこのあたりをやってくれていて、例えば以下の設定だと、
http://backend.example.com/quux
へのリダイレクトレスポンスは、リバプロが http://example.com/mirror/foo/quux
へのリダイレクトに「書き換え」てくれます。
ProxyPassReverse "/mirror/foo/" "http://backend.example.com/"
逆に、これを設定しない場合、外部へ返却されるリダイレクトレスポンスがバックエンド宛になってしまい、ブラウザはそのホスト名が引けなかったり、ネットワーク疎通できなかったりして、404 になることが多いです。 特に、PRG パターンとかで実装されていた WebApp だと、特定のページ遷移のみでこれが起こったりしますし、レスポンスヘッダを見てもアプリ観点では問題がないので、原因切り分けに悩むケースもあったりします。
なので、リダイレクトが関わるケースで挙動がおかしくなるのであればリバプロ設定を疑えっていうのは、なんか法則みたいなかんじで覚えておいても良いかもしれないですね。