バックエンド サービスでカスタム ヘッダーを作成する

このページでは、グローバル外部アプリケーション ロードバランサで使用されるバックエンド サービスでカスタム ヘッダーを構成する方法について説明します。

カスタム リクエスト ヘッダーとカスタム レスポンス ヘッダーを使用すると、ロードバランサが HTTP(S) のリクエストとレスポンスに追加できる追加のヘッダーを指定できます。ロードバランサで検出された情報に応じて、これらのヘッダーには次の情報が含まれます。

  • クライアントまでのレイテンシ
  • クライアントの IP アドレスの地理的位置
  • TLS 接続のパラメータ

カスタム リクエスト ヘッダーはバックエンド サービスでサポートされていますが、カスタム レスポンス ヘッダーはバックエンド サービスとバックエンド バケットでサポートされています。

ロードバランサは、バックエンドとクライアントの間でプロキシするすべての HTTP(S) リクエストとレスポンスに、デフォルトで特定のヘッダーを追加します。詳細については、ターゲット プロキシをご覧ください。

始める前に

  • 必要に応じて、次のコマンドで Google Cloud CLI を最新バージョンに更新します。

    gcloud components update
    

カスタム ヘッダーの動作

カスタム ヘッダーは次のように動作します。

  • ロードバランサがバックエンドにリクエストを転送する、ロードバランサはリクエスト ヘッダーを追加します。

    ロードバランサは、カスタム リクエスト ヘッダーをクライアント リクエストにのみ追加します。ヘルスチェック プローブには追加しません。バックエンドで認可に特定のヘッダーが必要であり、ヘルスチェック パケットにヘッダーが含まれていない場合、ヘルスチェックが失敗する可能性があります。

  • ロードバランサはレスポンス ヘッダーを設定してから、クライアントにレスポンスを返します。

カスタム ヘッダーを有効にするには、バックエンド サービスまたはバックエンド バケットのプロパティにヘッダーのリストを指定します。

各ヘッダーを header-name:header-value 文字列として指定します。ヘッダーには、ヘッダー名とヘッダー値を区切るコロンを含める必要があります。

ヘッダー名は次の要件を満たす必要があります。

  • ヘッダー名は、有効な HTTP ヘッダー フィールド名の定義でなければなりません(RFC 7230 を遵守)。
  • Host ヘッダーの構成は可能ですが、特定の制限が適用されます。
  • ヘッダー名を authority にすることはできません。これは Google Cloud が予約する特殊なキーワードです。グローバル外部アプリケーション ロードバランサなどの Envoy ベースのロードバランサの場合、このヘッダーは変更できません。代わりに、予約されたヘッダー名が干渉しないように、他のカスタム ヘッダーを作成することをおすすめします。
  • ヘッダー名を X-User-IP または CDN-Loop にすることはできません。
  • ホップバイホップ ヘッダー Keep-AliveTransfer-EncodingTEConnectionTrailerUpgradeProxy-AuthorizationProxy-Authenticate は使用しないでください。RFC 2616 により、これらのヘッダーはキャッシュに保存されず、ターゲット プロキシによって伝播されません。
  • ヘッダー名を X-GoogleX-Goog-X-GFEX-Amz- で始めることはできません。
  • 追加されたヘッダーのリストに、ヘッダー名を複数回使用することはできません。

ヘッダー値は、次の要件を満たす必要があります。

  • ヘッダー値は、HTTP ヘッダー フィールドで有効な定義でなければなりません(RFC 7230 に準拠、古いフォームは使用不可)。
  • ヘッダー値は空白にできます。
  • ヘッダー値には、中括弧で囲まれた 1 つ以上の変数を含めることができます。この変数は、ロードバランサで提供される値に展開されます。ヘッダー値に使用できる変数のリストについては、次のセクションで説明します。

gcloud コマンドライン ツールには、リクエスト ヘッダーを指定するフラグ --custom-request-header があります。このフラグでは、ヘッダー名とヘッダー値を必ず一重引用符(')で囲んでください。

フラグの一般的な形式は次のとおりです。

    --custom-request-header='HEADER_NAME:[HEADER_VALUE]'

次の例は、2 つの変数(client_regionclient_city)が中かっこで囲まれたヘッダー値の例です。

    --custom-request-header='X-Client-Geo-Location:{client_region},{client_city}'

カリフォルニア州のマウンテン ビューに存在するクライアントの場合、ロードバランサにより次のようなヘッダーが追加されます。

X-Client-Geo-Location:US,Mountain View

カスタム ヘッダーを使用してバックエンド サービスを作成するには、カスタム リクエスト ヘッダーを構成するをご覧ください。

Host ヘッダー

グローバル外部アプリケーション ロードバランサでカスタム Host ヘッダーを構成する場合、次の制限が適用されます。

  • カスタムの Host リクエスト ヘッダーは、既存の Host リクエスト ヘッダーを置き換える場合にのみ構成できます。
  • URL マップでヘッダー アクションを使用して、カスタム Host レスポンス ヘッダーを構成することはできません。ただし、バックエンド サービスではカスタム Host レスポンス ヘッダーを構成できます。
  • また、リクエスト ヘッダーとレスポンス ヘッダーの両方に以下が適用されます。
    • カスタム Host ヘッダーを追加または削除することはできません。
    • カスタム Host ヘッダーで変数を使用することはできません。

ヘッダー値でサポートされる変数

カスタム ヘッダー値には、以下の変数を使用できます。

変数 説明
cdn_cache_id リクエストの処理に使用されるキャッシュ インスタンスのロケーション コードと ID。これは、Logging の Cloud CDN リクエストログの jsonPayload.cacheId フィールドに入力されている値と同じです。
cdn_cache_status 現在のキャッシュ ステータス。Cloud CDN 対応のバックエンドから提供されるオブジェクトでは、hitmissrevalidatedstaleuncacheabledisabled のいずれかとなります。
origin_request_header クロスオリジン リソース シェアリング(CORS)のユースケースのリクエストに含まれる Origin ヘッダーの値を反映したものになります。
client_rtt_msec ロードバランサと HTTP(S) クライアント間の推定ラウンドトリップ送信時間(ミリ秒単位)。これは、ロードバランサの TCP スタックによって測定される平滑化されたラウンドトリップ時間(SRTT)パラメータです(RFC 2988 を遵守)。 平滑化された RTT は、RTT 測定値で発生する可能性のある変動と異常を処理するアルゴリズムです。
client_region クライアントの IP アドレスに関連付けられる国(またはリージョン)。これは、USFR などの Unicode CLDR リージョン コードです。(ほとんどの国では、このコードが ISO-3166-2 コードに直接対応しています)。
client_region_subdivision 下位地域区分 - クライアントの IP アドレスに関連付けられる国の区分(たとえば、都道府県や州)。これは Unicode CLDR サブディビジョン ID です(USCACAON など)。(この Unicode コードは、ISO-3166-2 標準で定義されている下位地域区分から派生しています)。
client_city リクエスト送信元の市区町村の名前です。たとえば、カリフォルニアの Mountain View は Mountain View です。この変数について有効な値の正規リストはありません。都市名には、US-ASCII 文字、数字、スペース、および !#$%&'*+-.^_`|~ を含めることができます。
client_city_lat_long リクエスト送信元の都市の緯度と経度です。たとえば、Mountain View からのリクエストの場合には 37.386051,-122.083851 となります。
client_ip_address クライアントの IP アドレス。通常、これは X-Forwarded-For ヘッダー内で最後から 2 番目にあるアドレス(クライアント IP アドレス)と同じです。ただし、クライアントがプロキシを使用している場合や、X-Forwarded-For ヘッダーが改ざんされている場合は除きます。
client_port クライアントの送信元ポート。
client_encrypted クライアントとロードバランサ間の接続が暗号化されている場合(HTTPS、HTTP/2 または HTTP/3 を使用)は、true。それ以外の場合は false です。
client_protocol クライアントとロードバランサ間の通信に使用される HTTP プロトコル。HTTP/1.0HTTP/1.1HTTP/2HTTP/3、のいずれか。
server_ip_address クライアントが接続するロードバランサの IP アドレス。これは、複数のロードバランサが共通のバックエンドを共有する場合に便利です。これは、X-Forwarded-For ヘッダーの最後の IP アドレスと同じです。
server_port クライアントが接続する宛先ポート番号。
tls_sni_hostname RFC 6066 で定義されたサーバー名表示(TLS または QUIC handshake 中にクライアントによって提供された場合)。ホスト名は小文字に変換され、末尾のドットはすべて削除されます。
tls_version SSL handshake 中にクライアントとロードバランサの間でネゴシエートされた TLS バージョン。可能な値は TLSv1TLSv1.1TLSv1.2TLSv1.3 です。クライアントが TLS ではなく QUIC を使用して接続した場合、値は QUIC です。
tls_cipher_suite TLS handshake 中にネゴシエートされた暗号スイート。値は、IANA TLS Cipher Suite Registry で定義された 4 桁の 16 進数です。たとえば、TLS_RSA_WITH_AES_128_GCM_SHA256 の場合は 009C となります。この値は、QUIC と暗号化されていないクライアント接続の場合には空です。
tls_ja3_fingerprint JA3 TLS / SSL フィンガープリント(クライアントが HTTPS、HTTP/2 または HTTP/3 を使用して接続している場合)。

ロードバランサで値を決定できない場合、変数は空の文字列に展開されます。例:

  • IP アドレスのロケーションが不明な場合の地理的なロケーションの変数
  • TLS が使用されていない場合の TLS パラメータ
  • リクエストに Origin ヘッダーが含まれていない場合の {origin_request_header}
  • リクエスト ヘッダーに含まれている場合の {cdn_cache_status} ヘッダー

地理的な値(リージョン、下位地域区分、都市)は、クライアントの IP アドレスに基づく推定値です。Google では、正確性を高め、地理的、政治的な変化を反映させるため、これらの値を提供するデータを更新しています。元の X-Forwarded-For ヘッダーに有効な位置情報が含まれている場合でも、Google はロードバランサで受信したパケットに含まれる送信元 IP アドレスの情報を使用して、クライアントの位置を推定します。

ロードバランサによって追加されたヘッダーにより、同じ名前の既存のヘッダーはすべて上書きされます。ヘッダー名では、大文字と小文字は区別されません。ヘッダー名が HTTP/2 バックエンドに渡されると、HTTP/2 プロトコルによりヘッダー名は小文字としてエンコードされます。

ヘッダー値では、先頭の空白と末尾の空白は重要ではなく、バックエンドには渡されません。ヘッダー値で中括弧を許可するために、ロードバランサでは 2 つの左中括弧({{)を単一の左中括弧({)に変換し、2 つの右中括弧(}})を単一の右中括弧(})に変換します。

相互 TLS カスタム ヘッダー

ロードバランサの TargetHttpsProxy で相互 TLS(mTLS)が構成されている場合、次の追加のヘッダー変数を使用できます。

変数 説明
client_cert_present TLS handshake 中にクライアントが証明書を提供した場合は true、それ以外は false
client_cert_chain_verified true は、構成された TrustStore に対してクライアント証明書チェーンが検証された場合、それ以外の場合は、false
client_cert_error エラー条件を表す事前定義の文字列。エラー文字列の詳細については、mTLS クライアント検証モードをご覧ください。
client_cert_sha256_fingerprint クライアント証明書の Base64 でエンコードされた SHA-256 フィンガープリント。
client_cert_serial_number クライアント証明書のシリアル番号。 シリアル番号が 50 バイトを超える場合、client_cert_errorclient_cert_serial_number_exceeded_size_limit に設定され、シリアル番号は空の文字列に設定されます。
client_cert_spiffe_id

サブジェクト代替名(SAN)フィールドの SPIFFE ID。値が無効であるか、2,048 バイトを超える場合、SPIFFE ID は空の文字列に設定されます。

SPIFFE ID が 2,048 バイトより長い場合、client_cert_errorclient_cert_spiffe_id_exceeded_size_limit に設定されます。

client_cert_uri_sans

URI 型の SAN 拡張機能のカンマ区切り Base64 エンコード リスト。 SAN 拡張機能はクライアント証明書から抽出されます。 client_cert_uri_sans フィールドに SPIFFE ID は含まれません。

client_cert_uri_sans が 512 バイトを超える場合、client_cert_errorclient_cert_uri_sans_exceeded_size_limit に設定され、カンマ区切りリストは空の文字列に設定されます。

client_cert_dnsname_sans

DNSName タイプの SAN 拡張機能のカンマ区切り Base64 エンコード リスト。SAN 拡張機能はクライアント証明書から抽出されます。

client_cert_dnsname_sans が 512 バイトを超える場合、client_cert_errorclient_cert_dnsname_sans_exceeded_size_limit に設定され、カンマ区切りリストは空の文字列に設定されます。

client_cert_valid_not_before クライアント証明書が無効になる前のタイムスタンプ(RFC 3339 日付文字列形式)。 例: 2022-07-01T18:05:09+00:00
client_cert_valid_not_after クライアント証明書が有効でなくなった後のタイムスタンプ(RFC 3339 日付文字列形式)。 例: 2022-07-01T18:05:09+00:00
client_cert_issuer_dn

Base64 でエンコードされた証明書の完全な発行者フィールドの DER エンコード。

client_cert_issuer_dn が 512 バイトを超える場合、文字列 client_cert_issuer_dn_exceeded_size_limitclient_cert_error に追加され、client_cert_issuer_dn は空の文字列に設定されます。

client_cert_subject_dn

Base64 でエンコードされた証明書の完全なサブジェクト フィールドの DER エンコード。

client_cert_subject_dn が 512 バイトを超える場合、文字列 client_cert_subject_dn_exceeded_size_limitclient_cert_error に追加され、client_cert_subject_dn は空の文字列に設定されます。

client_cert_leaf

証明書が検証に合格している確立済みの mTLS 接続のクライアント リーフ証明書。証明書のエンコードは RFC 9440 に準拠しています。つまり、バイナリの DER 証明書は Base64 でエンコードされ、両側がコロンで区切られています。

client_cert_leaf がエンコードされていない状態で 16 KB を超えると、文字列 client_cert_validated_leaf_exceeded_size_limitclient_cert_error に追加され、client_cert_leaf が空の文字列に設定されます。

client_cert_chain

クライアント証明書が検証に合格している確立済みの mTLS 接続のクライアント証明書チェーンの証明書のリスト。このリストはカンマ区切りで、標準の TLS 順序になっています(リーフ証明書は含みません)。証明書のエンコードは RFC 9440 に準拠しています。

Base64 エンコード前の client_cert_leafclient_cert_chain の合計サイズが 16KB を超えると、client_cert_validated_chain_exceeded_size_limitclient_cert_error に追加され、client_cert_chain が空の文字列に設定されます。

カスタム リクエスト ヘッダーを構成する

コンソール

既存のバックエンド サービスにカスタム リクエスト ヘッダーを追加するには:

  1. 負荷分散の概要ページに移動します。
    [負荷分散] ページに移動
  2. [バックエンド] をクリックします。
  3. バックエンド サービスの名前をクリックします。
  4. [編集]()をクリックします。
  5. [高度な構成(セッション アフィニティ、コネクション ドレインのタイムアウト、セキュリティ ポリシー)] をクリックします。
  6. [カスタム リクエスト ヘッダー] で、[ヘッダーを追加] をクリックします。
  7. カスタム リクエスト ヘッダーのヘッダー名ヘッダー値を入力します。
  8. その他のカスタム リクエスト ヘッダーを入力します。
  9. [保存] をクリックします。

カスタム リクエスト ヘッダーをバックエンド サービスから削除するには:

  1. 負荷分散の概要ページに移動します。
    [負荷分散] ページに移動
  2. [バックエンド] をクリックします。
  3. バックエンド サービスの名前をクリックします。
  4. [編集]()をクリックします。
  5. [高度な構成(セッション アフィニティ、コネクション ドレインのタイムアウト、セキュリティ ポリシー)] をクリックします。
  6. 削除するカスタム リクエスト ヘッダーの名前の横にある X をクリックします。
  7. [保存] をクリックします。

gcloud

カスタム リクエスト ヘッダーを指定するには、--custom-request-header フラグを指定して gcloud compute backend-services create または gcloud compute backend-services update コマンドを使用します。

カスタム リクエスト ヘッダーを使用してバックエンド サービスを作成するには:

gcloud compute backend-services create BACKEND_SERVICE_NAME \
    --global-health-checks \
    --global \
    --protocol HTTPS \
    --health-checks https-basic-check \
    --custom-request-header='HEADER_NAME:[HEADER_VALUE]'

リクエスト ヘッダーをさらに追加するには、--custom-request-header フラグを繰り返して、固有のヘッダー名と値を指定します。

既存のバックエンド サービスにカスタム ヘッダーを追加するには:

gcloud compute backend-services update BACKEND_SERVICE_NAME \
    --global \
    --custom-request-header='HEADER_1_NAME:[HEADER_1_VALUE]' \
    --custom-request-header='HEADER_2_NAME:[HEADER_2_VALUE]'

前の手順で、コマンドに指定したリクエスト ヘッダーでバックエンド サービス内のヘッダーを置き換えています

バックエンド サービスからすべてのヘッダーを削除するには:

gcloud compute backend-services update BACKEND_SERVICE_NAME \
    --global \
    --no-custom-request-headers

API

backendServices.patch メソッドに PATCH リクエストを送信します。

PATCH https://compute.googleapis.com/compute/v1/projects/PROJECT_ID/global/backendServices/BACKEND_SERVICE_NAME
"customRequestHeaders": [
   "client_city:Mountain View"
]

カスタム レスポンス ヘッダーを構成する

コンソール

既存のバックエンド サービスにカスタム レスポンス ヘッダーを追加するには:

  1. 負荷分散の概要ページに移動します。
    [負荷分散] ページに移動
  2. [バックエンド] をクリックします。
  3. バックエンド サービスの名前をクリックします。
  4. [編集]()をクリックします。
  5. [高度な構成(セッション アフィニティ、コネクション ドレインのタイムアウト、セキュリティ ポリシー)] をクリックします。
  6. [カスタム レスポンス ヘッダー] で、[ヘッダーを追加] をクリックします。
  7. カスタム レスポンス ヘッダーのヘッダー名ヘッダー値を入力します。
  8. 追加のカスタム レスポンス ヘッダーを入力します。
  9. [保存] をクリックします。

カスタム レスポンス ヘッダーをバックエンド サービスから削除するには:

  1. 負荷分散の概要ページに移動します。
    [負荷分散] ページに移動
  2. [バックエンド] をクリックします。
  3. バックエンド サービスの名前をクリックします。
  4. [編集]()をクリックします。
  5. [高度な構成(セッション アフィニティ、コネクション ドレインのタイムアウト、セキュリティ ポリシー)] をクリックします。
  6. 削除するカスタム レスポンス ヘッダーの名前の横にある X をクリックします。
  7. [保存] をクリックします。

gcloud

バックエンド サービスの場合は、--custom-response-header フラグを指定して gcloud compute backend-services create または gcloud compute backend-services update コマンドを使用します。

バックエンド バケットの場合は、--custom-response-header フラグを指定して gcloud compute backend-buckets create または gcloud compute backend-buckets update コマンドを使用します。

gcloud compute backend-services (create | update) BACKEND_SERVICE_NAME
    --custom-response-header='HEADER_NAME:[HEADER_VALUE]'
gcloud compute backend-buckets (create | update) BACKEND_BUCKET_NAME
    --custom-response-header='HEADER_NAME:[HEADER_VALUE]'

X-Frame-Options ヘッダーを使用した例:

gcloud compute backend-buckets update gaming-lab \
    --custom-response-header='X-Frame-Options: DENY'

Strict-Transport-Security ヘッダーを使用した例:

次の例は、HTTP Strict Transport Security(HSTS)をサポートするカスタム レスポンス ヘッダーを追加する方法を示しています。

gcloud compute backend-services update customer-bs-name \
    --global \
    --custom-response-header='Strict-Transport-Security: max-age=63072000'

API

バックエンド バケットの場合は、Method: backendBuckets.insert または Method: backendBuckets.update API 呼び出しを使用します。

バックエンド サービスの場合は、Method: backendServices.insert または Method: backendServices.update API 呼び出しを使用します。

次のいずれかの API 呼び出しを使用します。

POST https://compute.googleapis.com/compute/v1/projects/PROJECT_ID/global/backendBuckets

PUT https://compute.googleapis.com/compute/v1/projects/PROJECT_ID/global/backendBuckets/BACKEND_BUCKET_NAME

POST https://compute.googleapis.com/compute/v1/projects/PROJECT_ID/global/backendServices

PUT https://compute.googleapis.com/compute/v1/projects/PROJECT_ID/global/backendServices/BACKEND_SERVICE_NAME

JSON リクエストの本文に次のスニペットを追加します。

"customResponseHeaders":HEADER_NAME:[HEADER_VALUE]

Cloud Storage のレスポンス ヘッダーを設定する

Cloud Storage からのレスポンスに、他の HTTP ヘッダー(クロスオリジン リソース ポリシー、X-Frame-Options ヘッダー、X-XSS-Protection ヘッダーなど)を設定する必要がある場合、Google Cloud には Cloud Storage を使用して Cloud CDN のカスタム ヘッダーを設定するオプションが用意されています。この設定を行うには、このページで説明するように、ロードバランサのバックエンド バケットレベルでカスタム ヘッダーを構成します。

バックエンド バケット レベルで構成されたカスタム レスポンス ヘッダーは、クライアント リクエストがロードバランサの IP アドレスに送信された場合にのみレスポンスに追加されます。クライアントのリクエストが Cloud Storage API に直接送信された場合、カスタム ヘッダーはレスポンスに追加されません。

Google Cloud Armor でカスタム ヘッダーを使用する

Google Cloud Armor セキュリティ ポリシーを構成するときに、カスタム ヘッダーと値を挿入するように Google Cloud Armor を構成できます。Google Cloud Armor セキュリティ ポリシーが、グローバル外部アプリケーション ロードバランサまたは従来のアプリケーション ロードバランサのカスタム ヘッダーと同じカスタム ヘッダー名を挿入するように構成されている場合、ロードバランサによって入力された値は、Google Cloud Armor セキュリティ ポリシーで指定された値によって上書きされます。Google Cloud Armor ポリシーを上書きしたくない場合は、同じ名前を使用しないでください。

制限事項

グローバル ロードバランサで使用されるカスタム ヘッダーには、次の制限が適用されます。

  • バックエンド サービスごとのすべてのカスタム リクエスト ヘッダーの合計サイズ(変数を展開する前の名前と値の組み合わせ)は、8 KB、16 個のリクエスト ヘッダーを超えてはなりません。
  • バックエンド サービスごとのすべてのカスタム レスポンス ヘッダーの合計サイズ(変数を展開する前の名前と値の組み合わせ)は、8 KB、16 個のレスポンス ヘッダーを超えてはなりません。