Amazon Web Services ブログ

信頼は相互に: Amazon CloudFront が mTLS をサポート

本投稿は、 Sagar Desarda と Yutaka Oka、Tomoya Kudo による記事 「Trust goes both ways: Amazon CloudFront now supports viewer mTLS」を翻訳したものです。

本日より、Amazon CloudFront はエンドユーザーから CloudFront への相互 TLS 認証 (mTLS) をサポートし、高度に分散された機密性の高いアプリケーションのセキュリティを強化します。現代のアーキテクチャでは、クライアント・サーバー間の通信を保護するには標準的な TLS 以上のものが必要であり、mTLS は相互の認証を強制することでこのモデルを拡張します。これにより、データが交換される前にクライアントとサーバーの両方が互いの身元を検証することが保証されます。さらに、この新機能はプロトコルレベルできめ細かなアクセス制御と ID 検証を強制し、規制環境における監査とコンプライアンスを合理化します。

CloudFront を活用したアプリケーションにおける mTLS のメリット

mTLS は、サーバーとクライアント両者がデジタル証明書を提示して検証することを要求することで、セキュリティのレイヤーを追加し、相互の認証を実現します。その結果、mTLS は現在、ID 保証、暗号化通信、規制コンプライアンスがビジネスの信頼の基盤となる業界全体で広く採用されています。暗号化による ID 証明を提供し、認証情報ベースの攻撃を防ぎ、分散システム全体でゼロトラストの原則を強制します。主な業界のユースケースには以下が含まれます:

  • 金融サービス: 銀行、決済ゲートウェイ、信頼できる第三者機関 (TTP) との API トランザクションを保護するために、PCI DSS や PSD2 などのフレームワークによって一定のセキュリティ要件が義務付けられています。金融取引プラットフォームは、市場データや取引執行エンドポイントへのアクセスを許可する前に、mTLS を使用してブローカーやパートナー機関を認証することで、セキュリティを強化できます。
  • IoT および接続デバイス: コネクテッドカー、センサーなどのデバイスがクラウドにテレメトリデータを送信する前に認証し、なりすましデバイスやデータ注入から保護します。
  • エンタープライズアプリケーション: 社内のマイクロサービス間、または企業システムと HR、給与、分析などの SaaS プラットフォーム間で認証と暗号化を強制し、ラテラルムーブメントや不正なデータアクセスのリスクを軽減します。
  • ヘルスケア: EHR システム、医療機器、および機密の患者データを交換する API を認証することにより、HIPAA に準拠して保護対象医療情報(PHI)を保護します。
  • 通信およびメディア: エッジノードとオリジンサーバー間の制御およびコンテンツ配信チャネルを保護し、信頼できるインフラストラクチャコンポーネントのみがライブまたはオンデマンドのメディアトラフィックを交換できるようにします。

これらの多様で厳格なセキュリティニーズを満たすため、CloudFront は mTLS をサポートしました。組織はこれを使用して、リクエストがオリジンに到達する前に、エッジで直接アプリケーションやデバイス、サービスなどのクライアントを認証できます。この機能は、mTLS 保護をサービス間トラフィックからユーザー向けシナリオに拡張し、企業が最小限のレイテンシでグローバルにクライアント証明書検証を強制できるようにします。CloudFront mTLS は CloudFront Trust Store とシームレスに統合されるため、お客様は AWS Private Certificate Authority を使用するか、独自の CA を利用し、きめ細かな認証ポリシーを実装して証明書のプロビジョニングを自動化し、運用の複雑さを追加することなくコンプライアンスを達成できます。

はじめに

CloudFront ディストリビューションの mTLS 認証を実装するには、まずプライベート認証局を設定し、クライアント証明書を作成します。設定には、ルート認証局と中間認証局の公開鍵証明書を PEM ファイル形式で準備する必要があります。そして、この証明書ファイルを Amazon S3 バケットにアップロードする必要があります。これは認証プロセスで使用されるトラストストアのソースとして機能します。

この例では、OpenSSL を使用してプライベート認証局及びクライアント証明書を作成する方法を示します。または、フルマネージドサービスである AWS Certificate Manager Private CA を使用してこのプロセスを効率化することもできます。詳細については、AWS Private CA のドキュメントを確認してください。

1.プライベート CA の秘密鍵と証明書を生成します。

# CA 秘密鍵を生成
openssl genrsa -out Root_CA.key 4096

# CA 証明書を作成
openssl req -new -x509 -days 3650 -key Root_CA.key -out Root_CA.pem

1-a. 証明書作成プロセス中に、証明書の識別名(DN)フィールドの情報を提供するよう求められます。

1-b. オプションとして、ルートCAによって署名された中間認証局を作成できます。CloudFront は、mTLS 認証用のルート証明書を含む、最大 4 階層の証明書チェーンをサポートします。ルート CA と中間 CA 証明書を単一の PEM バンドル(CA バンドル)に結合する必要があります。cat コマンドを使用して CA バンドルファイルを作成します。

# CA バンドルを作成
cat Root_CA.pem Intermediate_CA.pem > Trust_store_bundle.pem

2. CA 階層を確立した後、クライアント証明書の秘密鍵と証明書署名要求(CSR)を生成します。

# クライアント証明書の秘密鍵を生成
openssl genrsa -out my_client.key 2048

# CSR を作成
openssl req -new -key my_client.key -out my_client.csr

2-a. クライアント証明書のサブジェクト名、地域、組織、組織単位のプロパティを入力します。オプションのパスワードチャレンジは空のままにしてください。

3. 以前に作成したルート CA を使用してクライアント証明書に署名します。

# ルート CA でクライアント CSR に署名
openssl x509 -req \
-in my_client.csr \
-CA Root_CA.pem \
-CAkey Root_CA.key \
-set_serial 01 \
-out my_client.pem \
-days 3650 \
-sha256

4. これらの手順を完了すると、ディレクトリに次のファイルが存在するはずです。

ファイル 説明
Root_CA.key ルート CA プライベートキー
Root_CA.pem または Trust_store_bundle.pem CA バンドル
my_client.csr クライアント証明書の署名リクエスト
my_client.key クライアント証明書のプライベートキー
my_client.pem クライアント証明書

トラストストアの設定

このセクションでは、トラストストアの設定方法について説明します。

前提条件
認証局からのルート CA 証明書または CA バンドル(PEM ファイル)を S3 バケットにアップロードしておく必要があります。(前のセクションを完了した場合は、S3 バケットにアップロードする必要がある Root_CA.pem ファイルをすでに作成しているはずです。)

1. CloudFront コンソールで、左側のメニューの Security の下にある Trust Store を選択します。Create trust store を選択します。

図1: CloudFront トラストストア

2. このページで S3 バケットの場所を指定します。Create trust store を押下します。CA バンドルは読み取られ、CloudFront トラストストアに保存されます

図2: トラストストアの作成

3. トラストストアが作成されると、コンソールはトラストストアの詳細ページに移動します。このページから、Associate to distribution ボタンを押下して、トラストストアをディストリビューションに関連付けることができます。

図3: トラストストア作成成功

4. このページで、トラストストアを関連付けるディストリビューションを選択できます。

図4: トラストストアを Amazon CloudFront ディストリビューションに関連付け

または、次のセクション(図 5 ) のディストリビューション設定からトラストストアを関連付けることもできます。

ディストリビューションの設定

前提条件

対象の CloudFront ディストリビューションのビューワープロトコルが HTTPS only になっている必要があります。

1. ビューワー mTLS 認証を有効にするには、ディストリビューション設定に移動し、Viewer mutual authentication (mTLS) 設定を On に切り替えます。

図5: CloudFront ディストリビューションで mTLS を有効にする

2. ユースケースに適した mTLS パラメータを選択します。

Mode

CloudFrontの mTLS は、すべてのクライアントが有効な証明書を要求する Required モードと、同じディストリビューションで mTLS クライアントと非 mTLS クライアントの両方を受け入れて、無効な証明書は拒否する形の混合した認証を同時に可能にする Optional モードを選択可能です。

Trust store
ビューワー mTLS 認証を有効にした後、以前に作成したトラストストアを選択して、ディストリビューションに関連付けます。

以下、2つのオプションパラメータがあり、両方ともデフォルトでは False です:

Ignore certificate expiration date: これが true の場合、クライアント証明書チェーン内の 1 つ以上の証明書が X509 の期限の検証をパスしない場合(現在時刻が NotBefore より前または NotAfter より後)でも、CloudFront はビューワーからの接続を受け入れます。X509 証明書の他の要素の検証は引き続き適用されます。クライアント証明書は、CA バンドル内の信頼できる証明書チェーンで署名されている必要があります。

Advertise trust store CA names: これが true の場合、CloudFront はディストリビューションが受け入れる認証局名のリストをビューワーにアドバタイズします。これは、トラストストアにある証明書識別名(DN)のリストです。

Connection function(オプション)
Connection function は、ビューワー mTLS のオプションの拡張機能です。mTLS ハンドシェイクプロセスの一部としてカスタム検証を実行できるため、クラアイアンと証明書情報をもとに、接続を許可、拒否、またはログに記録できます。後のセクションで、CloudFrontディストリビューション内で Connection function を使用する方法の例を示します。

CloudFront ビューワー証明書ヘッダー

CloudFront は、クライアント証明書から情報を抽出し、HTTP ヘッダーとしてビューワーリクエストに追加できます。これらのヘッダーをキャッシュキーの一部として使用したり、オリジンサーバーに転送することができます。また、CloudFront Functionsまたは Lambda@Edge でビューワーリクエストを処理する際に、これらのヘッダーを読み取ることもできます。

利用可能な CloudFront ビューワー証明書ヘッダーは次のとおりです:

  • CloudFront-Viewer-Cert-Serial-Number (証明書のシリアル番号)
  • CloudFront-Viewer-Cert-Issuer (証明書発行者の識別名)
  • CloudFront-Viewer-Cert-Subject (サブジェクト識別名)
  • CloudFront-Viewer-Cert-Validity (証明書の有効期限 – 開始と終了の ISO8601 形式の日付)
  • CloudFront-Viewer-Cert-PEM (URL エンコードされた PEM 形式のリーフ証明書)
  • CloudFront-Viewer-Cert-Present(証明書が存在する場合 1、存在しない場合 0、 Require mode では常に1)
  • CloudFront-Viewer-Cert-SHA256(クライアント証明書の SHA256 ハッシュ)

詳細については、Viewer mTLS headers for cache policies and forwarded to origin を参照してください。

mTLS 認証のテスト

mTLS 設定をテストするには、curl でクライアント証明書を使用します。

curl --key my_client.key \
--cert my_client.pem \
https://dxxxxxxxxxxxxx.cloudfront.net

  • –key:クライアントの秘密鍵ファイルを指定します。
  • –cert:クライアントの証明書ファイルを指定します。
  • dxxxxxxxxxxxxx.cloudfront.netを、mTLS が有効になっている実際の CloudFront ディストリビューションドメイン名に置き換えます。

以下は、成功シナリオと拒否シナリオの例です:

1. 認証成功の例(有効なクライアント証明書を使用):

HTTP/2 200
content-type: text/html; charset=UTF-8
content-length:xxx
date: xxx
...

2. 認証拒否の例(無効または欠落している証明書を使用):

* Request completely sent off
* Closing connection
* Recv failure: Connection reset by peer
* Send failure: Broken pipe
curl: (16) Recv failure: Connection reset by peer

次の図は CloudFront での mTLS 認証の全体的なプロセスを示しています。

図6 : CloudFront の mTLS 認証のプロセス

  1. CA バンドルを S3 バケットにアップロードします。
  2. トラストストアを作成し、CA 証明書バンドルへの Amazon S3 パスを提供します。
  3. クライアントが CloudFrontとの TLS セッションを開始します。TLS ハンドシェイク中に、クライアントは TLS 証明書を提示します。
  4. CloudFrontはクライアント証明書を検証し、mTLS セッションが確立されます。
    4-a. オプションで、TLS ハンドシェイクをトリガーに Connection function を実行できます。クライアント証明書から情報を抽出し、カスタムロジックに基づいて無効な証明書を持つクライアントからの接続を拒否できます。
  5. オプションで、ビューワーリクエストエッジ関数をトリガーして、CloudFront functions を実行できます。 cloudfront-viewer-cert ヘッダーを通じてクライアント証明書から情報を抽出できます。
  6. オリジンリクエストポリシーで cloudfront-viewer-cert ヘッダーを有効にすると、CloudFront はクライアント証明書の情報をオリジンサーバーに転送します。ヘッダーは、設定されたオリジンリクエストポリシーに従って送信されます。

CloudFront は、証明書ベースの検証を実装するために、Connection Function( TLS ハンドシェイク中に実行)とビューワーリクエストエッジ関数(ハンドシェイク完了後に実行)を使って、カスタム認証とセキュリティ制御を可能にします。詳細については、CloudFront Viewer mTLS のドキュメントを参照してください。

Connection Logs による監視

CloudFrontは、TLS ハンドシェイクに関する詳細な情報をキャプチャする Connection Logs を生成します。

Connection Logs の使用例:

  • mTLS 対応ディストリビューションの監視とトラブルシューティング
  • 成功した mTLS ハンドシェイクとクライアント証明書の追跡
  • 失敗した mTLS ハンドシェイクの可視化

さらに、Connection Functions を使用すると、Connection Logs にカスタムログデータを追加できます。カスタムデータを追加するには、Connection Functions の接続オブジェクトで使用可能な logCustomData ヘルパーメソッドを使用します。connectionLogCustomData フィールドに最大 800 バイトの有効な UTF-8 文字列をログに記録できます。

既存のアクセスログと同様に、CloudFront は CloudWatch vended logs を通じてConnection Logs を配信し、次の機能を提供します:

  • Connection Logs をCloudWatch Logs、Amazon Data Firehose、Amazon S3に送信
  • JSON、w3c、Parquet(Amazon S3のみ)などの他の出力ログファイル形式を選択可能

各 mTLS 接続は、CloudFront ログタイプ(Connection ログ、Standard ログ、Realtime ログ)全体で記録される一意の識別子 connectionId を生成します。この統一された識別子を使用して、Connection logs とアクセスログ全体でアクセスパターンを調査および関連付けることができます。例えば、connectionId を使用して特定のリクエストをトレースすることで、トラブルシューティングと分析がより効率的になります。詳細については、Observability using connection logs を参照してください。

Connection Functions と CloudFront KeyValueStore を使用した証明書失効検証

mTLS 認証では、証明書が有効期間内であっても、盗難や侵害により証明書が失効する可能性があります。CloudFront Connection Functions とCloudFront KeyValueStore を組み合わせることで、リアルタイムの証明書失効チェックを実装できます。

CloudFront KeyValueStore の準備

まず、失効した証明書のシリアル番号を保存する KeyValueStore を作成します。

1. CloudFrontコンソールで、左側のメニューの Functions を選択します。次に、上部の KeyValueStores タブを開き、Create KeyValueStore を選択します。

図7: KeyValueStore の作成

2. KeyValueStore の名前を入力し、Create を押下します。必要に応じて Amazon S3 からデータをインポートすることもできます。
3. 作成した KeyValueStore を選択し、キー値ペアの下の編集を選択して、失効した証明書のシリアル番号を入力します。

図8: シリアル番号の入力

4. Save changes を押下してエントリを保存します。

Connection Function の作成

クライアント証明書のシリアル番号をチェックする Connection function を作成します。

1. CloudFront コンソールで、左側のメニューの Functions を選択します。次に、上部の Connection Functions タブを選択し、Create connection function を選択します。
2. 関数の名前を入力し、Create を押下します。

図9: Connection function の作成

3. Associated KeyValueStore の下で、Associate existing KeyValueStore を選択し、先ほど作成した KeyValueStore を関連付けます。

図10: KeyValueStore の関連づけ

4. 次のコードを Function Code に貼り付け、Save Change ボタンを押下します。


import cf from 'cloudfront';

async function connectionHandler(connection) {
    const kvsHandle = cf.kvs();
    
    // 証明書のシリアル番号を取得
    const serialNumber = connection.clientCertificate.certificates.leaf.serialNumber.replace(/:/g, "");
    
    // KVS で失効ステータスをチェック
    const isRevoked = await kvsHandle.exists(serialNumber);
    
    if (isRevoked) {
        // 失効した証明書の接続を拒否
        connection.logCustomData(`Revoked certificate: ${serialNumber}`);
        console.log(`Denying connection for revoked certificate: ${serialNumber}`);
        return connection.deny();
    }
    
    // 有効な証明書の接続を許可
    connection.logCustomData(`Valid certificate: ${serialNumber}`);
    console.log(`Allowing connection for valid certificate: ${serialNumber}`);
    return connection.allow();
}

5. Test タブで、作成した関数をテストできます。証明書情報と KeyValueStore に追加したシリアル番号を入力します。次に、Test function を選択して、証明書が適切に失効することを確認します。

図11: 関数のテスト

6. Publish タブで、Publish connection function を押下します。
7. Associated distributions の下で、Add association を選択し、関数を関連付けるディストリビューションを選択して、Associate を押下します。

テストと検証

失効した証明書でテストして、接続が拒否されることを確認します:

# 失効した証明書でテスト(接続は拒否されるはずです)
# 注:実際のCloudFrontディストリビューションドメインに置き換えてください
curl --key revoked_client.key \
--cert revoked_client.pem \
https://dxxxxxxxxxxxxx.cloudfront.net

# 有効な証明書でテスト(接続は許可されるはずです)
curl --key valid_client.key \
--cert valid_client.pem \
https://dxxxxxxxxxxxxx.cloudfront.net

まとめ

インターネット上のセキュリティは常に信頼にかかっています。mTLS を使用することで、すべての接続の前に相互に検証されます。Amazon CloudFront を通じてビューワー mTLS を使用して、グローバル規模でデプロイおよび運用できるようになりました。速度を落とすことなく、アプリケーションと通信できるユーザーまたはデバイスを正確に決定できます。

AWSドキュメントをチェックして、エッジに mTLS 認証を導入する方法を確認し、ぜひ CloudFront ディストリビューションで mTLS をご利用ください。

著者について

Sagar-Desarda

Sagar Desarda

Sagar Desardaは、データ、分析、Gen AI ISV 向けのテクニカルアカウントマネージャー(TAM)およびビジネス開発(BD)組織の責任者です。Sagarのチームは、お客様と協力して AWS アーキテクチャを最適化し、ビジネスクリティカルなアプリケーションのシームレスな運用を確保し、採用を加速し、北米全体で市場投入の成功を推進します。さらに、Sagar は Edge Networking Services Specialist US チームのリーダーとして、新規ビジネスの成長を推進し、技術的なエンゲージメントを促進し、顧客向けの出版物を執筆しています。

Tomoya Kudo

Tomoya Kudo

Tomoya Kudo は、東京を拠点とするプロトタイピングエンジニアです。彼の主な焦点は、ベストプラクティスに基づいたソリューションを提案し、プロジェクトの成功を確実にするためのプロトタイプを開発することで、お客様の成功を支援することです。

Yutaka Oka

Yutaka Oka

Yutaka Oka は、東京を拠点とするシニアエッジスペシャリストソリューションアーキテクトです。彼の主な焦点は、AWS Edge Services を使用してコンテンツ配信を最適化および保護することでお客様を支援することです。