1. はじめに
VPC Service Controls(VPC-SC)は、Google Cloud の組織レベルのセキュリティ制御であり、企業のお客様がデータ漏洩のリスクを軽減できます。VPC Service Controls は、インターネットや他のサービスからマルチテナント サービスへの接続について、一定の承認済み IP、クライアント コンテキスト、デバイス パラメータに限定してアクセスを許可することで、マルチテナント サービスへのゼロトラスト スタイルのアクセスを提供します。これにより、意図的または意図しない損失を減らすことができます。VPC Service Controls の基本チュートリアル I で説明したように、VPC Service Controls を使用すると、明示的に指定したサービスのリソースとデータを保護する境界を作成できます。
このチュートリアルの目標は次のとおりです。
- VPC Service Controls の基本を理解する
- サービス境界を更新し、ドライラン モードを使用してテストする
- VPC Service Controls で 2 つのサービスを保護する
- Cloud Storage からオブジェクトを一覧表示する際の VPC Service Controls の下り(外向き)違反のトラブルシューティング
2. 設定と要件
このチュートリアルでは、次の前提条件が必要です。
- GCP 組織。
- 組織内のフォルダ。
- 同じ組織内の 2 つの GCP プロジェクトがフォルダに配置されている。
- 組織レベルで必要な権限。
- 両方のプロジェクトの請求先アカウント。
- VPC Service Controls の基本チュートリアル I VPC Service Controls と Access Context Manager の設定。

Resources-setup
- VPC Service Controls の基本チュートリアル I の「リソースの設定」セクションの説明に沿ってリソースを設定します。
- Cloud Storage の管理に必要な権限があることを確認します。
- このチュートリアルでは、クラウド コンソールではなく CLI を使用します。いずれかの開発環境で gcloud CLI を設定します。
- Cloud Shell: gcloud CLI がすでに設定されているオンライン ターミナルを使用するには、Cloud Shell をアクティブにします。
クラウド コンソールの右上にあるアイコンをクリックして、Cloud Shell をアクティブにします。セッションが初期化されるまで数秒かかることがあります。詳細については、Cloud Shell のガイドをご覧ください。

費用
Cloud のリソースや API を使用するには、Cloud コンソールで課金を有効にする必要があります。この Codelab の操作をすべて行って、費用が生じたとしても、少額です。このチュートリアルの終了後に請求が発生しないようにリソースをシャットダウンするには、作成したリソースを削除するか、プロジェクトを削除します。Google Cloud の新規ユーザーは、300 米ドル分の無料トライアル プログラムをご利用いただけます。
費用が発生するリソースは、VM インスタンスと Cloud Storage オブジェクトのみです。VM インスタンスの推定費用は、料金計算ツールで確認できます。Cloud Storage の推定費用については、こちらの料金表をご覧ください。
3. Storage バケットとオブジェクトを作成する
前述のように、前のチュートリアルで作成したリソースを再利用します。Cloud Storage バケットの作成を続行します。このチュートリアルでは、コンソールではなく gcloud CLI を使用します。
- Google コンソールで、ProjectX を選択します。このプロジェクトでは、ストレージ バケットとオブジェクトを作成します。
- 次のコマンドを実行して、Cloud Shell が ProjectX を使用するように設定されていることを確認します。
gcloud config set project PROJECT_ID
- 開発環境で次のコマンドを実行します。
gcloud storage buckets create gs://BUCKET_NAME --location=us-central1
- ProjectZ にある VM インスタンスから読み取れるように、ストレージ オブジェクトを作成します。.txt ファイルを作成します。
nano hello.txt
テキスト ファイルに任意のものを追加します。
- オブジェクトをバケットにアップロードします。
gcloud storage cp /home/${USER}/hello.txt gs://BUCKET_NAME
- オブジェクトを一覧表示して、オブジェクトがバケットにアップロードされていることを確認します。
gcloud storage ls gs://BUCKET_NAME
コンソールに hello.txt ファイルが表示されていることを確認します。
4. Cloud Storage API を保護する
前の Codelab では、境界を作成して Compute Engine API を保護しました。この Codelab では、ドライラン モードの境界を編集し、Cloud Storage を追加します。これにより、監査ログに VPC Service Controls の違反が表示され、境界保護の影響を判断できますが、境界を適用するまでリソースにはアクセスできます。
- Google コンソールで組織を選択し、 VPC Service Controls にアクセスします。組織スコープにいることを確認します。
- Cloud Shell を開き、前のラボで作成したドライラン境界「SuperProtection」を更新します。
gcloud access-context-manager perimeters dry-run update SuperProtection --policy=POLICY --add-restricted-services=storage.googleapis.com
- 境界を記述して、Cloud Storage API が更新されたことを確認する
gcloud access-context-manager perimeters dry-run describe SuperProtection --policy=POLICY
出力には、Cloud Storage API が制限付きサービスの下に表示されます。
Compute Engine API とともに、-vpcAccessibleServices: {}" ラベルを使用します。

5. Cloud Storage API が保護されていることを確認する
ドライラン モードで、ProjectZ で作成された VM インスタンスから Storage Bucket をホストする ProjectX へのオブジェクトを一覧表示して、「SuperProtection」境界が拒否を示していることを確認します。
- Cloud コンソールで、プロジェクト セレクタに移動して ProjectZ を選択し、[Compute Engine] > [VM インスタンス] に移動します。
- [SSH] ボタンをクリックして VM インスタンスに接続し、コマンドラインにアクセスします。

- 先ほどアップロードした hello.txt ファイルを一覧表示します。
gcloud storage ls gs://BUCKET_NAME
Cloud Storage API はドライラン モードで保護されているため、リソースを一覧表示できますが、ProjectZ の監査ログにエラー メッセージが表示されます。
- ProjectZ の Logs Explorer API に移動し、VPC Service Controls の最後のエラー メッセージを探します。このフィルタを使用すると、目的のログを取得できます。
protoPayload.status.details.violations.type="VPC_SERVICE_CONTROLS" "(Dry Run Mode) Request is prohibited by organization's policy. vpcServiceControlsUniqueIdentifier:UNIQUE_ID"
このフィルタは、Cloud Storage に属するドライラン モードの最後の違反を表示します。ログの例を次に示します。ProjectX にあるバケットのコンテンツを一覧表示しようとすると、違反が下り(外向き)違反であることが確認できます。
egressViolations: [
0: {
servicePerimeter: "accessPolicies/POLICY/servicePerimeters/SuperProtection"
source: "projects/PROJECTX_ID"
sourceType: "Network"
targetResource: "projects/PROJECTZ_ID"
}
]
resourceNames: [
0: "projects//buckets/BUCKET_NAME"
]
securityPolicyInfo: {
organizationId: "ORGANIZATION_ID"
servicePerimeterName: "accessPolicies/POLICY/servicePerimeters/SuperProtection"
}
violationReason: "NETWORK_NOT_IN_SAME_SERVICE_PERIMETER"
vpcServiceControlsUniqueId: "UNIQUE_ID"
}
methodName: "google.storage.objects.list"
- Cloud Storage への API 呼び出しで VPC Service Controls の違反が発生することが確認されたため、新しい構成で境界を適用します。Cloud Shell を開き、ドライラン境界を適用します。
gcloud access-context-manager perimeters dry-run enforce SuperProtection --policy=POLICY --async
- SSH を使用して VM インスタンスに接続し、ストレージ バケットを再度一覧表示して、ドライラン境界が正しく適用されていることを確認します。
gcloud storage ls gs://BUCKET_NAME
Storage オブジェクトのリストではなく、VM CLI で VPC Service Control の違反が発生します。
ERROR: (gcloud.storage.ls) User [PROJECT_NUMBER-compute@developer.gserviceaccount.com] does not have permission to access b instance [BUCKET_NAME] (or it may not exist): Request is prohibited by organization's policy. vpcServiceControlsUniqueIdentifier:"UNIQUE_ID"
VPC Service Controls を使用して境界外のリソースにデータの読み取りやコピーを行うことを禁止することで、データ漏洩を防止できました。
6. リストの拒否のトラブルシューティング。
VM インスタンスの CLI から返された拒否のトラブルシューティングを行います。監査ログを確認して、VPC Service Controls の一意の ID を探します。
- プロジェクト セレクタに移動して、ProjectZ を選択します。
- ログ エクスプローラで次のクエリを使用して、監査ログで VPC Service Controls の一意の ID を見つけます。
resource.type="audited_resource" protoPayload.metadata."@type"="type.googleapis.com/google.cloud.audit.VpcServiceControlAuditMetadata"
これにより、すべての VPC Service Controls 監査ログが表示されます。最後のエラーログを探します。API 呼び出しは VM インスタンスから行われたため、プリンシパルは Compute Engine サービス アカウント「PROJECT_NUMBER-compute@developer.gserviceaccount.com"」である必要があります。
VPC Service Controls の一意の ID がすでにあるため、次のフィルタを使用して、目的のログを直接取得できます。
protoPayload.metadata.vpcServiceControlsUniqueId="UNIQUE_ID"
- [VPC Service Controls] ヘッダーをクリックし、[拒否のトラブルシューティング] を選択します。これにより、VPC Service Controls Troubleshooter が開きます。
この API は、違反の理由や、違反が上り(内向き)か下り(外向き)かなど、役立つ情報をわかりやすい UI で表示します。
この演習では、次のことを行います。
authenticationInfo: {
principalEmail: "PROJECT_ID-compute@developer.gserviceaccount.com"
egressViolations: [
0: {
servicePerimeter: "accessPolicies/POLICY/servicePerimeters/SuperProtection"
source: "projects/PROJECTZ_ID"
sourceType: "Network"
targetResource: "projects/PROJECTX_ID"
}
violationReason: "NETWORK_NOT_IN_SAME_SERVICE_PERIMETER"
この情報から、Compute Engine サービス アカウントが ProjectZ から ProjectX のストレージ バケットにアクセスできるようにする下り(外向き)ルールを作成する必要があることがわかります。また、ネットワークが同じ境界内にないため、VPC がサービスと通信できるようにし、サービス境界間でデータを共有する必要があります。
- Cloud Shell を有効にして、テキスト エディタを使用して下り(外向き)ルールを含む .yaml ファイルを作成します。
nano egresstorage.yaml
- egressTo:
operations:
- serviceName: storage.googleapis.com
methodSelectors:
- method: \"*\"
resources:
- projects/PROJECTX_ID
egressFrom:
identities:
- serviceAccount:PROJECT_ID-compute@developer.gserviceaccount.com
- ProjectZ を保護する上り(内向き)ポリシーを更新します。
gcloud access-context-manager perimeters update SuperProtection --set-egress-policies=egresstorage.yaml --policy=POLICY
これで、VM インスタンスからバケットにアクセスできるようになりました。
- Cloud コンソールで、プロジェクト セレクタに移動して ProjectZ を選択し、[Compute Engine] > [VM インスタンス] に移動します。
- [SSH] ボタンをクリックして VM インスタンスに接続し、コマンドラインにアクセスします。
- VM CLI にアクセスしたら、Storage Bucket 内のオブジェクトを一覧表示してみます。
gcloud storage ls gs://BUCKET_NAME/
次のエラー メッセージが表示されます。
ERROR: (gcloud.storage.ls) User [PROJECT_ID-compute@developer.gserviceaccount.com] does not have permission to access b instance [BUCKET_NAME] (or it may not exist): PROJECT_ID-compute@developer.gserviceaccount.com does not have storage.objects.list access to the Google Cloud Storage bucket. Permission 'storage.objects.list' denied on resource (or it may not exist).
- Storage バケット内のオブジェクトを一覧表示するには、Compute Engine サービス アカウントにオブジェクト読み取り権限を付与する必要があります。
gcloud storage buckets add-iam-policy-binding gs://BUCKET_NAME --member=serviceAccount:PROJECT_ID-compute@developer.gserviceaccount.com --role=roles/storage.objectViewer
- もう一度、VM インスタンスの CLI から hello.txt ファイルを一覧表示してみましょう。
gcloud storage ls gs://BUCKET_NAME/ . . gs://BUCKET_NAME/hello.txt
これで、VPC Service Controls の権限違反なしでオブジェクトを一覧表示できるようになりましたが、ファイルのダウンロードはどうでしょうか?やってみましょう。
gcloud storage cp gs://BUCKET_NAME/hello.txt /home/${USER}
次の出力が得られます。
Copying gs://BUCKET_NAME/hello.txt to file:///home/${USER}
Completed files 1/1 | 54.0B/54.0B
7. クリーンアップ
サービスが使用されていない場合、VPC Service Controls の使用に追加料金は発生しませんが、このラボで使用した設定をクリーンアップすることをおすすめします。VM インスタンスや Cloud プロジェクトを削除して、料金が発生しないようにすることもできます。Cloud プロジェクトを削除すると、そのプロジェクト内で使用されているすべてのリソースに対する課金が停止します。
- VM インスタンスを削除するには、VM インスタンス名の左側にあるチェックボックスをオンにして、[削除] をクリックします。

- 境界を削除する手順は次のとおりです。
- Google Cloud コンソールで、[セキュリティ] をクリックし、組織スコープで [VPC Service Controls] をクリックします。
- [VPC Service Controls] ページで、削除する境界に対応するテーブル行の [削除アイコン] をクリックします。
- アクセスレベルを削除する手順は次のとおりです。
- Google Cloud コンソールで、フォルダ スコープの [Access Context Manager] ページを開きます。
- グリッドで、削除するアクセスレベルの行の「削除アイコン」をクリックし、[削除] をクリックします。
- Storage オブジェクトとバケットを削除するには、次の操作を行います。
- Google Cloud コンソールで、Cloud Storage の [バケット] ページを開きます。
- 作成したバケットの横にあるチェックボックスをオンにします。
- [削除] をクリックします。
- 表示されたウィンドウで、バケットを削除することを確認します。
- [削除] をクリックします。
- プロジェクトをシャットダウンする手順は次のとおりです。
- Google Cloud コンソールで、削除するプロジェクトの [IAM と管理] の [設定] ページに移動します。
- [IAM と管理の設定] ページで、[シャットダウン] をクリックします。
- プロジェクト ID を入力し、[このままシャットダウン] をクリックします。
8. 完了
この Codelab では、VPC Service Controls のドライラン境界を更新し、適用して、トラブルシューティングを行いました。
詳細
- VPC Service Controls のドキュメントをご覧ください。
- Access Context Manager のドキュメントをご覧ください。
- VPC-SC トラブルシューティングのドキュメントをご覧ください。
- 上り(内向き)ルールと下り(外向き)ルールのドキュメントをご覧ください。
- ドライランのドキュメント をご覧ください。
- Cloud Storage のドキュメントをご覧ください。
ライセンス
この作業はクリエイティブ・コモンズの表示 2.0 汎用ライセンスにより使用許諾されています。