相互TLSとIstioによるセキュアなアプリケーション通信
アプリケーション間のエンドツーエンドの相互TLSを実現するために、アプリケーション通信のセキュリティ保護、相互TLS、およびIstioについて詳しく説明します。
ユーザーがサービスメッシュを採用する最大の理由の1つは、暗号化によって検証可能なIDに基づいて、相互TLS(mTLS)を使用してアプリケーション間の安全な通信を可能にすることです。このブログでは、アプリケーション間の安全な通信の要件、mTLSがこれらの要件をどのように実現し、満たしているか、そしてIstioを使用してアプリケーション間でmTLSを有効にするための簡単な手順について説明します。
アプリケーション間の通信を保護するには何が必要ですか?
最新のクラウドネイティブアプリケーションは、多くの場合、複数のKubernetesクラスタまたは仮想マシンに分散されています。新しいバージョンは頻繁にステージングされ、ユーザーのリクエストに基づいて迅速にスケールアップおよびスケールダウンできます。最新のアプリケーションは、コロケーションに依存しないことでリソース利用効率を高めていますが、複数のエントリポイントの増加によって攻撃対象領域が拡大するため、これらの分散アプリケーション間の通信にアクセス ポリシーを適用し、セキュリティを確保することが非常に重要です。これを無視することは、データの損失、データの盗難、データの偽造、または単純なミスハンドリングによる大きなビジネスリスクを招くことになります。
アプリケーション間の安全な通信のための一般的な主要な要件は次のとおりです。
ID
IDは、あらゆるセキュリティアーキテクチャの基本的な要素です。アプリケーションがデータを安全に送信する前に、アプリケーションの**ID**を確立する必要があります。この*IDの確立*プロセスは**ID検証**と呼ばれ、既知の信頼できる**認証局**がアプリケーションワークロードに対して1つ以上のチェックを実行して、それが主張どおりのものであることを確認することが含まれます。認証局が満足すると、ワークロードにIDが付与されます。
パスポートの発行を考えてみましょう。あなたは当局にパスポートを申請し、当局はおそらくあなたに、あなたがあなたであることを証明するいくつかの異なるID検証(出生証明書、現在の住所、医療記録など)を求めるでしょう。すべてのID検証を満たすと、(うまくいけば)IDドキュメントが付与されます。あなたは、発行元の認証局のすべてのID検証要件を満たしていることの証明として、そのIDドキュメントを他の人に渡すことができます。そして、彼らが発行元の認証局(およびIDドキュメント自体)を信頼している場合、彼らはそれがあなたについて述べていることを信頼することができます(または、信頼できる認証局に連絡してドキュメントを検証することができます)。
IDはどのような形式でもかまいませんが、他のIDドキュメントと同様に、ID検証が弱いほど偽造が容易になり、意思決定に使用する人にとってIDドキュメントの有用性が低下します。そのため、コンピューティングでは、暗号化によって検証可能なIDが非常に重要です。パスポートや運転免許証と同様に、検証可能な認証局によって署名されています。それ以下のものに依存するIDは、悪用が比較的容易なセキュリティ上の弱点です。
システムには、IDとこれらのネットワークプロパティ間のマッピングを追跡する分散IDキャッシュを備えたIPアドレスなどのネットワークプロパティから派生したIDがある場合がありますが、IPアドレスは異なるワークロードに再割り当てされる可能性があり、IDキャッシュは常に最新の状態に更新されるとは限らないため、これらのIDは暗号化によって検証可能なIDほど強力な保証を提供しません。
アプリケーションに暗号化によって検証可能なIDを使用することが望ましいです。これは、接続確立中にアプリケーションの暗号化によって検証可能なIDを交換することが、IPアドレスをIDにマッピングすることに依存するシステムよりも本質的に信頼性が高く安全であるためです。これらのシステムは、結果整合性とステールネスの問題を抱えた分散IDキャッシュに依存しており、自動化されたポッドのチャーン率が高いKubernetesでは構造的な弱点となる可能性があります。
機密性
アプリケーション間で送信されるデータの暗号化は非常に重要です。なぜなら、侵害が一般的で、コストがかかり、事実上些細な世界では、*安全な*内部環境または他のセキュリティ境界に完全に依存することは、もはや適切ではなくなって久しいからです。中間者攻撃を防ぐために、ソースとデスティネーションのペアには一意の暗号化チャネルが必要です。混乱した代理人問題を回避するために、強力なIDの一意性の保証が必要だからです。つまり、チャネルを暗号化するだけでは不十分です。ソースとデスティネーションだけがデータを復号化できるように、一意のソースとデスティネーションIDから直接派生した一意のキーを使用して暗号化する必要があります。さらに、セキュリティチームの要件に応じて、特定の暗号を選択するなどして、暗号化をカスタマイズする必要がある場合があります。
整合性
ソースからデスティネーションにネットワーク経由で送信される暗号化データは、送信後はソースとデスティネーション以外のIDによって変更することはできません。つまり、受信データは送信データと同じです。データ整合性がない場合、中間者攻撃者は、ソースとデスティネーション間の通信中に、データの一部または全部を変更する可能性があります。
アクセス ポリシーの適用
アプリケーションの所有者は、アプリケーションにアクセス ポリシーを適用し、それらを適切に、一貫して、明確に適用する必要があります。通信チャネルの両端にポリシーを適用するには、各端のアプリケーションIDが必要です。潜在的な通信チャネルの両端に対して、明確な来歴チェーンを持つ暗号化によって検証可能なIDが得られたら、誰が何と通信できるかについてのポリシーの適用を開始できます。クライアント(例:Webブラウザ)とサーバー(例:Webサーバー)間の通信を保護する広く使用されている暗号化プロトコルである標準TLSは、サーバー側のIDのみを実際に検証し、義務付けています。しかし、包括的なエンドツーエンドのポリシー適用のためには、クライアントとサーバーの両方に対して、信頼性が高く、検証可能で、明確なIDを持つことが重要です。これは、内部アプリケーションの一般的な要件です。たとえば、`frontend`アプリケーションだけがバックエンド`checkout`アプリケーションの**GET**メソッドを呼び出すことができ、`POST`または`DELETE`メソッドを呼び出すことはできないシナリオを考えてみましょう。または、特定のJWT発行者によって発行されたJWTトークンを持つアプリケーションだけが、`checkout`アプリケーションの`GET`メソッドを呼び出すことができるシナリオを考えてみましょう。両端で暗号化IDを活用することにより、強力なアクセス ポリシーが、検証可能な監査証跡とともに、正しく、安全に、確実に適用されるようにすることができます。
FIPS準拠
連邦情報処理標準(FIPS)は、米国国立標準技術研究所(NIST)によって開発された連邦コンピュータシステムの標準とガイドラインです。FIPS準拠はすべての人に必要というわけではありませんが、FIPS準拠とは、機密情報を保護するために米国政府によって確立された必要なすべてのセキュリティ要件を満たすことを意味します。連邦政府と協力する場合は必須です。サイバーセキュリティに関する米国政府が策定したガイドラインに従うために、民間部門の多くはこれらのFIPS標準を自主的に使用しています。
上記のセキュアなアプリケーションの要件(ID、機密性、整合性)を説明するために、`frontend`アプリケーションが`checkout`アプリケーションを呼び出す例を使用してみましょう。図中の**ID**は、政府発行のパスポート、写真付き身分証明書など、あらゆる種類の身分証明書と考えることができます。
mTLSは上記の要件をどのように満たしていますか?
TLS 1.3(執筆時点での最新のTLSバージョン)仕様の主な目標は、2つの通信ピア間に安全なチャネルを提供することです。TLSセキュアチャネルには、次のプロパティがあります。
- 認証:チャネルのサーバー側は常に認証され、クライアント側はオプションで認証されます。クライアントも認証されると、セキュアチャネルは相互TLSチャネルになります。
- 機密性:データは暗号化され、クライアントとサーバーのみが表示できます。アプリケーション層のトラフィックを確実に保護するために、ソースとデスティネーションのIDドキュメントに明確に暗号化的にバインドされたキーを使用してデータを暗号化する必要があります。
- 整合性:チャネル経由で送信されたデータは、検出されずに変更することはできません。これは、特定のセッションのデータの暗号化と復号化のキーをソースとデスティネーションだけが持っているという事実によって保証されます。
mTLSの内部
暗号化によって検証可能なIDがチャネルのセキュリティ保護とアクセス ポリシーの適用のサポートに不可欠であり、mTLSがチャネルの両端で暗号化によって検証可能なIDを使用するための非常に重要な保証を義務付ける戦闘テスト済みのプロトコルであることを確立しました。それでは、mTLSプロトコルが実際にどのように機能するかについて詳しく見ていきましょう。
ハンドシェイクプロトコル
ハンドシェイクプロトコルは、通信ピアを認証し、暗号化モードとパラメータをネゴシエートし、共有キー素材を確立します。言い換えれば、ハンドシェイクの役割は、通信ピアのIDを検証し、セッションキーをネゴシエートすることです。これにより、残りの接続はセッションキーに基づいて暗号化できます。アプリケーションがmTLS接続を行うと、サーバーとクライアントは暗号スイートをネゴシエートします。暗号スイートは、アプリケーションが接続の残りの部分で使用する暗号化アルゴリズムを決定し、アプリケーションは使用する暗号セッションキーもネゴシエートします。ハンドシェイク全体は、改ざんに耐えるように設計されています。ソースまたはデスティネーションと同じ一意の、暗号化によって検証可能なIDドキュメントを持っていないエンティティによる干渉は拒否されます。このため、通信ピアがアプリケーションデータの処理を続行する前に、ハンドシェイク全体をチェックして整合性を検証することが重要です。
ハンドシェイクは、TLS 1.3仕様のハンドシェイクプロトコルの概要に従って、3つのフェーズで構成されていると考えることができます。`frontend`アプリケーションがバックエンド`checkout`アプリケーションを呼び出す例をもう一度使用してみましょう。
- フェーズ1:`frontend`と`checkout`は、残りのハンドシェイクとトラフィックデータを保護するために使用できる暗号化パラメータと暗号化キーをネゴシエートします。
- フェーズ2:このフェーズ以降のすべてが暗号化されます。このフェーズでは、`frontend`と`checkout`は、他のハンドシェイクパラメータと、クライアントも認証されるかどうか(つまり、mTLS)を確立します。
- フェーズ3:`frontend`は、暗号化によって検証可能なIDを介して`checkout`を認証します(そして、mTLSでは、`checkout`は同じ方法で`frontend`を認証します)。
TLS 1.2以降、ハンドシェイクに関していくつかの大きな違いがあります。詳細については、TLS 1.3仕様を参照してください。
- すべてのハンドシェイクメッセージ(フェーズ2と3)は、**フェーズ1でネゴシエートされた暗号化キーを使用して**暗号化されます。
- レガシー対称暗号化アルゴリズムは削除されました。
- 接続設定時のラウンドトリップを削減するゼロラウンドトリップ時間(0-RTT)モードが追加されました。
レコードプロトコル
ハンドシェイクフェーズでTLSプロトコルバージョン、セッションキー、およびHMACのネゴシエーションが完了すると、ピアはレコードプロトコルによってチャンク化された暗号化データを安全に交換できます。トラフィックの機密性と整合性を確保するために、ハンドシェイクからネゴシエートされたまったく同じパラメータを使用してトラフィックを暗号化することが重要です(そして仕様の一部として必須です)。
TLS 1.3仕様の2つのプロトコルをまとめて、frontend
アプリケーションとcheckout
アプリケーションを使用して、以下のようにフローを説明します。
frontend
とcheckout
のID証明書は誰が発行するのでしょうか? これらは一般的に、独自のルート証明書を持つ認証局(CA)、またはルートCAの中間証明書を使用するCAによって発行されます。ルート証明書は基本的にルートCAを識別する公開鍵証明書であり、おそらくあなたの組織には既に存在しています。ルート証明書は、独自のルート署名付きID証明書に加えて、frontend
(またはcheckout
)に配布されます。これは、日常の基本的な公開鍵基盤(PKI)の仕組みです。CAは、エンティティのIDドキュメントを検証し、証明書の形式で偽造不可能なIDドキュメントを付与する責任を負います。
CAと中間CAは、大規模な分散型IPおよびIDマップキャッシュでは不可能な方法で、高可用性と安定した永続的に検証可能なID保証を維持する構造的な方法で、IDの真実のソースとして信頼できます。 frontend
とcheckout
のID証明書が同じルート証明書によって発行されている場合、frontend
とcheckout
は、実行されているクラスタ、ノード、またはスケールに関係なく、ピアIDを一貫して確実に検証できます。
mTLSがどのように暗号化ID、機密性、および整合性を提供するかについて学習しました。数千以上のアプリケーションに複数のクラスタで成長した場合のスケーラビリティはどうでしょうか? 複数のクラスタに単一のルート証明書を確立すると、アプリケーションが別のクラスタから接続要求を受信した場合でも、ルート証明書によって信頼されている限り、システムは気にする必要がありません。システムは、接続上のIDが暗号で検証されていることを認識しています。 アプリケーションポッドのIPが変更された場合、または別のクラスタまたはネットワークに再デプロイされた場合、アプリケーション(またはその代わりに動作するコンポーネント)は、CAによって作成された信頼できる証明書を使用して、宛先にトラフィックを生成するだけです。 500以上のネットワークホップでも、直接でもかまいません。アプリケーションのアクセスポリシーは、トポロジに関係なく、IDキャッシュを追跡してどのIPアドレスがどのアプリケーションポッドにマップされているかを計算する必要なく、同じ方法で適用されます。
FIPSコンプライアンスはどうでしょうか? TLS 1.3仕様によると、TLS準拠のアプリケーションはTLS_AES_128_GCM_SHA256
暗号スイートを実装する必要があり、TLS_AES_256_GCM_SHA384
の実装も推奨されています。どちらもNISTによるTLSのガイドラインにも含まれています。 RSAまたはECDSAサーバー証明書も、TLS 1.3仕様とNISTのTLSガイドラインの両方で推奨されています。 mTLS接続にmTLSとFIPS 140-2または140-3準拠の暗号化モジュールを使用する限り、FIPS 140-2または140-3検証の正しい道を進んでいます。
何が問題になる可能性があるか
TLS 1.3仕様で規定されているとおりにmTLSを正確に実装することが重要です。 TLS仕様に従って適切なmTLSを使用しないと、検出されずに発生する可能性のある問題がいくつかあります。
接続の途中で誰かが暗号化データを密かにキャプチャした場合はどうなりますか?
接続がTLS仕様で概説されているハンドシェイクおよびレコードプロトコルに正確に従っていない場合、たとえば、接続がハンドシェイクプロトコルに従っているが、レコードプロトコルでハンドシェイクからネゴシエートされたセッションキーとパラメータを使用していない場合、ハンドシェイクがレコードプロトコルに関連付けられていない可能性があり、ハンドシェイクとレコードプロトコルの間でIDが異なる可能性があります。 TLSでは、ハンドシェイクとレコードプロトコルが同じ接続を共有する必要があります。これは、それらを分離すると、中間者攻撃の攻撃対象領域が増加するためです。
mTLS接続は、ハンドシェイクの開始から終了まで、一貫したエンドツーエンドのセキュリティを備えています。暗号化データは、証明書の公開鍵を使用してネゴシエートされたセッションキーで暗号化されます。送信元と宛先のみが秘密鍵を使用してデータを復号化できます。言い換えれば、秘密鍵を持つ証明書の所有者だけがデータを復号化できます。ハッカーが証明書の秘密鍵を制御していない限り、中間者攻撃を正常に実行するためにmTLS接続を操作する方法はありません。
送信元または宛先のIDが暗号で保護されていない場合はどうなりますか?
IDがIPアドレスなどのネットワークプロパティに基づいている場合、他のポッドに再割り当てされる可能性があり、IDを暗号化技術を使用して検証できません。このタイプのIDは暗号化IDに基づいていないため、システムにはIDキャッシュがあり、ID、ポッドのネットワークラベル、対応するIPアドレス、およびポッドがデプロイされているKubernetesノード情報の マッピングを追跡している可能性があります。IDキャッシュを使用すると、ポッドのIPアドレスが再利用され、IDが誤って認識される可能性があり、IDキャッシュが短期間同期しなくなった場合にポリシーが正しく適用されません。たとえば、ピア間の接続に暗号化IDがない場合、システムは古くなっているか不完全な可能性のあるIDキャッシュからIDを取得する必要があります。
IDをワークロードIPにマップするこれらのIDキャッシュは、ACID(原子性、一貫性、分離性、耐久性)ではなく、強力な保証を持つものにセキュリティシステムを適用することをお勧めします。次のプロパティと質問を検討してください。
- 古さ:ピアは、キャッシュ内のエントリが最新であることをどのように確認できますか?
- 不完全性:キャッシュミスがあり、システムが接続を閉じることができない場合、キャッシュの同期だけが失敗している場合、ネットワークは不安定になりますか?
- IPがない場合はどうなりますか? たとえば、AWS LambdaサービスにはデフォルトでパブリックIPがありません。
- 非トランザクション:IDを2回読み取ると、同じ値が表示されますか? アクセスポリシーまたは監査の実装で注意しないと、これが実際の問題を引き起こす可能性があります。
- 誰がガード自身をガードしますか? CAのようにキャッシュを保護するための確立されたプラクティスはありますか? キャッシュが改ざんされていないという証拠はありますか? CAではない複雑なインフラストラクチャのセキュリティについて推論(および監査)せざるを得ませんか?
上記のいくつかは他のものよりも悪いです。フェイルクローズドの原則を適用できますが、それでも上記のすべてが解決されるわけではありません。
IDは、承認ポリシーなどのアクセスポリシーの適用にも使用され、これらのアクセスポリシーは、システムがアクセスを許可または拒否するための迅速な決定を下さなければならないリクエストパスにあります。 IDが誤って認識されるたびに、アクセスポリシーが検出または監査されずにバイパスされる可能性があります。たとえば、IDキャッシュには、checkout
ポッドの以前に割り当てられたIPアドレスがcheckout
IDの1つとして関連付けられている場合があります。 checkout
ポッドがリサイクルされ、同じIPアドレスがfrontend
ポッドの1つに割り当てられた場合、そのfrontend
ポッドは、キャッシュが更新される前にcheckout
のIDを持つ可能性があり、誤ったアクセスポリシーが適用される可能性があります。
次の大規模マルチクラスタデプロイメントを想定して、IDキャッシュの古さの問題を説明しましょう。
- 各クラスタにノードが100個あり、ノードごとにポッドが20個ある100個のクラスタ。ポッドの総数は200,000です。
- ポッドの0.25%は常に(ロールアウト、再起動、リカバリ、ノードチャーンなど)チャーンされており、各チャーンは10秒のウィンドウです。
- チャーンされている500個のポッドは、10秒ごとに10,000個のノード(キャッシュ)に分散されます。
- キャッシュシンクロナイザーが停止した場合、5分後にシステムの失効率はどのくらいになりますか? - 7.5%にもなる可能性があります!
上記は、キャッシュシンクロナイザーが定常状態にあると想定しています。キャッシュシンクロナイザーにブラウンアウトが発生した場合、ヘルスチェックに影響を与え、チャーン率が上がり、カスケード型の不安定性につながります。
CAは、他の誰かを提示し、CAをだまして証明書を発行させると主張する攻撃者によって侵害される可能性もあります。その後、攻撃者はその証明書を使用して他のピアと通信できます。これは、証明書の失効によって証明書を失効させ、無効にすることで状況を改善できる場所です。そうでない場合、攻撃者は有効期限が切れるまで侵害された証明書を悪用する可能性があります。ルート証明書の秘密鍵をオフラインで保管されているHSMに保管し、ワークロード証明書の署名に中間証明書を使用することが重要です。 CAがブラウンアウトになったり、5分間停止したりした場合、新しいワークロード証明書や更新されたワークロード証明書を取得することはできませんが、以前に発行された有効な証明書は、ワークロードに強力なID保証を提供し続けます。発行の信頼性を高めるために、中間CAを異なるゾーンとリージョンにデプロイできます。
IstioでのmTLS
mTLSを有効にする
Istioでメッシュ内アプリケーションのmTLSを有効にするのは非常に簡単です。必要なのは、アプリケーションをメッシュに追加することだけです。これは、サイドカーインジェクションまたはアンビエントのいずれかの名前空間にラベルを付けることによって行うことができます。サイドカーの場合、サイドカーをアプリケーションポッドに挿入するには、ロールアウトの再起動が必要になります。
暗号化ID
Kubernetes環境では、Istioは、サービスアカウントに基づいてアプリケーションのIDを作成します。 アプリケーションをメッシュに追加した後、ID証明書がメッシュ内の各アプリケーションポッドに提供されます。
デフォルトでは、ポッドのID証明書の有効期限は24時間で、Istioは12時間ごとにポッドID証明書をローテーションします。そのため、侵害(たとえば、CAの侵害やポッドの秘密鍵の盗難)が発生した場合、侵害された証明書は証明書の有効期限が切れるまでの非常に限られた期間のみ機能し、したがって、発生する可能性のある損害を制限します。
厳密なmTLSを適用する
デフォルトのmTLS動作は、可能な場合は常にmTLSですが、厳密には適用されません。 アプリケーションがmTLSトラフィックのみを受け入れるように厳密に適用するには、IstioのPeerAuthenticationポリシー(メッシュ全体、名前空間ごと、またはワークロードごと)を使用できます。 さらに、IstioのAuthorizationPolicyを適用して、ワークロードへのアクセスを制御することもできます。
TLSバージョン
TLSバージョン1.3は、Envoyのデフォルトの暗号スイート(たとえば、Istio 1.19.0のTLS_AES_256_GCM_SHA384
)を使用したメッシュ内アプリケーション通信のIstioのデフォルトです。古いTLSバージョンが必要な場合は、ワークロードのメッシュ全体の最小TLSプロトコルバージョンを構成できます。
まとめ
インターネットエンジニアリングタスクフォース(IETF)によって策定されたTLSプロトコルは、最も広くレビューされ、専門家によって承認され、実戦でテストされたデータセキュリティプロトコルの1つです。TLSは世界中で広く使用されています。安全なWebサイトにアクセスするたびに、TLSを使用して信頼できるサイトに安全に接続されていることを示す南京錠アイコンが表示されるため、安心して買い物ができます。TLS 1.3プロトコルは、エンドツーエンドの認証、機密性、および整合性を備えて設計されており、アプリケーションのIDと通信が侵害されないようにし、中間者攻撃を防ぎます。それを実現するため(そして標準準拠のTLSと見なされるため)には、通信ピアを適切に認証するだけでなく、ハンドシェイクから確立されたキーを使用してトラフィックを暗号化することも重要です。これで、mTLSが安全なアプリケーション通信要件(暗号化ID、機密性、整合性、アクセス ポリシーの適用)を満たすのに優れていることがわかったので、Istioを使用して、わずかな構成で、メッシュ内アプリケーション通信をmTLSにアップグレードできます。
ブログのレビューと更新の提案に多大な時間を費やしてくださったLouis Ryan、Ben Leggett、John Howard、Christian Posta、Justin Pettitに深く感謝いたします。