理系学生日記

おまえはいつまで学生気分なのか

忍者TOOLS

リダイレクト時の遷移挙動がおかしかったらリバプロ設定を疑ってもいい

リバースプロキシ経由でアクセスしたときにリダイレクトでおかしくなるケースって、だいたいリバプロの設定と社会が悪いです。

リバースプロキシを導入する理由というのは多々あります。セキュリティだったらい、SSL オフロードであったり、負荷分散、圧縮もそう。

トラフィックを受けつけるポイントでもあるので、それを利用した様々な処理を埋め込むこともできます。認証や認可もそう。

それでですね、こういうリバプロを経由したときに、ちょっとしたところで「あれ」って挙動をするときがあります。例えば、

  • リダイレクトしたときにエラーになるんだけど
  • 一部の画面遷移で 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 だと、特定のページ遷移のみでこれが起こったりしますし、レスポンスヘッダを見てもアプリ観点では問題がないので、原因切り分けに悩むケースもあったりします。

なので、リダイレクトが関わるケースで挙動がおかしくなるのであればリバプロ設定を疑えっていうのは、なんか法則みたいなかんじで覚えておいても良いかもしれないですね。

参考文献