1. 簡介
在本程式碼研究室中,您將瞭解如何使用 VPC Service Controls 保護 BigQuery API。本程式碼研究室一開始不會有任何受服務範圍保護的 API 服務,因此您可以對公開資料集執行查詢,並將結果儲存在專案資料表中。查詢會在一個專案中執行,而資料表 (用於儲存結果) 則是在另一個專案中建立,模擬資料可儲存在一個專案中,但需要使用不同專案存取的情況。
接著,我們將導入服務範圍,保護資料專案。您將瞭解如何使用輸入和輸出規則修正觀察到的違規事項,稍後也會新增存取層級,透過內部 IP 位址限制存取權。本程式碼研究室的目標如下:
- 瞭解如何分別使用輸入和輸出規則,修正輸入和輸出違規事項。
- 瞭解發生特定違規行為的原因。
- 分析已套用違規修正的範圍。
- 修改修正措施 (輸入 / 輸出規則),利用存取層級選項允許來自虛擬私有雲網路內部 IP 位址的流量,藉此變更修正措施的範圍。
2. 資源設定和需求
事前準備
在本程式碼研究室中,我們假設您已瞭解:
- 執行 BigQuery 查詢的基本概念:您可以查看這個程式碼研究室,瞭解如何在 BigQuery 中查詢 Wikipedia 資料集
- 如何建立及管理資料夾
- 如何在資料夾中建立專案,或將現有專案移入資料夾
- 如何建立範圍存取政策
- 如何建立及設定服務範圍
- 如何在記錄檔中找出安全性政策違規事項
設定
我們的初始設定如下:
- Google Cloud 機構。
- 機構下的資料夾。在本程式碼研究室中,我們將其稱為
codelab-folder。 - 兩個 Google Cloud 專案都放在同一個資料夾
codelab-folder下。在本程式碼研究室中,我們將這些函式稱為project-1和project-2- 如果尚未建立資料夾和專案,請在 Google Cloud 控制台中,於機構下建立資料夾,並在該資料夾下建立兩個新專案。
- 必要權限:
- 管理資料夾的 IAM 角色:在資料夾層級指派
- 專案管理 IAM 角色:在專案層級指派
- 設定 VPC Service Controls 所需的 IAM 角色:在組織層級指派
- 用於管理 BigQuery 的 IAM 角色:在專案層級指派
- 管理 Compute Engine 執行個體的 IAM 角色:在專案層級指派
- 兩個專案 (
project-2和project-1) 的帳單帳戶。
建立一般服務範圍
在本程式碼研究室中,我們會使用保護 project-1 的一般服務周邊。
- 建立一般 perimeter
perimeter-1,並新增project-1。
建立 Compute Engine VM
在本程式碼研究室中,我們將使用 1 個位於 project-2 的 Compute Engine 執行個體,並使用名為 default 的預設 VPC 網路。us-central1
- 您可以參考說明文件,瞭解如何從公開映像檔建立 Compute Engine 執行個體。
費用
如要使用雲端資源/API,請在 Google Cloud 控制台中啟用計費功能。建議您關閉使用的資源,以免產生本程式碼研究室以外的費用。Google Cloud 新使用者可參加價值 $300 美元的免費試用計畫。
會產生費用的資源是 BigQuery 和 Compute Engine 執行個體。您可以使用 BigQuery Pricing Calculator 和 Compute Engine Pricing Calculator 估算費用。
3. 存取 BigQuery,不受 VPC Service Controls 限制
查詢公開資料集並將結果儲存在 project-1 中
- 存取
project-2和project-1,然後前往 BigQuery Studio 頁面,確認是否可以存取 BigQuery API。您應該可以這麼做,因為即使project-1位於 service perimeter 中,perimeter 尚未保護任何服務。 - 從
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。(選取「CREATE NEW DATASET」(建立新資料集),除非使用現有資料集)。
- 將資料表命名為:
codelab-table。 - 按一下 [儲存]。
執行 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-2 和 project-1 都不受 BigQuery 使用限制。只要使用者具備適當的 IAM 權限,就能從任何位置存取 BigQuery。
這張圖表說明主體查詢 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 違規情形

違規事項稽核記錄會位於 project-1,因為違規跨越 perimeter 的行為發生在該處。您可以使用觀察到的 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-2 針對 project-1 中的資料集執行查詢。由於服務範圍 perimeter-1 保護 BigQuery API,因此從專案 (project-2) 執行查詢時,從資料集專案 (project-1) 建立 BigQuery 工作的作業會因 VPC Service Controls 外送違規而失敗。設定服務範圍後,除非服務範圍設定允許,否則無法從 project-1 向服務範圍外部發出 BigQuery API 要求,也無法從服務範圍外部向受保護的專案發出要求。
如要修正輸出違規事項,請根據下列項目建立輸出規則:
- 來源 (FROM):即使用者電子郵件地址和情境 (例如:來電者 IP 位址、裝置狀態、位置等)
- 目的地 (TO):即目標資源、服務和方法/權限。
如要修正觀察到的輸出違規行為,請建立輸出規則,允許 BigQuery 服務上執行查詢的使用者帳戶 (user@example.com) 透過 bigquery.jobs.create 方法/ 權限,將流量導向 targetResource (project-2)。

設定輸出規則的預期行為:
- FROM | 身分:只有指定的
user@example.com身分可跨越安全範圍邊界。 - TO | projects:只有在目的地為指定專案
project-2時,指定身分才能跨越範圍界線。 - TO | 服務:只有在 API 呼叫適用於指定服務和方法時,指定身分才能在範圍外啟動流量,並導向指定專案。否則,舉例來說,如果他們嘗試使用受服務範圍保護的其他服務,作業就會遭到封鎖,因為系統不允許使用其他服務。
測試修正:輸出規則
設定輸出規則後,請執行相同的查詢。
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 | 身分:只有指定的
user@example.com身分可跨越安全範圍邊界。 - TO | projects:只有在目的地是指定的專案
project-1時,指定的身分才能跨越安全防護範圍界線。 - TO | 服務:只有當 API 呼叫適用於 BigQuery API,且指定方法為
bigquery.tables.getData時,指定身分才能在安全防護範圍內啟動流量。
從此執行相同查詢時,應可正常運作,不會發生 VPC Service Controls 違規情形。
我們已在 project-1 中成功限制 BigQuery API,因此只能由 user@example.com 使用,user2@example.com 無法使用。
這張圖表說明兩個不同的主體如何嘗試查詢相同的資料集。VPC Service Controls 會拒絕
user2@example.com (藍色虛線) 的存取要求,因為服務範圍設定不允許這些使用者從 project-1 執行 BigQuery 作業,或對 project-1 執行 BigQuery 作業。user@example.com (綠色實線) 的存取作業成功,因為 VPC Service Controls 設定允許他們從 project-1 執行作業,以及對 project-1 執行作業。
7. 根據內部 IP 位址,限制 Service Perimeter 允許的流量
目前的設定可讓指定使用者在 project-1 中從任何位置對 BigQuery 執行查詢;只要使用者獲得查詢資料的 IAM 權限,並使用自己的帳戶,就能在網際網路上的任何位置執行查詢。從安全性的角度來看,這表示如果帳戶遭盜用,任何取得帳戶存取權的人都能存取 BigQuery 資料,不會受到任何額外限制。
您可以在輸入和輸出規則中使用存取層級指定使用者情境,進一步實施限制。舉例來說,您可以根據來源 IP 允許存取,並搭配先前設定的輸入規則,授權存取權給呼叫端身分。如果使用者用戶端已指派公開 IP,或使用者用戶端是從 Google Cloud 專案運作,則可透過來源 IP 存取公開 IP CIDR 範圍,或採用內部 IP 位址。
建立存取層級,並以內部 IP 位址為基礎設定存取條件
在同一個範圍存取權政策資料夾下,開啟 Access Context Manager 頁面,建立存取層級。
- 在 Access Context Manager 頁面中,選取「建立存取層級」。
- 在「New Access Level」(建立新的存取層級) 窗格中:
- 提供標題:可以使用
codelab-al。 - 在「條件」部分,按一下「IP 子網路」。
- 選取「私人 IP」分頁,然後點選「選取 VPC 網路」。
- 在「新增虛擬私有雲網路」窗格中,您可以瀏覽並找到
default網路,或以//compute.googleapis.com/projects/project-2/global/networks/default格式手動輸入完整網路名稱。 - 按一下「新增虛擬私有雲網路」。
- 按一下「選取 IP 子網路」。
- 選取 VM 執行個體所在的區域。在本程式碼研究室中,這個值是
us-central1。 - 按一下 [儲存]。
- 提供標題:可以使用
我們已建立存取層級,但系統尚未在任何 perimeter 或輸入/輸出政策中強制執行。

在輸入規則中新增存取層級
如要確保輸入規則允許的使用者也通過存取層級驗證,請務必在輸入規則中設定存取層級。授權存取查詢資料的 Ingress 規則位於 perimeter-1。修改輸入規則,將來源定義為存取層級 codelab-al。

測試新設定
在輸入規則中新增存取層級後,除非從專案 project-2 的虛擬私有雲網路 default 中的用戶端執行,否則相同的 BigQuery 查詢會失敗。如要驗證這項行為,請在端點裝置連上網際網路時,從 Google Cloud 控制台執行查詢。查詢會終止,並顯示違反進入規則的訊息。
您可以從位於 project-2 的虛擬私有雲網路 default 執行相同查詢。同樣地,如果從位於 project-2 的 Compute Engine 執行個體使用 VPC 網路 default 執行相同的 BigQuery 查詢,也會失敗。這是因為 Ingress 規則仍設定為只允許主體 user@example.com。不過,VM 使用的是 Compute Engine 預設服務帳戶。
如要從 Compute Engine 執行個體成功執行相同指令,請確認下列事項:project-2
- 虛擬機器具有使用 BigQuery API 的存取範圍。只要選取「允許所有 Cloud API 的完整存取權」做為 VM 存取權範圍,即可完成這項操作。
- 附加至 VM 的服務帳戶需要下列 IAM 權限:
- 在
project-2中建立 BigQuery 工作 - 從
project-1中的 BigQuery 資料表取得 BigQuery 資料
- 在
- 預設 Compute Engine 服務帳戶必須獲得輸入和輸出規則的允許。
現在我們需要在輸入規則中新增 Compute Engine 預設服務帳戶 (允許從 BigQuery 資料表取得資料),並在輸出規則中新增該帳戶 (允許建立 BigQuery 工作)。

在 project-2 VPC 網路的 Compute Engine 執行個體中,執行下列 bq query 指令:default
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 指令查詢,就會失敗,包括:
- 如果是在
project-2中使用預設 VPC 網路的 VM 上執行,但位於與存取層級中新增的子網路不同的區域,或 - 如果使用者
user@example.com透過網際網路上的使用者端執行。
這張圖說明由同一主體 (
user@example.com) 從兩個不同位置發起的存取要求:網際網路和 Compute Engine 執行個體。VPC Service Controls 會封鎖直接透過網際網路存取 BigQuery 的要求 (藍色虛線),但允許從 VM 存取 (綠色實線),同時模擬 Compute Engine 預設服務帳戶。這是因為服務範圍已設定為允許從內部 IP 位址存取受保護的資源。
8. 清除
雖然服務未使用時,使用 VPC Service Controls 無須另外付費,但建議您清除本實驗室中使用的設定。您也可以刪除 VM 執行個體和 BigQuery 資料集,或 Google Cloud 專案,以免產生費用。刪除 Cloud 專案後,系統就會停止對該專案使用的所有資源收取費用。
- 如要刪除 VM 執行個體,請完成下列步驟:
- 如要刪除服務範圍,請完成下列步驟:
- 在 Google Cloud 控制台中,依序選取「Security」和「VPC Service Controls」,存取權政策的範圍層級為資料夾層級。
- 在「VPC Service Controls」頁面中,找出要刪除的範圍,然後在對應的資料表列中按一下「Delete」(刪除)。
- 如要刪除存取層級,請完成下列步驟:
- 如要關閉專案,請完成下列步驟:
9. 恭喜!
在本程式碼研究室中,您建立了 VPC Service Controls 範圍、強制執行範圍,並排解範圍問題。
瞭解詳情
您也可以探索下列情境:
- 在專案受到 VPC Service Controls 保護後,對公開資料集執行相同的查詢。
- 在與
project-1相同的周邊範圍內新增project-2。 - 在自己的周邊新增
project-2,並將project-1保留在目前的周邊。 - 執行查詢來更新資料表中的資料,而不只是擷取資料。
授權
這項內容採用的授權為 Creative Commons 姓名標示 2.0 通用授權。
