VPC Service Controls - BigQuery 保護程式碼研究室 I

1. 簡介

在本程式碼研究室中,您將瞭解如何使用 VPC Service Controls 保護 BigQuery API。程式碼研究室一開始沒有任何受服務範圍保護的 API 服務,也就是允許在公開資料集執行查詢,並將結果儲存在專案資料表中。查詢會在一項專案中執行,而資料表 (儲存結果的位置) 會在另一項專案中建立,並模擬設定;資料可以儲存於一個專案,但需要使用其他專案存取。

接下來,我們將推出用來保護資料專案的服務範圍。您將瞭解如何運用輸入規則和輸出規則修正觀察到的違規事項,再新增存取層級,使用內部 IP 位址限制存取行為。本程式碼研究室的目標如下:

  • 瞭解如何分別使用輸入規則和輸出規則,修正輸入和輸出的違規情況。
  • 瞭解發生特定違規的原因。
  • 分析套用違規問題修正的範圍。
  • 透過選擇允許來自虛擬私有雲網路中內部 IP 位址的流量 (使用存取層級) 來修改修正項目 (輸入 / 輸出規則) 以變更範圍。

2. 資源設定和需求

事前準備

在本程式碼研究室中,我們假設您已知道:

設定

初始設定的設計如下:

初始設計時採用服務範圍保護沒有 API。

建立一般服務範圍

在本程式碼研究室中,我們將使用一般服務範圍保護 project-1

建立 Compute Engine VM

在本程式碼研究室中,我們將使用位於 us-central1project-2 中的 1 個 Compute Engine 執行個體,並使用名為 default 的預設虛擬私有雲網路。

費用

您必須在 Google Cloud 控制台中啟用計費功能,才能使用雲端資源/API。建議您停用已使用的資源,以免產生本程式碼研究室以外的費用。新使用者符合 $300 美元免費試用方案的資格。

BigQuery 和 Compute Engine 執行個體是會產生費用的資源。您可以使用 BigQuery Pricing CalculatorCompute Engine Pricing Calculator 來估算費用。

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. 按一下「Save Results」,然後選取「BigQuery table」。(請參閱下方的螢幕截圖)。儲存 BigQuery 結果。
  2. 選取 project-1 做為目的地專案。
  3. 將資料集命名為 codelab_dataset。(除非使用現有資料集,否則請選取「建立新的資料集」)。儲存 BigQuery 結果時選擇目的地專案。
  4. 將資料表命名為:codelab-table
  5. 按一下 [儲存]

由於從 project-2 執行查詢,因此公開資料集資料已成功儲存在 project-1 中。

查詢資料集儲存於 project-1 (來源:project-2)

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,因此應能成功執行查詢。只要使用者俱備適當的身分與存取權管理權限,即可從任何地方存取 BigQuery。

進行程式碼研究室設定,但不使用 VPC Service Controls 服務範圍。這張圖表說明主體查詢 BigQuery 資料集的程序。每項 BigQuery 查詢都會啟動一個 BigQuery 工作,然後實際執行實際作業。在這種情況下,系統會擷取資料。從 Compute Engine 執行個體和網際網路查詢主體存取權,同時透過公開資料集和另一個 Google Cloud 專案進行查詢。查詢資料 (GetData) 的程序順利完成,且未遭到 VPC Service Controls 封鎖。

4. 保護來源資料集專案中的 BigQuery API

修改範圍 perimeter-1 的設定,並限制 BigQuery API 服務以及 project-1 中的受保護資源。

設定服務範圍

確認強制執行服務範圍

請在 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-2project-1 資料集執行查詢的時機。從用於執行查詢的專案中資料集專案 (project-1) 建立 BigQuery 工作的作業失敗,因為服務範圍「perimeter-1」保護 BigQuery API,導致 VPC Service Controls 發生輸出違規問題。project-2設定範圍後,任何 BigQuery API 要求都不得從 project-1 向範圍外發出,或在範圍外提出受保護專案的要求;除非受到服務範圍設定允許

您可以根據以下條件建立輸出規則,藉此修正輸出違規事件:

  • 來源 (FROM):包括使用者的電子郵件地址和背景資訊 (例如來電者 IP 位址、裝置狀態、位置等)
  • 目的地 (TO):也就是目標資源、服務和方法或權限。

如要修正觀察到的輸出違規事件,請建立輸出規則,透過透過 BigQuery 服務執行查詢的使用者帳戶 (user@example.com) 和 bigquery.jobs.create 方法/ 權限,允許流量前往 targetResource (project-2)。

輸出違規 修正設定。

已設定輸出規則的預期行為:

  • 寄件者 |身分:只有指定的身分 user@example.com 才能跨越範圍邊界。
  • 收件者 |專案:只有在目的地為指定專案 project-2 時,指定身分才能跨越邊界。
  • 收件者 |服務:只有在 API 呼叫用於指定的服務和方法時,指定的身分才能啟動範圍外的流量。在其他情況下,舉例來說,如果使用者嘗試使用受服務範圍保護的其他服務,作業就會因為不允許其他服務而遭到封鎖。

測試修正結果:輸出規則

建立輸出規則後,請執行相同的查詢。

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 工作所發起的 API 呼叫,是嘗試從 BigQuery 資料表取得資料。

6. 修正違規問題,以取得 BigQuery 資料表資料

輸入規則修正了輸入違規事件,同時更精細地控管允許跨服務範圍邊界的人員,以及所允許存取權的情境,例如來源/ 目標專案和可存取的 API 方法。

輸入規則修正了以下輸入規則:

  • 來源 (FROM):包括使用者的電子郵件地址和背景資訊 (例如來電者 IP 位址、裝置狀態、位置等)
  • 目的地 (TO):也就是目標資源、服務和方法或權限。

輸入規則會允許指定使用者在指定服務和方法中傳送至 project-1 的流量。

修正輸入違規問題

已設定的輸入規則的預期行為:

  • 寄件者 |身分:只有指定的身分 user@example.com 才能跨越範圍邊界。
  • 收件者 |專案:只有在目的地為指定專案 project-1 時,指定身分才能跨越邊界。
  • 收件者 |服務:只有在 API 呼叫適用於 BigQuery API 和指定方法 bigquery.tables.getData 時,指定的身分才能啟動範圍內的流量。

因此相同的查詢應可在未違反 VPC Service Controls 的情況下正常運作。

我們已成功限制 project-1 中的 BigQuery API,確保只有 user@example.com (而非 user2@example.com) 才能使用 API API。

保護 BigQuery API 的 VPC Service Controls 範圍此圖表說明兩個不同的主體如何嘗試查詢同一個資料集。VPC Service Controls 不允許透過 user2@example.com 存取 (虛線藍線),因為系統不允許透過服務範圍設定project-1執行 BigQuery 作業。成功透過「user@example.com」(綠色實線) 存取,因為 VPC Service Controls 設定允許執行從 project-1 開始的作業。

7. 根據內部 IP 位址限制服務範圍允許的流量

目前的設定可讓指定的使用者從任何位置在 project-1 中對 BigQuery 查詢。並具備查詢資料的 IAM 權限,且只要他們使用自己的帳戶即可。從安全性的角度來看,這表示一旦帳戶被入侵,任何獲得帳戶存取權的人都能存取 BigQuery 資料,不受任何其他限制。

如要進一步限制,您可以在輸入和輸出規則中使用存取層級來指定使用者情境。舉例來說,您可以將根據來源 IP 存取的輸入規則,與先前設定的輸入規則 (透過呼叫端身分授權存取) 搭配使用。只要使用者用戶端已獲派公開 IP,或是使用內部 IP 位址 (如果使用者用戶端是透過 Google Cloud 專案進行操作),即可透過來源 IP 存取這兩種公開 IP CIDR 範圍。

運用內部 IP 位址存取條件建立存取層級

在相同的範圍存取權政策資料夾下,開啟 Access Context Manager 頁面建立存取層級

  1. 在 Access Context Manager 頁面中,選取「建立存取層級」
  2. 在「New Access Level」(新增存取層級) 窗格中:
    1. 提供標題:您可以使用 codelab-al
    2. 在「條件」部分中,按一下「IP 子網路」
    3. 選取「私人 IP」分頁標籤,然後點選「選取虛擬私有雲網路」
    4. 在「Add VPC Networks」窗格中,您可以瀏覽及尋找 default 網路,或是手動輸入完整網路名稱 (格式為 //compute.googleapis.com/projects/project-2/global/networks/default)。
    5. 按一下「新增虛擬私有雲網路」
    6. 按一下「選取 IP SUBNET」
    7. 選取 VM 執行個體所在的區域。在本程式碼研究室中,為 us-central1
    8. 按一下 [儲存]

我們建立了存取層級,但尚未對任何範圍或輸入/輸出政策強制執行。

透過 IP 子網路設定的存取層級

在輸入規則中新增存取層級

為強制允許輸入規則允許的使用者通過存取層級驗證,就必須在輸入規則中設定存取層級。授權查詢資料存取權的輸入規則位於 perimeter-1。修改輸入規則,將來源定義為存取層級 codelab-al

使用虛擬私有雲網路的存取層級

測試新設定

之後在輸入規則中新增存取層級後,除非為專案 project-2 從虛擬私有雲網路 default 的用戶端執行,否則相同的 BigQuery 查詢將會失敗。如要確認這項行為,請在端點裝置連上網際網路時,透過 Google Cloud 控制台執行查詢。查詢將失敗,同時附帶一個輸入內容違反事件跡象。

同一個查詢可以從位於 project-2 的虛擬私有雲網路「default」執行。同樣地,使用虛擬私有雲網路 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 虛擬私有雲網路 project-2 中的 Compute Engine 執行個體,執行下列 bq 查詢指令

bq query --nouse_legacy_sql \
'SELECT name, total
FROM `project-1.codelab_dataset.codelab-table`
ORDER BY total DESC
LIMIT 10;'

在目前的設定下,只有在下列情況下,BigQuery 指令才會成功:

  • 使用 project-2 中的預設虛擬私有雲網路在 VM 上執行,以及
  • 位於指定的 us-central1 區域 (IP 子網路),以及
  • 運作時,會以服務範圍設定的預設 Compute Engine 服務帳戶執行。

如果從其他地方執行,BigQuery 指令查詢就會失敗,包括:

  • 如果在 VM 使用 project-2 的預設虛擬私有雲網路,但所在區域與在存取層級中新增的子網路不同,或者
  • 由使用者 user@example.com 透過網際網路使用者用戶端執行。

允許 GCE 預設服務帳戶存取的服務範圍。此圖表顯示由相同主體 user@example.com 從兩個不同位置啟動的存取作業:網際網路和一個 Compute Engine 執行個體。VPC Service Controls 會封鎖直接透過網際網路存取 BigQuery 的功能 (藍色虛線),而在模擬 Compute Engine 預設服務帳戶時,系統允許從 VM (綠色實線) 存取。我們將服務範圍設為允許透過內部 IP 位址存取受保護的資源,因此允許存取的行為。

8. 清除

在未使用 VPC Service Controls 的情況下,使用 VPC Service Controls 不會另外收費,但最佳做法是清除本研究室中使用的設定。您也可以刪除 VM 執行個體、BigQuery 資料集或 Google Cloud 專案,以免產生費用。刪除 Cloud 專案之後,系統就會停止對該專案使用的所有資源收取費用。

  • 如要刪除 VM 執行個體,請完成下列步驟:
    • 在 Google Cloud 控制台中,前往「VM instances」(VM 執行個體) 頁面。
    • 勾選 VM 執行個體名稱左側的核取方塊,然後選取「Delete」(刪除),再按一下「Delete」(刪除) 加以確認。刪除 Compute Engine 執行個體。
  • 如要刪除服務範圍,請完成下列步驟:
    • 在 Google Cloud 控制台中,依序選取「安全性」和存取權政策限定層級 (在本例中為資料夾層級) 的「VPC Service Controls」
    • 在「VPC Service Controls」頁面中,找出要刪除的範圍對應的表格列,然後按一下「Delete」(刪除)
  • 如要刪除存取層級,請完成下列步驟:
    • 在 Google Cloud 控制台中,開啟資料夾範圍的「Access Context Manager頁面。
    • 在格狀檢視畫面中,找出要刪除的存取層級所在的資料列,依序選取「三點圖示選單」和「刪除」
  • 如要關閉專案,請完成下列步驟:
    • 前往 Google Cloud 控制台中的 IAM 與管理員設定您想刪除的專案頁面。
    • 在「IAM 與」「管理設定」頁面,選取「關閉」
    • 輸入專案 ID,然後選取「仍要關閉」

9. 恭喜!

在本程式碼研究室中,您已建立並強制執行 VPC Service Controls 範圍,並排解相關問題。

瞭解詳情

您也可以探索下列情境:

  • 在專案受 VPC Service Controls 保護之後,對公開資料集執行相同的查詢。
  • 在與 project-1 相同的範圍中新增 project-2
  • 在本身的範圍內新增 project-2,並將 project-1 保留在目前的範圍內。
  • 您可以執行查詢來更新資料表中的資料,不只是要擷取資料。

授權

這項內容採用的是創用 CC 姓名標示 2.0 通用授權。