Service Fabric クラスターでの X.509 証明書ベースの認証

この記事では、Service Fabric クラスターのセキュリティの概要を補足し、Service Fabric クラスターでの証明書ベースの認証の詳細について説明します。 読者が基本的なセキュリティの概念と、クラスターのセキュリティを制御するために Service Fabric で公開されているコントロールについて理解していることを前提としています。

このタイトルで取り上げられているトピック:

  • 証明書ベースの認証の基本
  • ID とそれらの各ロール
  • 証明書の構成規則
  • トラブルシューティングとよく寄せられる質問

証明書ベースの認証の基本

セキュリティに関する簡単な復習として、証明書とは、エンティティ (サブジェクト) に関する情報を、それらの非対称暗号化キーのペアの所有にバインドすることを目的としたインストルメントであり、そのために公開キー暗号化の中核的構造体となります。 証明書によって表されるキーは、データの保護やキー所有者の ID の証明に使用できます。証明書は、公開キー基盤 (PKI) システムと組み合わせて使用すると、インターネット ドメインの所有権や、証明書の発行者 (証明機関または CA と呼ばれる) によってそれに付与された特定の特権など、サブジェクトの追加の特性を表すことができます。 証明書の一般的な用途は、トランスポート層セキュリティ (TLS) 暗号化プロトコルをサポートすることであり、コンピューター ネットワーク経由のセキュリティ保護された通信を可能にします。 具体的には、クライアントとサーバーで証明書を使用して、通信のプライバシーと整合性を確保し、相互認証も行います。

Service Fabric では、クラスターの基本レイヤー (フェデレーション) は、参加しているノードの信頼性の高い、セキュリティ保護されたネットワークを実現するために、TLS (プロトコルの中で特に) にも基づいています。 Service Fabric クライアント API を介したクラスターへの接続では、トラフィックを保護するためだけでなく、パーティの ID を確立するためにも TLS が使用されます。 具体的には、Service Fabric での認証に使用する場合、証明書は、次の要求を証明するために使用できます。a) 証明書資格情報のプレゼンターが証明書の秘密キーの所有権を持つ。b) 証明書の SHA-1 ハッシュ ('拇印') がクラスター定義に含まれる宣言と一致する。または c) 証明書の識別されたサブジェクト共通名がクラスター定義に含まれる宣言と一致し、証明書の発行者が既知または信頼されている。

上記の一覧で、'b' は口語で '拇印のピン留め ' として知られています。このケースでは、宣言は特定の証明書を参照し、認証スキームの長所は、他のあらゆる点で有効かつ適切な形式のオブジェクトでありながら、他の証明書と同じハッシュ値を生成する証明書を偽造することが計算上実行不可能であるという前提にあります。 項目 'c' は、証明書の宣言の代替形式を表します。この場合、スキームの長所は、証明書のサブジェクトと発行機関の組み合わせにあります。 このケースでは、宣言は証明書のクラスを参照しています。同じ特性を持つ 2 つの証明書はすべて、完全に等しいと見なされます。

次のセクションでは、Service Fabric ランタイムで証明書を使用して検証し、クラスターのセキュリティを確保する方法を詳しく説明します。

ID とそれらの各ロール

認証や通信チャネルのセキュリティ保護の詳細に入る前に、関与しているアクターと、それらがクラスターで果たしている役割を挙げることが重要です。

  • Service Fabric ランタイム ("システム" と呼ぶ): クラスターを表す抽象化と機能を提供する一連のサービス。 システム インスタンス間のクラスター内通信を参照する場合は、"クラスター ID" という用語を使用します。クラスターの外部からのトラフィックの受信者/ターゲットとしてクラスターを参照する場合は、"サーバー ID" という用語を使用します。
  • ホステッド アプリケーション ("アプリケーション" と呼ぶ): クラスターの所有者によって提供されるコード。クラスターで調整され、実行されます
  • クライアント: クラスターの構成に従って、クラスターに接続し、その機能を実行できるエンティティ。 'user' と 'admin' の 2 つのレベルの特権をそれぞれ区別します。 'user' クライアントは主に読み取り専用操作に制限されます (ただし読み取り専用機能だけではない) が、'admin' クライアントはクラスターの機能に無制限にアクセスできます。 (詳細については、Service Fabric クラスターでのセキュリティ ロールに関するページを参照してください)。
  • (Azure のみ) Service Fabric クラスターを操作および管理するためのコントロールを調整し、公開する Service Fabric サービス (単に "サービス" と呼びます)。 環境によって、"サービス" は、Azure Service Fabric リソース プロバイダー、または Service Fabric チームによって所有され、運用されている他のリソース プロバイダーを参照している場合があります。

セキュリティ保護されているクラスターでは、これらの各ロールは、定義済みのロール名とそれに対応する資格情報の組み合わせとして宣言された、独自の個別の ID で構成できます。 Service Fabric では、証明書またはドメインベースのサービス プリンシパルとしての資格情報の宣言をサポートしています。 (Windows ベースまたは Kerberos ベースのID もサポートされていますが、この記事の範囲を超えています。Service Fabric クラスターの Windows ベースのセキュリティに関するページを参照してください)。Azure クラスターでは、クライアント ロールを Microsoft Entra ID ベースの ID として宣言することもできます。

上で触れているように、Service Fabric ランタイムでは、クラスターに 'admin' と 'user' の 2 つのレベルの特権が定義されます。 管理者クライアントと "システム" コンポーネントはどちらも 'admin' 特権で動作するため、相互に区別がつきません。 クラスター内またはクラスターとの接続を確立すると、認証された呼び出し元に、Service Fabric ランタイムによって、その後の承認のベースとして、2 つのロールのいずれかが付与されます。 認証については、次のセクションで詳しく説明します。

証明書の構成規則

検証規則

Service Fabric クラスターのセキュリティ設定では、原則として、次の側面について記述します。

  • 認証の種類。これは、クラスターの作成時の不変の特性です。 このような設定の例としては、'ClusterCredentialType'、'ServerCredentialType' があり、使用できる値は 'none'、'x509'、'windows' です。 この記事では、x509 型の認証に焦点を当てています。
  • (認証) 検証規則。これらの設定は、クラスターの所有者によって設定され、特定のロールで受け入れられる資格情報を記述します。 例の詳細については、すぐ後で説明します。
  • 認証の結果を調整するか、またはわずかに変更するために使用される設定。ここでの例としては、証明書失効リストの適用を制限または制限解除するフラグなどがあります。

Note

次に示すクラスター構成の例は、この記事で説明している Service Fabric 機能を直接サポートする最も要約された形式として、XML 形式のクラスター マニフェストからの抜粋です。 スタンドアロンの JSON クラスター マニフェストでも、Azure リソース管理テンプレートでも、クラスター定義の JSON 表現で、同じ設定を直接表現できます。

証明書検証規則は、次の要素で構成されます。

  • 対応するロール: クライアント、管理者クライアント (特権ロール)
  • 拇印またはサブジェクトの共通名によって宣言された、ロールに承認された資格情報

拇印ベースの証明書検証宣言

拇印ベースの検証規則の場合、クラスター内またはクラスターへの接続を要求する呼び出し元によって提示される資格情報は、次のように検証されます。

  • 資格情報は有効で適切な形式の証明書である: そのチェーンを構築でき、署名が一致する
  • 証明書が有効期限内である (NotBefore < = 現在 < NotAfter)
  • すべての空白を除き、大文字と小文字を区別しない文字列比較として、証明書の SHA-1 ハッシュが宣言と一致している

拇印ベースの宣言では、チェーンの構築または検証時に検出されるすべての信頼エラーが抑制されます。ただし、期限切れの証明書を除きます。その場合もプロビジョニングは存在します。 具体的に言うと、失効状態が不明かオフラインである、信頼されていないルート、無効なキーの使用、部分チェーンに関連した障害は、致命的でないエラーと見なされます。このケースでの前提は、証明書がキー ペアのエンベロープにすぎないということです。セキュリティは、クラスター所有者が秘密キーを保護するための手段を設定しているという事実にかかっています。

クラスター マニフェストからの次の抜粋では、一連の拇印ベースの検証規則の例を示しています。

<Section Name="Security">
  <Parameter Name="ClusterCredentialType" Value="X509" />
  <Parameter Name="ServerAuthCredentialType" Value="X509" />
  <Parameter Name="AdminClientCertThumbprints" Value="d5ec...4264" />
  <Parameter Name="ClientCertThumbprints" Value="7c8f...01b0" />
  <Parameter Name="ClusterCertThumbprints" Value="abcd...1234,ef01...5678" />
  <Parameter Name="ServerCertThumbprints" Value="ef01...5678" />
</Section>

上の各エントリは、先述のように特定の ID を参照します。各エントリでは、文字列のコンマ区切りのリストとして、複数の値を指定することもできます。 この例では、受信資格情報が正常に検証されると、SHA-1 拇印 'd5ec...4264' 付きの証明書のプレゼンターに、'admin' ロールが付与されます。逆に、証明書 '7c8f...01b0' によって認証される呼び出し元には、主に読み取り専用操作に制限される 'user' ロールが付与されます。 拇印が 'abcd...1234' または 'ef01...5678' である証明書を提示する受信呼び出し元は、クラスター内のピア ノードとして受け入れられます。 最後に、クラスターの管理エンドポイントに接続するクライアントでは、サーバー証明書の拇印が 'ef01...5678' であると想定されます。

先述のように、Service Fabric は期限切れの証明書を受け入れるためのプロビジョニングを行います。その理由は、証明書には有効期限があり、拇印 (特定の証明書インスタンスを参照する) によって宣言されている場合、証明書の有効期限が切れることで、クラスターへの接続に失敗するか、クラスターが完全に崩壊します。 拇印がピン留めされた証明書のローテーションは簡単に忘れられたり、無視されたりしがちであり、残念ながらそのような状況からの回復は困難です。

そのため、クラスター所有者は、拇印によって宣言された自己署名証明書が有効と見なされることを、次のように明示的に指定できます。

  <Section Name="Security">
    <Parameter Name="AcceptExpiredPinnedClusterCertificate" Value="true" />
  </Section>

この動作は、CA が発行した証明書までには及びません。そのような場合、失効し、侵害されたことが既知の期限切れの証明書が、CA の証明書失効リストに含まれなくなるとすぐに、"有効" になり、そのためにセキュリティ上のリスクが生じる可能性があります。 自己署名証明書を使用する場合、クラスター所有者は、証明書の秘密キーの保護の責任を負う唯一のパーティと見なされます。これは、CA 発行の証明書の場合は当てはまらず、クラスター所有者は、自分の証明書が侵害されたと断定される方法やタイミングを認識しない可能性があります。

共通名ベースの証明書検証の宣言

共通名ベースの宣言では、次のいずれかの形式を使用します。

  • サブジェクト共通名 (のみ)
  • 発行者をピン留めしたサブジェクトの共通名

まず、両方の宣言スタイルの例を示しているクラスター マニフェストからの抜粋を考えてみましょう。

    <Section Name="Security/ServerX509Names">
      <Parameter Name="server.demo.system.servicefabric.azure-int" Value="" />
    </Section>
    <Section Name="Security/ClusterX509Names">
      <Parameter Name="cluster.demo.system.servicefabric.azure-int" Value="1b45...844d,d7fe...26c8,3ac7...6960,96ea...fb5e" />
    </Section>

宣言では、それぞれサーバー ID とクラスター ID が参照されています。CN ベースの宣言には、標準の 'Security' とは別に、クラスター マニフェストに独自のセクションがあることに注意してください。 どちらの宣言でも、'Name' は証明書の識別されたサブジェクト共通名を表し、'Value' フィールドは次のように想定される発行者を表します。

  • 最初のケースでは、宣言で、サーバー証明書の識別されたサブジェクトの共通名要素が、文字列 "server.demo.system.servicefabric.azure-int" と一致すると想定されることが示されています。空の 'Value' フィールドは、証明書チェーンのルートが、サーバー証明書が検証されているノードまたはコンピューターで信頼されていることを示しています。Windows では、これは、証明書が "信頼されたルート CA" ストアにインストールされている任意の証明書までチェーンできることを意味します。
  • 2 番目のケースでは、証明書の共通名が文字列 "cluster.demo.system.servicefabric.azure-int" に一致し、かつ証明書の直接の発行者の拇印が、'Value' フィールドのコンマ区切りのエントリのいずれかと一致する場合に、証明書のプレゼンターがクラスター内のピア ノードとして受け入れられることを宣言で示しています。 (この規則の種類は、口語で "発行者がピン留めされた共通名" と呼ばれます)。

どちらのケースも、証明書のチェーンが構築され、エラーが発生しないことが期待されます。つまり、失効エラー、部分チェーン、または時間が無効な信頼エラーは致命的と見なされ、証明書の検証が失敗します。 発行者をピン留めすると、"信頼されていないルート" 状態が致命的でないエラーと見なされます。外観にかかわらず、これは検証の厳密な形式です。これにより、クラスター所有者は、一連の承認された/受け入れられた発行者を独自の PKI に制限できます。

証明書チェーンが構築されると、リモート名として宣言されたサブジェクトで、標準の TLS/SSL ポリシーに対して、それが検証されます。証明書のサブジェクト共通名またはサブジェクト別名のいずれかがクラスター マニフェストの CN 宣言と一致する場合、その証明書は一致と見なされます。 このケースでは、ワイルドカードがサポートされ、文字列の照合では大文字と小文字が区別されません。

(上記のシーケンスは、証明書によって宣言されたキー使用法の種類ごとに実行される可能性があります。証明書でクライアント認証キーの使用法が指定されている場合、チェーンは最初にクライアント ロールに対して構築および評価されます。成功した場合は、評価が完了し、検証が成功します。証明書にクライアント認証の使用法が存在しない場合、または検証に失敗した場合、Service Fabric ランタイムはサーバー認証のチェーンをビルドして評価します)。

この例を完成させるために、次の抜粋で、共通名によるクライアント証明書の宣言を示しています。

    <Section Name="Security/AdminClientX509Names">
      <Parameter Name="admin.demo.client.servicefabric.azure-int" Value="1b45...844d,d7fe...26c8,3ac7...6960,96ea...fb5e" />
    </Section>
    <Section Name="Security/ClientX509Names">
      <Parameter Name="user.demo.client.servicefabric.azure-int" Value="1b45...844d,d7fe...26c8,3ac7...6960,96ea...fb5e" />
    </Section>

上記の宣言は、それぞれ管理者 ID とユーザー ID に対応しています。この方法で宣言された証明書の検証は、前の例のクラスター証明書とサーバー証明書についての説明とまったく同じです。

Note

共通名ベースの宣言は、ローテーション、一般的に言えば、クラスター証明書の管理を簡素化することを目的としています。 ただし、クラスターの継続的な可用性とセキュリティを確保するために、次のレコメンデーションに従うことが推奨されます。

  • 信頼されたルートに依存するように発行者のピン留めを優先する
  • 異なる PKI からの発行者の混在を避ける
  • すべての想定される発行者が証明書宣言に一覧表示されていることを確認します。発行者が一致しないと、検証が失敗します
  • PKI の証明書ポリシー エンドポイントが検出可能、利用可能、アクセス可能であることを確認します。これは、AIA、CRL、または OCSP エンドポイントがリーフ証明書で宣言されており、証明書チェーンの構築を完了できるように、それらにアクセス可能であることを意味します。

これをまとめて試してみて、X.509 証明書でセキュリティ保護されたクラスターで接続の要求を受け取ると、Service Fabric ランタイムでは、前述のように、クラスターのセキュリティ設定を使用して、リモート パーティの資格情報が検証されます。成功した場合、呼び出し元/リモート パーティは認証されていると見なされます。 資格情報が複数の検証規則と一致する場合、ランタイムによって、いずれかの一致した規則の最上位の特権ロールが呼び出し元に付与されます。

プレゼンテーション規則

前のセクションでは、証明書によってセキュリティ保護されたクラスターでの認証のしくみについて説明しました。このセクションでは、Service Fabric ランタイム自体によって、クラスター内通信に使用される証明書が検出され読み込まれる方法について説明します。これらを "プレゼンテーション" 規則と呼びます。

検証規則と同様に、プレゼンテーション規則では、拇印または共通名で表された、ロールと関連付けられた資格情報宣言を指定します。 検証規則とは異なり、共通名ベースの宣言には発行者のピン留めのためのプロビジョニングはありません。これにより、柔軟性が向上するだけでなく、パフォーマンスが向上します。 プレゼンテーション規則は、クラスター マニフェストの 'NodeType' セクションに、個々のノード タイプごとに宣言されます。この設定はクラスターの Security セクションから分離され、各ノードの種類で、その完全な構成を 1 つのセクションに指定することができます。 Azure Service Fabric クラスターでは、ノードの種類の証明書宣言の既定が、クラスターの定義の Security セクションの対応する設定になります。

拇印ベースの証明書のプレゼンテーション宣言

先述のように、Service Fabric ランタイムでは、クラスター内の他のノードのピアとして、およびクラスター管理操作用のサーバーとして、その役割が区別されます。 原則として、これらの設定は別々に構成できますが、実際には揃えられる傾向があります。 この記事の残りの部分では、わかりやすくするために、設定が一致しているものと仮定しています。

クラスター マニフェストからの次の抜粋を考えてみましょう。

  <NodeTypes>
    <NodeType Name="nt1vm">
      <Certificates>
        <ClusterCertificate X509FindType="FindByThumbprint" X509FindValue="cc71...1984" X509FindValueSecondary="49e2...19d6" X509StoreName="my" Name="ClusterCertificate" />
        <ServerCertificate X509FindValue="cc71...1984" Name="ServerCertificate" />
        <ClientCertificate X509FindValue="cc71...1984" Name="ClientCertificate" />
      </Certificates>
    </NodeType>
  </NodeTypes>

'ClusterCertificate' 要素は、省略可能なパラメーター ('X509FindValueSecondary')、または適切な既定値を持つパラメーター (' X509StoreName ') を含む完全なスキーマを示しています。その他の宣言は、省略形を示しています。 上記のクラスター証明書の宣言では、'nt1vm' の種類のノードのセキュリティ設定が、証明書 'cc71..1984' をプライマリとして、および '49e2..19d6' 証明書をセカンダリとして初期化されていることを示しています。両方の証明書が LocalMachineMy' 証明書ストア (または Linux の同等のパス var/lib/sfcerts) にあることが想定されています。

共通名ベースの証明書プレゼンテーション宣言

ノードの種類の証明書は、下の例に示すように、サブジェクト共通名で宣言することもできます。

  <NodeTypes>
    <NodeType Name="nt1vm">
      <Certificates>
        <ClusterCertificate X509FindType="FindBySubjectName" X509FindValue="demo.cluster.azuredocpr.system.servicefabric.azure-int" Name="ClusterCertificate" />
      </Certificates>
    </NodeType>
  </NodeTypes>

どちらの種類の宣言でも、Service Fabric ノードでは起動時に構成が読み取られ、指定された証明書が検索されて読み込まれ、それらの NotBefore 属性の降順で並べ替えられます。期限切れの証明書は無視され、このノードによって試行されたすべての Service Fabric 接続に対して、リストの最初の要素がクライアント資格情報として選択されます。 (実際には、Service Fabric では最後に発行された証明書が優先されます)。

Note

バージョン 7.2.445 (7.2 CU4) より前では、Service Fabric によって、最も有効期限が遅い証明書 ('NotAfter' プロパティが最も遅い証明書) が選択されています

共通名ベースのプレゼンテーション宣言では、大文字と小文字が区別される正確な文字列比較として、そのサブジェクトの共通名が、宣言の X509FindValue (または X509FindValueSecondary) フィールドに等しい場合、証明書が一致と見なされます。 これは、ワイルドカード照合や大文字と小文字が区別されない文字列比較をサポートする検証規則とは対照的です。

その他の証明書構成設定

前に説明したように、Service Fabric クラスターのセキュリティ設定では、認証コードの動作をわずかに変更することもできます。 Service Fabric クラスター設定の記事では、包括的かつ最新の設定の一覧を示していますが、ここでは、証明書ベースの認証について完全に解明するために、厳選した一部のセキュリティ設定について詳しく説明します。 各設定について、目的、既定値/動作、認証に与える影響、および使用可能な値について説明します。

前述のように、証明書検証には、常に証明書のチェーンの構築と評価という意味が含まれます。 CA によって発行された証明書の場合、この明らかにシンプルな OS API 呼び出しでは通常、発行元 PKI のさまざまなエンドポイントへのいくつかの送信呼び出し、応答のキャッシュなどを必要とします。 Service Fabric クラスターでの証明書検証呼び出しの普及により、PKI のエンドポイントでの何らかの問題によって、クラスターの可用性が低下したり、完全な機能停止が発生したりする可能性があります。 送信呼び出しを抑制することはできません (この詳細については、下記の FAQ のセクションを参照してください) が、次の設定を使用して、CRL 呼び出しの失敗によって発生する検証エラーをマスクすることができます。

  • CrlCheckingFlag - "Security" セクションで、UINT に変換される文字列。 この設定の値は、Service Fabric によって、チェーン構築の動作を変更して、証明書チェーンの状態エラーをマスクするために使用されます。これは、'dwFlags' パラメーターとして Win32 CryptoAPI CertGetCertificateChain 呼び出しに渡され、この関数で受け入れられる任意の有効なフラグの組み合わせに設定できます。 0 の値によって、Service Fabric ランタイムで信頼状態エラーを強制的に無視させますが、これは推奨されません。その使用によってセキュリティが著しく侵害されることがあるためです。 既定値は 0x40000000 (CERT_CHAIN_REVOCATION_CHECK_CHAIN_EXCLUDE_ROOT) です。

使用するタイミング: 完全に形成されていないか、証明書をサポートするための適切な公開キー インフラストラクチャがない自己署名証明書または開発者証明書を使用したローカル テストの場合。 エアギャップ環境で、PKI 間の移行時に軽減策として使用することもできます。

使用方法: 失効チェックで、キャッシュされた URL のみにアクセスさせる例を説明します。 前提:

#define CERT_CHAIN_REVOCATION_CHECK_CACHE_ONLY         0x80000000

クラスター マニフェスト内の宣言は次のようになります。

  <Section Name="Security">
    <Parameter Name="CrlCheckingFlag" Value="0x80000000" />
  </Section>
  • IgnoreCrlOfflineError - "Security" セクションの下の、'false' の既定値のブール値。 "失効オフライン" チェーン構築エラー状態 (または、後続のチェーン ポリシー検証エラー状態) を抑制するためのショートカットを表します。

使用するタイミング: 適切な PKI で裏付けされていない開発者証明書を使用したローカル テスト。 エアギャップ環境での軽減策として、または PKI にアクセスできないことがわかっている場合に使用します。

使用方法:

  <Section Name="Security">
    <Parameter Name="IgnoreCrlOfflineError" Value="true" />
  </Section>

その他の注目すべき設定 (すべて "Security" セクション下):

  • AcceptExpiredPinnedClusterCertificate - 拇印ベースの証明書検証専用のセクションで説明しました。期限切れの自己署名クラスター証明書の受け入れを許可します。
  • CertificateExpirySafetyMargin - 証明書の NotAfter タイムスタンプ前の、その間に証明書が期限切れになるリスクがあると見なされる分単位で表される間隔。 Service Fabric では、クラスター証明書が監視され、それらの残りの可用性に関する正常性レポートが定期的に発行されます。 "安全" 間隔内で、これらの正常性レポートは "警告" 状態に昇格されます。 既定値は 30 日です。
  • CertificateHealthReportingInterval - クラスター証明書の残りの有効期間に関する正常性レポートの頻度を制御します。 レポートは、この間隔あたり 1 回だけ発行されます。 値は秒単位で表され、既定値は 8 時間です。
  • EnforcePrevalidationOnSecurityChanges - セキュリティ設定の変更の検出時のクラスター アップグレードの動作を制御するブール値。 "True" に設定した場合、クラスター アップグレードでは、プレゼンテーション ルールのいずれかに一致する証明書の少なくとも 1 つが、対応する検証ルールに合格することを確認する試みを行います。 事前検証は、任意のノードに新しい設定が適用される前に実行されますが、アップグレードの開始時には、クラスター マネージャー サービスのプライマリ レプリカをホストしているノードでのみ実行されます。 執筆時点では、この設定の既定値は 'false' ですが、7.1 以降のランタイム バージョンを使用する新しい Azure Service Fabric クラスターでは ' true ' に設定されます。

エンド ツー エンドのシナリオ (例)

プレゼンテーション規則、検証規則、および調整フラグについて説明しましたが、これはすべてどのように連携するのでしょうか。 このセクションでは、安全なクラスター アップグレードのために、セキュリティ設定をどのように利用するかを示す 2 つのエンド ツー エンドの例について説明します。 これは、Service Fabric での適切な証明書管理に関する包括的な論文になることを意図しているのではなく、そのトピックに関する手引書とされることを期待しています。

プレゼンテーション規則と検証規則を区別することによって、それらは分岐可能かどうか、およびその結果がどうなるかについての明白な疑問 (または懸念) が生じます。 実際に、ノードの認証証明書の選択が、別のノードの検証規則を通過しない可能性があります。 事実、この違いは、認証関連のインシデントの主な原因です。 同時に、これらの規則の区別によって、クラスターのセキュリティ設定を変更するアップグレード中も、クラスターの動作を続行させることができます。 最初の手順として検証規則を最初に補強することで、現在の資格情報を引き続き使用しながら、クラスターのすべてのノードを新しい設定に収束させることを考慮してください。

Service Fabric クラスターでは、アップグレードが最大 5 つの "アップグレード ドメイン" または UD 経由で行われることを思い出してください。 特定の時点で、現在の UD のノードのみがアップグレードまたは変更され、クラスターの可用性で許可されている場合に限り、次の UD にアップグレードが続行されます。 (詳細については、Service Fabric クラスターのアップグレードと、同じトピックに関するその他の記事を参照してください)。証明書やセキュリティの変更は、クラスターからノードが分離されたり、クラスターがクォーラム損失の瀬戸際に置かれる可能性があるため、特に危険です。

ノードのセキュリティ設定を説明するために、次の表記を使用します。

Nk: {P:{TP=A}, V:{TP=A}}、ここで:

  • 'Nk' は、アップグレード ドメイン k 内のノードを表します
  • 'P' は、ノードの現在のプレゼンテーション規則を表します (クラスター証明書のみを参照していることを前提としています)。
  • 'V' は、ノードの現在の検証規則を表します (クラスター証明書のみ)
  • 'TP=A' は拇印ベースの宣言 (TP) を表し、"A" は証明書の拇印です
  • 'CN=B' は、共通名ベースの宣言 (CN) を表します。'B' は証明書のサブジェクト共通名です

拇印によって宣言されたクラスター証明書のローテーション

次のシーケンスでは、拇印によって宣言されたセカンダリ クラスター証明書を安全に導入するために、2 段階アップグレードを使用する方法について説明します。最初のフェーズでは、検証規則に新しい証明書宣言を導入し、2 番目のフェーズでそれをプレゼンテーション規則に導入します。

  • 初期状態:N0 = {P:{TP=A}, V:{TP=A}}, ...Nk = {P:{TP=A}, V:{TP=A}} - クラスターは静止状態で、すべてのノードは共通の構成を共有しています
  • アップグレード ドメイン 0 の完了時:N0 = {P:{TP=A}, V:{TP=A, TP=B}}, ...Nk = {P:{TP=A}, V:{TP=A}} - UD0 内のノードは証明書 A を提示し、証明書 A または B を受け入れます。他のすべてのノードは証明書 A のみを提示して、受け入れます
  • 最後のアップグレード ドメインの完了時:N0 = {P:{TP=A}, V:{TP=A, TP=B}}, ...Nk = {P:{TP=A}, V:{TP=A, TP=B}} - すべてのノードは証明書 A を提示し、すべてのノードは証明書 A または B を受け入れます

この時点で、クラスターは再度平衡状態になり、セキュリティ設定のアップグレードや変更の第 2 フェーズを開始できます。

  • アップグレード ドメイン 0 の完了時:N0 = {P:{TP=A, TP=B}, V:{TP=A, TP=B}}, ...Nk = {P:{TP=A}, V:{TP=A, TP=B}} - UD0 内のノードは B の提示を開始します。これはクラスター内の他のすべてのノードによって受け入れられます。
  • 最後のアップグレード ドメインの完了時:N0 = {P:{TP=A, TP=B}, V:{TP=A, TP=B}}, ...Nk = {P:{TP=A, TP=B}, V:{TP=A, TP=B}} - すべてのノードが証明書 B を提示するように切り替えられました。証明書 A は、その後の一連のアップグレードでクラスター定義から廃止または削除できるようになりました。

拇印から共通名ベースの証明書宣言へのクラスターの変換

同様に、証明書宣言の種類の変更 (拇印から共通名へ) では、上記と同じパターンに従います。 検証規則では、同じクラスター定義で、拇印と共通名の両方によって、特定のロールの証明書を宣言できることに注意してください。 一方、プレゼンテーション規則では、1 つの形式の宣言のみが許可されます。 ちなみに、クラスター証明書を拇印から共通名に変換する安全な方法は、最初に拇印によって目的のターゲット証明書を導入し、次にその宣言を共通名ベースのものに変更することです。 次の例では、拇印 'A' とサブジェクト共通名 'B' が同じ証明書を参照していることを前提としています。

  • 初期状態:N0 = {P:{TP=A}, V:{TP=A}}, ...Nk = {P:{TP=A}, V:{TP=A}} - クラスターは静止状態で、すべてのノードが共通の構成を共有し、A はプライマリ証明書拇印です
  • アップグレード ドメイン 0 の完了時:N0 = {P:{TP=A}, V:{TP=A, CN=B}}, ...Nk = {P:{TP=A}, V:{TP=A}} - UD0 内のノードは証明書 A を提示し、拇印 A または共通名 B のいずれかの証明書を受け入れます。他のすべてのノードは証明書 A のみを提示し、受け入れます
  • 最後のアップグレード ドメインの完了時:N0 = {P:{TP=A}, V:{TP=A, CN=B}}, ...Nk = {P:{TP=A}, V:{TP=A, CN=B}} - すべてのノードは証明書 A を提示し、すべてのノードは証明書 A (TP) または B (CN) を受け入れます

現在のところ、その後のアップグレードでプレゼンテーション規則の変更を続行できます。

  • アップグレード ドメイン 0 の完了時:N0 = {P:{CN=B}, V:{TP=A, CN=B}}, ...Nk = {P:{TP=A}, V:{TP=A, CN=B}} - UD0 内のノードは CN によって検出された証明書 B を提示し、拇印 A または共通名 B の証明書を受け入れます。他のすべてのノードは、拇印によって選択された証明書 A のみを提示し、受け入れます
  • 最後のアップグレード ドメインの完了時:N0 = {P:{CN=B}, V:{TP=A, CN=B}}, ...Nk = {P:{CN=B}, V:{TP=A, CN=B}} - すべてのノードは CN によって検出された証明書 B を提示し、すべてのノードは証明書 A (TP) または B (CN) のいずれかを受け入れます

フェーズ 2 の完了によって、クラスターの共通名ベースの証明書への変換もマークされます。拇印ベースの検証の宣言は、その後のクラスター アップグレードで削除できます。

Note

Azure Service Fabric クラスターでは、上で示したワークフローは Service Fabric リソース プロバイダーによって調整されます。クラスター所有者は引き続き、指定された規則 (プレゼンテーションまたは検証) に従って、クラスターに証明書をプロビジョニングする責任を負い、複数の手順で変更を行うことが推奨されます。

別の記事で、証明書の管理と Service Fabric クラスターへのプロビジョニングのトピックを取り上げます。

トラブルシューティングとよく寄せられる質問

Service Fabric クラスターで認証に関連した問題のデバッグは簡単ではありませんが、次のヒントや助言が役に立つものと考えます。 調査を開始する最も簡単な方法は、クラスターのノード (必ずしも兆候を示しているノードだけではなく、稼働しているが近隣のいずれかのノードに接続できないノードも) の Service Fabric イベント ログを調べることです。 Windows では、重要なイベントは通常、'Applications and Services Logs\Microsoft-ServiceFabric\Admin' または 'Operational' チャネルの下にそれぞれ記録されます。 場合によっては、CAPI2 ログを有効にして、証明書検証、CRL/CTL の取得などに関する詳細をキャプチャすることが役に立つ場合があります。(再現を完了したら、それを無効にすることを忘れないでください。それは詳細になりすぎる可能性があります)。

認証の問題が発生しているクラスターで現れる一般的な兆候は:

  • ノードがダウンしている/循環している
  • 接続試行が拒否される
  • 接続試行がタイムアウトする

各兆候はさまざまな問題によって発生する可能性があり、同じ根本原因で異なる兆候が示されることがあります。そのため、一般的な問題の小さなサンプルだけを、修正のためのレコメンデーションと共に一覧表示します。

  • ノードはメッセージを交換できますが、接続できません。 接続試行が終了する可能性のある原因として、"証明書が一致しません" というエラーがあります。Service Fabric から Service Fabric への接続で、一方のパーティが、受信者の検証規則に失敗した証明書を提示しています。 次のいずれかのエラーが伴う場合があります。

    0x80071c44	-2147017660	FABRIC_E_SERVER_AUTHENTICATION_FAILED
    

    さらに診断/調査を行うには: 接続を試行している各ノードで、提示されている証明書を特定します。証明書を調査し、検証規則をエミュレートしてみます (拇印または共通名の等価性をチェックし、発行者の拇印が指定されている場合はそれをチェックします)。

    他の付随する一般的なエラーコードは、次のようなものがあります。

    0x800b0109	-2146762487	CERT_E_UNTRUSTEDROOT
    

    このケースでは、証明書は共通名によって宣言され、次のいずれかが当てはまります。

    • 発行者がピン留めされておらず、ルート証明書が信頼されていない、または
    • 発行者はピン留めされているが、宣言にこの証明書の直接の発行者の拇印が含まれない
  • ノードは稼働していますが、他のノードに接続できません。他のノードは、障害の発生しているノードから受信トラフィックを受信しません。 このケースでは、ローカル ノードで証明書の読み込みが失敗する可能性があります。 次のエラーを探します。

    • 証明書が見つかりません - プレゼンテーション規則で宣言されている証明書が、LocalMachine\My (または指定された) 証明書ストアの内容によって解決できることを確認してください。 エラーの可能性のある原因には次のものが含まれる可能性があります。

      • 拇印宣言内の無効な文字
      • 証明書がインストールされていない
      • 証明書の有効期限が切れている
      • 共通名の宣言にプレフィックス 'CN=' が含まれている
      • 宣言でワイルドカードを指定し、完全一致が証明書ストアに存在しない (宣言:CN=*.mydomain.com、実際の証明書:CN=server.mydomain.com)
    • 不明な資格情報 - 証明書に対応する秘密キーがないことを示し、通常は次のエラーコードが伴います。

      0x8009030d	-2146893043	SEC_E_UNKNOWN_CREDENTIALS
      0x8009030e	-2146893042	SEC_E_NO_CREDENTIALS
      

      解決するには、秘密キーの存在をチェックします。SFAdmins に秘密キーへの 'read|execute' アクセスが付与されていることを確認します。

    • 不正なプロバイダーの種類 - Crypto New Generation (CNG) 証明書 ("Microsoft Software Key Storage Provider") を示します。現在のところ、Service Fabric では CAPI1 証明書のみがサポートされています。 通常、次のエラーコードが伴います。

      0x80090014	-2146893804	NTE_BAD_PROV_TYPE
      

      解決するには、CAPI1 (例:"Microsoft Enhanced RSA and AES Cryptographic Provider") プロバイダーを使用してクラスター証明書を再作成します。 暗号化プロバイダーの詳細については、「暗号化プロバイダーについて」を参照してください