mediba Adventカレンダー 13日目の記事です。
ソリューション事業本部の苅部からはVPC-SC対応について書いていきます。
概要
Google CloudにてVPC-SCを導入すると既存のデータパイプラインに思わぬ影響を及ぼすことがあります。
私の場合、すでに稼働しているプロジェクトへの導入でポリシー違反の詳細を確認しながら試行錯誤していましたが、かなりの時間を要してしまいました。
そのため、この記事では事前に想定されるポリシー違反(エラーメッセージ)と対策を共有します。これから導入を予定されている方の一助となれば幸いでございます。
VPC-SCとは?
Google Cloudのセキュリティを強化するための機能で、データの不正アクセスや不正なデータ転送を防ぐことを目的としています。具体的には、Google Cloudのサービスやプロジェクト間でのデータアクセスを制限し、リソースを特定の仮想的なセキュリティ境界(ペリメーター)内に閉じ込めることができます。
そして事前に定義した内容に沿わない通信は遮断され「ポリシー違反」としてログに記録されます。
ポリシー違反の種別
エラーの種別は主に以下の3種類になります。
-
NO_MATCHING_ACCESS_LEVEL
- (事前に許可した)IPアドレスとの不一致による違反
-
NETWORK_NOT_IN_SAME_SERVICE_PERIMETER
- サービス境界を超えた 外向きあるいは内向きのアクセスによる違反
-
RESOURCES_NOT_IN_SAME_SERVICE_PERIMETER
- 1つのリクエストが複数のリソースにアクセスしていて、それぞれのリソースが同じサービス境界内にない場合の違反
エラーログとして violationReason
の項目にこれらの文字列が入ります。
では、実際に発生したポリシー違反の内容を見ていきます。
1) Google AnalyticsのBigQueryエクスポート
Google AnalyticsではBigQueryエクスポートができますが、このエクスポートがポリシー違反となりviolationReasonとして NO_MATCHING_ACCESS_LEVEL
が記載されます。
"ingressViolations": [
{
"targetResourcePermissions": [
"bigquery.jobs.create"
],
"targetResource": "projects/XXX"
}
],
"violationReason": "NO_MATCHING_ACCESS_LEVEL"
対策
firebase-measurement@system.gserviceaccount.com
のサービスアカウントをアクセスレベルで許可設定をします。
2) Google Search ConsoleのBigQueryエクスポート
Google Search ConsoleはBigQueryにエクスポートする機能がありますが、これもポリシー違反となります。
"ingressViolations": [
{
"targetResourcePermissions": [
"bigquery.datasets.get"
],
"targetResource": "projects/XXX"
}
],
"violationReason": "NO_MATCHING_ACCESS_LEVEL"
対策
search-console-data-export@system.gserviceaccount.com
のサービスアカウントをアクセスレベルで許可します。
3) BillingのBigQueryエクスポート
Billingでの費用データのBigQueryエクスポートも同様です。
"ingressViolations": [
{
"targetResource": "projects/XXX"
"targetResourcePermissions": [
"vpcsc.permissions.unavailable"
],
}
],
"violationReason": "NO_MATCHING_ACCESS_LEVEL"
対策
cloud-account-pricing@cloud-account-pricing.iam.gserviceaccount.com
のサービスアカウントをアクセスレベルで許可します。
4) Cloud Run関数
Cloud Run関数(Cloud Run Functions)(旧Cloud Functions)をバックグラウンドで動かす場合にはIPアドレス起因でポリシー違反となります。
"ingressViolations": [
{
"targetResource": "projects/XXX",
"targetResourcePermissions": [
"bigquery.jobs.create"
]
}
],
"violationReason": "NO_MATCHING_ACCESS_LEVEL",
※848655640797
はCloud Runを実行しているプロジェクト番号と考えられます。
対策
Cloud Run関数作成時に自動的に払い出されるサービスアカウント<project number>-compute@developer.gserviceaccount.com
をアクセスレベルで許可します。
5) Firebase関連
私が観測した範囲では以下のサービスアカウントでポリシー違反となりましたので、それぞれアクセスレベルで許可しました。
service-<project number>@gcp-sa-firebasestorage.iam.gserviceaccount.com
service-<project number>@gcp-sa-firebase.iam.gserviceaccount.com
firebase-service-account@firebase-sa-management.iam.gserviceaccount.com
6) Google Apps Scriptの定期実行でのBigQuery接続
GASを定期実行する場合は実行元がGoogleのIPアドレスとなるためポリシー違反となります。
"ingressViolations": [
{
"targetResourcePermissions": [
"bigquery.jobs.create"
],
"targetResource": "projects/XXX"
}
],
"violationReason": "NO_MATCHING_ACCESS_LEVEL"
対策
サービスアカウントを作成し、GASの認証情報をサービスアカウントに切り替えます。そしてそのサービスアカウントをアクセスレベルで許可します。
7) Google ColabからBigQueryへの接続
ColabからのBigQuery接続でサービス境界の上り(内向き)ポリシー違反となります。
violationReasonとしてNETWORK_NOT_IN_SAME_SERVICE_PERIMETER
が記載されます。
"ingressViolations": [
{
"targetResource": "projects/XXX",
"targetResourcePermissions": [
"vpcsc.permissions.unavailable"
],
"source": "projects/495559152420"
}
],
"violationReason": "NETWORK_NOT_IN_SAME_SERVICE_PERIMETER"
対策
GAS同様にサービスアカウントを作成し、認証情報をサービスアカウントに切り替えます。そしてそのサービスアカウントをアクセスレベルで許可します。
8) Connected SheetsからBigQueryへの接続
Google スプレッドシートにはBigQueryに接続するインターフェイスとしてConnected Sheetsが用意されていますが、サービス境界の下り(外向き)ポリシー違反となります。
"egressViolations": [
{
"targetResourcePermissions": [
"bigquery.vpcsc.importData"
],
"source": "projects/XXX",
"targetResource": "projects/628550087766"
}
],
"violationReason": "RESOURCES_NOT_IN_SAME_SERVICE_PERIMETER"
※628550087766
はGoogleSpreadSheetのプロジェクト番号のようです。
対策
Googleのドキュメントを参考にして、Egressの境界設定をします。
設定例
- egressTo:
operations:
- serviceName: 'bigquery.googleapis.com'
methodSelectors:
- permission: 'bigquery.vpcsc.importData'
resources:
- projects/628550087766
egressFrom:
identityType: ANY_USER_ACCOUNT
9) Connected SheetからBigQueryへの接続(定期更新)
前述のEgress設定をしたとしても、自動更新で接続した場合にはIPアドレス起因でポリシー違反となります。
"ingressViolations": [
{
"targetResourcePermissions": [
"bigquery.tables.getData"
],
"targetResource": "projects/XXX"
}
],
"violationReason": "NO_MATCHING_ACCESS_LEVEL"
Googleのドキュメントにもあるように定期更新の場合、IPアドレスが問題となります。
コネクテッド シートの定期更新では、IP アドレスやデバイス情報などのエンドユーザー コンテキストは反映されません。エンドユーザー コンテキストを使用してアクセスを制限する VPC Service Controls の境界では、定期更新が失敗します。
https://cloud.google.com/bigquery/docs/connected-sheets?hl=ja
対策
Connected Sheetは認証情報のサービスアカウントへの切り替えができず、対策しようが無いので諦めます。
私の場合、この影響でデータパイプラインの見直しをせざるを得なくなり、工数が大幅に膨らんでしまいました。
※SpreadSheetへの依存度を減らし、BigQueryのスケジュールクエリへ移行する形になりました。
10) Looker Studioでの「データ抽出」経由でのBigQueryへの接続(自動更新)
Looker Studioにはデータソース利用としての「データ抽出」機能があり自動更新もできますが、Connected Sheets同様にIPアドレス起因でポリシー違反となります。
"ingressViolations": [
{
"targetResourcePermissions": [
"bigquery.jobs.create"
],
"targetResource": "projects/XXX"
}
],
"violationReason": "NO_MATCHING_ACCESS_LEVEL",
対策
Google Workspace または Cloud Identity の管理対象組織であれば、認証情報をサービスアカウントへ切り替えできるようです。
[サービス アカウント認証情報] オプションは、Google Workspace または Cloud Identity の管理対象組織でのみ使用できます。
サービス アカウントは、Google Workspace または Cloud Identity の管理者が設定する必要があります。管理者である場合は、サービス アカウントの設定方法をご確認ください。
つまり、当該サービスアカウントをアクセスポリシーで許可することでサービス境界を通過することができます。
Looker Studio でサービス アカウントを使用するメリット
スケジュール設定されたメールやスケジュール設定されたデータ抽出などの自動機能では、VPC Service Controls の境界の背後にあるデータソースが使用されます。
11) Cloud Shellでのデータ操作
例えばCloud Shellでbq ls
コマンドを実行するとサービス境界の上り(内向き)ポリシー違反となります。
"ingressViolations": [
{
"targetResource": "projects/XXXX",
"source": "projects/751522334863",
"targetResourcePermissions": [
"bigquery.datasets.get"
]
}
],
"violationReason": "RESOURCES_NOT_IN_SAME_SERVICE_PERIMETER",
Cloud Shellの実行元は別プロジェクト(751522334863
)となり、プロジェクトを超えた通信となるため境界ポリシーに抵触しているようです。
対策
Cloud Shellは諦めて、別途VPC-SCで保護された領域でVMを立ち上げるか、或いは許可されたNWに接続したローカル環境から操作します。
12) プロジェクトを超えたBigQueryへの接続
VPC-SCで保護されたプロジェクトから別プロジェクトのテーブルへクエリ発行する場合は外向き(Egress)ポリシーに抵触します。
例えばVPC-SCで保護された2つのプロジェクト間(プロジェクトAにおいてプロジェクトBのテーブルへのクエリ)でのエラーを見てみます。
プロジェクトA側のエラー
sourceとtargetResourceの関係から A→BのEgress違反ということがわかります。
外向き(Egress)の境界設定をしていないため、外(B)に出ることができない状態です。
"egressViolations": [
{
"source": "projects/projectA",
"targetResource": "projects/projectB",
"sourceType": "Resource",
"targetResourcePermissions": [
"bigquery.tables.getData"
]
}
],
"violationReason": "RESOURCES_NOT_IN_SAME_SERVICE_PERIMETER",
プロジェクトB側のエラー
B→AのEgress違反になっています。
こちらも外向き(Egress)の境界設定をしていないため、外(A)に出ることができない状態です。
"egressViolations": [
{
"targetResource": "projects/projectA",
"targetResourcePermissions": [
"bigquery.jobs.create"
],
"sourceType": "Resource",
"source": "projects/projectB"
}
],
"violationReason": "RESOURCES_NOT_IN_SAME_SERVICE_PERIMETER",
※プロジェクトA側でEgress設定した上で(外に出ることができる状態になった上で)、初めてプロジェクトB側でVPC-SCのエラーが表示されます。
対策
プロジェクトA、BそれぞれにEgressポリシーを設定します。
プロジェクトAでの設定例
- egressTo:
operations:
- serviceName: 'bigquery.googleapis.com'
methodSelectors:
- method: '*'
resources:
- projects/projectB
egressFrom:
identityType: ANY_USER_ACCOUNT
プロジェクトBでの設定例
- egressTo:
operations:
- serviceName: 'bigquery.googleapis.com'
methodSelectors:
- method: '*'
resources:
- projects/projectA
egressFrom:
identityType: ANY_USER_ACCOUNT
上記の例は保護されたプロジェクト同士の例ですが、保護されていないプロジェクトのテーブルに対してクエリ発行する場合も都度設定が必要です。
Googleのオープンデータセットとの疎通設定例
- egressTo:
operations:
- serviceName: 'bigquery.googleapis.com'
methodSelectors:
- method: 'bigquery.tables.getData'
resources:
- projects/20398604589
egressFrom:
identityType: ANY_USER_ACCOUNT
その他 ポリシー違反以外のエラー
BigQuery Editions (Standard)
Editions StandardはVPC-SCに対応していません。
"status": {
"code": 9,
"message": "Accessing resources in VPC-SC perimeters is disallowed in STANDARD edition. See https://cloud.google.com/bigquery/docs/editions-intro for more information."
}
対策
Enterprise以上に切り替える必要があります。
なおEnterpriseはStandard比でスロット時間単価が1.5倍になりますので、相応の費用の増加を見込んでおく必要があります。
BigQueryのクエリ結果のGoogleドライブへの保存
クエリ結果をGoogleドライブへ保存できなくなります。
"status": {
"code": 7,
"message": "Export to Google Drive is blocked for projects with VPC-SC enabled"
}
対策
境界設定で解決することができないため、CSVとしてローカル環境にダウンロードするか、GoogleSpreadSheetにエクスポートします。
まとめ
VPC-SC対応では以下のような整理で進めました。
NO_MATCHING_ACCESS_LEVEL
実行元のIPアドレス起因となるため、
「認証情報がユーザー」の場合は認証情報をサービスアカウントへの切り替えて、そのサービスアカウントをアクセスポリシーで許可する。
「認証情報がサービスアカウント」の場合はそのサービスアカウントをアクセスポリシーで許可する。
「認証情報がユーザー」で、かつサービスアカウントへの切り替えができない場合には諦める。
NETWORK_NOT_IN_SAME_SERVICE_PERIMETER
境界内リソースへの内向き or 外向きのアクセスに起因するため、サービスアカウントをアクセスポリシーで許可、あるいは境界ポリシーを設定する
RESOURCES_NOT_IN_SAME_SERVICE_PERIMETER
複数のリソースへのアクセスに起因するため境界ポリシーを設定する
おわりに
すでに稼働しているプロジェクトへの適用は難しく、私自身の知識もなかったため試行錯誤が続き苦労しましたが、結果的にはGoogleCloudの新たな領域への理解が深まり、たいへん勉強になりました。
参考ページ