■問3(難易度:普通)
テーマ:HTTPS通信をしつつ、プロキシサーバも導入する方法
【問われていること】
・HTTPによる認証
HTTPの概要:TCP、つまり、コネクションを確立して通信する。keep aliveを利用するのが一般的なので忘れがちだが、要求・応答を1回やるとコネクションは切断する通信。
・HTTPパケットの構造
図4.1.2 P250
要求側はリクエストライン、HTTPヘッダ、HTTPボディ
応答側はステータスライン、HTTPヘッダ、HTTPボディ
の構造になっている
リクエストラインに入るものは以下。Webサーバに(大きな分類で)何をしたいのかを記述する。
GET :指定したページを取得する。Get /....html HTTP/1.1
POST :指定したページに情報を送る。情報はHTTPボディに書いてあるので、URLには表示されない。
CONNECT:指定したサーバへのトンネリングを要求する。CONNECT www...co.jp:443 HTTP/1.1
↑でざっくりとしたことは書いた。
次は追加情報をHTTPヘッダに記述する。代表的な項目は以下。
要求側
Authorization :認証はBASIC認証 or ダイジェスト認証?
User-Agent :ブラウザの種類
Referer :遷移前にいたURL。XSS対策。必要
Cookie :セッションIDやタイムスタンプなどブラウザに保存されているデータ=Cookie。
X-Forwarded-For :プロキシを経由していると経由したサーバの履歴が載ってる。
応答側
Set-Cookie :クライアントのブラウザにクッキーを設定する
Location :リダイレクト先のURL
WWW-Authenticate:認証が必要かどうかの情報
・プロキシサーバでクライアント↔サーバの通信をチェックするには?
本問題ではHTTPSの場合、プロキシサーバはHTTPパケットをどこまで見れるか?が焦点になっている。
クライアント↔サーバでトンネリングが成立していると、クライアントとサーバの間にいるプロキシサーバはリクエストライン(ステータスライン)より下にあるパケットは読み取ることができない。
トンネリングが成立=クライアントとサーバが持つセッション鍵で通信が暗号化されているため、セッション鍵を持たないプロキシサーバは中身の閲覧が不可能。
上記を解決する方法は「プロキシサーバをプライベート認証局にして、公開鍵証明書を発行する」。
具体的な手順は以下。
事前準備
0.クライアントにプロキシのルート証明書を入れる。これでクライアントはプロキシが発行した証明書を信用する。
クライアント→サーバに通信開始
1.クライアント→プロキシ→サーバとHTTP要求され、サーバはサーバのデジタル証明書を送り返す。
2.プロキシはサーバのディジタル証明書を横取りして、プロキシ自身のディジタル証明書をクライアントに送る。
プロキシのディジタル証明書のCN=サーバのディジタル証明書のCNに設定しておく。
これをやっておかないと3で拒否される。
3.クライアントはプロキシから送られてきた、プロキシの証明書を確認する。
0より、クライアントはプロキシの証明書を信じる。
プロキシの証明書のCNがサーバのCNと同じであるため、クライアントはプロキシの証明書をサーバの証明書と信じていることになった。
結果、クライアント↔プロキシとプロキシ↔サーバは別々のセッション鍵を持つ。
クライアントとサーバの通信は第3者からは暗号化され、その通信の内容はプロキシのみ確認できる状態になっている。
・証明書の正当性はなにで確認するのか?
本問題だと、クライアントがプロキシから送られてきた証明書を検証するが(2)、具体的に何を見ていたかが問われている。以下を確認していた。
・有効期限内か?
・失効リストに入っていないか?
・CNが接続先のURLになっているか?
・証明書の発行先(CA)は信頼できるのか?
・証明書に付与したディジタル証明が正しいか?
この検証に失敗した=変なところから証明書が送られてきている
つまり、中間者攻撃されていると思ったほうが良い。