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 を保護する通常のサービス境界を使用します。

Compute Engine VM の作成

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

費用

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

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

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

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

  1. [BigQuery Studio] ページにアクセスして project-2project-1 にアクセスし、BigQuery API にアクセスできるかどうかを確認します。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
  • Table: 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 プロジェクトからクエリを実行しています。データをクエリするプロセス(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 違反が発生します

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

修正のテスト: 下り(外向き)ルール

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

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

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

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

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

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

BigQuery API を保護する VPC Service Controls の境界この図は、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 ページを開き、アクセスレベルを作成します。

  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. [保存] をクリックします。

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

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 サービス アカウントが上り(内向き)ルールと下り(外向き)ルールで許可される必要があります。

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

アクセスレベルを使用した 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 によってブロックされますが、VM からのアクセス(緑色の実線)は Compute Engine のデフォルト サービス アカウントの権限を借用することで許可されます。保護されたリソースに内部 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 &[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 汎用ライセンスにより使用許諾されています。