仙石浩明の日記

2006年5月2日

VPN-Warp 入門編 (6)

前回は、WWW ブラウザで VPN-Warp へアクセスする方法を紹介しました。 基本的には https://リレーサーバのホスト名/パス という URL を WWW ブラウザでアクセスすれば、 relayagent に設定したフォワード先の WWW サーバへつながるわけですが、 二点ほど注意すべき点があります。

  1. 「https」と「http」の違い
  2. ホスト名の違い

WWW サーバに直接アクセスする場合の URL を、 例えば http://intra/path としましょう。 この場合、WWW サーバへ送られるリクエストヘッダは、 次のようになります(説明の都合上大幅に単純化しています):

GET /path HTTP/1.1
Host: intra

一方、VPN-Warp 経由 (つまり、ブラウザ → リレーサーバ → relayagent → WWW サーバ) でアクセスする場合に、 WWW サーバへ送られるリクエストヘッダは、URL が https://relay.klab.org/path ですから、 次のようになります:

GET /path HTTP/1.1
Host: relay.klab.org

両者を比べると、「Host: 」フィールドの部分が異なりますね。 多くの WWW サーバには、バーチャルホストと呼ばれる機能があって、 一台の WWW サーバで、いろんなホスト名の URL を受け付けて、 ホスト名に応じて異なるページを見せることができるわけですが、 要はこの「Host: 」フィールドを見て、 配信するコンテンツを切替えているわけです。

したがって、「Host: relay.klab.org」のままでは、 「intra」のコンテンツを見ることができないケースが多いでしょう。 この (2) ホスト名の違い の問題を解決するために、 relayagent には「Host: 」フィールドの書き換え機能があります。 この場合でしたら、 「-h intra」オプションを追加指定することにより、 リクエストヘッダの「Host: 」フィールドを「intra」に書き換えます。

これで少なくともリクエストヘッダは、直接アクセスする場合と、 VPN-Warp 経由でアクセスする場合が同じになりました。 コンテンツの HTML 文書で URL を絶対指定したりしない限りは、 普通にブラウズできるでしょう... か?

コンテンツが全て静的なページから構成されているのであれば、 その通りなのですが、 普通は PHP や Java などを使用して動的に生成するページもあるでしょう。 その場合、PHP インタプリタやサーブレットコンテナは、 いま生成中のページの URL がなんであるか把握していて、 ページを出力するときに、絶対指定を出力してしまうケースがあるので 注意が必要です。

特に、(1) 「https」と「http」の違い は留意しておくべきでしょう。 WWW サーバにとっては、80番ポートでアクセスを受け付けているわけですから、 PHP インタプリタないしサーブレットコンテナは、 「http」なページを出力中だと認識しているはずです。 ところが WWW ブラウザにとっては、アクセスしている URL は「https」です。 WWW サーバがレスポンス中に「http」な URL を出力してしまうと、 ブラウザはその URL をたどれなくなります。

とはいえ、動的なページを出力する際に絶対 URL を指定してしまうと、 コンテンツの URL を変更したいときも不便ですし、 そもそも相対 URL で済むところをわざわざ絶対指定する必然性もないので、 普通の Web アプリケーションを使う限りはあまり問題とはならないようです。 WWW サーバのレスポンスを全て監視して、 適宜 URL の書き換えを行なえば解決できる問題ではあるのですが、 ごく少数の絶対 URL の書き換えのためだけに、 全てのレスポンスを監視するのは、 パフォーマンスの点で割が合わないと言えそうです。

むしろ問題となるのは、リダイレクトです。 リダイレクトの場合、WWW サーバは次のようなレスポンスヘッダを返します (説明のため大幅に単純化しています):

HTTP/1.1 301 Moved Permanently
Location: http://intra/path

このような 301 レスポンスを受け取ると、 WWW ブラウザは「Location: 」フィールドで指定された URL のページを 表示しようとします。 そして「Location: 」フィールドは絶対 URL で指定されます。

WWW サーバは、ページの URL は「http://intra/...」である と認識していますから、 同じホスト名の URL へリダイレクトを行なう場合 「Location: 」フィールドには「http://intra/...」が指定されます。 これをそのまま WWW ブラウザに伝えてしまうと、 WWW ブラウザは「http://intra/...」すなわち VPN-Warp を介さずに 直接 WWW サーバへアクセスしようとしてしまいます。

この問題を解決するために、 relayagent にはレスポンスヘッダの「Location: 」フィールドを書き換える機能が あります。 すなわち「-H」オプションを指定すると、 「Location: 」フィールドのホスト名とフォワード先のホスト名 (今回の例の場合は intra ですね) が一致する場合、 それをリレーサーバの URL へ書き換えます。 前述したレスポンスヘッダの場合であれば、

HTTP/1.1 301 Moved Permanently
Location: https://relay.klab.org/path

に書き換えるわけです。これでめでたく WWW ブラウザは リダイレクト先のページも、VPN-Warp 経由でアクセスするようになります。

Filed under: システム構築・運用 — hiroaki_sengoku @ 15:13

No Comments »

No comments yet.

RSS feed for comments on this post.

Leave a comment