プライベート CA を使用して相互 TLS を設定する

このページでは、Certificate Authority Service を使用して証明書を Certificate Manager TrustConfig リソースにアップロードし、プライベート認証局(CA)を作成する手順について説明します。

また、アプリケーション ロードバランサの相互 TLS の構成に必要なネットワーク セキュリティ リソースも作成します。

始める前に

  • 相互 TLS の概要を確認します。
  • Google Cloud CLI をインストールします。ツールの完全な概要については、gcloud CLI の概要をご覧ください。ロード バランシングに関連するコマンドについては、API と gcloud CLI のリファレンスをご覧ください。

    gcloud CLI を初めて実行する場合は、最初に gcloud init を実行して認証します。

  • CA プールの作成方法を確認します。

  • グローバル外部アプリケーション ロードバランサまたは従来のアプリケーション ロードバランサを使用している場合は、次のサポート対象のバックエンドのいずれかでロードバランサが設定されていることを確認してください。

    • VM インスタンス グループのバックエンド
    • Cloud Storage バケット(バックエンド バケットに加えて、ロードバランサに接続されているバックエンド サービスが 1 つ以上ある場合にのみサポートされます)
    • Cloud Run、App Engine、または Cloud Run 関数
    • ハイブリッド接続
  • リージョン外部アプリケーション ロードバランサ、クロスリージョン内部アプリケーション ロードバランサ、またはリージョン内部アプリケーション ロードバランサを使用している場合は、次のいずれかのサポート対象のバックエンドを使用してロードバランサが設定されていることを確認します。

    • VM インスタンス グループのバックエンド
    • Cloud Run
    • ハイブリッド接続

権限

このガイドで必要になる権限を取得するには、プロジェクトに対する次の IAM ロールを付与するよう管理者に依頼してください。

  • TargetHTTPProxy などのロードバランサ リソースを作成する: Compute ロードバランサ管理者roles/compute.loadBalancerAdmin
  • Certificate Manager リソースを使用する: Certificate Manager オーナーroles/certificatemanager.owner
  • セキュリティとネットワーキングのコンポーネントを作成する: Compute セキュリティ管理者(roles/compute.networkAdmin)と Compute セキュリティ管理者(roles/compute.securityAdmin
  • プロジェクトを作成する(オプション): プロジェクト作成者roles/resourcemanager.projectCreator

ロールの付与の詳細については、アクセスの管理をご覧ください。

必要な権限は、カスタムロールや他の事前定義ロールから取得することもできます。

プライベート CA を作成する

CA Service を使用してプライベート CA を作成し、ルート証明書を作成します。

  1. CA プールを作成するには、gcloud privateca pools create コマンドを使用します。

    gcloud privateca pools create CA_POOL \
       --location=us-central1
    

    CA_POOL は、親 CA プールの ID または名前に置き換えます。

  2. CA プールにプライベート CA を作成するには、gcloud privateca roots create コマンドを使用します。

    gcloud privateca roots create CA_ROOT \
       --pool=CA_POOL \
       --subject="CN=my-ca, O=Test LLC" \
       --location=us-central1
    

    次のように置き換えます。

    • CA_ROOT: プライベート CA の ID または名前
    • CA_POOL: 親 CA プールの ID または名前
  3. 新しい CA の説明を取得して root.cert ファイルを作成するには、gcloud privateca roots describe コマンドを使用します。

    gcloud privateca roots describe CA_ROOT \
       --pool=CA_POOL \
       --location=us-central1 \
       --format='value(pemCaCertificates)' > root.cert
    
    export ROOT=$(cat root.cert | sed 's/^[ ]*//g' | tr '\n' $ | sed 's/\$/\\n/g')
    

    次のように置き換えます。

    • CA_ROOT: プライベート CA の ID または名前
    • CA_POOL: 親 CA プールの ID または名前

    詳しくは以下をご覧ください。

プライベート CA を使用して TrustConfig を作成する

プライベート CA を使用して生成されたルート証明書を使用して、PKI を表す Certificate Manager TrustConfig リソースを作成します。ここでは、TrustConfig リソースは、ルート証明書を表す単一の信頼アンカーを持つシンプルなトラストストアであることを前提としています。

次の手順では、TRUST_CONFIG_NAMETrustConfig リソースの名前に置き換えます。

  • trust_config.yaml ファイルを作成するには、次のコマンドを使用します。

    cat << EOF > trust_config.yaml
    name: TRUST_CONFIG_NAME
    trustStores:
    - trustAnchors:
       - pemCertificate: "${ROOT?}"
    EOF
    
  • Certificate Manager の TrustConfig リソースを作成するには、gcloud certificate-manager trust-configs import コマンドを使用します。

    gcloud certificate-manager trust-configs import TRUST_CONFIG_NAME  \
       --source=trust_config.yaml \
       --location=REGION
    

    次のように置き換えます。

    REGION: クロスリージョン内部アプリケーション ロードバランサ、グローバル外部アプリケーション ロードバランサ、または従来のアプリケーション ロードバランサには、global を使用します。リージョン外部アプリケーション ロードバランサまたはリージョン内部アプリケーション ロードバランサには、ロードバランサを構成したリージョンを使用します。

クライアント認証リソースを作成する

クライアント認証(ServerTLSPolicy とも呼ばれます)リソースを使用すると、クライアント証明書の検証で使用するサーバーサイド TLS モードと TrustConfig リソースを指定できます。クライアントがロードバランサに無効な証明書を提示するか、証明書を提示しない場合は、clientValidationMode でクライアント接続の処理方法を指定します。詳細については、MTLS クライアント検証モードをご覧ください。

  • clientValidationModeALLOW_INVALID_OR_MISSING_CLIENT_CERT に設定されている場合、検証が失敗した場合やクライアント証明書が欠落していても、すべてのリクエストがバックエンドに渡されます。
  • clientValidationModeREJECT_INVALID に設定されている場合、TrustConfig リソースの検証が可能なクライアント証明書を提示するリクエストのみがバックエンドに渡されます。

ServerTLSPolicy リソースを作成するには、次の手順を完了します。

  1. 接続の処理方法に応じて、次のいずれかのオプションを選択します。

    次の手順では、SERVER_TLS_POLICY_NAME をサーバー TLS ポリシーの名前に置き換え、PROJECT_ID を Google Cloud プロジェクトの ID に置き換えます。

    • オプション 1: clientValidationModeALLOW_INVALID_OR_MISSING_CLIENT_CERT に設定されている。

      server_tls_policy.yaml ファイルを作成するには、次のコマンドを使用します。

      グローバル

      外部アプリケーション ロードバランサとクロスリージョン内部アプリケーション ロードバランサの場合は、次のコマンドを使用します。

      cat << EOF > server_tls_policy.yaml
      name: SERVER_TLS_POLICY_NAME
      mtlsPolicy:
        clientValidationMode: ALLOW_INVALID_OR_MISSING_CLIENT_CERT
        clientValidationTrustConfig: projects/PROJECT_ID/locations/global/trustConfigs/TRUST_CONFIG_NAME
      EOF
      

      リージョン

      リージョン外部アプリケーション ロードバランサとリージョン内部アプリケーション ロードバランサの場合は、次のコマンドを使用します。

      cat << EOF > server_tls_policy.yaml
      name: SERVER_TLS_POLICY_NAME
      mtlsPolicy:
        clientValidationMode: ALLOW_INVALID_OR_MISSING_CLIENT_CERT
        clientValidationTrustConfig: projects/PROJECT_ID/locations/REGION/trustConfigs/TRUST_CONFIG_NAME
      EOF
      
    • オプション 2: clientValidationModeREJECT_INVALID に設定されている。

      server_tls_policy.yaml ファイルを作成するには、次のコマンドを使用します。

      グローバル

      外部アプリケーション ロードバランサとクロスリージョン内部アプリケーション ロードバランサの場合は、次のコマンドを使用します。

      cat << EOF > server_tls_policy.yaml
      name: SERVER_TLS_POLICY_NAME
      mtlsPolicy:
        clientValidationMode: REJECT_INVALID
        clientValidationTrustConfig: projects/PROJECT_ID/locations/global/trustConfigs/TRUST_CONFIG_NAME
      EOF
      

      リージョン

      リージョン外部アプリケーション ロードバランサとリージョン内部アプリケーション ロードバランサの場合は、次のコマンドを使用します。

      cat << EOF > server_tls_policy.yaml
      name: SERVER_TLS_POLICY_NAME
      mtlsPolicy:
        clientValidationMode: REJECT_INVALID
        clientValidationTrustConfig: projects/PROJECT_ID/locations/REGION/trustConfigs/TRUST_CONFIG_NAME
      EOF
      
  2. ServerTlsPolicy リソースを作成するには、gcloud network-security server-tls-policies import コマンドを使用します。

    グローバル

    外部アプリケーション ロードバランサとクロスリージョン内部アプリケーション ロードバランサの場合は、次のコマンドを使用します。

    gcloud network-security server-tls-policies import SERVER_TLS_POLICY_NAME \
      --source=server_tls_policy.yaml \
      --location=global
    

    リージョン

    リージョン外部アプリケーション ロードバランサとリージョン内部アプリケーション ロードバランサの場合は、次のコマンドを使用します。

    gcloud network-security server-tls-policies import SERVER_TLS_POLICY_NAME \
      --source=server_tls_policy.yaml \
      --location=REGION
    
  3. 省略可: 現在のプロジェクトのロケーションにあるすべてのクライアント認証(ServerTlsPolicies)リソースを一覧表示します。

    コンソール

    1. Google Cloud コンソールで、[クライアント認証] ページに移動します。

      [クライアント認証] に移動

    2. すべての ServerTlsPolicies リソースが表示されます。

    gcloud

    すべてのクライアント認証(ServerTlsPolicies)リソースを一覧表示するには、gcloud network-security server-tls-policies list コマンドを使用します。

    gcloud network-security server-tls-policies list \
      --location=REGION
    

    次のように置き換えます。

    REGION: クロスリージョン内部アプリケーション ロードバランサ、グローバル外部アプリケーション ロードバランサ、または従来のアプリケーション ロードバランサには、global を使用します。リージョン外部アプリケーション ロードバランサまたはリージョン内部アプリケーション ロードバランサには、ロードバランサを構成したリージョンを使用します。

ロードバランサに mTLS を設定する

相互 TLS 認証を機能させるには、ロードバランサを設定した後、ServerTLSPolicy リソースを使用してターゲット HTTPS プロキシを更新する必要があります。

  1. クライアント認証(ServerTLSPolicy)リソースが作成されていることを確認します。手順については、クライアント認証リソースを作成するをご覧ください。

  2. プロジェクト内のすべてのターゲット HTTPS プロキシを一覧表示するには、gcloud compute target-https-proxies list コマンドを使用します。

    gcloud compute target-https-proxies list
    

    ServerTLSPolicy リソースを接続するターゲット HTTPS プロキシの名前をメモします。以降のステップでは、この名前を TARGET_HTTPS_PROXY_NAME として表しています。

  3. ターゲット HTTPS プロキシの構成をファイルにエクスポートするには、gcloud compute target-https-proxies export コマンドを使用します。

    グローバル

      gcloud compute target-https-proxies export TARGET_HTTPS_PROXY_NAME \
          --destination=TARGET_PROXY_FILENAME \
          --global
      

    次のように置き換えます。

    • TARGET_HTTPS_PROXY_NAME: ターゲット プロキシの名前。
    • TARGET_PROXY_FILENAME: yaml ファイルの名前。例: mtls_target_proxy.yaml

    リージョン

     gcloud compute target-https-proxies export TARGET_HTTPS_PROXY_NAME \
         --destination=TARGET_PROXY_FILENAME \
         --region=REGION
     

    次のように置き換えます。

    • TARGET_HTTPS_PROXY_NAME: ターゲット プロキシの名前。
    • TARGET_PROXY_FILENAME: yaml ファイルの名前。例: mtls_target_proxy.yaml
    • REGION: ロードバランサを構成したリージョン。
  4. 現在のプロジェクトの指定されたロケーションにある ServerTlsPolicies リソースを一覧表示します。

    コンソール

    1. Google Cloud コンソールで、[クライアント認証] ページに移動します。

      [クライアント認証] に移動

    2. すべての ServerTlsPolicies リソースが表示されます。

    gcloud

    すべてのクライアント認証(ServerTlsPolicies)リソースを一覧表示するには、gcloud network-security server-tls-policies list コマンドを使用します。

    gcloud network-security server-tls-policies list \
      --location=REGION
    

    次のように置き換えます。

    REGION: クロスリージョン内部アプリケーション ロードバランサ、グローバル外部アプリケーション ロードバランサ、または従来のアプリケーション ロードバランサには、global を使用します。リージョン外部アプリケーション ロードバランサまたはリージョン内部アプリケーション ロードバランサには、ロードバランサを構成したリージョンを使用します。

    mTLS を構成する ServerTlsPolicies リソースの名前をメモします。この名前は、次のステップで SERVER_TLS_POLICY_NAME として参照しています。

  5. ServerTlsPolicy リソース ファイル TARGET_PROXY_FILENAME を追加するには、次のコマンドを使用します。PROJECT_ID は、Google Cloud プロジェクトの ID に置き換えます。

    echo "serverTlsPolicy: //networksecurity.googleapis.com/projects/PROJECT_ID/locations/REGION/serverTlsPolicies/SERVER_TLS_POLICY_NAME" >> TARGET_PROXY_FILENAME
    
  6. ターゲット HTTPS プロキシの構成をファイルからインポートするには、gcloud compute target-https-proxies import コマンドを使用します。

    グローバル

       gcloud compute target-https-proxies import TARGET_HTTPS_PROXY_NAME \
           --source=TARGET_PROXY_FILENAME \
           --global
       

    次のように置き換えます。

    • TARGET_HTTPS_PROXY_NAME: ターゲット プロキシの名前。
    • TARGET_PROXY_FILENAME: yaml ファイルの名前。例: mtls_target_proxy.yaml

    リージョン

       gcloud compute target-https-proxies import TARGET_HTTPS_PROXY_NAME \
           --source=TARGET_PROXY_FILENAME \
           --region=REGION
       

    次のように置き換えます。

    • TARGET_HTTPS_PROXY_NAME: ターゲット プロキシの名前。
    • TARGET_PROXY_FILENAME: yaml ファイルの名前。例: mtls_target_proxy.yaml
    • REGION: ロードバランサを構成したリージョン。

mTLS カスタム ヘッダーを追加する

mTLS を有効にすると、カスタム ヘッダーを使用して mTLS 接続に関する情報を渡すことができます。また、ロギングを有効にして、mTLS 接続エラーをログにキャプチャすることもできます。

バックエンド サービスに mTLS カスタム ヘッダーを追加する

グローバル外部アプリケーション ロードバランサまたは従来のアプリケーション ロードバランサの場合、カスタム ヘッダーを使用して mTLS 接続に関する情報をバックエンド サービスに渡すことができます。

  1. プロジェクト内のすべてのバックエンド サービスを一覧表示するには、gcloud compute backend-services list コマンドを使用します。

    gcloud compute backend-services list
    

    カスタム ヘッダーとロギングを有効にするため、バックエンド サービスの名前をメモします。この名前は、次のステップで BACKEND_SERVICE として参照されます。

  2. バックエンド サービスを更新するには、gcloud compute backend-services update コマンドを使用します。

    gcloud compute backend-services update BACKEND_SERVICE \
      --global \
      --enable-logging \
      --logging-sample-rate=1 \
      --custom-request-header='X-Client-Cert-Present:{client_cert_present}' \
      --custom-request-header='X-Client-Cert-Chain-Verified:{client_cert_chain_verified}' \
      --custom-request-header='X-Client-Cert-Error:{client_cert_error}' \
      --custom-request-header='X-Client-Cert-Hash:{client_cert_sha256_fingerprint}' \
      --custom-request-header='X-Client-Cert-Serial-Number:{client_cert_serial_number}' \
      --custom-request-header='X-Client-Cert-SPIFFE:{client_cert_spiffe_id}' \
      --custom-request-header='X-Client-Cert-URI-SANs:{client_cert_uri_sans}' \
      --custom-request-header='X-Client-Cert-DNSName-SANs:{client_cert_dnsname_sans}' \
      --custom-request-header='X-Client-Cert-Valid-Not-Before:{client_cert_valid_not_before}' \
      --custom-request-header='X-Client-Cert-Valid-Not-After:{client_cert_valid_not_after}'
    

mTLS カスタム ヘッダーを URL マップに追加する

クロスリージョン内部アプリケーション ロードバランサ、リージョン外部アプリケーション ロードバランサ、リージョン内部アプリケーション ロードバランサの場合は、カスタム ヘッダーを使用して mTLS 接続に関する情報を URL マップに渡すことができます。

プロジェクト内のすべての URL マップを一覧表示するには、gcloud compute url-maps list コマンドを使用します。

   gcloud compute url-maps list
   

カスタム ヘッダーとロギングを有効にするために、URL マップの名前をメモします。次のステップでは、この名前を URL_MAP_NAME と表しています。

グローバル

クロスリージョン内部アプリケーション ロードバランサの URL マップを編集するには、gcloud compute url-maps edit コマンドを使用します。

   gcloud compute url-maps edit URL_MAP_NAME --global
   

以下に、カスタム リクエスト ヘッダー(requestHeadersToAdd)で変数を使用する方法を示す YAML ファイルの例を示します。同じ変数を使用して、カスタム レスポンス ヘッダー(responseHeadersToAdd)を送信できます。

   headerAction:
      requestHeadersToAdd:
      - headerName: "X-Client-Cert-Present"
        headerValue: "{client_cert_present}"
      - headerName: "X-Client-Cert-Chain-Verified"
        headerValue: "{client_cert_chain_verified}"
      - headerName: "X-Client-Cert-Error"
        headerValue: "{client_cert_error}"
      - headerName: "X-Client-Cert-Hash"
        headerValue: "{client_cert_sha256_fingerprint}"
      - headerName: "X-Client-Cert-Serial-Number"
        headerValue: "{client_cert_serial_number}"
      - headerName: "X-Client-Cert-SPIFFE"
        headerValue: "{client_cert_spiffe_id}"
      - headerName: "X-Client-Cert-URI-SANs"
        headerValue: "{client_cert_uri_sans}"
      - headerName: "X-Client-Cert-DNSName-SANs"
        headerValue: "{client_cert_dnsname_sans}"
      - headerName: "X-Client-Cert-Valid-Not-Before"
        headerValue: "{client_cert_valid_not_before}"
      - headerName: "X-Client-Cert-Valid-Not-After"
        headerValue: "{client_cert_valid_not_after}"
      - headerName: "X-Client-Cert-Issuer-Dn"
        headerValue: "{client_cert_issuer_dn}"
      - headerName: "X-Client-Cert-Subject-Dn"
        headerValue: "{client_cert_subject_dn}"
      - headerName: "X-Client-Cert-Leaf"
        headerValue: "{client_cert_leaf}"
      - headerName: "X-Client-Cert-Chain"
        headerValue: "{client_cert_chain}"
   

リージョン

リージョン外部アプリケーション ロードバランサまたはリージョン内部アプリケーション ロードバランサの URL マップを編集するには、gcloud compute url-maps edit コマンドを使用します。

   gcloud compute url-maps edit URL_MAP_NAME --region=REGION
   

以下に、カスタム リクエスト ヘッダー(requestHeadersToAdd)で変数を使用する方法を示す YAML ファイルの例を示します。同じ変数を使用してカスタム レスポンス ヘッダー(responseHeadersToAdd)を送信できます。

   defaultService: regions/REGION/backendServices/BACKEND_SERVICE_1
      name: regional-lb-map
      region: region/REGION
   headerAction:
      requestHeadersToAdd:
      - headerName: "X-Client-Cert-Present"
        headerValue: "{client_cert_present}"
      - headerName: "X-Client-Cert-Chain-Verified"
        headerValue: "{client_cert_chain_verified}"
      - headerName: "X-Client-Cert-Error"
        headerValue: "{client_cert_error}"
      - headerName: "X-Client-Cert-Hash"
        headerValue: "{client_cert_sha256_fingerprint}"
      - headerName: "X-Client-Cert-Serial-Number"
        headerValue: "{client_cert_serial_number}"
      - headerName: "X-Client-Cert-SPIFFE"
        headerValue: "{client_cert_spiffe_id}"
      - headerName: "X-Client-Cert-URI-SANs"
        headerValue: "{client_cert_uri_sans}"
      - headerName: "X-Client-Cert-DNSName-SANs"
        headerValue: "{client_cert_dnsname_sans}"
      - headerName: "X-Client-Cert-Valid-Not-Before"
        headerValue: "{client_cert_valid_not_before}"
      - headerName: "X-Client-Cert-Valid-Not-After"
        headerValue: "{client_cert_valid_not_after}"
      - headerName: "X-Client-Cert-Issuer-Dn"
        headerValue: "{client_cert_issuer_dn}"
      - headerName: "X-Client-Cert-Subject-Dn"
        headerValue: "{client_cert_subject_dn}"
      - headerName: "X-Client-Cert-Leaf"
        headerValue: "{client_cert_leaf}"
      - headerName: "X-Client-Cert-Chain"
        headerValue: "{client_cert_chain}"
   

次のステップ