ユーザー指定の証明書を使用して相互 TLS を設定する

このページでは、ルート証明書と署名付きの中間証明書を作成し、それらの証明書を Certificate Manager TrustConfig リソースにアップロードする手順を説明します。アップロードする証明書がすでにある場合は、新しい証明書を作成する手順をスキップします。

また、アプリケーション ロードバランサの相互 TLS(mTLS)を構成に必要なネットワーク セキュリティ リソースも作成します。この手順では、OpenSSL を使用してルート証明書と中間証明書を作成します。

始める前に

権限

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

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

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

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

鍵と署名済み証明書を生成する

このセクションでは、openssl コマンドを使用してルート証明書と中間証明書を作成します。

ルート証明書と、有効な keyUsage フィールドと extendedKeyUsage フィールドを含む署名付き中間証明書を生成するには、次のコマンドを使用します。

  1. 有効な署名証明書を作成するために必要な最小限の構成を含むサンプルの example.cnf ファイルを作成します。これらの証明書に追加のフィールドを設定する場合は、このファイルを編集できます。

    cat > example.cnf << EOF
    [req]
    distinguished_name = empty_distinguished_name
    [empty_distinguished_name]
    # Kept empty to allow setting via -subj command line arg.
    [ca_exts]
    basicConstraints=critical,CA:TRUE
    keyUsage=keyCertSign
    extendedKeyUsage=clientAuth
    EOF
    
  2. ルート証明書を作成します。

    openssl req -x509 \
        -new -sha256 -newkey rsa:2048 -nodes \
        -days 3650 -subj '/CN=root' \
        -config example.cnf \
        -extensions ca_exts \
        -keyout root.key -out root.cert
    
  3. 中間証明書の署名リクエストを作成します。

    openssl req \
        -new -sha256 -newkey rsa:2048 -nodes \
        -subj '/CN=int' \
        -config example.cnf \
        -extensions ca_exts \
        -keyout int.key -out int.req
    
  4. 中間証明書を作成します。

    openssl x509 -req \
        -CAkey root.key -CA root.cert \
        -set_serial 1 \
        -days 3650 \
        -extfile example.cnf \
        -extensions ca_exts \
        -in int.req -out int.cert
    

許可リストに登録済みの証明書を生成する

このセクションでは、openssl コマンドを使用して許可リストに登録済み証明書のサンプルを作成します。

許可リストに登録済みの証明書を生成するには、次のコマンドを使用します。

   openssl req -x509 \
       -new -sha256 -newkey rsa:2048 -nodes \
       -days 3650 -subj '/CN=localhost' \
       -keyout allowlisted.key -out allowlisted.cert

証明書をフォーマットする

新規または既存の証明書を TrustStore に含めるには、YAML ファイルに読み込めるように、証明書を 1 行にまとめて環境変数に格納します。次のコマンドを使用して、証明書をフォーマットし、環境変数に保存します。

export ROOT_CERT=$(cat root.cert | sed 's/^[ ]*//g' | tr '\n' $ | sed 's/\$/\\n/g')
export INTERMEDIATE_CERT=$(cat int.cert | sed 's/^[ ]*//g' | tr '\n' $ | sed 's/\$/\\n/g')

新規または既存の許可リストに登録済みの証明書を信頼構成に含めるには、YAML ファイルに読み込めるように、証明書を 1 行にまとめて環境変数に格納します。次のコマンドを使用して、許可リストに登録済みの証明書をフォーマットし、環境変数に格納します。

export ALLOWLISTED_CERT=$(cat allowlisted.cert | sed 's/^[ ]*//g' | tr '\n' $ | sed 's/\$/\\n/g')

TrustConfig リソースを作成する

PKI を表す Certificate Manager TrustConfig リソースを作成します。この TrustConfig リソースには、2 つの信頼アンカーと 2 つの中間 CA 証明書のあるトラストストアが含まれています。前の証明書をフォーマットするの手順で作成した環境変数から証明書の内容を読み取ります。

追加のトラスト アンカーまたは中間 CA 証明書を使用してトラストストアを作成するには、適切なセクションに pemCertificate 行を追加します。信頼アンカーまたは中間 CA 証明書の数が少ない場合は、不要な行を削除します。

この例の TrustConfig リソースには、許可リストに登録済みの証明書が含まれています。pemCertificate フィールドの複数のインスタンスを使用することで、許可リストに登録済みの証明書を複数指定できます。

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

  1. トラストストアを含む trust_config.yaml ファイルを作成するには、次のコマンドを使用します。

    cat << EOF > trust_config.yaml
    trustStores:
    - trustAnchors:
      - pemCertificate: "${ROOT_CERT?}"
      - pemCertificate: "${ROOT_CERT_2?}"
      intermediateCas:
      - pemCertificate: "${INTERMEDIATE_CERT?}"
      - pemCertificate: "${INTERMEDIATE_CERT_2?}"
    EOF
    
  2. 省略可: 許可リストに登録済みの証明書を含む trust_config.yaml ファイルを作成するには、次のコマンドを使用します。

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

    グローバル

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

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

    リージョン

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

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

ネットワーク セキュリティ リソースを作成する

サーバーの TLS ポリシー(ServerTLSPolicy ネットワーク セキュリティ リソース)を使用すると、クライアント証明書の検証で使用するサーバー側 TLS モードと TrustConfig リソースを指定できます。クライアントがロードバランサに無効な証明書を提示するか、証明書を提示しない場合は、clientValidationMode でクライアント接続の処理方法を指定します。

  • 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
    

詳細については、MTLS クライアント検証モードをご覧ください。

中間証明書を使用してクライアント キーに署名する

このセクションでは、リーフ証明書を生成するための追加の構成オプションについて説明します。中間証明書(int.certint.key)を使用してすでに TrustConfig リソースを作成している場合は、次の操作を行います。

  1. クライアント キー構成ファイルを作成します。

    cat > client.config << EOF
    [req]
    default_bits              = 2048
    req_extensions            = extension_requirements
    distinguished_name        = dn_requirements
    prompt                    = no
    
    [extension_requirements]
    basicConstraints          = critical, CA:FALSE
    keyUsage                  = critical, nonRepudiation, digitalSignature, keyEncipherment
    extendedKeyUsage          = clientAuth
    
    [dn_requirements]
    countryName               = US
    stateOrProvinceName       = California
    localityName              = San Francisco
    0.organizationName        = example
    organizationalUnitName    = test
    commonName                = test.example.com
    emailAddress              = test@example.com
    
    EOF
    

    SPIFFE ID が関連付けられている場合:

    • 次のように subjectAltName[extension_requirements] セクションに追加します。

      subjectAltName            = @sans_list
      
    • client.config ファイルの下部に、次の内容の新しいセクションを追加します。

      [sans_list]
      URI.1                     = spiffe://example.com/test-identity
      
  2. 鍵に署名します。

    openssl req -new -keyout client.key -out client.csr -config client.config
    
    openssl x509 -req -in client.csr -out client.cert -extfile client.config -extensions extension_requirements -days 365 -CA int.cert -CAkey int.key
    
  3. テストするために、ロードバランサの IP アドレスに curl リクエストを送信します。

    curl -v -k --key client.key --cert client.cert https://IP_ADDRESS
    

    IP_ADDRESS は、ロードバランサの IP アドレスに置き換えます。

次のステップ