1. はじめに
この Codelab では、VPC Service Controls を使用して BigQuery API を保護する方法を学習します。この Codelab は、サービス境界で保護された API サービスがない状態で始まり、一般公開データセットに対してクエリを実行し、その結果をプロジェクト テーブルに保存できるようにします。クエリは 1 つのプロジェクトで実行され、テーブル(結果が保存されるテーブル)は別のプロジェクトに作成されます。これは、データを 1 つのプロジェクトに保存できても、別のプロジェクトからアクセスする必要がある設定を模倣したものです。
次に、データ プロジェクトを保護するためのサービス境界を導入します。確認された違反を上り(内向き)ルールと下り(外向き)ルールを使用して修正し、その後アクセスレベルを追加して、内部 IP アドレスを使用してアクセスを制限する方法について学習します。この Codelab の目標は次のとおりです。
- 上り(内向き)ルールと下り(外向き)ルールをそれぞれ使用して、上り(内向き)違反と下り(外向き)違反をそれぞれ修正する方法を理解する。
- 違反が発生した理由を把握する。
- 適用された違反の修正の範囲を分析します。
- 修正(上り(内向き) / 下り(外向き)ルール)を変更し、アクセスレベルを使用して VPC ネットワークの内部 IP アドレスからのトラフィックを許可するオプションを利用してスコープを変更する。
2. リソースの設定と要件
始める前に
この Codelab は、以下を理解していることを前提としています。
- BigQuery クエリの実行の基本: BigQuery で Wikipedia データセットに対してクエリを実行する方法については、こちらの Codelab をご覧ください。
- フォルダを作成、管理する方法
- フォルダ内にプロジェクトを作成する方法、またはフォルダ内で既存のプロジェクトを移動する方法
- スコープ アクセス ポリシーを作成する方法
- サービス境界を作成して構成する方法
- ログでセキュリティ ポリシー違反を見つける方法
セットアップ
初期設定は次のようになります。
- Google Cloud 組織。
- 組織のフォルダ。この Codelab では、この Codelab の名前を
codelab-folder
とします。 - 同じフォルダ
codelab-folder
に配置された 2 つの Google Cloud プロジェクト。この Codelab では、これらのクラスの名前をproject-1
、project-2
とします。- フォルダとプロジェクトがまだ作成されていない場合は、Google Cloud コンソールで組織の下にフォルダを作成し、作成したフォルダの下に2 つの新しいプロジェクトを作成します。
- 必要な権限:
- フォルダを管理するための IAM ロール: フォルダレベルで割り当て
- プロジェクトを管理するための IAM ロール: プロジェクト レベルで割り当てられます。
- VPC Service Controls の構成に必要な IAM ロール: 組織レベルで割り当てられます。
- BigQuery を管理するための IAM ロール: プロジェクト レベルで割り当て
- Compute Engine インスタンスを管理するための IAM ロール: プロジェクト レベルで割り当てられます
project-2
とproject-1
の両方のプロジェクトの請求先アカウント。
通常のサービス境界を作成する
この Codelab では、project-1
を保護する通常のサービス境界を使用します。
perimeter-1
の通常の境界を作成し、project-1
を追加します。
Compute Engine VM の作成
この Codelab では、us-central1
にある project-2
で 1 つの Compute Engine インスタンスを使用し、default
という名前のデフォルトの VPC ネットワークを使用します。
- 公開イメージから Compute Engine インスタンスを作成するためのガイドラインとして、ドキュメントをご覧ください。
費用
クラウド リソース/API を使用するには、Google Cloud コンソールで課金を有効にする必要があります。この Codelab の終了後に課金が発生しないように、使用済みのリソースはシャットダウンすることをおすすめします。Google Cloud の新規ユーザーは、300 米ドル分の無料トライアル プログラムをご利用いただけます。
費用が発生するリソースは、BigQuery と Compute Engine インスタンスです。BigQuery 料金計算ツールと Compute Engine 料金計算ツールを使用して費用を見積もることができます。
3. VPC Service Controls の制限なしで BigQuery にアクセス
一般公開データセットに対してクエリを実行し、project-1
に結果を保存する
- [BigQuery Studio] ページにアクセスして
project-2
とproject-1
にアクセスし、BigQuery API にアクセスできるかどうかを確認します。project-1
がサービス境界内にある場合でも、境界でまだサービスが保護されていないため、この操作を行うことができます。 project-2
から、次のクエリを実行して一般公開データセットにクエリを実行します。
SELECT name, SUM(number) AS total
FROM `bigquery-public-data.usa_names.usa_1910_2013`
GROUP BY name
ORDER BY total DESC
LIMIT 10;
一般公開データセットに対してクエリを実行した後(project-2
に残っています):
- [結果を保存する] をクリックし、[BigQuery テーブル] を選択します。(以下のスクリーンショットを参照)。
- 宛先プロジェクトとして
project-1
を選択します。 - データセットに
codelab_dataset
という名前を付けます。(既存のデータセットを使用しない場合は、[新しいデータセットを作成] を選択します)。 - テーブルに
codelab-table
という名前を付けます。 - [保存] をクリックします。
project-2
からクエリを実行した結果、一般公開データセット データが project-1
に正常に保存されました。
project-2
から project-1
に保存されたクエリのデータセット
project-2
BigQuery Studio を開いた状態で、次のクエリを実行してデータを選択します。
- プロジェクト:
project-1
- データセット:
codelab_dataset
- Table:
codelab-table
SELECT name, total
FROM `project-1.codelab_dataset.codelab-table`
ORDER BY total DESC
LIMIT 10;
project-2
も project-1
も BigQuery の使用が制限されているため、クエリは正常に実行されるはずです。ユーザーが適切な IAM 権限を持っている限り、どこからでも BigQuery にアクセスできます。
この図は、プリンシパルが BigQuery データセットに対してクエリを実行するプロセスを示しています。BigQuery クエリごとに BigQuery ジョブが起動され、ジョブが実際のオペレーション(このシナリオではデータを取得する)を実行します。Compute Engine インスタンスとインターネットからのプリンシパル アクセスを示し、一般公開データセットと別の Google Cloud プロジェクトからクエリを実行しています。データをクエリするプロセス(
GetData
)は、VPC Service Controls によってブロックされることなく成功しました。
4. ソース データセット プロジェクトで BigQuery API を保護する
境界 perimeter-1
の構成を変更し、保護されたリソースを project-1
にして BigQuery API サービスを制限します。
サービス境界の適用を確認する
前のステップと同様に、project-2
から BigQuery Studio で次のクエリを実行します。
SELECT name, total
FROM `project-1.codelab_dataset.codelab-table`
ORDER BY total DESC
LIMIT 10;
VPC Service Controls の RESOURCES_NOT_IN_SAME_SERVICE_PERIMETER
違反が発生します
違反の監査ログは project-1
に保存されます。これは、境界を越える違反が発生した場所であるためです。ログは、観測された vpcServiceControlsUniqueId
でフィルタリングできます(VPC_SC_DENIAL_UNIQUE_ID
を観測された一意の ID に置き換えます)。
severity=ERROR
resource.type="audited_resource"
protoPayload.metadata.@type="type.googleapis.com/google.cloud.audit.VpcServiceControlAuditMetadata"
protoPayload.metadata.vpcServiceControlsUniqueId="[*VPC_SC_DENIAL_UNIQUE_ID*]"
違反は、以下を含むegressViolations
です。
principalEmail
: [クエリを実行するユーザー アカウント]callerIp
: [クエリを実行しているユーザー エージェントの IP アドレス]
"egressViolations": [
{
"targetResource": "projects/project-2",
"sourceType": "Resource",
"source": "projects/project-1",
"servicePerimeter": "accessPolicies/REDACTED/servicePerimeters/perimeter-1",
"targetResourcePermissions": [ "bigquery.jobs.create"]
} ],
5. BigQuery ジョブを作成するための違反の修正
この図は、プリンシパルが
project-1
内のデータセットに対して project-2
からクエリを実行するタイミングを示しています。クエリの実行元のプロジェクト(project-2
)のデータセット プロジェクト(project-1
)から BigQuery ジョブを作成するオペレーションが、BigQuery API を保護するサービス境界 perimeter-1
による VPC Service Controls の下り(外向き)違反で失敗します。境界が設定されると、project-1
から境界外に向けて開始したり、境界外で保護されたプロジェクトに向けて BigQuery API リクエストを開始したりできなくなります。サービス境界の構成で許可されていない限り
以下に基づいて下り(外向き)ルールを作成することで、下り(外向き)違反を修正できます。
- 送信元(FROM): ユーザーのメールアドレスとコンテキスト(例: 発信者の IP アドレス、デバイスの状態、場所など)
- 宛先(TO): ターゲット リソース、サービス、メソッドまたは権限。
確認された下り(外向き)違反を修正するには、BigQuery サービスでクエリを実行するユーザー アカウント(user@example.com
)と bigquery.jobs.create
メソッド/ 権限によって targetResource(project-2
)へのトラフィックを許可する下り(外向き)ルールを作成します。
構成された下り(外向き)ルールで想定される動作:
- FROM |ID: 指定された ID
user@example.com
のみが境界境界を越えることが許可される必要があります。 - TO |projects: 指定した ID は、宛先が指定されたプロジェクト
project-2
の場合にのみ、境界を越えることができます。 - TO |サービス: API 呼び出しが指定されたサービスとメソッドに対するものである場合にのみ、指定された ID で境界外から指定されたプロジェクトへのトラフィックを開始できます。それ以外の場合、たとえばサービス境界で保護されている別のサービスを試行した場合、他のサービスは許可されていないため、オペレーションがブロックされます。
修正のテスト: 下り(外向き)ルール
下り(外向き)ルールが適用されたら、同じクエリを実行します。
SELECT name, total
FROM `project-1.codelab_dataset.codelab-table`
ORDER BY total DESC
LIMIT 10;
別の違反が発生します。今回は NO_MATCHING_ACCESS_LEVEL
上り(内向き)違反です。新しい違反は、ターゲット プロジェクトとメソッドが最初の違反とは異なります。
新しい違反は上り(内向き)違反で、
principalEmail
: [クエリを実行するユーザー アカウント]callerIp
: [クエリを実行しているユーザー エージェントの IP アドレス]
ingressViolations: [
0: {
servicePerimeter: "accessPolicies/REDACTED/servicePerimeters/perimeter-1"
targetResource: "projects/project-1"
targetResourcePermissions: [0: "bigquery.tables.getData"]}
]
bigquery.tables.getData
メソッドの違反は、BigQuery テーブルからデータを取得しようとした BigQuery ジョブによって開始された API 呼び出しが原因です。
6. BigQuery テーブルデータを取得するための違反の修正
上り(内向き)ルールによって上り(内向き)違反が修正されると同時に、許可されるアクセスのコンテキスト(送信元/ ターゲット プロジェクト、アクセス可能な API メソッドなど)とともに、サービス境界を越えられるユーザーをきめ細かく制御できます。
上り(内向き)違反は、以下で構成される上り(内向き)ルールによって修正されます。
- 送信元(FROM): ユーザーのメールアドレスとコンテキスト(例: 発信者の IP アドレス、デバイスの状態、場所など)
- 宛先(TO): ターゲット リソース、サービス、メソッドまたは権限。
上り(内向き)ルールは、指定されたサービスとメソッドで、指定されたユーザーによる project-1
へのトラフィックを許可します。
構成された上り(内向き)ルールで想定される動作:
- FROM |ID: 指定された ID
user@example.com
のみが境界境界を越えることが許可される必要があります。 - TO |projects: 指定した ID は、宛先が指定されたプロジェクト
project-1
の場合にのみ、境界を越えることができます。 - TO |サービス: API 呼び出しが BigQuery API に対して行われ、指定されたメソッド
bigquery.tables.getData
の場合にのみ、指定された ID で境界内でトラフィックを開始できます。
これ以降、同じクエリの実行は VPC Service Controls の違反なしに適切に機能するはずです。
project-1
で BigQuery API を制限し、user@example.com
でのみ使用でき、user2@example.com
では使用できないようにしました。
この図は、2 つの異なるプリンシパルが同じデータセットに対してクエリを実行しようとしている様子を示しています。
user2@example.com
によるアクセス(青い点線)は、サービス境界の構成により project-1
との間で BigQuery オペレーションの実行が許可されていないため、VPC Service Controls によって拒否されています。user@example.com
によるアクセス(緑色の実線)は、VPC Service Controls の構成で project-1
との間でのオペレーションの実行が許可されているため、成功しています。
7. サービス境界で許可されるトラフィックを内部 IP アドレスに基づいて制限する
現在の構成では、指定されたユーザーは任意の場所から project-1
の BigQuery に対してクエリを実行できます。データのクエリを行う IAM 権限が付与されていれば、インターネット上のどこからでもアクセスできる必要があります。セキュリティの観点から見ると、これは、アカウントが不正使用された場合に、アカウントへのアクセス権を取得したユーザーなら誰でも、追加の制限なしに BigQuery データにアクセスできることを意味します。
上り(内向き)ルールと下り(外向き)ルールのアクセスレベルを利用してユーザー コンテキストを指定することで、さらに制限を実装できます。たとえば、呼び出し元の ID によるアクセスを承認する事前構成済みの上り(内向き)ルールと組み合わせて、送信元 IP に基づくアクセスを許可できます。送信元 IP によるアクセスは、両方のパブリック IP CIDR 範囲で可能です。ただし、ユーザー クライアントにパブリック IP が割り当てられている場合は、ユーザー クライアントが Google Cloud プロジェクトから動作している場合は内部 IP アドレスを使用できます。
内部 IP アドレスのアクセス条件を使用してアクセスレベルを作成する
同じスコープ アクセス ポリシー フォルダで、Access Context Manager ページを開き、アクセスレベルを作成します。
- [Access Context Manager] ページで、[アクセスレベルを作成] を選択します。
- [新しいアクセスレベル] ペインで次の操作を行います。
- タイトルを指定します。
codelab-al
を使用できます。 - [条件] セクションで、[IP サブネットワーク] をクリックします。
- [プライベート IP] タブを選択し、[VPC ネットワークを選択] をクリックします。
- [VPC ネットワークの追加] ペインでは、
default
ネットワークを参照して見つけるか、//compute.googleapis.com/projects/project-2/global/networks/default
の形式で完全なネットワーク名を手動で入力します。 - [VPC ネットワークを追加] をクリックします。
- [IP サブネットを選択] をクリックします。
- VM インスタンスが配置されているリージョンを選択します。この Codelab では
us-central1
です。 - [保存] をクリックします。
- タイトルを指定します。
Google はアクセスレベルを作成しましたが、このアクセスレベルはまだ境界ポリシーや上り(内向き) / 下り(外向き)ポリシーに適用されていません。
上り(内向き)ルールにアクセスレベルを追加する
上り(内向き)ルールで許可されたユーザーがアクセスレベルに照らして検証されるようにするには、上り(内向き)ルールでアクセスレベルを構成する必要があります。クエリデータへのアクセスを承認する上り(内向き)ルールは perimeter-1
にあります。上り(内向き)ルールを変更して、アクセスレベル codelab-al
として送信元を定義します。
新しい構成のテスト
上り(内向き)ルールにアクセスレベルを追加すると、プロジェクト project-2
の VPC ネットワーク default
のクライアントから実行しない限り、同じ BigQuery クエリは失敗します。この動作を確認するには、エンドポイント デバイスがインターネットに接続されているときに、Google Cloud コンソールからクエリを実行します。クエリが正常に終了せず、上り(内向き)違反が示されます。
project-2
にある VPC ネットワーク default
から同じクエリを実行できます。同様に、VPC ネットワーク default
を使用して、project-2
にある Compute Engine インスタンスから同じ BigQuery クエリを実行しても失敗します。これは、上り(内向き)ルールがプリンシパル user@example.com
のみを許可するようにまだ構成されているためです。ただし、VM は Compute Engine のデフォルトのサービス アカウントを使用しています。
project-2
の Compute Engine インスタンスから同じコマンドを正常に実行するには、次のことを確認します。
- VM には、BigQuery API を使用するためのアクセス スコープがある。これを行うには、VM のアクセス スコープとして [すべての Cloud API に完全アクセス権を許可] を選択します。
- VM に接続されているサービス アカウントには、次の操作を行う IAM 権限が必要です。
project-2
で BigQuery ジョブを作成するproject-1
にある BigQuery テーブルから BigQuery データを取得する
- デフォルトの Compute Engine サービス アカウントが上り(内向き)ルールと下り(外向き)ルールで許可される必要があります。
次に、Compute Engine のデフォルトのサービス アカウントを、(BigQuery テーブルからのデータの取得を許可する)上り(内向き)ルールと、(BigQuery ジョブの作成を許可する)下り(外向き)ルールに追加する必要があります。
default
VPC ネットワーク上の project-2
にある Compute Engine インスタンスから、次の bq query コマンドを実行します。
bq query --nouse_legacy_sql \
'SELECT name, total
FROM `project-1.codelab_dataset.codelab-table`
ORDER BY total DESC
LIMIT 10;'
現在の構成では、次の場合にのみ BigQuery コマンドが成功します。
project-2
のデフォルト VPC ネットワークを使用して VM で実行し、- 指定された
us-central1
リージョン(IP サブネットワーク)に配置されている。 - サービス境界で構成されたデフォルトの Compute Engine サービス アカウントを使用して実行します。
以下を含む他の場所から実行すると、BigQuery コマンドクエリは失敗します。
project-2
のデフォルト VPC ネットワークを使用する VM で実行しているが、アクセスレベルで追加されたサブネットとは異なるリージョンにある場合- インターネット上のユーザー クライアントでユーザー
user@example.com
が実行した場合。
この図は、同じプリンシパル
user@example.com
が、インターネットと Compute Engine インスタンスの 2 つの異なるロケーションから開始したアクセスを示しています。インターネットからの BigQuery への直接アクセス(青色の点線)は VPC Service Controls によってブロックされますが、VM からのアクセス(緑色の実線)は Compute Engine のデフォルト サービス アカウントの権限を借用することで許可されます。保護されたリソースに内部 IP アドレスからアクセスできるようにサービス境界が構成されているため、アクセスを許可されています。
8. クリーンアップ
サービスが使用されていない場合、VPC Service Controls の使用に対して別途料金はかかりませんが、このラボで使用した設定をクリーンアップすることをおすすめします。VM インスタンスと BigQuery データセット、または Google Cloud プロジェクトを削除して、料金が発生しないようにすることもできます。Cloud プロジェクトを削除すると、そのプロジェクト内で使用されているすべてのリソースに対する課金が停止します。
- VM インスタンスを削除するには、次の手順を完了します。
- Google Cloud コンソールで、[VM インスタンス] ページに移動します。
- VM インスタンス名の左側にあるチェックボックスをオンにしてから、[削除] を選択し、確認のためもう一度 [削除] をクリックします。
- サービス境界を削除するには、次の操作を行います。
- Google Cloud コンソールで、[セキュリティ] を選択してから、アクセス ポリシーのスコープとなるレベル(この場合はフォルダレベル)で [VPC Service Controls] を選択します。
- [VPC Service Controls] ページで、削除する境界に対応するテーブル行で [削除] をクリックします。
- アクセスレベルを削除するには、次の操作を行います。
- Google Cloud コンソールで、フォルダ スコープで [Access Context Manager] ページを開きます。
- グリッドで、削除するアクセスレベルの行を特定して、その他メニューを選択し、[削除] を選択します。
- プロジェクトをシャットダウンするには、次の手順を行います。
- Google Cloud コンソールで、[IAM &[Admin Settings] ページ。
- [IAM と[Admin Settings] ページで、[Shutdown] を選択します。
- プロジェクト ID を入力し、[シャットダウンする] を選択します。
9. 完了
この Codelab では、VPC Service Controls の境界を作成して適用し、トラブルシューティングを行いました。
詳細
次のシナリオも調べることができます。
- プロジェクトが VPC Service Controls で保護されたら、一般公開データセットに対して同じクエリを実行する。
project-1
と同じ境界にproject-2
を追加します。project-2
を独自の境界に追加し、project-1
を現在の境界に保持します。- データの取得だけでなく、テーブル内のデータの更新にもクエリを実行します。
ライセンス
この作業はクリエイティブ・コモンズの表示 2.0 汎用ライセンスにより使用許諾されています。