Cisco FTD で HTTPS 通信を復号して IPS を通してみる

## はじめに
この記事は、Cisco Systems Japan Advent Calendar 2024 シリーズ1 の 25日目として投稿しています。
https://qiita.com/advent-calendar/2024/cisco
毎年みんなでいろいろ好き勝手に記事を書いて楽しく盛り上がっております。

## HTTPS の通信を IPS で検知することの難しさ
当たり前ですが、最近、Web ブラウザでどこかのサイトにアクセスする際には、https:// で始まる URL がアドレスバーに入ります。HTTP を TLS で暗号化した HTTPS が使われます。
IPS (Intrusion Provention System) でウェブアクセスの通信を検査する際、HTTP でもヒットする Rule (signature) はいろいろありますが、HTTPS になると、パケットの中身が暗号化されているので IPS で検査に使える Rule は大きく減ってしまいます。
Cisco Secure Firewall Threat Defense (FTD) には Encrypted Visibility Engine (EVE) という、通信を復号しなくてもクライアントのアプリケーションの危険度を検知してブロックする素晴らしい機能があるため、これを活用するのも1つの手段であり、非常に有益です。しかしながら、完全にパケットの中身を見ることができる機能ではありません。

## FTD で Decryption Policy を使って HTTPS の通信を復号
FTD の Decryption Policy を使うことで、HTTPS と QUIC の通信を FTD で一時的に復号して IPS や Malware Defense、Firewall のポリシーを適用できます。そこで許可された通信は再度暗号化されてオリジンサーバに向かいます。
FTD の Decryption Policy に作る Rule にて実際に通信を復号する Decryption を実施する Action は以下の2つです。

・Decrypt Resign

outbound の通信に対して適用する Action です。主に Firewall 内部のクライアントからインターネットの先にあるサーバへの通信を復号する際に使われます。
FTD は Man-in-the-Middle の位置づけとなり、FTD はサーバ証明書をクライアントが信頼する CA で再度サインします。これにより、クライアントの Web ブラウザで確認できるサーバ証明書はオリジンサーバが使っている CA がサインしたサーバ証明書ではなく、その CA がサインしたサーバ証明書に置き換わりますが、その CA はクライアントが信頼できる CA なので Web ブラウザに警告は出ません。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/309674/e166e9a6-7905-bd78-8dbf-7a8b419ac625.png)

・Decrypt Known Key
inbound の通信に対して適用する Action です。主に Firewall の先 (一般的にはインターネットの先) にあるクライアントから内部にあるサーバへの通信を復号する際に使われます。
オリジンサーバで運用している信頼されたルート CA がサインしたサーバ証明書と秘密鍵を FMC 経由で FTD にインストールし、条件に合致した通信を FTD で復号します。この場合はそもそもオリジンサーバのサーバ証明書そのものがクライアントに提示されるため、やはりクライアントの Web ブラウザに警告が出ません。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/309674/3b4f5ee1-7d3a-4607-0c9a-3634f6e366e7.png)

## FMC 管理の FTD で Decryption Policy を試してみる

以下の環境を使って実際に試してみます。

・FMC version 7.6.0 
・FTD version 7.6.0 outside:192.168.10.131/24, inside:192.168.150.131/24
・適当な Web サーバとクライアント、Local CA (すべて Windows PC で構築)
・FTD の Access Control Policy は全通信を許可 (Action: Allow)、ただし、Intrusion Policy は適用
・Intrusion Policy の Rule で /etc/passwd にアクセスしたら hit するという Rule (SID:1122) で Action: Block を適用 --> これにより、クライアントの Web ブラウザのアドレスに /etc/passwd を含めた場合に IPS が通信を検知できる

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/309674/eb713cdb-4588-bc3a-ca98-d6f7573e89a0.png)

### Decrypt Resign を試してみる

前提条件は以下の通りで、outbound の Decryption を試してみます。

・クライアント 192.168.150.73/24 GW:192.168.150.131 (Firewall inside)
Local CA は信頼されたルート証明機関としてインストール済み
・サーバ cisco.com (本当の cisco.com の Web Server)
・なので、クライアントからサーバに接続ができるように FTD で NAT を行い、DNS も本物を使う

Decryption をしない状態で cisco.com にクライアントの Web ブラウザからアクセスした際のサーバ証明書は以下の通りで、本当に信頼されたルート CA からサインされています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/309674/98f30a90-e540-45d2-01ae-2a89d7374641.png)

この状態で、

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/309674/d262d9e3-d422-388e-3305-d266744d79cc.png)

とアドレスに入力してアクセスすると、Access Denied にはなりますが、これは FTD の IPS でヒットしてブロックしたわけではありません。
FMC の Unified Event Viewer で確認しても Intrusion Event にヒットした経歴がありません。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/309674/91e118dc-b4e2-67ff-b797-91ced37b9b9f.png)

では、ここから Decrypt Resign の設定をしていきましょう。
今回は、FMC で Local CA を作成し、その証明書をクライアントに信頼されたルート CA としてインストールします。
FMC から Object --> PKI --> Internal CAs --> Generate CA にて Local CA を作成できます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/309674/7adeea5c-e978-91ad-a5b7-d9766d75bcd8.png)

作成した CA の証明書をダウンロードします。その際、パスワードを設定します。ダウンロードした証明書をクライアントにコピーします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/309674/023d9779-c065-4f6d-2f4c-41f5b7619024.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/309674/42105a39-a1a0-e1d8-86bc-a3a6c133d224.png)

FMC に戻って Policies --> Decryption --> Create Decryption Policy にて Outbound Connections の Decryption Policy を作成します。利用する Internal CA は、今 FMC で作った Local CA を選択します。Destination Port を HTTPS で選択して Apply --> Next と進みます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/309674/5c3e9a67-f47d-9916-0be6-8fb3ac4cac20.png)

FMC version 7.6 以降では、あらかじめシスコが定義した復号不可のサイトやアプリケーションを復号しないというアクションを選べるようになっています。このまま Create Policy をクリックします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/309674/bdc36b5a-b336-be0a-1e9f-fb476c7704cf.png)

以下のように Decryption Policy ができあがりました。自動生成された Decrypt Resign の Rule で、送信元ネットワークを Firewall の Inside 側だけに絞るように変更します。合わせて Rule 名も自動生成されているので、わかりやすい名前に変更します。Save して Rule を保存し、さらに Save して Decryption Policy そのものを FMC に保存します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/309674/8e2f1428-6d1d-9bd2-4dec-788614f98ad8.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/309674/ffc3921e-4faf-1ab2-edd5-87c7ac7a31d9.png)

作成した Decryption Policy を Access Control Policy に紐づけます。Policies --> Access Control から FTD で利用している Access Control Policy を選択して edit を開始します。Decryption から作成した Decryption Policy を選択して Apply し、さらに Save して Access Control Policy を保存します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/309674/c4bcee43-ddf5-600a-d818-d3a270082007.png)

FMC で Deploy を実施し、ここまでの設定変更を FTD に反映させたら再度検証開始です。
クライアントから Web ブラウザで cisco.com にアクセスしてみると Decryption Policy 適用前とは異なり、証明書の発行者が FMC で作成した Local CA になっていることがわかります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/309674/ed815590-7a2c-ae38-392d-d7442a19698d.png)

Decryption Policy 適用前には検知できなかった /etc/passwd へのアクセスを試してみます。やはりアクセスできませんが、cisco.com のサーバまで通信が届いておらずタイムアウトになります。
FMC の Unified Event Viewer で確認してみると、Intrusion Block が記録されています。つまり、FTD が HTTPS の通信を復号し、パケットの中身を見て、IPS の policy にヒットした通信を Block したことがわかります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/309674/32bfe6df-1e65-af3d-ae97-50b295bb29ad.png)

Unified Event Viewer で SSL Policy や SSL Rule のカラムを有効にすると、Decryption Policy や Rule にヒットしていることもわかります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/309674/04187d89-7788-5bb9-ec70-a299758938f3.png)

ということで、Decrypt Resign にてサーバ証明書を FTD が再サインすることで HTTPS の通信を中身を見て IPS を活かせることがわかりました。

### Decrypt Know Key を試してみる

今度は inbound の Decryption を試してみます。前提条件は以下の通りです。

・CA w10-2-164-server.gsso-jp-test.local
現実世界の信頼されたルート CA の代わりにローカルに CA 構築
・Web サーバ 192.168.150.72/24 GW:192.168.150.131 (Firewall inside)
信頼された CA (ローカルの CA) にてサインされたサーバ証明書をインストール済み
Subject: w10-2-164-webserver.gsso-jp-test.local
・クライアント 192.168.10.73/24 GW:192.168.10.131 (Firewall outside)
信頼された CA (ローカルの CA) の証明書を「信頼されたルート CA」としてインストール済み
・DNS での名前解決は問題なく実現できてる (とりあえず、hosts ファイルで対応)

先の Decrypt Resign のテストのときに利用した FMC での NAT 設定や、Decryption Policy は、一旦削除して FTD に Deploy しておきます。
この状態で FTD を介したクライアントの Web ブラウザから Web サーバへの HTTPS アクセスを実施すると、以下のようにこの環境で信頼された CA でサインされたサーバ証明書が Web サーバで使われていることがわかります。アラートもありません。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/309674/abefc509-2ccc-9d1d-d452-2a5598ed76bd.png)

では、ここから Decrypt Known Key の設定をしていきましょう。
Decrypt Resign のときは FTD でサーバ証明書を再サインしましたが、Decrypt Known Key の場合はオリジンサーバのサーバ証明書と秘密鍵を FMC から FTD にインストールする必要があります。
あらかじめオリジンサーバからサーバ証明書と秘密鍵を FMC にアクセスする PC にコピーしておき、FMC にて Objects --> PKI --> Internal Certs から Add Internal Cert をクリックします。
準備しておいたサーバ証明書と秘密鍵のファイルを選択し、任意の名前をつけて Save します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/309674/a9cd0dea-dd2f-6e16-da53-f51baf6ac098.png)

以下のようにこのオリジンサーバのサーバ証明書が FMC にインストールされました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/309674/fee990f1-7667-9ae1-8105-bb1c71058017.png)

ここから Decryption Policy を作成します。FMC で Policies --> Decryption から Create Decryption Policy をクリックし、今度は Inbound Connections を選択します。Internal Certificates には今作成したオリジンサーバの証明書を選択し、Next をクリックします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/309674/488571fe-b4ee-8d6e-8e53-1d94c8d68ee9.png)

Decrypt Resign のときはここで復号不可能なサイトやアプリケーションの除外設定を有効にする手順がありましたが、Decrypt Known key においては宛先のサーバはすべて管理者が知っている (すなわち、サーバの証明書と秘密鍵を FMC にインストールしている) 状態なので、ここでは何も選択することができません。このまま Create Policy をクリックします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/309674/776fd00e-049f-a4a8-9e79-dea387dd237a.png)

Decrypt Resign のときと同様に Decryption Policy ができあがりました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/309674/d16f53e2-df29-9a8b-3b6e-359cdbd4f4c1.png)

自動生成された Rule で宛先のネットワークをオリジンサーバ宛てに絞る設定を入れ、さらに名前をわかりやすいものに変更して Rule を Save します。最後に Decryption Policy を Save してここまでの設定を FMC に保存します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/309674/8b9a0825-6ea8-22af-045a-53b1c079b58b.png)

作成した Decryption Policy を Access Control Policy に適用するところは Decrypt Resign と同じです。Access Control Policy を Save して Deploy を実施して FTD に設定を反映させてください。

クライアントの Web ブラウザで再度 Web サーバに HTTPS でアクセスしてみます。Decrypt Resign のときと異なり、サーバ証明書はオリジナルのままです。再サインされていません。これが Decrypt Resign と Decrypt Known Key の違いです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/309674/da61d0e8-9fd7-8c01-3bd5-4f0dbc25f12a.png)

FMC の Unified Event Viewer で SSL Policy と SSL Rule のカラムを有効にして見てみると、正しく Decryption が効いていることがわかります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/309674/f1d5ee92-bee5-4208-d7db-1b7094879c64.png)

では、この状態で

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/309674/061a3202-e6af-31ef-a847-551fad2e401e.png)

にアクセスしてみましょう。
やはり接続できず、Intrusion Block が記録されました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/309674/96edda04-d625-45b9-aac2-f860872ff32f.png)

ということで、Decrypt Know Key にてサーバ証明書はそのまま FTD が保持することで HTTPS の通信を中身を見て IPS を活かせることがわかりました。

## FTD で Decryption Policy を使うときの注意点

通信の間に入り込んで、暗号化された通信を復号してしまうということは、クライアントやサーバを「騙す」必要があります。
具体的には Decrypt Resign であれば「クライアントが信頼する CA で」証明書を FTD が再サインする必要があり、Decrypt Known Key であれば「世界中が信頼する CA でサインされた証明書と秘密鍵」を FTD が利用する必要があります。
つまり、前者であれば「管理者がコントロールできるクライアント PC」からの通信を復号して検査することになり、後者であれば「管理者がコントロールできるサーバ」への通信を復号して検査することにあります。
証明書の取り扱いの手間がかかることには注意が必要です。

また、Decryption Policy の利用においては、FTD が動く機器のリソースを多く消費します。FTDv や古い型番の Cisco Firewall ハードウェアであれば、パフォーマンスへのインパクトは大きいです。最近の型番の Cisco Firewall ハードウェアであれば (Firewall 1200, 3100, 4200 等) 強力な Crypt Accelerator を積んでいるため、旧機種や仮想版の FTD に比べるとパフォーマンスへのインパクトは大きくないものの決して無視できるような要素でもありません。
実際に Decryption Policy を使うのであれば、機器選定のサイジングには注意が必要です。
EVE (Encrypted Visibility Engine) も併用し、本当に復号したい通信だけを Decryption Policy に入れる、等のデザインの配慮が必要です。

## おわりに

FTD の EVE を使うことによって、暗号化された通信を復号することなくクライアントのアプリケーションの危険度をある程度は把握して通信を止めることができますが、暗号化された通信を完全に検査するにはやはり通信の復号が必要です。
FTD では比較的簡単にこの設定ができるようになっており、また新しいハードウェアであれば専用の Crypt Accelerator を積んでいるため、証明書の取り扱いが正しくできるのであれば、積極的に使っていきたい機能です。
この記事がその設定のお役に立てれば幸いです。