プロキシサーバとは
プロキシサーバとは、クライアントからサーバへ http 通信する際、直接やり取りするのが好ましくない、および (もしくは) 効率的で無い場合に利用される代理応答サーバのことです。
プロキシサーバの具体的なメリット・必要性は以下の通りです。
- 悪意あるユーザからの直接アクセスを防ぐことによりセキュリティを向上できる
- 社内のインターネットアクセスをプロキシサーバへ集中させることにより、誰がいつどのようなサイトを見ているか、といったログ情報を集中管理できる。
- ユーザが閲覧したサイトのコンテンツをプロキシサーバの HDD 等のディスクにキャッシュし、2 人目以降が同じサイトを見ようとする際にキャッシュから応答することでインターネット通信量を減らし、効率化できる
なお、一般に単にプロキシサーバと言えば、クライアントと Web サーバの間に入り、クライアントに代わり Web サーバと http 通信するものを指しますが、実はプロキシはそれだけでなく、FTP, Radius, SIP 等の様々なアプリケーションで利用されています (ただし、仕組みは一概に同じとは言えません)。
この記事では単にプロキシと呼ぶ場合は http プロキシを指すこととし、http プロキシについてのみ解説します。
プロキシサーバの具体的なフローは下記の通りです。
意外と重要なポイントとしては、②③に書かれている通り、DNS とプロキシでは、プロキシ通信のほうが順序が先です。つまり、DNS による名前解決はプロキシサーバが行います。
なので、プロキシを使っている環境ではクライアント側の DNS サーバ設定を変更しても効果がありません。
また、「①のクライアント⇒プロキシサーバの http Request」と「④のプロキシサーバ ⇒ Web サーバの http Request」の中身を確認してみましょう。ほとんど変わりませんが、以下 2 点で異なります。
1. TCP ポート番号
80 番も使うことができますが、8080 や 3128 といったポートを使うことが多いです。
2. GET メソッドの URI
例えば "http://www.example.com/news/index.html" のサイトを見る際は以下のように記載します。
GET の直後の /news が URI にあたります。
これがプロキシ接続の場合は以下のように変わります。
https 通信のプロキシ接続
https 通信時において、プロキシサーバへ GET メソッドを使うことはできません。まず、https で使われる TLS は『通信の末端の 2 台間以外は通信内容が分かってはならない』というのが大前提です。それはプロキシサーバも例外ではありません。クライアントと Web サーバの通信の中身は、プロキシサーバにも見えてはならないのです。
上記の通り、プロキシサーバでは GET メソッドを書き換える必要がありますが、https 暗号化の中身は覗けないため、書き換えることができません。なので https 通信については http の GET メソッドではなく CONNECT メソッドを使います。
これを受信した後は、プロキシサーバはクライアントに「HTTP/1.1 200 Connection Established」の http メッセージを返し、その後はこの送信元 IP :送信元ポート番号の組み合わせの通信については、TLS や https 通信の中身には一切触れず、IP ヘッダと TCP ヘッダを変更して Web サーバへ転送するのみになります。
https 通信のプロキシアクセスログ
https 通信においては、本来アクセスログとして取得すべき領域である GET メソッドは、TLS で暗号化されているため見ることができません。そのため、CONNECT メソッドを見ます。
ただし、GET メソッドと異なり、CONNECT メソッドは取得するファイルまではありませんので、ログも FQDN のみしか残せません。つまり、http の場合はファイル名までログに残せますが、https の場合はどのファイルへアクセスしたかはログに残せず、どのホストへアクセスしたかのみをログに残します。
[http の場合] GET http://www.example.com/news/index.html
[https の場合] CONNECT www.example.com:443
プロキシサーバによるhttps通信の傍受
前述の通り、基本的にはプロキシサーバは https 通信の中身を覗くことができません。ただ、絶対に https 通信を覗けないか、というと例外が 2 つだけ方法があります。
1 つ目は、https 通信したいサーバの秘密鍵をプロキシサーバに持たせることです。しかしこれは例えば google.com 等のインターネット上のサーバで秘密鍵をもらうことは現実的に不可能です (秘密鍵が取得できる=そのサーバの暗号化機能は簡単に取り外し、傍受できる)。社内 PC から社内サーバへのアクセスに社内プロキシを使っている、などの構成であればこのような構成が可能です。
2 つ目は、プロキシサーバに動的にサーバ証明書 (例えばexample.com にアクセスする場合はコモンネーム= www.example.com) を生成・保持し、https 通信が来た場合はそのサーバ証明書をクライアントに提示する、という方法です。これにより一度プロキシサーバで復号化させることができます。
ただし、プロキシサーバが生成するサーバ証明書のルート証明書を、あらかじめ全ての PC にインストール(信頼されたルート証明機関として登録)する必要があります。これが出来ない場合はブラウザ上で警告画面が出ます。
サーバ証明書等のデジタル証明書の詳細については、以下をご参照下さい。
また、プロキシサーバを利用する際は通常はブラウザにプロキシ設定を入れますが、『透過型プロキシ』を導入すれば、ブラウザの設定無しにプロキシサーバを使わせることができます。
透過型プロキシの仕組みの詳細は以下をご参照下さい。
また、プロキシの負荷が高いときは特定 URL についてはプロキシを迂回するよう構成することができます。
コメント
「2.GETメソッドのURI」の「例えば “http://www.example.com/news/index.html” のサイトを見る際は以下のように記載します。]は「①のクライアント⇒プロキシサーバの http Request」でしょうか?
また、「これがプロキシ接続の場合は以下のように変わります。」は「④のプロキシサーバ ⇒ Web サーバの http Request」でしょうか?
bass さん、こんばんは。はい、その認識で合っています。