VPC Service Controls - BigQuery の保護 Codelab I

1. はじめに

この Codelab では、VPC Service Controls を使用して BigQuery API を保護する方法を学びます。この Codelab は、サービス境界で保護されていない API サービスから始まり、一般公開データセットに対してクエリを実行し、結果をプロジェクト テーブルに保存できます。クエリは 1 つのプロジェクトで実行され、テーブル(結果が保存される場所)は別のプロジェクトで作成されます。これは、データを 1 つのプロジェクトに保存できるが、別のプロジェクトを使用してアクセスする必要がある設定を模倣したものです。

次に、データ プロジェクトを保護するサービス境界を導入します。上り(内向き)ルールと下り(外向き)ルールを使用して違反を修正する方法を学習し、後でアクセスレベルを追加して内部 IP アドレスを使用してアクセスを制限します。この Codelab の目標は次のとおりです。

  • 上り(内向き)ルールと下り(外向き)ルールを使用して、上り(内向き)違反と下り(外向き)違反を修正する方法について説明します。
  • 特定の違反が発生した理由を把握する。
  • 適用された違反修正の範囲を分析します。
  • アクセスレベルを使用して、VPC ネットワーク内の内部 IP アドレスからのトラフィックを許可するオプションを活用して、スコープを変更するように修正(上り(内向き) / 下り(外向き)ルール)を変更します。

2. リソースの設定と要件

始める前に

この Codelab では、次のことをすでに理解していることを前提としています。

セットアップ

初期設定は次のように設計されています。

サービス境界で API を保護しない初期設計。

標準サービス境界を作成する

この Codelab では、project-1 を保護する通常のサービス境界を使用します。

  • 標準の境界perimeter-1 を作成し、project-1 を追加します。

Compute Engine VM の作成

この Codelab では、us-central1 に配置され、default という名前のデフォルト VPC ネットワークを使用する project-2 に 1 つの Compute Engine インスタンスを使用します。

費用

Cloud のリソースや API を使用するには、Google Cloud コンソールで課金を有効にする必要があります。この Codelab の終了後に課金が発生しないように、使用したリソースをシャットダウンすることをおすすめします。Google Cloud の新規ユーザーは、300 米ドル分の無料トライアル プログラムをご利用いただけます。

費用が発生するリソースは、BigQuery と Compute Engine インスタンスです。BigQuery 料金計算ツールCompute Engine 料金計算ツールを使用して、費用を見積もることができます。

3. VPC Service Controls の制限なしで BigQuery にアクセスする

一般公開データセットに対してクエリを実行し、結果を project-1 に保存する

  1. project-2project-1 にアクセスして、BigQuery Studio ページにアクセスできるかどうかを確認します。project-1 がサービス境界内にある場合でも、境界はまだサービスを保護していないため、この操作は可能です。
  2. 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 のまま):

  1. [結果を保存する] をクリックし、[BigQuery テーブル] を選択します。(下のスクリーンショットを参照)。BigQuery の結果を保存します。
  2. 宛先プロジェクトとして project-1 を選択します。
  3. データセットに codelab_dataset という名前を付けます。(既存のデータセットを使用する場合を除き、[新しいデータセットを作成] を選択します)。BigQuery の結果を保存するときに宛先プロジェクトを選択する。
  4. テーブルに codelab-table という名前を付けます。
  5. [保存] をクリックします。

project-2 からクエリを実行した結果、一般公開データセットのデータが project-1 に正常に保存されました。

project-2 から project-1 に保存されたデータセットをクエリする

project-2 BigQuery Studio に残ったまま、次のクエリを実行して、次のデータを選択します。

  • プロジェクト: project-1
  • データセット: codelab_dataset
  • テーブル: codelab-table
SELECT name, total
FROM `project-1.codelab_dataset.codelab-table`
ORDER BY total DESC
LIMIT 10;

project-2project-1 のどちらも BigQuery の使用が制限されていないため、クエリは正常に実行されます。ユーザーが適切な IAM 権限を持っていれば、BigQuery へのアクセスはどこからでも可能です。

VPC Service Controls のサービス境界を使用しない Codelab の設定。 この図は、プリンシパルが BigQuery データセットをクエリする際のプロセスを示しています。BigQuery の各クエリは BigQuery ジョブを開始し、そのジョブが実際のオペレーション(このシナリオではデータの取得)を実行します。プリンシパル アクセスは、Compute Engine インスタンスとインターネットから、一般公開データセットと別の Google Cloud プロジェクトからクエリを実行することで示されます。VPC Service Controls によってブロックされることなく、データをクエリするプロセス(GetData)が成功します。

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 違反が発生する

下り(外向き)VPC Service Controls の違反

境界を越える違反が発生したため、違反監査ログは 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 ジョブを作成するための違反の修正

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 | サービス: 指定された ID は、API 呼び出しが指定されたサービスとメソッドに対するものである場合にのみ、指定されたプロジェクトに対して境界外のトラフィックを開始できます。それ以外の場合(たとえば、サービス境界で保護されている別のサービスを試した場合)、他のサービスは許可されていないため、オペレーションはブロックされます。

修正をテストする: 下り(外向き)ルール

下り(外向き)ルールが設定されたら、同じクエリを実行します。

SELECT name, total
FROM `project-1.codelab_dataset.codelab-table`
ORDER BY total DESC
LIMIT 10;

別の違反が発生します。今回は NO_MATCHING_ACCESS_LEVEL 上り(内向き)違反です。新しい違反は、ターゲット プロジェクトとメソッドの点で最初の違反とは異なります。

上り(内向き)の VPC Service Controls の違反

新しい違反は、次の上り(内向き)違反です。

  • 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 | サービス: 指定された ID は、API 呼び出しが BigQuery API と指定されたメソッド bigquery.tables.getData の場合にのみ、境界内のトラフィックを開始できます。

以降、同じクエリの実行は、VPC Service Controls 違反なしで適切に機能します。

project-1 で BigQuery API を制限し、user@example.com でのみ使用できるようにしました。user2@example.com では使用できません。

BigQuery API を保護する VPC Service Controls 境界 この図は、2 つの異なるプリンシパルが同じデータセットをクエリしようとしている様子を示しています。user2@example.com(青い点線)によるアクセスは、サービス境界構成によって project-1 から 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 が割り当てられている場合はパブリック IP CIDR 範囲で、ユーザー クライアントが Google Cloud プロジェクトから動作している場合は内部 IP アドレスを使用して実現できます。

内部 IP アドレスのアクセス条件でアクセスレベルを作成する

同じスコープ設定されたアクセス ポリシー フォルダで、Access Context Manager ページを開き、アクセスレベルを作成します。

  1. [Access Context Manager] ページで、[アクセスレベルを作成] を選択します。
  2. [新しいアクセスレベル] ペインで、次の操作を行います。
    1. タイトルを指定します。codelab-al を使用できます。
    2. [条件] セクションで、[IP サブネットワーク] をクリックします。
    3. [プライベート IP] タブを選択し、[VPC ネットワークを選択] をクリックします。
    4. [VPC ネットワークを追加] ペインで、default ネットワークを参照して見つけるか、//compute.googleapis.com/projects/project-2/global/networks/default 形式でネットワークの完全な名前を手動で入力します。
    5. [VPC ネットワークを追加] をクリックします。
    6. [IP サブネットを選択] をクリックします。
    7. VM インスタンスが配置されているリージョンを選択します。この Codelab では us-central1 です。
    8. [保存] をクリックします。

アクセスレベルを作成しましたが、どの境界や上り(内向き) / 下り(外向き)ポリシーにもまだ適用されていません。

IP サブネットワークで構成されたアクセスレベル

上り(内向き)ルールにアクセスレベルを追加する

上り(内向き)ルールで許可されたユーザーがアクセスレベルに対して検証されるようにするには、上り(内向き)ルールでアクセスレベルを構成する必要があります。クエリデータへのアクセスを承認する上り(内向き)ルールは perimeter-1 にあります。上り(内向き)ルールを変更して、送信元をアクセスレベル codelab-al として定義します。

VPC ネットワークのアクセスレベル

新しい構成のテスト

上り(内向き)ルールにアクセスレベルを追加した後、プロジェクト 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 サービス アカウントは、上り(内向き)ルールと下り(外向き)ルールで許可されている必要があります。

次に、上り(内向き)ルール(BigQuery テーブルからデータを取得できるようにするため)と下り(外向き)ルール(BigQuery ジョブを作成できるようにするため)に Compute Engine のデフォルト サービス アカウントを追加する必要があります。

アクセスレベルを使用した VPC Service Controls サービス境界の構成

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 が実行した場合。

GCE のデフォルトのサービス アカウントのアクセスを許可するサービス境界。 この図は、同じプリンシパル user@example.com によって、インターネットと Compute Engine インスタンスという 2 つの異なるロケーションから開始されたアクセスを示しています。インターネットから BigQuery に直接アクセスする(青い点線)ことは VPC Service Controls によってブロックされますが、Compute Engine のデフォルト サービス アカウントを偽装して VM からアクセスする(緑色の実線)ことは許可されます。アクセスが許可されているのは、内部 IP アドレスから保護されたリソースへのアクセスを許可するようにサービス境界が構成されているためです。

8. クリーンアップ

サービスが使用されていない場合、VPC Service Controls の使用に追加料金は発生しませんが、このラボで使用した設定をクリーンアップすることをおすすめします。料金が発生しないように、VM インスタンスと BigQuery データセット、または Google Cloud プロジェクトを削除することもできます。Cloud プロジェクトを削除すると、そのプロジェクト内で使用されているすべてのリソースに対する課金が停止します。

  • VM インスタンスを削除するには、次の操作を行います。
    • Google Cloud コンソールで、[VM インスタンス] ページに移動します。
    • VM インスタンス名の左側にあるチェックボックスをオンにして、[削除] を選択し、もう一度 [削除] をクリックして確定します。Compute Engine インスタンスの削除。
  • サービス境界を削除する手順は次のとおりです。
    • Google Cloud コンソールで、アクセス ポリシーがスコープ設定されているレベル(この場合はフォルダレベル)で、[セキュリティ]、[VPC Service Controls] の順に選択します。
    • [VPC Service Controls] ページで、削除する境界に対応するテーブル行の [削除] をクリックします。
  • アクセスレベルを削除するには、次の操作を行います。
    • Google Cloud コンソールで、フォルダ スコープの [Access Context Manager] ページを開きます。
    • グリッドで、削除するアクセスレベルの行を特定し、その他メニューを選択して、[削除] を選択します。
  • プロジェクトをシャットダウンするには、次の操作を行います。
    • Google Cloud コンソールで、削除するプロジェクトの [IAM と管理] の [設定] ページに移動します。
    • [IAM と管理の設定] ページで、[シャットダウン] を選択します。
    • プロジェクト ID を入力し、[このままシャットダウン] を選択します。

9. 完了

この Codelab では、VPC Service Controls の境界を作成し、適用して、トラブルシューティングを行いました。

詳細

次のシナリオも確認できます。

  • プロジェクトが VPC Service Controls で保護された後、一般公開データセットに対して同じクエリを実行します。
  • project-1 と同じ境界に project-2 を追加します。
  • project-2 を独自の境界に追加し、project-1 を現在の境界に残します。
  • データを取得するだけでなく、クエリを実行してテーブル内のデータを更新します。

ライセンス

この作業はクリエイティブ・コモンズの表示 2.0 汎用ライセンスにより使用許諾されています。