re:Invent 2024: StubHubのAWS Private CAを活用したPKI再構築事例
はじめに
海外の様々な講演を日本語記事に書き起こすことで、隠れた良質な情報をもっと身近なものに。そんなコンセプトで進める本企画で今回取り上げるプレゼンテーションはこちら!
📖 AWS re:Invent 2024 - Reduce costs and operational overhead by building enterprise-scale PKI (SEC341)
この動画では、AWS上でEnterprise規模のPKIを構築することによるコスト削減と運用効率化について解説しています。AWS Certificate Manager(ACM)とAWS Private CAの基本的な機能の違いから、StubHubがAWS上でPKIを再構築した実例を詳しく紹介しています。特に、AWS Private CAを活用したActive Directory、SCEP、Kubernetesなど各種コネクタの実装方法や、Root CAを専用アカウントに配置する重要性、世代別の命名規則の採用など、具体的なベストプラクティスが示されています。また、証明書の有効期間設定や階層構造のシンプル化、AWS Resource Access Managerを用いたアカウント間でのCA共有など、運用面での実践的な知見も共有されています。
※ 画像をクリックすると、動画中の該当シーンに遷移します。
re:Invent 2024関連の書き起こし記事については、こちらのSpreadsheet に情報をまとめています。合わせてご確認ください!
本編
AWS上でのEnterprise規模PKI構築:セッション概要と参加者分析
みなさん、ようこそ。本日は SEC 341 として、AWS上でEnterprise規模のPKIを構築することによるコスト削減と運用オーバーヘッドの削減についてお話しします。本日は Anthony Scheller さんにもご参加いただいています。彼の自己紹介は後ほどお願いするとして、まず私の方から。Zach Miller と申します。シカゴを拠点とする Amazon Web Services の Principal Security SA で、Amazonには約5年在籍しています。では Tony、お願いします。Anthony Scheller です。現在、StubHubのSecurity Engineerとして、カリフォルニア州サンタモニカを拠点に働いています。
では、本日の内容についてご説明させていただきます。まず基本的な内容として、AWS Certificate Manager(ACM)とAWS Private CAについて説明します。皆様の多くはPKIの概念をご存知かと思いますが、CAの階層構造や失効など、基本的な部分について改めて確認し、全員が同じ理解を持てるようにしたいと思います。次に、StubHubのPKIに関するAWSでの取り組みについて、なぜAWS上でPKIを再構築することにしたのか、その目的は何だったのか、そして最終的にどのようなソリューションになったのかを見ていきます。そして最も重要な点として、この過程で得られた教訓と、それらの経験からどのように学ぶことができるかについて説明します。
また、AWS Private CAの運用に関する推奨プラクティスやAWSのビジョンについても説明します。これには、Active Directory証明書やSCEP(Simple Certificate Enrollment Protocol)を使用したモバイルデバイス向けの証明書など、さまざまなユースケースを実現するために構築しているコネクタについても含まれます。最後に、AWS Private CAを使用したPKI運用全般のベストプラクティスについてお話しします。始める前に、手を挙げていただきたいのですが - エンジニアの方はどのくらいいらっしゃいますか?素晴らしいですね。コンプライアンス担当者やそれに関連する役職の方は?1、2名ですか?プロジェクトマネージャーなど、非技術職の方は?素晴らしい。そして、PKIについてある程度ご存知の方は?ほとんどの方ですね。では、基本的な内容は最小限に抑えていきましょう。
AWS Certificate ManagerとPrivate CAの基本概念
Private CA、というよりも証明書全般について話しましょう。AWSには知っておくべき2つの証明書サービスがあります。1つはAWS Certificate Manager(ACM)で、もう1つはAWS Private CAです。ACMは主にパブリックおよびプライベートのTLS証明書用で、Application Load Balancer、API Gateway、CloudFrontなどの統合サービスで使用することを想定しています。他にも多くのサービスがありますが、おそらくこの3つが最も一般的です。このサービスは、パブリックまたはプライベートの証明書を発行し、これらのリソースにバインドすることができ、更新もサポートします。
ACMには管理された更新という概念があり、証明書の更新時期が来ると、自動的に新しい証明書を発行し、ALBなどのリソースにバインドします。その価値はお分かりいただけると思います - 更新を手動で追跡する必要がないのです。私がシステム管理者だった頃は、証明書関連の作業が多く、Linuxサーバーに常にログインしてキーストアに手動で証明書を入れていました。管理が難しく、ミスを起こす可能性もありました。もう二度と証明書の仕事はしないと言っていたのに、今では毎日証明書の話ばかりしています。
画面の左側を見ていただくと、ACMに証明書をインポートできることがわかります。DigiCertやSectigoなどの外部CAや他のCAから証明書を取得した場合、それらをACMにインポートできます。インポートしない場合の利点は自動更新管理ですが、インポートされた証明書については自動更新管理を行うことができません。 ACMやAmazon Trust Servicesから直接発行される証明書については、ALBなどの統合サービスで自動更新管理を行うことができます。これらのパブリック証明書をリクエストし、CloudFrontディストリビューションやAPI Gatewayなどと関連付けることができます。
また、プライベート証明書を発行することもでき、これらのプライベート証明書はバックエンドのPrivate Certificate Authorityから発行されます。Private CAでCAを作成し、AWS Certificate Manager(ACM)を使用してそこからプライベート証明書を発行できます。なぜそうするのかと思われるかもしれませんが、これにより自動更新管理が可能になり、通常では設定できないALBに証明書をバインドすることができます。マネージドサービスであるALBには直接ログインして証明書を設定することはできないため、ACMを使用してこれを行います。
多くのお客様は、ACMと統合されていないサービスのユースケースでプライベート証明書を使用します。例えば、StubHubはKubernetesコンテナへの証明書発行を容易にするためにPKIを構築しました。このようなケースでは、APIを直接呼び出して証明書を発行できます。後ほどお話しする他のユースケースのためのConnectorもご用意しています。Private CAやACMから証明書を取得する方法は複数あります。
さらに詳しく説明すると、先ほど申し上げたように、 ACMから直接プライベート証明書を取得できますが、APIを呼び出してIoTデバイス、VPN、Service Mesh用の証明書を取得することもできます。これらのプライベート証明書は高度にカスタマイズ可能です。任意の有効期間を設定でき、コード署名や電子メール暗号化などの異なる目的に使用できます。Private CAを使用したプライベート証明書では、より多くの柔軟性とカスタマイズが可能です。一方、ACMでは、TLS証明書のみを発行でき、有効期間は13ヶ月に限定されています。コード署名証明書や、3年間あるいは90日間有効なプライベートTLS証明書が必要なユースケースがある場合、Private CAから証明書を発行し、必要に応じてカスタマイズすることができます。
PKIの階層構造と証明書失効の仕組み
まずはCAの階層構造とは実際に何なのかについてお話ししましょう。証明書認証局(CA)の階層構造は、デジタル証明書の信頼を管理するために使用される逆ツリー構造です。最上位にはRoot Certificate Authority(ルート認証局)があり、これは階層内で最も信頼される認証局です。ルート認証局から直接証明書を発行したい特定のユースケースもあるかもしれませんが、ほとんどの場合、それは推奨されません。
これには主に2つの理由があります。1つ目は暗号化のブラストラディウス(影響範囲)です。AWSではあまり心配する必要はありませんが、もしRoot CAの鍵が侵害されたり誤って管理されたりした場合、そのRoot CAから発行されたすべての証明書が中間者攻撃やその他の悪意のある活動の対象となる可能性があります。2つ目の理由は、Root CAを使用してエンティティ証明書に署名する場合、証明書機関をエンティティに公開するために作成しなければならないアーキテクチャが、本質的にブラストラディウスを増大させてしまうということです。
次に、Intermediate CA(中間認証局)のレイヤーについて説明します。これはRoot CAとIssuing CAの間の暗号化の仲介役として機能します。その役割は、追加の証明書に関するブラストラディウスをさらに区画化することです。先ほど説明したRoot CAについて、最悪のシナリオとして秘密鍵が流出したり誤って扱われたりした場合を考えると、理論的には、そのブランチから発行された証明書のみが影響を受けることになります。Intermediate CAは他のCAやIssuing CAの署名に使用され、このツリー構造を下っていくと、Issuing CAはロードバランサーやサーバーに配置する可能性のあるエンドエンティティ証明書を発行するために使用されます。
ベストプラクティスについて説明しましょう。AWSおよび一般的に、Root CAはオフラインに保持するか、ネットワークやアイデンティティ管理のブラストラディウスからできるだけ遠ざけておく必要があります。AWSでは、Root証明書は独自のAWSアカウントに保持する必要があります。また、OCSPのような同期的な失効の仕組みや、CRL(証明書失効リスト)などを使用して、証明書の失効を実装する必要があります。
個々のCAにかかるオーバーヘッドとコストに対処する方法として、Cross-account CA sharingについて説明しましょう。高可用性を確保し、複数のアカウントでCAのプレゼンスポイントを持ちたい場合、このCross-account sharing機能がなければ、それらすべてのAWSアカウントで新しいCAインスタンスを作成する必要があります。Private CAのインスタンス1つあたり約400ドルのコストとオーバーヘッドを考えると、この機能は複雑さとコストの両方を削減するのに役立ちます。
挙手していただきたいのですが、AWS Resource Access Managerをご存知の方はどれくらいいらっしゃいますか?何人かいらっしゃいますね。ご存じない方のために説明すると、AWS Resource Access ManagerはAWSのマネージドサービスで、特定のリソースをクラウドアカウントの境界を越えて共有することができます。これは、AWSクラウドアカウントID(実際のアカウント番号)を使用するか、AWS Organizationsの組織単位と共有するなど、さまざまな方法で実現できます。これがスケーラビリティにとって重要である理由については、後ほど説明します。
StubHubのPKI再構築:目的と実装の詳細
ここでは、Cross-Account Certificate Authority共有が実際にどのように機能するかを示すリファレンスアーキテクチャを見ていきます。先ほど説明したように、Root CAは独自のAWSアカウントに配置し、無効化して安全に保管するのがベストプラクティスです。そして、ここではセキュリティアカウントの中央に位置するIssuing CAがあります。これは、Intermediate CAやIssuing CAなど、お客様が選択する階層構造に応じて構成できます。AWS Resource Access Managerを使用することで、特定のIssuing CAを両サイドのアカウントと共有することができます。各アカウントに実際のインスタンスを作成する代わりに、アカウントの境界を越えて共有することが可能です。
次に、レジリエンスについて説明しましょう。AWS Private Certificate Authorityは単一リージョン内で高可用性を実現していますが、StubHubのように常時高可用性が必要な場合、単一障害点があることは決して望ましくありません。リージョナルなプレゼンスポイントが必要になるかもしれません。これを実現するには2つの方法があります。1つ目のアプローチは、単一のRoot CA(これはリージョナルな構成要素です)を持ち、同じリージョン内にRootによって署名されたIssuing CAまたはSubordinate CAを配置する方法です。さらに、同じRootによって署名された追加のリージョンにIssuing CAを配置することもできます。このアプローチの利点は、管理するRoot CAが1つだけで済むことです。つまり、クライアントがTLSを検証する際に、クライアントのTrust Storeにインストールして管理するCA証明書が1つで済みます。欠点は、同じRootを共有しているため、リージョン間で完全な冗長PKIを実現できないことです。ただし、ほとんどの場合、これで十分です。
また、完全な冗長アーキテクチャを実装することもできます。あるリージョンにRoot CAとそれに対応するIntermediate CAおよびIssuing CAを配置し、同じアーキテクチャを別のリージョンに複製する方法です。利点は、リージョン間で完全な冗長性を確保できることです。欠点は、管理してクライアントにインストールするCA証明書が増えることです。
レジリエンスに関してもう1つ重要な点は、Root CAを1つのリージョンに配置する方が理にかなっているということです。なぜなら、Root CAは他のCAに署名する目的でのみ使用するからです。Root CAのリージョンで障害が発生した場合でも、その停止中にIntermediate CAなどの新しいCAに緊急で署名する必要性は低いでしょう。私はそのような状況に遭遇したお客様を見たことがありません。私の観点からすると、新しいCAを緊急に作成する必要がある特別なユースケースがない限り、管理が少なくて済む単一のRoot CAの方が理にかなっています。通常、新しいCAの作成は何ヶ月も前から計画されることです。
新しいCAを緊急に作成する必要性は、一般的に見られるシナリオではありません。問題が発生しても、簡単に延期することができます。2つのRoot CAを使用する方法も確かに機能しますし、失効に関して特定のユースケースがある可能性もあります。
証明書を失効させる理由について説明しましょう。証明書には自然な有効期限があります。例えば、2025年1月に発行された12ヶ月有効な証明書の場合、2026年1月頃に新しいリソースに紐づけて再発行する必要があります。しかし、3月にその証明書の秘密鍵が、例えば開発者が誤ってGitHubに公開してしまうなどの理由で露出してしまった場合はどうでしょうか?証明書を失効させる理由は他にもありますが、要するに自然な有効期限を待たずに無効化したい場合があるのです。
AWS Private CAで証明書を失効させる場合、それは単なるAPI呼び出しです。Private CAに対して失効させるためのAPI呼び出しを行うのですが、クライアントは証明書が失効しているかどうかを確認する方法を持っている必要があります。一般的な仕組みとして2つあります。1つはCRL(Certificate Revocation List)で、もう1つはOCSP(Online Certificate Status Protocol)です。 違いとしては、CRLは失効した証明書の静的なリストです。証明書を失効させるAPIを呼び出すと、そのリストに追加されます。Private CAではこれをS3に保存し、TLSクライアントが失効状態を確認したい場合、証明書内のフィールドにCRLのURLが記載されています。クライアントはそのCRLをダウンロードし、リストを確認して証明書のシリアル番号が存在するかどうかを確認します。リストに載っていれば失効しているため信頼してはいけません。リストにない場合は信頼して問題ありません。
OCSPはより動的なクエリ・レスポンス型の仕組みです。クライアントはOCSPレスポンダーのエンドポイントに証明書のシリアル番号を送信して問い合わせを行い、その証明書が有効か、失効しているか、不明かという応答を受け取ります。CRLはレガシーなクライアントや、IoTセンサーやモバイルフォンのような帯域幅やメモリが制限されているユースケースに適しています。このような状況で、何千もの失効した証明書を含む大きなファイルをダウンロードするのは合理的ではありません。また、CAクライアントは通常CRLを24時間程度キャッシュするため、古いCRLを保持している間に証明書が失効しても、更新されたCRLをダウンロードするまではクライアントがその証明書を信頼し続けてしまう期間が発生する可能性があります。
注目すべき点として、両方のアプローチを組み合わせることが可能です。多くの顧客がOCSPとCRLの両方を使用しており、ほとんどのクライアントは最初にOCSPをチェックします。レスポンダーに到達できない場合は、CRLをダウンロードするか、すでにダウンロードしているCRLをチェックします。Private CAでは、OCSPは有料サービスですが、CRLは追加コストなしで利用できます。OCSPはオンラインである必要があるため、長期間オフラインになるクライアントの場合、OCSPはあまり意味をなさないかもしれません。
OCSPにおけるTLSクライアントのワークフローを見てみましょう。まず最初のステップとして証明書を失効させます。この場合、CRLを更新する代わりに、OCSPレスポンダーを更新し、失効した証明書のシリアル番号を提供します。クライアントはTLSを開始するために証明書を要求し、その後OCSPレスポンダーに問い合わせを行います。CRLと同様に、これらのレスポンダーのURLは証明書の詳細に記載されています。
これらのResponderにクエリを送信します。実際には、特定の地理的位置からの配信を高速化するために、OCSP Responderの前にCloudFrontを配置しています。これらのレスポンスはCloudFrontにキャッシュされますが、キャッシュにない場合は、OCSP Responderに戻って、この特定のシリアル番号の証明書が失効しているかどうかのステータスを確認します。Responderは、この場合、失効しているかどうかを確認し、まずCloudFrontにキャッシュし、その後クライアントにレスポンスを返して、その証明書を信頼しないように通知します。CloudFrontでのキャッシュの利点は、同じ証明書について別のクライアントが情報を要求した場合、CloudFrontにキャッシュされているため、より迅速なレスポンスが得られることです。
StubHubのPKI再構築から得られた教訓と推奨プラクティス
以上が失効についての説明でした。ここでTonyに戻して、StubHubのAWSでのPKIの取り組みについて話してもらいましょう。まずはStubHubの簡単な紹介をさせていただきます。 StubHubは、個人やパートナーがライブイベントのチケットを売買できるマーケットプレイスです。私たちは、Peer-to-Peerマーケット取引業界のリーダーとして20年以上の実績があり、StubHubとViagogoという2つのブランドを運営しています。1つは主に米国で、もう1つは国際的に展開しています。世界90カ国以上で最高クラスのチケット取引サービスを提供しています。
では、なぜStubHubは独自のPKIを再構築することにしたのでしょうか? StubHubは、主に2つの理由でプラットフォーム全体の近代化を選択しました。1つは開発者の生産性を向上させること、もう1つは全体的なセキュリティ体制をさらに成熟させることです。さらに、私たちは完全にAWSへの移行を計画していました。その際、一からスタートすることになったため、クラウドアカウントのアーキテクチャ、環境構造、ネットワーキング、Identity Access Management、ロギング、エッジセキュリティなど、PKIを含むすべてのクラウド基盤を見直す機会としました。
PKIとAWSへの移行に関して、私たちは特に証明書の管理とローテーションに関するAWSのネイティブな統合機能を活用したいと考えていました。これには、AWS Certificate Managerと、Load Balancer、CloudFront Distribution、API Gatewayなど、すでに使用を計画していたサービスや統合機能での活用が含まれます。当時の既存のPKIはこれらを十分に活用できていなかったため、再設計することを選択しました。以前のPKIは、新しいクラウドアカウントの環境アーキテクチャに対応するように構築されていませんでした。私たちは、内部PKIがProduction、QA、Developmentなどの新しい環境に直接マッピングされることを確実にしたかったのです。
そのため、この近代化における重要なプロジェクトの1つであるWorkload IdentityのためのSPIREの活用に、既存のPKIを使用することが実際にはできませんでした。最後に、以前のPKIは、アクセス制御に関する新しいニーズを満たしていませんでした。私たちは、認可された組織のみがPKIから証明書を要求でき、それ以外は要求できないようにすることを確実にしたかったのです。また、以前は実現できなかったロギングとモニタリングの要件も満たす必要がありました。
私がWorkload Identityについて話をしましたが、これは一体何なのでしょうか。Workload Identityとは、個々のワークロードに暗号化された識別情報を付与し、それを使って他のサービスに対して認証を行うメカニズムのことを指します。ここで言う他のサービスとは、社内の他のサービスやCloud Service Provider、APIなど、様々なものが該当します。この仕組みの本質的な目的は、最小権限の原則を実現することにあります。確かにWorkload Identityを使用することには他にも多くのメリットがありますが、この話の文脈、特にStubHubのユースケースにおいては、最小権限の原則の実現が主な目的でした。
これらの暗号化された識別情報をワークロードに配布するメカニズムの1つが、オープンソースのサービスであるSPIREです。既にご存知の方もいらっしゃると思いますが、SPIREは個々のワークロードに対して暗号化された識別情報を安全に管理・配布するためのオープンソースシステムです。
Workload Identityの利点は、個々のワークロードが必要以上の範囲で識別情報を共有する必要がないということです。例えば、Kubernetesでは、1つのNamespace内の複数のPodが同じService Accountを共有したり、1つのVirtual Machine上で動作する複数のサービスがそのVirtual Machineの識別情報を共有したりするケースがあります。SPIREとWorkload Identityを使用することで、実際に実行されているプロセスに対して、特定の暗号化された識別情報を付与することが可能になります。
この実装はSPIFFE(Secure Production Identity Framework For Everyone)フレームワークを活用しています。主要な利点の1つは、これらのワークロードがSPIREのエコシステムに参加するために、シードトークンやシークレットを渡す必要がないことです。Self Attestationという概念があり、これは特定の属性セットに基づいてワークロードを登録する機能です。これらの属性には、特定の名前を持つCluster内でワークロードが実行されていること、特定のNamespaceでワークロードが実行されていること、Pod IDを持つService Accountを使用していることなどが含まれます。これらの特定の属性にすべて一致するワークロードがあれば、SPIREがそのワークロードに対して識別情報を配布します。
この単一のワーカー識別情報は、様々な異なる接続先への認証に使用することができます。もう1つの利点は、Cloud Service ProviderやOperating Systemに依存しないことです。そのため、データセンターやAWSなどの様々なCloud Service Providerで使用する場合でも簡単に導入できます。また、最小権限の原則を実現し、Private Certificate AuthorityやKMSなどのAWS内のサービスとネイティブに連携することができます。
では、PKIはどのように関係してくるのでしょうか?SPIREは単独で使用する場合、暗号化認証局として機能し、2つの形式でワークロードIDを発行します。1つはX.509ベースのワークロードID、もう1つはSPIRE暗号化認証局によって署名されたJWTです。また、StubHubで実現したかったように、上流または外部の暗号化認証局を使用することもできます。私たちは、SPIRE環境内のワークロードと、TLSやコード署名が必要なSPIRE環境外のワークロードの両方に使用できる単一の認証局階層を持っています。具体的には、JWTの署名にPrivate Certificate AuthorityとKMSとの統合を使用しており、これにより失効関連の機能を完全にコントロールすることができます。
PKIのアーキテクチャを再設計する際の目標について説明しましょう。私たちは3つのカテゴリーに分けて考えました。第一に、高可用性と耐障害性を備えたソリューションが必要です。第二に、当然ながらセキュリティを確保する必要があります。そして最後に、容易に保守できることを確認したいと考えています。耐障害性の観点からは、先ほど述べたように毎日大量の証明書を発行しているため、単一障害点を排除したいと考えています。セキュリティの観点からは、信頼できるエンティティのみが証明書を要求したり、内部システムに対して管理作業を行えるようにしたいと考えています。
内部PKIソリューションに対する管理作業に関しては、不正アクセスを防止する必要があります。内部PKIソリューションは、これらの保護を追加できるよう、高い監査性を備える必要があります。すべてを効果的にモニタリングできるようにしたいと考えています。さらに、適切な証明書の失効を確実に行う必要があります。私たちの場合、Online Certificate Status Protocolの実装を選択しました。保守性については、すでにインフラストラクチャ・アズ・コードを大規模に採用している組織であるため、Terraformを使用することにしました。理想的には、鍵材料を扱う必要がない、またはTerraformのステートファイルに鍵材料を保存する必要がない場合を想定して、インフラストラクチャのデプロイメントパイプラインを活用して内部PKIソリューションをデプロイしたいと考えていました。
これらが私たちの目標ですが、どのような制約があるのでしょうか?StubHubでは、少人数精鋭のチーム制を採用しています。これらのチームは多くの責任を担っているため、選択するソリューションのメンテナンス要件を低く抑える必要があります。StubHubのSecurity Engineeringは、クラウドアカウントアーキテクチャ、DevSecOps管理、エッジセキュリティ、PKI、SPIRE、その他の重要なコンポーネントなど、プラットフォーム内の多くの基盤的な構成要素の所有と運用を担当しています。内部PKIの保守だけを担当する専任チームは存在しません。さらに、より安全で堅牢なPKIアーキテクチャを目指す一方で、内部PKIアーキテクチャの改善にあたってはコスト意識を持ちたいと考えています。
これらを踏まえて、私たちはAWS Private Certificate Authorityを選択しました。この認証局を選んだ理由を、先ほどの3つの目標に分けて説明します。先に述べたように、リージョン内での高可用性が確保されています。また、単一のRoot Certificate Authorityを使用して、クロスリージョンの高可用性や拠点の設置も実現できます。これはAWS Private Certificate Authorityを使用することで確かに実現可能です。さらに、HSMインフラストラクチャやOCSPインフラストラクチャに関して、高可用性を考慮する必要がないという利点もありました。
セキュリティの観点から、証明書をリクエストできる人物と管理作業を実行できる人物のアイデンティティを分離する必要がありました。AWS Identity and Access Managementやサービスコントロールポリシーを活用することで、アイデンティティの観点から望んでいた多層防御アーキテクチャを実現することができました。セキュリティの面では、すべてを高度に監査可能にしたいと考えていました。AWS Private Certificate Authorityでは、管理作業と運用作業の両方がAWS CloudTrailに記録されます。これらのログはすでに集約していたため、簡単に決断を下すことができました。
保守の容易さについては、複数のアカウント間でCertificate Authorityを共有する簡単な方法が必要でした。新しいアカウントが頻繁に作成されるクラウドアカウントアーキテクチャに移行していることを考えると、すべてのアカウントにインスタンスをデプロイすることなくCertificate Authorityを共有する必要がありました。AWS Resource Access Managerを活用し、組織単位IDに基づいて適切な環境とPrivate Certificate Authorityを共有しています。組織管理アカウントの組織単位に基づいて、本番環境のCertificate Authorityは本番環境のAWSアカウントとのみ共有しています。また、AWSサービスとのネイティブな統合を活用したいと考え、AWS Certificate Managerのようなツールを使用して更新を処理し、開発者が証明書を簡単に適用できるようにしました。この方法により、開発者は鍵材料を直接扱うことなく、ロードバランサーやCloudFront、API Gatewayなどのリソースに証明書を簡単に適用できます。
StubHubのPKIアーキテクチャ:設計と実装の詳細
こちらが、私たちが構築した参照アーキテクチャの概要図です。先ほど触れたように、本番環境用と非本番環境用の2つの異なるCA階層を選択しました。複数の環境がありますが、顧客や社内プラットフォームチームのニーズを考慮すると、Certificate Authority階層を必要以上に複雑にする必要はないと判断しました。
右側に、Root Certificate Authorityを独自のAWSアカウント(この場合はPKIアカウント)に配置しました。そこから、AWS Resource Access Managerを使用してRoot Certificate Authorityをセキュリティエンジニアリングのアカウントと共有しました。これは、中間CAと発行CAを兼ねる下位CAが、それぞれのRoot Certificate Authorityによって署名される必要があったためです。また、リージョンごとの拠点も必要でした。ここではUS-EAST-1とUS-WEST-2という2つの異なるリージョンが示されています。セキュリティエンジニアリングアカウント内の各リージョンには、それぞれの環境(US-EAST-1の本番環境、US-EAST-1の非本番環境、US-WEST-2も同様)があります。
その後、Resource Access Managerを使用して、特定のCertificate Authorityを組織単位に共有することにしました。これにより、リージョンの観点とクラウドアカウントの観点の両方から拠点を確保できました。これらの中間兼発行Certificate Authorityを使用して、エンドエンティティ証明書を発行し、ワークロードアイデンティティソリューションで使用されるSPIREローカルCertificate Authorityに署名することができます。 このような講演に参加する立場として、実際のデプロイ方法が気になるところです。先ほど申し上げたように、私たちは Infrastructure-as-code とTerraformを積極的に活用しており、標準化されたInfrastructure-as-codeのデプロイメントパイプラインを使用しています。
私たちは、Private Certificate Authority、Resource Access Manager、CA証明書、および関連する権限を組み合わせたカスタムのTerraformモジュールを作成しました。証明書機関の役割(IAMロールではなく、RootかSubordinateかという役割)に基づいて、モジュールは適切な権限を関連付け、それらの証明書機関を適切なアカウントに共有するという選択を行います。また、堅牢な多層防御戦略の一環として、AWS Organizations Service Control Policiesを活用して、証明書機関自体の変更を防ぎ、有効・無効化を制御しています。新しい証明書機関の作成と署名を許可せず、Resource Access Managerのリソースポリシーや共有自体の変更も同様に制限しています。
AWSへの移行の経験と、私たちの目標、そしてWorkload Identityについて、学んだ教訓を共有させていただきます。 まず、組織のニーズを尊重しつつも、過度に複雑にならないように内部PKIアーキテクチャを構築することが重要です。管理に多大な労力が必要で、投資対効果が得られないような複雑な階層構造は避けるべきです。次に、AWSであるかどうかに関わらず、すべてのPKIで重要な点として、堅牢な構成管理プロセスを確保する必要があります。内部PKIを構築する際には、クライアントのTrust StoreにそれらのCA証明書をインストールする必要があるためです。
AWS特有の方法としては、AWS Systems Manager(SSM)を使用するか、ブートストラッププロセス中にAMIやコンテナイメージの観点からGolden Imageを作成して、それらのCA証明書をTrust Storeにインストールすることができます。いずれにしても、構成管理には常に適切なプロセスが必要です。
最後に、あまり明白ではないかもしれませんが、私の経験上、意図的な世代別の命名規則を持つことが重要です。CA証明書が25年、15年、あるいはその他の長期間後に期限切れになる際、新しい証明書機関に有機的に移行するために同時に稼働させる必要がある場合があります。その際、適切な世代別の命名規則があれば、構造を簡単に理解でき、期限切れが近づいている証明書機関階層から新しい階層への移行がスムーズになります。
AWS Private CAのコネクタ:多様なユースケースへの対応
ここでZachに戻して、Connectorについて話してもらいます。ありがとう、Tony。Tonyは、StubHubがCode SigningやKubernetesのService Meshにおけるサービス間のMutual TLSなど、PKIに関する要件を持っていたことについて話しました。これらは、ALBでのTLS終端と同様に、かなり一般的なユースケースです。 数年前、これらは顧客が「Private CAは素晴らしそうですね。オンプレミスで自前のPKIを管理する必要がなくなりそうです」と私たちに話してくるユースケースでした。 しかし、WindowsシステムやMobile Device ManagementのためのSCEPに関する特定のユースケースがありました。
このサービスのビジョンは、最終的にはすべての証明書のユースケースに対応できるエンタープライズ規模のPKIとなることです。そしてそれを実現するために、私たちは各種コネクタを開発しています。今日お話しするコネクタは、Active Directory、SCEP、そしてKubernetesのためのものです。 これらは主に、単純にAPIコールで証明書を取得したり、ACMを使用したりするだけでは対応できないユースケース、例えばWindowsのドメイン参加デバイスが証明書を必要とする場合などに対応するためのものです。 例えば、Active Directory用のコネクタでは、Secure LDAPとの通信を保護したり、内部サイト、人事給与システム、その他の一般公開されていない内部向けアプリケーションへのアクセスのために、ユーザーやマシンを登録したりする際に証明書を使用することができます。
このコネクタは、従来のActive Directory Certificate Services(AD CS)と同様の使用感を実現するために開発されました。 プロセスの流れは次のようになります:Windowsの社用ノートPCなどのドメイン参加オブジェクトが起動してドメインに参加すると、自動登録サーバーを指定するグループポリシーオブジェクトを受け取ります。従来のWindowsの世界では、これは通常、オンプレミスで動作するWindows CAでした。私たちのケースでは、追加コストなしでAWSアカウントに存在するこのサーバーレスコネクタがその役割を果たします。このコネクタを構築し、AWS Directory ServiceのManaged ADまたはオンプレミスのActive Directoryとの接続を確立します。オンプレミスの場合は、AWS Directory ServiceのAD Connectorと呼ばれる同様のコネクタを使用します。AD用のこのコネクタは基本的に登録サーバーとして機能し、これらのリクエストをPrivate CAへのAPIコールに変換して証明書を取得します。Windowsノートパソコンが起動してグループポリシーを取得し、自動登録サーバー(この場合はコネクタ)と通信すると、テンプレートのリストが返されます。
コネクタは、マシン認証、TLS、コード署名用のテンプレートのリストを返します。デバイスはこの情報を受け取り、CSRを作成してコネクタに送信し、AWS Private CAから証明書を取得してデバイスに配布します。重要なのは、これがユーザーにとって完全に透過的だということです。ユーザーは、Windowsノートパソコンが起動する以外には何も見えず、バックグラウンドで証明書を取得して認証できるようになります。これはAD CSと同じ動作です。Windowsユーザーや管理者にとって、実質的な変更はありません。これは大きなメリットです。なぜなら、Windows CAインフラストラクチャやHardware Security Module(もし使用している場合)を管理する必要がなくなりますが、ユーザーにとっては同じ体験が維持されるからです。ユーザーにとっては透過的な変更となります。
同様に、TonyがKubernetesとSPIFFE SPIREのユースケースについて話したKubernetes用のコネクタについてですが、Kubernetesデバイスやクラスタに証明書を発行する方法の1つは、Kubernetesのネイティブユーティリティであるcert-managerを使用することです。これにより、普段通りにサービスをデプロイし、CAの場所やテンプレートなどを指定するYAMLデプロイメントファイルを作成することができます。cert-managerを使用してAWS Private CAから証明書を取得できるサービスを作成することができます。私たちはAWS Private CA用のこのプロバイダープラグインを構築しました。これにより、普段通りcert-managerを使用しながら、AWS Private CAから証明書を取得することができます。これには、複数のCAを指定できるという素晴らしい機能があります。これはcert-managerの機能ですが、例えばUS-EAST-1のAPIエンドポイントに到達できない場合や障害が発生した場合に、AntonioのアーキテクチャーでのUS-WEST-2の例のように、別のCAを指定することができます。cert-managerとこのプラグインを使用することで、AWS Private CAを使用してKubernetesクラスタに証明書を簡単に取得することができます。
SCEPのコネクタは、Active Directoryのユースケースと似ています。AD用のコネクタをリリースしたとき、多くのお客様から「これは素晴らしいが、デザインチームが使用するiPhoneやMacノートパソコンがあり、まだ証明書が必要だ」という声がありました。これらの他のユースケースのために、オンプレミスのPKIを完全に廃止することができず、両方を維持しなければなりませんでした。そのため、私たちはこれらの異なるユースケースに対応するためにこれらのコネクタを開発しています。AD用のコネクタを使用しているものの、まだMacノートパソコンやその他のデバイスが必要なお客様のために、SCEPのコネクタを開発しました。これは、Microsoft IntuneやJamf Proなどの一般的なMDMソリューションと統合され、モバイルデバイスの登録やデバイスプロファイル、証明書の発行を容易にします。
この SCEP 用コネクターを使用することで、エンタープライズ向けの単一の CA を使用でき、少数ながら証明書発行機能を維持する必要がある特殊なデバイスのユースケースに対応できます。AD 用コネクターと同様に、ユーザーや管理者にとってはシームレスな移行が可能です。なぜなら、このコネクター を作成するだけで、追加コストも管理も必要ないからです。コネクターの設定と関連する権限を構成し、選択した MDM にモバイルデバイスを登録するだけです。SCEP 用のコネクターには複数のタイプがあります:Jamf Pro やその他の MDM で使用できる汎用コネクターと、Microsoft Intune の機能とより統合された Intune 専用のコネクターです。これらのコネクターを設定し、モバイルデバイスを MDM に登録すると、その MDM は AWS Private CA からこのコネクター経由で証明書を取得できることを認識します。利点は、CA を管理する必要なく AWS Private CA から証明書を取得できることで、ユーザーエクスペリエンスは全く変わりません。ユーザーは普段通りスマートフォンを使用するだけで、証明書の存在を意識する必要もありません。
PKI運用のベストプラクティスとセッションのまとめ
これらのベストプラクティスの多くはすでに説明しましたが、念入りに確認するためにいくつか見ていきましょう。 例えば、CA の構造とポリシーを文書化することは当たり前のように聞こえますが、重要です。なぜなら、25年から50年後に誰かが Root CA や Intermediate CA を置き換える必要が出てきた時、それを構築した人がもうその会社にいないかもしれないからです。階層構造のブランチ、有効期間、その他の重要な詳細について、すべてを文書化して理解しておく必要があります。
CA の有効期間について、私は比較的強い意見を持っています。AWS Private CA としてではなく個人的な意見として、特にプライベート CA の場合、有効期間を長くすることをお勧めします。CA 証明書の秘密鍵は FIPS 140-2 レベル3の HSM に保管され、サービスから外に出ることはありません。鍵の漏洩は不可能ではありませんが、極めて現実的ではありません。短い有効期間は必要ないと考えており、長期の有効期間には利点があります。例えば、Amazon Trust Services は150年の有効期間を持つ Root CA を持っています。これは、クライアントの信頼ストアに新しい Root CA を更新することが困難だからです。Tony が言及したように、Root CA 証明書が信頼ストアにないと、クライアントはその証明書を信頼しません。
文書化の議論と同様に、階層構造をシンプルに保つことが重要です。Private CA では1つの CA につき400ドルを支払う必要があるため、階層構造をシンプルにすることでコストを削減できます。また、ガバナンスの理解と実装も容易になります。製造部門と企業インフラを分離するなど、CA 階層に多くのブランチを持つ顧客もいて、それには正当な理由があります。しかし、ほとんどの顧客にとって、シンプルに保つことで運用がはるかに容易になります。
Tony が StubHub のアーキテクチャで示したように、Root CA を専用アカウントに保持することは重要です。彼らは PKI アカウントに Root CA を置き、アクセスを厳しく制限し、特定の SCP を使用して Root CA の再有効化や新しい CA の作成を防いでいます。AWS RAM を使用して CA をアカウント間で共有することは、主にコストの考慮事項ですが、ガバナンスにも関係します。制限されたアクセスを持つ中央アカウントにすべての CA があれば、アプリケーション開発者が誤って CA を削除したり再設定したりすることを防げます。AWS におけるアカウントの境界は一種の聖域であり、ワークロードを分離して PKI を中央アカウントに置き、他の開発者アカウントと共有することができます。
最も強調したい「してはいけないこと」は、Root CAからIdentity証明書を発行しないことです。これが適切な極めて特殊なユースケースもあるかもしれませんが、ほとんどの場合はやめておくべきです。キーポイントとして、私たちが議論した2つのサービスを振り返ってみましょう。ACMはTLS証明書のみを扱い、有効期間は13ヶ月で、パブリックまたはプライベートを選べます。ALBやAPI Gatewayなどの統合リソースに使用することをお勧めします。Private CAではあらゆるタイプのプライベート証明書を発行できますが、パブリック証明書は発行できません。相互TLS認証、コードサイニング、メール暗号化、マシン認証など、様々なユースケースに活用できます。Private CAでは、ユースケースに応じて7日から10年までの有効期間を含め、テンプレートを自由にカスタマイズすることができます。
このセッションで最も重要なポイントは、Anthonyが話した実践から得られた教訓だと思います。私はこういった話をよくしますが、Anthonyは実際にこれを構築した人なので、とても貴重な教訓を持っています。特に、PKIはシンプルに保ち、設定管理をどのように行うかを考えることが重要です。これはPKIに限らずすべてに当てはまりますが、Root CA証明書をデバイスに配布することは非常に重要です。そのため、Root CAを切り替える必要が出てきた場合など、Trust Storeへの変更を自動化されたプロセスで展開できると便利です。
Anthonyが言及したように、これを行うためにAMIやコンテナイメージを使用することができます。Amazonでは、開発者向けに「これがあなたのシステム用のTrust Storeです」という内部コードリポジトリも提供しています。これも一つの方法です。一般的に、堅牢な設定管理は非常に役立ちます。そして最後に、Anthonyが言及したように、世代別の命名規則を使用してください。例えば50年後、あなたがもうここで働いていない時に、誰かが第1世代のIssuing CAを置き換えようとするかもしれません。
その場合、新しいIssuing CAを作成して第2世代と名付けます。そして、新しい証明書はすべて第2世代CAから発行を開始します。第1世代CAは、それが発行したすべての証明書が自然に期限切れになるまで稼働させ続け、その後で削除できます。例えば、50個の証明書が残っていて6ヶ月で期限切れになる場合、追加の1つを6ヶ月間稼働させ続け、新しいCAからすべてを発行して、古いものは自然に期限切れになったら削除します。強制的に失効させて新しい証明書をすべてにプッシュすることもできますが、両方を稼働させ続けて、自然に期限切れになったら古い方を削除する方が良いと思います。ただし、新しいCAを誤って削除しないように、世代別の命名規則を使用することが重要です。構築時にいなかった人でも、これがどのように機能し、どのようにセットアップされているかが明確に分かるようにしておきたいものです。
はい、以上です。お時間をいただき、ありがとうございました。アンケートにご協力いただき、良かった点や改善点をお聞かせください。質問がある方は、ホールで私たちを見つけてください。Anthonyは実際にこれらを構築した人なので、難しい質問は彼に投げかけてください。お時間をいただき、重ねてお礼申し上げます。
※ こちらの記事は Amazon Bedrock を利用することで全て自動で作成しています。
※ 生成AI記事によるインターネット汚染の懸念を踏まえ、本記事ではセッション動画を情報量をほぼ変化させずに文字と画像に変換することで、できるだけオリジナルコンテンツそのものの価値を維持しつつ、多言語でのAccessibilityやGooglabilityを高められればと考えています。
Discussion