UTM製品は、SSLによって暗号化されている通信の中身を見てUTM処理を行うものがあります。イマイチ振る舞いが分からなかったので、いろいろと調べました。きっとこんな感じだろレベルであり、あってるかどうかは不明です。なお、絵を描く気力はなかったです。
SSL通信の流れ
クライアントとサーバ間で、SSLのセッションとコネクションを確立するまでの流れは以下の通りです。
- クライアントとサーバ間で暗号化方式のネゴシエーションを行う。
- サーバは、クライアントにサーバ証明書(とCA中間証明書)を送る。
- クライアントは、受信したサーバ証明書を検証する。(検証プロセスは後述)
- クライアントは、サーバ証明書からサーバの公開鍵を取り出す。
- クライアントは、共通鍵の元を作る。
- クライアントは、サーバの公開鍵を利用して、共通鍵の元を暗号化する。
- クライアントは、暗号化した共通鍵の元をサーバへ送る。
- サーバは、暗号化された共通鍵の元を受け取り、サーバの秘密鍵で復号する。
- サーバとクライアントは、互いに持っている共通鍵の元を利用して共通鍵を生成する。
- サーバとクライアントは、生成した共通鍵を利用して通信を暗号化する。
サーバ証明書に書かれている事
3つのことが書かれている。
- tbsCertificate : 証明書の基本的な情報と公開鍵(=証明書が証明したい内容)
- signatureAlgorithm : 署名アルゴリズム
- signatureValue : 認証局の署名
証明書検証の流れ
- クライアントは、サーバ証明書に記載された認証局が、自身の信頼された認証局に登録されているかを確認する。(証明書の発行者が信じるに値するかをチェックする)
- クライアントは、自身に登録されている認証局の公開鍵を利用して、サーバ証明書の署名を検証する。(信じられる発行者が発行した証明書かどうかをチェックする)
- クライアントは、サーバ証明書に記載されているコモンネームが、アクセスしようとしているサーバのFQDNと一致することを確認する。(信じられる証明書に記載されている場所にアクセスしているかチェックする)
SSLインスペクションにおけるSSL通信の仕組み
SSLインスペクションでは、暗号化されたSL通信に対してUTM処理を行う必要があります。
しかし、「SSL通信の流れ」で確認した通り、クライアントとサーバ間のセッションとコネクションの確立において、通信の復号化に必要な共有鍵は一切交換されません。クライアントとサーバの間でやり取りされる情報は、「サーバの公開鍵」と「公開鍵で暗号化された共有鍵の元」だけです。共有鍵のヒントとなる「公開鍵で暗号化された共有鍵の元」を復号するためには「サーバの秘密鍵」が必要ですから、経路上に存在するUTM装置はお手上げです。
そこでUTM装置は、綺麗な中間者攻撃を行います。SSLインスペクションにおいて、SSLセッションとコネクションを確立する流れは以下の通りです。
- クライアントはサーバに暗号化方式のネゴシエーションを行う。
- クライアントからサーバへのネゴシエーションを検知したUTM製品は、クライアントからサーバへのネゴシエーションをいったんストップする。
- UTM製品は、クライアントの代わりにサーバに暗号化方式のネゴシエーションを行う。
- サーバとUTM製品間で暗号化方式のネゴシエーションを行う。
- サーバは、UTM製品にサーバ証明書(と中間CA証明書)を送る。
- UTM製品は、受信したサーバ証明書を検証する。
- 以降は、UTM製品とサーバ間で上述したSSL通信の流れを実施します。その結果、UTM製品とサーバ間でSSLのセッションとコネクションが確立します。
- UTM製品は、サーバのサーバ証明書のtbsCertificateの中の「発行者」と「公開鍵」をUTM製品のものに書き換える。(多分。自宅のFG60Bにdeep-scanの設定が入らなかったため、UTM製品が作るオレオレサーバ証明書が入手できなかった)
- UTM製品は、サーバのサーバ証明書を元に作ったオレオレtbsCertificateに対して、UTM製品のオレオレ認証局の秘密鍵で署名する。その結果、発行者と公開鍵以外は、サーバのサーバ証明書と同じ「オレオレサーバ証明書」が完成する。
- UTM製品は、ストップしていたクライアントからサーバへの暗号化方式のネゴシエーションに代理応答する形で、クライアントと暗号化方式のネゴシエーションを行う。
- UTM製品は、クライアントにオレオレサーバ証明書(とオレオレCA証明書)を送る。
- クライアントは、受信したUTM製品のオレオレサーバ証明書を検証する。
- ここで検証が失敗します。なぜなら、クライアント自身の信頼された認証局に、UTM製品のオレオレ認証局が存在しないためです。信頼していない認証局が発行したオレオレサーバ証明書は信じないというわけです。
- この問題を解決するため、クライアントにUTM製品のオレオレ認証局のCA証明書をインポートする必要があります。UTM製品のオレオレ認証局を信頼された認証局にすると、UTM製品のオレオレサーバ証明書の検証は成功します。信じられる発行者が発行したサーバ証明書なのですから。
- オレオレサーバ証明書に記載されている実在証明に関する情報は、サーバのサーバ証明書と同一です。従って、サーバのサーバ証明書がEV SSLであれば、UTM製品が発行したオレオレサーバ証明書であっても、ブラウザには鍵マークと緑色の企業名が表示されます。
- クライアントは、UTM製品のオレオレサーバ証明書からUTM製品の公開鍵を取り出す。
- クライアントは、共通鍵の元を作る。
- クライアントは、UTM製のオレオレサーバ証明書の公開鍵を利用して、共通かぎの元を暗号化する。
- クライアントは、暗号化した共通鍵の元をUTM製品へ送る。
- UTM製品は、暗号化された共通鍵の元を受け取り、UTM製品の秘密鍵で復号する。
- クライアントとUTM製品は、互いに持っている共通鍵の元を利用して共通鍵を生成する。
- クライアントとUTM製品は、生成した共通鍵を利用して通信を暗号化する。
最終的には、クライアントとUTM製品間、UTM製品とサーバ間で、2つのSSL通信が確立します。こうすることで、UTM製品はサーバとクライアントがやりとりする通信を平文で得ることができますので、UTM処理を行うことができます。よくできてるなーと思いますし、SSLインスペクションが高負荷であること理由も納得がいきます。
備考
ふと、UTM製品用にサーバ証明書をインストールしたらどうなるんだろうかと思いました。しかし、サーバのサーバ証明書に含まれるtbsCertificateをクライアントに提示しないと、実在証明の検証失敗による証明書エラーが出てしまうので意味がないですね。
tbsCertificateの情報はそのままで、サーバ証明書の公開鍵だけをUTM製品のサーバ証明書の公開鍵に変更すると、証明書のハッシュ値と署名と異なってしまうのでやはり検証エラーになります。
これを回避するには自分で再署名して署名を作り直すしかありません。結局オレオレ認証局に頼るしかないので、結果は同じですね。サーバ証明書が無駄になります。