この記事のこと
この記事はNTTコムウェア AdventCalendar 2023 21日目の記事です。
UTM/Proxyなどの構築・運用経験があり、サーバ証明書周りの知識がある程度あることを前提にしています。
(アプライアンスの記事はあまり見かけないのでなんか気恥ずかしい)
自分のこと
普段はセキュリティ製品を使った構築とそのセキュリティ運用・製品運用を行っています。上から下の工程を一通り担当する少し珍しい仕事をしているかもしれません。もともと1人NW・セキュリティ担当していたこともあり当たり前に感じてますが…
さて、タイトルのとおり、TLS通信の復号設定について気になった(悩んだ)セキュリティ製品のTLS1.3の制御についてお伝えします。
なぜ悩んだのかのこと
やった、やっとTLS1.3の検査に対応したぞ!
・TLS1.2よりTLS1.3のほうがいろいろセキュアでいいに決まってる。
・みんな使ってるのだから、対応できるなら無条件で対応させてあげればいい。
・イマドキ問題なくトラフィックも検査できるでしょ。
と大して悩むこともないだろうと思って意気揚々と実装へ。
なにせ色々なセキュリティベンダが「TLS1.3対応してます!」と言っていたから安心してました。
- Paloalto(UTM)
https://docs.paloaltonetworks.com/pan-os/10-1/pan-os-admin/decryption/decryption-concepts/tlsv13-ssl-decryption-support - Fortinet(UTM)
https://docs.fortinet.com/document/fortigate/7.4.1/administration-guide/29991/tls-1-3-support - Zscaler(Cloud-Proxy)
https://help.zscaler.com/ja/zia/supported-cipher-suites-ssl-inspection - Broadcom(Cloud-Proxy)
https://knowledge.broadcom.com/external/article/203825
「ヨシッ!いける!」と思って使い始めたのに、
・これ本当に1.3?
1.2になってない?
・オリジンの証明書見えてない?
本当に復号・検査している?
と疑いがでてくる…
技術的に製品の特長(仕様)をちゃんとわかった上で構築・動作試験、
利用開始しなければいけないのですが、やって気付くことの方が多いので、
TLS1.3の復号(トラフィック検査)について少しでも気づきを提供できたらと思いました。
暗号化通信を復号するために必要なこと
この先の話の前提について大雑把に書きます。
クライアントサイド
以下のTLS ClientHelloを送信すること
・TLS1.3~TLS1.1を含むこと
・SNI(Server Name Indication)を含むこと ※無いとどうなるか後述
セキュリティ製品(クライアントとサーバの間に入るモノ)
以下に対応できること
・TLS1.3~TLS1.1
・オリジンのサーバ証明書のCN/SANsを読み取れること
・SNIを読み取れること
サーバサイド
以下に対応できること
・TLS1.3~TLS1.1
・サーバ証明書のCN/SANsどちらかにアクセス先のURLが書かれていること
おおよそSNIとサーバ証明書が大事なのだなと思ってもらえればOKです。
ざっくりSNI:HTTPのHostヘッダに相当する部分です。アクセス先のドメイン部分(qiita.comとか)が書いてあり、これによってHTTPが暗号化されてもどのVirtualHostにアクセスしたいのか判別できるようになります。
困ったこと
早速ですが、ClientHelloにSNIが
ある | ない |
---|---|
復号化除外判定が動作する。 | 復号化除外判定が動作しない。 セキュリティ製品によっては、似たような除外処理設定が複数必要。 |
ということで、復号させたくない場合(復号除外)の判定処理に前提条件がありました。
どうやって復号するためのトリガーを引くのか、正直気にしてなかった反省があります。
Q.なんでSNIが必要なの?
A.ドメインやURLに関係するセキュリティ機能が、HTTPSだとSNIに依存しがちだから
Q.SNIがない通信なんてイマドキあるの?
A.組み込みとか…opensslが古いとか…あえて無い(送信しない)とか
-
SNIがある普通の通信は、ブラウザのURL表記を気にしておけば思う通りに動きます。
ちゃんと、セキュリティ製品が対応するCipher Suiteかどうかぐらい確認しておきましょう。
対応するSuiteは大体3個しかありません。 -
SNIが無い通信だと、復号除外機能しないこと(製品)があります。
つまり、サーバ証明書のCN/SANチェックをしないということです。
openssl s_client -noservername -connect <検証URL>:443 -tls1_2 -crlf <Enter>
GET /index.html HTTP/1.1 <Enter>
Host: <検証URL> <Enter>
みたいなことで クライアントサイド-製品-サーバサイド へアクセスを試すとわかります。
-noservername オプションが大事なところです。SNI無しで通信します。
-crlf をつけると後続のGET文などを自分で打てるようになります。
この辺はRFCでもMUSTで決まってるので、適当にやるとBad RequestとしてMUSTで終わってしまいイマイチな検証になります。
また、サーバ証明書のCN/SANをチェックしないとなると他の項目(Date、Issuerなど)もチェックしないのか?という疑問もでてきますね。
これは別のプロファイル・ポリシーでチェックされる、されない場合があるのでここも軽く確認は必要です。
(中締め)
本当に、自分が扱う製品が期待する動作をするのかどうか、そのために必要な試験をイメージしその通りに試験できているかを誰かに確認(レビュー)してもらったり、「こんな試験する・動作したよ!」と言いまわってると誰かに「こんなときはどうなるの?」と質問もらえたりするので、アピールがてらやってみましょう。
そういえば…みたいに気づくことが多いです。
URLフィルタのこと
で、TLSや復号とは直接関係ないんですが、
- SNIがあれば、SNIでURLフィルタが機能する。
- SNI無しでサーバ証明書をチェックしないとなると、暗号化・復号化された通信においてURLフィルタは動作するのか?
というのがなかなか大きな疑問になりました。URLフィルタができないUTM/Proxyとなっては意味がないので。
- 許可したつもり:許可できていない
- 遮断したつもり:遮断できていない
ということになってしまいます。
特に後者は事象に気づきづらい上にインシデント対応できていない状態で厄介です。
この点、なかなかメーカによって実装が違います。
たとえば、Paloaltoは判定方法についてはKBとして公開されています。
- SNIが無ければCNを検査する
https://knowledgebase.paloaltonetworks.com/KCSArticleDetail?id=kA10g000000PObsCAG&lang=en_US%E2%80%A9&refURL=http%3A%2F%2Fknowledgebase.paloaltonetworks.com%2FKCSArticleDetail - Path(ディレクトリ)を検査する
https://knowledgebase.paloaltonetworks.com/KCSArticleDetail?id=kA10g000000PMRlCAO&lang=en_US%E2%80%A9
👆を復号有無含めて自分なりに表にしたのが下記です。
通信種別 | SNIあり | SNIなし |
---|---|---|
復号対象外 | SNIで判定する。 | 証明書CNで判定する。 (SANsは見ない) |
復号対象 | hostヘッダ+リクエストラインで判定する。※1 | 復号対象:hostヘッダ+リクエストラインで判定する。 ※平文HTTPはここに該当 |
この場合、SNIが無いときのURLフィルタの特徴はCN判定があることとhostヘッダの扱いです。
- CNで検査する。
- SANsを見るとも見ないともどこにも記載はないので、そのように動作しないと考えるべき。(動作検証すればわかりますが)
- 平文のHTTP、または復号化されたHTTPSにおいては、リクエストターゲット(「GET /drafts/abc/edit」のGETメソッドより先の部分)も確認の対象です。
カスタムURLカテゴリの書き方次第でhostヘッダ部分のみを対象とするか、リクエストターゲットを含むか指定できます。よっぽど細かく制御したい要件が無ければhostヘッダ部分しか気にしないと思います。
この辺は「細かく制御できるよ!」と書いている管理者ガイドの通りですが、逆に言うと、平文として処理できないなら細かくディレクトリ制御は効かないということです。
URLのディレクトリ部分(リクエストターゲット)は、SNI・サーバ証明書・Connectメソッド文にそもそも乗ってこないので当然といえる動作です。
メソッド部(リクエストライン)含めて実際は制御ができます。GETはOKだけどPOSTはNGとかですね。 全部GETで実装しちゃうとアレですが。その前に復号しないといけないですけども。
これらについても、フィルタしたいドメインの記載が CNにあり・なし&SANにあり・なし の条件でオレオレ証明を作って先ほど書いたアクセス方法を試せば確認できます。
※機器固有のお作法通りにアクセス試験しないと全く再現性のない結果に悩みます。
このURLフィルタの動作はPaloaltoのものであり、製品が異なれば・設定を変えれば動作は異なります。
たとえばZsclaerでは、SNIかhostしか見ません。※SNIが無い利用は想定されないのでしょう
この辺は過去の類似製品の運用経験で「イケる」と思って確認も検証もしないと失敗します。
一人FAQのこと
証明書チェック(判定)ゆるくない?
- そう思います。
- SNIがあれば問題ないです。
opensslもgnutlsも10年以上前からSNI対応してます。->Wikipedia
イマドキSANにドメイン書くよね?
- そう思います。
- CloudflareとかCDNに発行依頼かけるとそんな証明書をくれますし、そうではなくてもマルチドメイン証明書を利用することも一般的で、CNと一致しないことも普通でしょう。
- SNIがあれば、実際の運用上は困ることは無い気がします。
(SANフィールドの値とSNIが一致しなくてアクセスできない話はまた別)
▼ SAN(証明書のサブジェクトの別名(=Subject Alternative Names))
TLS1.3だと証明書(CN/SAN)暗号化するけど大丈夫?
- だからSNIが大事。
- だからTLS1.3は復号しましょう。できないならBlockかTLS1.2運用しましょう。
メーカによってはデフォルトはTLS1.2。
※オフィシャルの理由はPinningされていると例外が効かないという話なので違いますが
TLS1.3をブロックするのか、復号対象とするのか、1.2までを復号対象とするのかの運用ポリシーの決定が必要。
Encrypted SNI(SNIの暗号化)大丈夫?
- 一般的にESNIを検知/遮断することはできるから(グレートFWみたいに)弾くことはできる。
- TLS1.3を使わなければESNIは(仕様上)使えない。
(だからといって1.3を許可しないのもよろしくないので1.3を使えるようにすべき)
ESNIが一般的になってしまうとセキュリティ確保が難しくなるので、それこそC&C通信など姿を隠したいと考えるモノだけが利用するようになると思います
セキュリティ上、なんか大丈夫?
セキュリティ対策の限界をわかった上でカバーするのが セキュリティエンジニア の おしごと ですね!
NoSNIでC&Cサーバとネゴられたらどうなるかとかイメージしてみましょう。
外部に出るとき、明示型・透過型Proxyが絶対必要で悪性URL情報がアップデートされているなら大丈夫でしょう(多分)。
Torとかトンネルするようなカテゴリ・BlockすべきURLをBlock設定しているかの方がよっぽど大事です。
その他気になること
- なぜかTLSバージョンが下がってネゴる
- 「アクセスを試すとわかります。」「確認できます」と書いた部分、確実に再現させるためにも工夫がいる(各社known issueなバグと「仕様です」があって…)
※とはいえ再現性がないとサイエンスではないので頑張らないといけない - フィールドにおいて再現性100%のバグへの対処
など、色々ネタはあるんですがまたどこかで…
--
※記載されている会社名、製品名、サービス名は、各社の商標または登録商標です。