VPC Service Controls を使用する

VPC Service Controls は、Google Cloud の機能で、データ漏洩を防ぐためのセキュアな境界を設定できます。このガイドでは、Cloud Functions で VPC Service Controls を使用して、関数のセキュリティを強化する方法を説明します。

この統合に関する既知の制限については、VPC Service Controls のドキュメントをご覧ください。

組織レベルの設定

VPC Service Controls を Cloud Functions で使用するには、サービス境界と組織のポリシーを構成する必要があります。この構成は組織レベルで行われます。この設定により、Cloud Functions を使用するときに VPC Service Controls のチェックが適用され、デベロッパーは VPC Service Controls に準拠する関数のみをデプロイできるようになります。

VPC Service Controls の境界を設定する

サービス境界を設定するには、組織閲覧者roles/resourcemanager.organizationViewer)と Access Context Manager 編集者roles/accesscontextmanager.policyEditor)のロールが必要です。

VPC Service Controls クイックスタートに従って次の操作を行います。

  1. サービス境界を作成する。
  2. 1 つ以上のプロジェクトを境界に追加する。

  3. Cloud Functions API を制限する。

サービス境界を設定すると、Cloud Functions API のすべての呼び出しが同じ境界内で発生しているか確認されます。

省略可: 開発用マシンの境界アクセスを有効にする

VPC Service Controls のチェックが Cloud Functions API に適用されるため、Cloud Functions API の呼び出しは同じサービス境界内から発生しない限り失敗します。そのため、Cloud Functions API、Cloud Console の Cloud Functions UI、gcloud コマンドライン ツールで関数を管理するには、次のいずれかのオプションを選択します。

  • VPC Service Controls の境界内のマシンを使用する。たとえば、Compute Engine VM や、VPN 経由の VPC ネットワークに接続されたオンプレミス マシンを使用できます。

  • 関数デベロッパーの境界へのアクセスを許可する。たとえば、IP アドレスやユーザー ID に基づいて境界のアクセスを有効にするアクセスレベルを作成できます。詳細については、境界の外部から保護されたリソースへのアクセスを許可するをご覧ください。

組織のポリシーを設定する

組織のポリシーを管理するには、組織ポリシー管理者roles/orgpolicy.policyAdmin)のロールが必要です。

VPC Service Controls に準拠し、データの漏洩を防ぐには、次の組織のポリシーを設定してサービス境界における Cloud Functions の許可されるネットワーク設定を管理します。

許可される上り(内向き)設定を制限する

cloudfunctions.allowedIngressSettings 組織のポリシーでは、デベロッパーが Cloud Functions で使用できる上り(内向き)設定を管理します。この組織ポリシーを使用すると、デベロッパーが値 ALLOW_INTERNAL_ONLY を必ず使用するように設定できます。

Console

  1. Cloud Console で、許可される上り(内向き)設定ポリシーのページに移動します。

    [組織のポリシー] に移動

  2. [編集] をクリックします。

  3. [編集] ページで、[カスタマイズ] を選択します。

  4. [ポリシーの適用] で、[置換] を選択します。

  5. [ポリシーの値] で [カスタム] を選択します。

  6. [ポリシーの種類] で、[許可] を選択します。

  7. [カスタム値] で、「ALLOW_INTERNAL_ONLY」を入力します。

  8. [保存] をクリックします。

gcloud

gcloud beta resource-manager org-policies allow コマンドを使用します。

gcloud beta resource-manager org-policies allow \
  cloudfunctions.allowedIngressSettings ALLOW_INTERNAL_ONLY \
  --organization ORGANIZATION_ID

ORGANIZATION_ID は組織 ID です。

この組織のポリシーが適用されると、すべての関数で上り(内向き)設定に値 ALLOW_INTERNAL_ONLY を使用しなければならなくなります。つまり、HTTP 関数はサービス境界内の VPC ネットワークから発生するトラフィックのみを受け入れます。異なる値を指定する関数のデプロイは失敗します。

VPC コネクタを要求する

cloudfunctions.requireVPCConnector 組織のポリシーは、サーバーレス VPC アクセス コネクタが関数に必要かどうかを管理します。制約が適用されるよう、この組織のポリシーを設定します。

Console

  1. Cloud Console の [VPC コネクタが必須(Cloud Functions)] ポリシーページに移動します。

    [組織のポリシー] に移動

  2. [編集] をクリックします。

  3. [編集] ページで、[カスタマイズ] を選択します。

  4. [適用] で、[オン] を選択します。

  5. [保存] をクリックします。

gcloud

gcloud beta resource-manager org-policies enable-enforce コマンドを使用します。

gcloud beta resource-manager org-policies enable-enforce \
  cloudfunctions.requireVPCConnector \
  --organization ORGANIZATION_ID

ORGANIZATION_ID は組織 ID です。

この組織のポリシーが適用されると、すべての関数でサーバーレス VPC アクセス コネクタの使用が必要になります。コネクタを指定しない関数のデプロイは失敗します。

許可される VPC コネクタの下り(外向き)設定を制限する

cloudfunctions.allowedVpcConnectorEgressSettings 組織のポリシーは、デベロッパーが Cloud Functions で使用できる下り(外向き)設定を管理します。値 ALL_TRAFFIC のみを許可するように、この組織のポリシーを設定します。

Console

  1. Cloud Console で、許可される VPC コネクタの下り(外向き)設定ポリシーのページに移動します。

    [組織のポリシー] に移動

  2. [編集] をクリックします。

  3. [編集] ページで、[カスタマイズ] を選択します。

  4. [ポリシーの適用] で、[置換] を選択します。

  5. [ポリシーの値] で [カスタム] を選択します。

  6. [ポリシーの種類] で、[許可] を選択します。

  7. [カスタム値] で、「ALL_TRAFFIC」を入力します。

  8. [保存] をクリックします。

gcloud

gcloud beta resource-manager org-policies allow コマンドを使用します。

gcloud beta resource-manager org-policies allow \
  cloudfunctions.allowedVpcConnectorEgressSettings ALL_TRAFFIC \
  --organization ORGANIZATION_ID

ORGANIZATION_ID は組織 ID です。

この組織のポリシーが適用されると、すべての関数で下り(外向き)設定に値 ALL_TRAFFIC を使用しなければならなくなります。つまり、関数ですべての下り(外向き)トラフィックを VPC ネットワーク経由でルーティングする必要があります。異なる値を指定する関数のデプロイは失敗します。

プロジェクト レベルの設定

サービス境界内の個々のプロジェクトでは、VPC Service Controls を使用するために追加の構成を行う必要があります。

VPC ネットワークの構成

データ漏洩のリスクを軽減しつつ、Google API とサービスにアクセスするには、リクエストを制限付きの仮想 IP(VIP)範囲である 199.36.153.4/30restricted.googleapis.com)に送信する必要があります。

プロジェクト内の各 VPC ネットワークで、制限付きの VIP 範囲へのトラフィック以外の送信トラフィックをブロックする手順は次のとおりです。

  1. ファイアウォール ルールの構成を行い、VPC ネットワークの外部へデータが送信されるのを防ぎます。

    • すべての送信トラフィックをブロックする下り(外向き)拒否ルールを作成します。

    • TCP ポート 443 で 199.36.153.4/30 へのトラフィックを許可する、下り(外向き)許可ルールを作成します。先ほど作成した下り(外向き)拒否ルールよりも前にこの優先度が設定されていることを確認します。これにより、制限付き VIP 範囲へのみ下り(外向き)が許可されます。

  2. *.googleapis.comrestricted.googleapis.com に解決されるよう、DNS を構成します。

  3. *.cloudfunctions.net を IP 範囲 199.36.153.4/30 にマッピングする A レコードを DNS で構成します。Cloud DNS でこれを行うことができます。

    gcloud dns managed-zones create ZONE_NAME \
    --visibility=private \
    --networks=https://www.googleapis.com/compute/v1/projects/PROJECT_NAME/global/networks/default \
    --description=none \
    --dns-name=cloudfunctions.net
    
    gcloud dns record-sets transaction start --zone=ZONE_NAME
    
    gcloud dns record-sets transaction add --name=*.cloudfunctions.net. \
    --type=A 199.36.153.4 199.36.153.5 199.36.153.6 199.36.153.7 \
    --zone=ZONE_NAME \
    --ttl=300
    
    gcloud dns record-sets transaction execute --zone=ZONE_NAME
    

この時点で、VPC ネットワーク内から発信されるリクエストは次のようになります。

  • VPC ネットワークを離れることができないため、サービス境界外への下り(外向き)通信を防ぎます。
  • アクセスできるのは VPC Service Controls をチェックする Google API とサービスのみであるため、Google API を介したデータの引き出しが発生しません。

Cloud Build サービス アカウントに VPC Service Controls の境界へのアクセスを許可する

Cloud Functions では、Cloud Build を使用してソースコードを実行可能なコンテナに構築します。VPC Service Controls で Cloud Functions を使用するには、サービス境界にアクセスできるように Cloud Build サービス アカウントを構成する必要があります。

サービス アカウント名を見つける

Node 8 と Go 1.11

テナント プロジェクトでビルドが実行されるため、次の回避策を使用する必要があります。

  1. プロジェクトに関数をデプロイします。Google Cloud Console のデフォルトを使用します。

    関数を作成

  2. デプロイが失敗するのを待ち、リスト内の関数名をクリックして関数の詳細ページに移動します。

  3. Build failed: Unable to build your function due to VPC Service Controls から始まる「デプロイ失敗」のエラー メッセージを確認します。エラー メッセージには、サービス アカウントの名前であるメールアドレスが含まれます。

次のようなスクリプトを使用して、コマンドラインからサービス アカウントのアドレスを確認することもできます。

#!/bin/bash

REGION="us-central1" # Your region
CONNECTOR_NAME="test-connector" # Your VPC connector name

# Deploy and delete an HTTP-triggered function
gcloud functions deploy FUNCTION_NAME --trigger-http --runtime nodejs8 --region $REGION --ingress-settings=internal-only --egress-settings=all --vpc-connector $CONNECTOR_NAME -q
gcloud functions delete FUNCTION_NAME --region $REGION -q

# Search log entries for Cloud Build failures
LOG_ENTRIES=$(gcloud logging read "resource.type=\"audited_resource\" AND protoPayload.serviceName=\"containerregistry.googleapis.com\"" --freshness=10m)
SERVICE_ACCTS=$(echo "$LOG_ENTRIES" | grep -oE "\d+@\w+.gserviceaccount.com" | sort | uniq)

# Print out service account IDs
echo "$SERVICE_ACCTS"

ここで、FUNCTION_NAME には、単純な Hello World 関数などの任意の HTTP 関数を使用できます。

その他のランタイム

  1. Java 11、Python 3.7 または 3.8、Node 10、Go 1.13 を使用している場合は、Google Cloud Console の [IAM] ページから Cloud Build サービス アカウントを探します。

    Open IAM

  2. 正しいプロジェクトが、[プロジェクト] プルダウンに表示されていることを確認します。

  3. cloudbuild.gserviceaccount.com を検索します。my-project-number@cloudbuild.gserviceaccount.com 形式のメールアドレスはサービス アカウント名です。

サービス アカウントにサービス境界へのアクセスを許可します。

サービス アカウント名ができたら、ユーザー アカウントまたはサービス アカウントによるアクセスを制限するガイドに沿って、アクセスレベルを作成します。既存の境界にアクセスレベルを追加するの手順に沿って、サービス境界にアクセスレベルを追加します。

Cloud Build サービス アカウントに VPC Service Controls サービス境界へのアクセスを許可すると、関数のデプロイは成功します。

VPC Service Controls に準拠した関数のデプロイ

VPC Service Controls を Cloud Functions 用に構成した後、サービス境界内にデプロイされたすべての関数が、指定された組織のポリシーに準拠していることを確認する必要があります。つまり、以下のようになります。

  • すべての関数は、サーバーレス VPC アクセス コネクタを使用する必要がある。詳細については、VPC ネットワークへの接続をご覧ください。
  • すべての関数は、内部からのトラフィックのみを許可する必要がある。詳細については、上り(内向き)設定をご覧ください。
  • すべての関数は、すべての送信トラフィックを VPC ネットワーク経由でルーティングする必要がある。詳細については、下り(外向き)設定をご覧ください。

上記の条件を満たしていない関数のデプロイは失敗します。

既存の関数が VPC Service Controls に準拠しているか確認する

VPC Service Controls を設定すると、サービス境界内のプロジェクトで作成された新しい関数の準拠状況が自動的に確認されます。ただし、既存のワークロードの中断を避けるため、既存の関数は機能し続けます。その結果、そうした関数は組織のポリシーに準拠していない場合があります。

既存の関数を監査し、必要に応じて関数を更新または再デプロイすることをおすすめします。この処理を容易にするために、Cloud Functions API を使用して関数を一覧表示し、適切なネットワーク設定を指定していない関数をハイライト表示するスクリプトを作成できます。