GCP 網路基礎:看懂 VPC、Subnet、防火牆與 IAP
在 GCP 建好第一台 VM 後,下一個問題通常是網路:它為什麼能連上網際網路?HTTP 已經開了,SSH 還要不要對外開放?如果 VM 沒有外部 IP,又該怎麼登入?
這篇會沿著同一條連線路徑整理三件事:VM 放在哪個 VPC 與 Subnet、防火牆如何決定流量能不能通過,以及管理者如何透過 SSH 或 IAP 連進 VM。最後會建立一個沒有外部 IP 的練習環境,把這些設定串起來驗證。
先選閱讀路線:觀念、完整實作與清理
- 只讀觀念:先讀第一到四節,再回答文末情境題;不用建立資源。7 天計畫 Day 3 的閱讀/推演也走這條路線。
- 完整實作:第五節約 60–75 分鐘,從獨立專案準備、Custom VPC、IAP 連線,做到允許/拒絕/復原對照與清理。權限等待及排錯另計。
- 中途停止:先停用本次測試拒絕規則,再清理本次資源。不要為了排錯開放公開 SSH 或更動組織政策。
教材核對:2026-10-22。實作可能產生 VM、磁碟及用量費用;試用資格、免費額度及帳戶限制需另外核對。

先抓住邊界:VPC 是全球資源,Subnet 與它的 CIDR 是區域資源,VM 的網路介面落在某個 Subnet;防火牆依目標與來源判斷流量。IAP 能把管理連線送進沒有外部 IP 的 VM,而 Custom mode 讓正式環境能預先避開跨區域、跨環境與地端網段衝突。
一、VPC 與 Subnet 的範圍
VPC 是什麼?
VPC(Virtual Private Cloud,虛擬私有雲) 是 Project 裡的虛擬網路。Subnet、路由與防火牆規則都由設定定義,底層交換器與路由器則由 Google 維護。
先記住三個範圍:
- VPC 是全球資源:同一個 VPC 可以包含多個 Region 的 Subnet
- Subnet 是區域資源:同 Region 的多個 Zone 可以使用同一個 Subnet
- VM 網路介面屬於 Subnet:VM 會從所在 Subnet 取得內部 IP
和 AWS VPC 的差別
最容易混淆的是資源範圍:GCP VPC 是全球資源,AWS VPC 則屬於單一 Region。
| 特性 | GCP VPC | AWS VPC | 說明 |
|---|---|---|---|
| VPC 範圍 | 全球 | 區域 | GCP VPC 可包含多個 Region 的 Subnet |
| Subnet 範圍 | 區域 | 可用區 | GCP Subnet 可跨同 Region 內的多個 Zone |
| 跨區域連線 | 同一 VPC 內有系統路由 | 需另外連接 VPC | 仍要檢查防火牆、路由模式與費用 |
表格超出欄寬時,可左右捲動;鍵盤可聚焦表格後用左右方向鍵查看。
假設要在台灣 asia-east1 與新加坡 asia-southeast1 部署服務,GCP 可以把兩個 Subnet 放在同一個 VPC:
1 個 VPC
├── asia-east1 Subnet (10.1.0.0/24)
└── asia-southeast1 Subnet (10.2.0.0/24)
而在 AWS 需要:
VPC-Taiwan (需手動建立 VPC Peering)
VPC-Singapore
這樣不需要先建立跨 Region 的 VPC Peering。不過「有路由」不代表應用一定能通,防火牆、名稱解析與服務本身仍要設定,跨區域流量也可能產生費用。
Default、Auto 與 Custom Mode
建立 VPC 時常看到以下三種情況:
| 模式 | 子網路建立方式 | 適用場景 | 生產建議 |
|---|---|---|---|
| Default | 專案建立時可能自動建立 | 短期 Lab、測試 | 先檢查預設規則 |
| Auto Mode | 每個 Region 自動建立 Subnet | 快速建立多區網路 | 留意網段衝突 |
| Custom Mode | 手動決定 Region 與 CIDR | 正式環境、混合雲 | 通常較好管理 |
表格超出欄寬時,可左右捲動;鍵盤可聚焦表格後用左右方向鍵查看。
流程圖暫時無法顯示。可先查看下方的流程與節點文字,或重新整理頁面後再試。
查看流程與節點文字
箭頭表示流程方向;方括號與引號內是節點名稱,可搭配下方圖解閱讀。
flowchart TB
START["準備建立新的 VPC 網路"] --> SCENARIO{"主要使用情境?"}
SCENARIO -->|"正式環境、GKE、混合雲<br/>或未來跨網路整合"| CUSTOM["Custom Mode<br/>先做 IPAM 與環境切分"]
SCENARIO -->|"可整個刪除的短期<br/>個人 Lab/PoC"| DEFAULT["Default VPC<br/>先限縮預設防火牆"]
SCENARIO -->|"低風險多 Region 快速部署,<br/>且已確認不會網段衝突"| AUTO["Auto Mode<br/>記錄自動 CIDR 與轉換限制"]
DEFAULT --> REVIEW["建立前審查 CIDR、防火牆、路由與擁有者"]
AUTO --> REVIEW
CUSTOM --> REVIEW
REVIEW --> OPERATE["持續維護 IPAM 與規則基線"]
AUTO --> CHANGE{"日後需要完全掌控網段?"}
CHANGE -->|"是"| ONE_WAY["單向轉成 Custom Mode<br/>不能再回到 Auto"]
CHANGE -->|"否"| OPERATE
ONE_WAY --> OPERATE 為什麼正式環境常用 Custom Mode?
- 能先避開網段衝突:建立前就能對照地端、其他 VPC 與合作夥伴使用的 CIDR
- 只建立需要的 Subnet:不會自動在每個 Region 配一段 IP
- 環境比較好區分:Dev、Staging、Prod 可以各自規劃範圍
- 方便納入 IPAM:網路團隊能追蹤每段位址的用途與擁有者
Auto Mode 建立得快,但自動分配的網段日後可能和地端或其他雲端環境重疊。短期 Lab 問題不大;只要環境準備長期使用或需要連接其他網路,就值得先做 CIDR 盤點,再用 Custom Mode 建立。

圖中的 default 網路已經包含多個自動 Subnet 與預設防火牆規則;my-secure-vpc 則只有手動建立的 Subnet 與規則。Custom Mode 的重點不是比較安全的名稱,而是建立者必須明確決定每一段網路與存取規則。
模式可以單向轉換
Auto Mode 可以轉成 Custom Mode,轉換後不能再切回 Auto。準備轉換前,先確認後續 Subnet 都會改由團隊自行規劃與建立。
二、Subnet 與 CIDR 怎麼規劃?
Subnet 是什麼?
Subnet(子網路) 是 VPC 裡的一段 IP 位址範圍,VM 網路介面會從這裡取得內部 IP,部分服務也會使用額外的次要範圍。
它有幾個重要特性:
- 屬於單一 Region:同 Region 的多個 Zone 可以使用
- CIDR 不可重疊:同一個 VPC 裡,各個 Subnet 範圍不能互相重疊
- 主要範圍只能擴大:建立後不能縮小或直接換成另一段 CIDR
看懂 CIDR 表示法
CIDR(Classless Inter-Domain Routing) 用來表示一段 IP 範圍:
10.0.1.0/24
│ │
IP 起點 │
子網路遮罩(表示多少位元固定)
常見 CIDR 範圍對照表:
| CIDR | 可用 IP 數量 | 適用場景 | 範例 |
|---|---|---|---|
| /32 | 1 | 單一 IP | 10.0.1.5/32 |
| /28 | 16 | 極小型子網路 | 10.0.1.0/28 |
| /24 | 256 | 小型應用(標準) | 10.0.1.0/24 |
| /20 | 4,096 | 中型應用 | 10.0.0.0/20 |
| /16 | 65,536 | 大型應用 | 10.0.0.0/16 |
| /8 | 16,777,216 | 企業級超大網段 | 10.0.0.0/8 |
表格超出欄寬時,可左右捲動;鍵盤可聚焦表格後用左右方向鍵查看。
記得扣掉保留位址
/24總共有 256 個位址,但 GCP 會保留主要範圍中的 4 個,因此可分配給資源的是 252 個。估算容量時不要只看 CIDR 的總數,還要把成長、維護期間的額外資源與 GKE Pod 等需求一起算進去。
私有 IP 範圍選擇
根據 RFC 1918,可用於私有網路的 IP 範圍為:
| 類別 | CIDR 範圍 | 可用 IP 總數 | 建議用途 |
|---|---|---|---|
| Class A | 10.0.0.0/8 | 16,777,216 | 大型企業、多環境 |
| Class B | 172.16.0.0/12 | 1,048,576 | 中型組織 |
| Class C | 192.168.0.0/16 | 65,536 | 小型專案、家用網路 |
表格超出欄寬時,可左右捲動;鍵盤可聚焦表格後用左右方向鍵查看。
表中的 Class A、B、C 是舊稱,現代網路規劃以 CIDR 為準。172.16.0.0/12 也不等同傳統 Class B,只要記住三段 RFC 1918 私有範圍即可。
規劃時可以照這個順序:
- 先盤點地端、其他 VPC、VPN 與合作夥伴已使用的網段
- 再按 Region 和環境切分,保留未來擴充空間
- 如果會使用 VPC-native GKE,另外預留 Pod 與 Service 的 Secondary Range
範例:規劃多環境 Subnet
假設你要在 asia-east1 開 Dev / Staging / Prod 三個環境:
VPC: my-company-vpc(VPC 本身沒有單一 CIDR;以下是 Subnet 規劃)
├── asia-east1-dev (10.1.0.0/20) → 4,096 IPs
├── asia-east1-staging (10.2.0.0/20) → 4,096 IPs
└── asia-east1-prod (10.3.0.0/20) → 4,096 IPs
├── Primary Range: 10.3.0.0/20 → 4,096 IPs (VMs)
├── Secondary Range 1: 10.3.16.0/24 → 256 IPs (GKE Pods)
└── Secondary Range 2: 10.3.17.0/24 → 256 IPs (GKE Services)
這個範例想表達的是:
- Dev、Staging、Prod 使用不同範圍,規則和路由比較容易閱讀
- 每個環境預留成長空間,不要只按今天的 VM 數量切到剛剛好
- GKE 的 Pod 與 Service 使用獨立 Secondary Range,避免和 VM 位址混在一起
流程圖暫時無法顯示。可先查看下方的流程與節點文字,或重新整理頁面後再試。
查看流程與節點文字
箭頭表示流程方向;方括號與引號內是節點名稱,可搭配下方圖解閱讀。
flowchart TB
subgraph DISCOVER["盤點與容量估算"]
direction LR
INVENTORY["盤點地端、VPN、其他 VPC/專案<br/>與合作夥伴已使用的 CIDR"] --> CONFLICT["排除重疊與不可路由<br/>的候選範圍"]
end
CONFLICT --> DEMAND["估算各 Region/環境的資源<br/>與成長量"]
subgraph CAPACITY["容量與成長"]
direction LR
DEMAND --> RESERVED["扣除保留位址<br/>並加入成長緩衝"]
end
RESERVED --> GKE{"是否使用 VPC-native GKE<br/>或其他需要 Secondary Range 的服務?"}
GKE -->|"是"| SECONDARY["分開規劃 Pod 與 Service<br/>Secondary CIDR"]
GKE -->|"否"| SPLIT
subgraph ALLOCATE["分配與預留"]
direction LR
SECONDARY --> SPLIT["按 Region 與 Dev/Staging/Prod<br/>切出不重疊區塊"]
end
SPLIT --> FUTURE["預留未來 Region、環境、併購<br/>與混合雲空間"]
FUTURE --> VALIDATE{"所有 Primary/Secondary/地端網段<br/>是否不重疊且容量足夠?"}
VALIDATE -->|"否"| DEMAND
VALIDATE -->|"是"| IPAM["記錄到 IPAM/架構文件<br/>指定擁有者與變更流程"]
IPAM --> CREATE["建立 Subnet,驗證路由、<br/>Private Google Access 與防火牆"] 用 gcloud 建立 Subnet
先把網路、位置、主要與次要範圍列清楚。以下是方案推演,不會建立雲端資源;完整可執行指令在第五節,會明確帶入本次專案與名稱。
| 設定 | 規劃範例 | 核對方式 |
|---|---|---|
| VPC/Region | my-company-vpc/asia-east1 | 確認網路擁有者與可用區域 |
| Primary range | 10.3.0.0/20 | 盤點其他 Subnet、地端與互連網段是否重疊 |
| Secondary ranges | Pods 10.3.16.0/24、Services 10.3.17.0/24 | 依實際 GKE 模式與容量另行規劃,不把示例當正式尺寸 |
| Private Google Access | 依服務需求啟用 | 核對支援的 API、DNS、路由及防火牆,與 IAM 授權分開驗證 |
表格超出欄寬時,可左右捲動;鍵盤可聚焦表格後用左右方向鍵查看。
--range、--secondary-range 與 --enable-private-ip-google-access 分別對應這些設定。VPC 沒有一個可直接分配給 VM 的總 CIDR;位址範圍設定在 Subnet 上。
三、防火牆規則怎麼設計?
GCP 防火牆基礎
GCP 的 VPC 防火牆會控制進出 VM 網路介面的流量。它是有狀態的(Stateful):一條連線若被允許建立,對應的回程流量會自動放行,不需要再為回應方向另開一條規則。
判斷規則時要留意:
- 規則屬於 VPC,但可以用 Network Tag 或 Service Account 限定目標 VM
- 在匹配的 VPC firewall rules 中,Priority 數字越小,優先權越高
- 沒有其他匹配規則時,會套用隱含的 Ingress 拒絕與 Egress 允許
- 同一個 Priority 同時匹配 ALLOW 和 DENY 時,DENY 生效
防火牆規則的組成元素
一條防火牆規則包含以下關鍵元素:
| 元素 | 說明 | 範例 |
|---|---|---|
| Direction | 流量方向 | INGRESS (進入) / EGRESS (出去) |
| Action | 動作 | ALLOW / DENY |
| Priority | 優先權 (0-65535) | 1000 (數字越小優先權越高) |
| Source/Destination | 來源/目的地 | IP 範圍、Service Account、Tag |
| Protocol & Port | 協定與連接埠 | tcp:22 (SSH), tcp:80 (HTTP) |
| Target | 套用對象 | 特定 VM Tag、Service Account |
表格超出欄寬時,可左右捲動;鍵盤可聚焦表格後用左右方向鍵查看。
多條規則同時匹配時怎麼判斷?
下圖只描述 VPC firewall rules 之間的判斷。 先確認規則已啟用且匹配方向、來源、目標、協定與 port,再比較 Priority。
若環境另外套用階層式、全域或區域 Firewall Policy,先依實際政策評估順序判斷政策層與委派行為。全域/區域政策相對於 classic VPC rules 的順序也能設定;不能把不同政策的所有 Priority 混在一起排序。
流程圖暫時無法顯示。可先查看下方的流程與節點文字,或重新整理頁面後再試。
查看流程與節點文字
箭頭表示流程方向;方括號與引號內是節點名稱,可搭配下方圖解閱讀。
flowchart TB
PACKET["已依環境評估適用政策<br/>進入 VPC rules 的判斷"] --> SCOPE{"規則啟用、方向、VPC、目標 VM、<br/>來源/目的地、協定與<br/>Port 是否落在規則範圍?"}
SCOPE -->|"否"| NEXT["排除該規則,<br/>繼續尋找匹配項"]
NEXT --> MATCH{"還有其他可能匹配的規則?"}
MATCH -->|"有"| SCOPE
SCOPE -->|"是"| COLLECT["收集所有匹配規則"]
COLLECT --> PRIORITY["選 Priority 數字最小的一組"]
PRIORITY --> TIE{"同一 Priority 是否同時有<br/>ALLOW 與 DENY?"}
TIE -->|"是"| DENY["DENY 勝出,<br/>拒絕封包"]
TIE -->|"否"| ACTION["依該規則的 ALLOW<br/>或 DENY 執行"]
MATCH -->|"沒有"| DIRECTION{"封包方向?"}
DIRECTION -->|"Ingress"| IMPLIED_DENY["套用隱含<br/>DENY ALL"]
DIRECTION -->|"Egress"| IMPLIED_ALLOW["套用隱含<br/>ALLOW ALL"]
ACTION --> STATEFUL["已允許的連線由<br/>Stateful 防火牆<br/>自動放行對應回程流量"] 例如:
| 規則 | Priority | Action | Source | Port |
|---|---|---|---|---|
| Rule A | 1000 | ALLOW | 0.0.0.0/0 | tcp:80 |
| Rule B | 900 | DENY | 10.0.0.0/8 | tcp:80 |
表格超出欄寬時,可左右捲動;鍵盤可聚焦表格後用左右方向鍵查看。
假設兩條 VPC rules 都已啟用、方向與目標相同,且沒有先終止評估的政策:來自 10.0.0.5 的 HTTP 請求會被 Rule B 拒絕,因為 900 比 1000 更優先。文件示例來源 203.0.113.1 不符合 Rule B,才會由 Rule A 允許。這是規則判讀題,不要求開放真實 HTTP 服務。
簡單記法
先確認政策層與規則是否啟用,再比較匹配的 VPC rules。隱含 Ingress 拒絕/Egress 允許是回退規則,不等於所有現有專案的完整設定。
八個實際管理規則時會用到的原則
1. 最小權限原則 (Least Privilege)
只允許服務真正需要的來源、目標與 port。
先比較設計,還不建立規則:
| 設計欄位 | 範圍過大 | 較符合本次管理需求 |
|---|---|---|
| 來源 | 所有 IPv4 0.0.0.0/0 | IAP IPv4 35.235.240.0/20 |
| 協定與連接埠 | TCP、UDP 全部連接埠與 ICMP | TCP 22 |
| 目標 | 整個網路的 VM | 僅本次 VM 的專用標記 |
| 身分驗證 | 誤以為網路放行即可登入 | 另外核對 IAP 與 Linux SSH 權限 |
表格超出欄寬時,可左右捲動;鍵盤可聚焦表格後用左右方向鍵查看。
不要為了觀察「錯誤示範」而真的建立允許全部流量的規則。第五節使用兩條範圍相同的 SSH 規則做對照,並有獨立復原入口。
2. 明確 IP 範圍與連接埠
0.0.0.0/0 代表所有 IPv4 來源,適合公開網站的 HTTP/HTTPS,不適合直接套用到 SSH、RDP 或資料庫 port。管理入口可以限制在辦公室固定 IP、透過 VPN 進入,或改走後面介紹的 IAP。
常見做法:
- 使用公司辦公室的固定 IP 作為管理入口
- 透過 Cloud VPN 或 Cloud Interconnect 連接 On-Premise
- 對外服務僅開放必要連接埠(80, 443)
3. 選擇 Network Tags 或 Service Accounts
Network Tag 設定方便,但只要有權修改 VM Tag,就可能讓其他 VM 套用同一條規則。使用目標 Service Account 時,還能搭配 IAM 控制誰可以把身分附加到 VM。
| 方法 | 優點 | 缺點 |
|---|---|---|
| Network Tags | 設定直觀 | 能修改 Tag 的人可改變規則套用範圍 |
| Service Accounts | 可搭配 IAM 管理身分使用 | 設定與權限關係較多 |
表格超出欄寬時,可左右捲動;鍵盤可聚焦表格後用左右方向鍵查看。
選擇前先核對信任邊界:
- 使用 Network Tags:控制誰能修改 VM 的標記;標記被複用時,其他 VM 也可能被規則選中。
- 使用目標 Service Account:控制誰能把該身分附加到 VM,並檢查此服務帳號自身的 API 權限;防火牆選取器不會自動限縮其 IAM 權限。
- 不因為想選取防火牆目標,就替不需要呼叫 API 的 VM 新增高權限服務帳號。本篇 Lab 使用本次專用標記與不附掛服務帳號的 VM。
這些 Network Tags 與 Firewall Policy 的 Secure Tags 是不同機制;IAP TCP forwarding 的 IAM 授權也不會因為 VM 加上網路標記就自動取得。
4. 階層化策略 (Hierarchical Firewall Policies)
多個 Project 共用安全基線時,可以在 Organization 或 Folder 層級集中管理規則。要讓後續層級補上應用流量,必須先確認上層如何終止或委派評估;上層終止性的 DENY 不能被下層較小的 Priority 推翻。
Organization Level
├── DENY all RDP (tcp:3389) globally ← 全公司禁止 RDP
│
Folder Level (Production)
├── DENY outbound to public internet ← 生產環境禁止對外連線
│
Project Level
└── ALLOW specific application traffic ← 僅在上層委派/未終止評估的範圍內適用
這樣做的好處是:
- 安全基線一致:例如統一禁止公開 RDP
- 降低 Project 誤設影響:應用團隊不能輕易繞過上層政策
- 責任較清楚:安全團隊管基線,應用團隊管服務需求
5. 優先權數值規劃
先訂一套 Priority 區間,避免每個人都隨手填 1000,最後無法看出規則用途。
| Priority 範例 | 作用 | 需要確認 |
|---|---|---|
| 100 | 經核實的緊急阻擋 | 來源、目標與協定必須匹配,且有解除條件 |
| 1000 | 業務允許 | 限定應用真正需要的來源、目標與 port |
| 65534 | 明確拒絕並視需求記錄 | 不覆蓋較高優先序的允許;Logging 另評估用量與費用 |
表格超出欄寬時,可左右捲動;鍵盤可聚焦表格後用左右方向鍵查看。
這張表是管理慣例的示意,不會建立規則,也不是跨政策的全域排序。
以下只是一種範例,團隊可以依自己的變更流程調整:
| 優先權範圍 | 用途 |
|---|---|
| 0-999 | 緊急阻擋規則(惡意 IP、漏洞連接埠) |
| 1000-9999 | 正常業務規則 |
| 10000-64999 | 低優先權允許規則 |
| 65000-65534 | 團隊保留的顯式拒絕規則;65535 另有平台隱含規則 |
表格超出欄寬時,可左右捲動;鍵盤可聚焦表格後用左右方向鍵查看。
6. 啟用日誌與監控
對需要稽核或排錯的規則啟用 Logging,再用 Firewall Insights 協助找出未使用或過寬的規則。
建立或更新經核准的規則時,可用 --enable-logging 啟用;先確認 Project、network、來源與目標,不把開啟日誌當成縮小網路存取範圍。日誌可能產生費用,本篇 Lab 不要求啟用 Logging。官方規格也列明:只記錄 TCP/UDP 連線、不支援隱含規則,並非逐封包完整紀錄;沒有日誌不代表沒有流量。
日誌可以用來:
- 稽核追蹤:查看已啟用 Logging 的規則所產生的連線紀錄;不能把它當成所有封包或所有規則的完整紀錄
- 異常偵測 - 發現非預期的流量模式
- 合規要求 - 有助於滿足 PCI-DSS、HIPAA 等的稽核紀錄要求(合規是一整套控制措施,單靠開 log 不等於就「符合」,但 log 通常是其中跑不掉的一項)
Firewall Insights 可協助找出:
- 觀測期間未命中的規則:核對資料來源、觀測期間與使用情境;未命中不等於不再需要,還可能是備援或定期工作使用
- 需檢查範圍的規則:來源過寬、陰影或重複等情況應配合服務需求判讀;公開 HTTP 的必要來源與公開 SSH 不應直接視為同一個風險
- 重複規則 - 邏輯上重複的規則
7. 定期稽核與自動化清理
規則也需要退場流程,否則幾年後只會剩下一堆沒人敢刪的設定。
建議流程:
- 每季稽核 - 使用 Firewall Insights 檢視未使用規則
- 標記移除 - 將未使用規則標記為 “To-Be-Removed”
- 測試期 - 保留 30 天觀察是否有影響
- 確認後移除 - 透過 IaC 或受控流程刪除並更新文件
8. 上線前測試
先在 Staging 或隔離環境同時測試應該允許與應該拒絕的流量,再套用到正式環境。
測試時確認:
- 允許規則是否生效?(測試正常流量)
- 拒絕規則是否生效?(測試異常流量)
- 優先權順序是否正確?(測試衝突規則)
- 日誌記錄是否正常?(檢查 Cloud Logging)
流程圖暫時無法顯示。可先查看下方的流程與節點文字,或重新整理頁面後再試。
查看流程與節點文字
箭頭表示流程方向;方括號與引號內是節點名稱,可搭配下方圖解閱讀。
flowchart TB
subgraph DESIGN["設計最小規則"]
direction LR
NEED["提出網路存取需求"] --> DEFINE["定義來源、目標、方向、Port、<br/>理由、擁有者與到期條件"]
DEFINE --> MINIMIZE["限縮 CIDR、目標與 Priority<br/>避免公開管理入口"]
end
MINIMIZE --> STAGING["在 Staging 同時測試<br/>應允許、應拒絕與衝突規則"]
STAGING --> PASS{"行為與 Firewall Logs 是否符合預期?"}
PASS -->|"否"| DEFINE
PASS -->|"是"| DEPLOY["經審查後部署,啟用 Logging<br/>並留下變更與回復方式"]
subgraph OPERATE["觀測與稽核"]
direction LR
DEPLOY --> OBSERVE["觀察命中、拒絕、異常流量<br/>與 Firewall Insights"]
OBSERVE --> REVIEW{"規則仍被使用、<br/>必要且不過寬?"}
end
REVIEW -->|"是"| OBSERVE
REVIEW -->|"否或即將到期"| DISABLE["先停用或標記待移除<br/>保留觀察窗口"]
subgraph RETIRE["安全退場"]
direction LR
DISABLE --> IMPACT{"觀察期出現<br/>必要流量受影響?"}
IMPACT -->|"沒有"| DELETE["刪除規則並更新文件/IaC"]
end
IMPACT -->|"有"| DEFINE 四、SSH、OS Login 與 IAP 怎麼選?
管理 VM 時,除了確認「連不連得上」,也要看 VM 是否需要外部 IP、登入權限如何撤銷,以及能不能留下稽核紀錄。直接把 SSH 開到網際網路會多出幾項管理負擔:
- 外部 IP 和 TCP 22 會被持續掃描
- SSH 金鑰要分發、輪替與撤銷
- 人員離職或換職務時,要確認權限真的已移除
- 登入與操作紀錄需要另外整理
下面三種方式解決的問題不完全相同:SSH Key 是 Linux 登入憑證,OS Login 用 IAM 管理作業系統登入,IAP 則提供不經外部 IP 的 TCP 轉送路徑。它們也可以組合使用。
流程圖暫時無法顯示。可先查看下方的流程與節點文字,或重新整理頁面後再試。
查看流程與節點文字
箭頭表示流程方向;方括號與引號內是節點名稱,可搭配下方圖解閱讀。
flowchart TB
CONNECT["管理者需要連入 Compute Engine VM"] --> PRIVATE{"VM 是否禁止外部 IP,<br/>或屬於正式/高敏感環境?"}
PRIVATE -->|"是"| IAP["使用 Cloud IAP TCP Forwarding<br/>無外部 IP、IAM 驗證與集中稽核"]
PRIVATE -->|"否"| TEAM{"是否為多人協作,並希望用 IAM<br/>統一加入、撤銷與 2FA?"}
TEAM -->|"是"| OSLOGIN["使用 gcloud compute ssh + OS Login<br/>仍需可到達 VM 的連線路徑"]
TEAM -->|"否,短期個人 Lab/PoC"| KEY["可使用傳統 SSH Key<br/>限縮來源 IP 並設定金鑰輪替/清理"]
IAP --> CONTROLS["允許 35.235.240.0/20 到必要 Port<br/>授予 IAP 與 OS Login 最小角色"]
OSLOGIN --> CONTROLS2["限縮 tcp:22 來源、防火牆目標<br/>並用 IAM 管理登入權限"]
KEY --> CONTROLS3["避免 0.0.0.0/0 開放 SSH<br/>記錄並撤銷 Metadata 金鑰"]
CONTROLS --> TEST["測試授權使用者可連線、<br/>未授權者與非必要來源應被拒絕"]
CONTROLS2 --> TEST
CONTROLS3 --> TEST 方法一:傳統 SSH Key
這裡先理解流程,不執行變更:產生公私鑰 → 將公鑰交給核准的 VM 登入機制 → 經可到達的 SSH 路徑連線 → 結束時撤銷不再需要的授權。
直接覆寫 VM 的 ssh-keys metadata 可能移除別人的金鑰;啟用 OS Login 的 VM 也不會以 metadata SSH 金鑰作為同一套登入設定。不要把這兩種模式混在一起操作。後面的獨立 Lab 透過 gcloud compute ssh 使用環境允許的登入方式,不更改整個專案的 SSH 模式。
優點:
- 設定直接,標準 SSH 工具都能使用
- 適合範圍有限、生命週期短的個人 Lab
要自行處理:
- 金鑰分發、輪替與撤銷
- 外部 IP 或其他可到達 VM 的網路路徑
- 防火牆來源限制與登入稽核
短期個人練習可以使用;多人或正式環境通常改用集中管理的身分方式。
方法二:gcloud CLI 搭配 OS Login
實際設定前由管理者確認目標 VM 的有效 OS Login 設定與登入角色。專案層級啟用會影響多台 VM,不能把它當作個人 Lab 的必做準備;資源層級設定也必須符合組織政策。
本篇不提供自動變更專案 metadata 或自我授權的片段。若使用 OS Login,先依官方角色需求確認登入資格;附掛服務帳號、跨組織使用者或需要 sudo 時,還有相應的額外條件。
OS Login 的價值在於:
- 用 IAM 角色管理誰可以登入 VM
- 人員權限異動時,不必逐台移除 metadata 金鑰
- 可搭配 OS Login 兩步驟驗證與稽核功能
要注意的是:
- OS Login 解決的是登入身分,不會自動建立私有連線路徑
- 若不使用 IAP、VPN 或內部網路,VM 仍需要可到達的 SSH 路徑
它適合團隊協作,也常和 IAP 一起使用。
方法三:透過 Cloud IAP 轉送 SSH
IAP TCP forwarding 會先驗證 IAM,再把 TCP 流量轉送到內部 IP。這表示 VM 可以不配置外部 IP,也不用自己維護 Bastion Host。
它可以減少公開管理入口,但仍要正確設定來源範圍、IAP 角色與 OS Login/SSH 權限。IAP 是連線通道,不會取代 VM 端的登入驗證。
先逐項核對:
- IAP API 與控制平面存取已就緒。
- 防火牆允許 IAP IPv4
35.235.240.0/20到指定 VM 的 TCP 22。 - 操作者具備通道與必要的 Compute 查詢權限。
- VM 的 OS Login/metadata SSH 登入模式與角色正確。
完整建立、連線與清理指令集中在下一節。Network Tag 限定的是防火牆目標,不是 IAP 的 IAM 授權範圍;需要限制可連線的 VM 時,管理者應核對 IAP 的資源授權方式。
連線過程如下:
當你執行 gcloud compute ssh --tunnel-through-iap 時:
gcloud連到 IAP Proxy(tunnel.cloudproxy.app)並建立 HTTPS 隧道- IAP 檢查使用者是否有
iap.tunnelResourceAccessor角色 - IAP 把 SSH 流量轉送到目標 VM
- VM 再透過 SSH Key 或 OS Login 驗證登入身分
IAP 負責授權與轉送,VM 端仍會驗證 SSH 或 OS Login 身分。排錯時要把這兩層分開看:IAP 角色不足會卡在建立隧道,OS Login 或 SSH 權限不足則會卡在登入 VM。
三種方式放在一起看
| 方式 | 外部 IP | 身分管理 | 連線路徑 | 常見用途 |
|---|---|---|---|---|
| 傳統 SSH Key | 視路徑而定 | 手動管理金鑰 | 公開 IP、VPN 或內部網路 | 個人 Lab |
| gcloud + OS Login | 視路徑而定 | Google IAM | 公開 IP、IAP 或內部網路 | 團隊管理 |
| Cloud IAP + OS Login | 不需要 | IAM 加 VM 端登入 | IAP TCP forwarding | 私有 VM 管理 |
表格超出欄寬時,可左右捲動;鍵盤可聚焦表格後用左右方向鍵查看。
別把身分與連線路徑混在一起
OS Login 管理「誰能登入」,IAP 提供「怎麼連到沒有外部 IP 的 VM」。如果需求是 VM 不配置外部 IP,又要讓管理者從外部登入,通常會把 IAP 和 OS Login 搭配使用。
IAP 還能搭配什麼?
情境感知存取(Context-Aware Access)
如果組織有更細的存取需求,可以依裝置狀態、來源位置等條件限制連線。實際可用條件會受到授權版本與組織設定影響。
IAP Desktop
IAP Desktop 是開源桌面工具(官方頁面註明非 Google 官方支援的產品),可集中管理 Windows RDP、Linux SSH 與檔案傳輸。如果平常不想一直下 gcloud 指令,可以評估是否符合團隊的操作習慣。
稽核記錄
需要追查誰在什麼時間建立連線時,可以從 Cloud Audit Logs 查看 IAP 相關活動,再依組織需求串接告警或後續分析流程。
五、實作:建立 Custom VPC 並透過 IAP 連線
這次要完成的環境
預留 60–75 分鐘,包含前置檢查、第一次 SSH、拒絕對照、復原與清理;等待權限或排錯另計。使用 Cloud Shell Bash,需要 gcloud、GNU timeout 與 grep。VM、磁碟及相關用量可能收費,不能把 e2-micro 當成無條件免費。
本次只建立獨立 VPC、us-central1 的 Subnet、一台沒有外部 IP/服務帳號的 Debian VM,以及兩條只套用本次 VM 標記的 TCP 22 規則:
| 規則 | Priority | 動作 | 初始狀態 | 用途 |
|---|---|---|---|---|
本次名稱加 -iap | 1000 | ALLOW | 啟用 | IAP 來源到本次 VM 的 SSH |
本次名稱加 -block | 900 | DENY | 停用 | 短暫阻擋同一路徑,觀察對照後停用 |
表格超出欄寬時,可左右捲動;鍵盤可聚焦表格後用左右方向鍵查看。
這裡不放行整個內網、不公開 HTTP、不建立 NAT、不執行自我授權或專案 IAM Binding 變更指令。VM 不呼叫需要服務身分的 API,因此不附掛服務帳號。Subnet 會啟用 Private Google Access;這只是支援服務的網路前提,不是 IAM 授權或一般 Internet 出站能力。
先確認自己有建立/刪除這些資源、啟用 API、讀取專案與 Billing,以及 IAP 通道與 SSH 登入所需權限。 Metadata SSH 與 OS Login 的權限不同;本練習不變更專案 SSH 模式。若組織要求 OS Login,使用既有核准權限;若禁止本次網路、映像或位置,停止並記錄待辦,不修改組織政策。
IAP 通道與 SSH 權限表 與 OS Login 設定 可供管理者核對。不要為了 Lab 直接把自己升成 Owner。
提前中止或連線失敗時: 不要重做準備產生新名稱。保留本次設定檔,先用停用測試拒絕規則恢復路徑,再到清理本次資源逐項處理。
舊版使用的
my-secure-vpc、asia-east1-prod、secure-vm、secure-vm-sa與專案 IAM Binding 不會被新設定檔接管。曾做過舊版時,先查回舊專案與實際資源/授權來源,依用途確認後處理;不要因為本次新名稱查無資料,就當成舊資源已清理。
一次準備與設定恢復
改好第一行 Project ID,再執行整段。這一步只查詢雲端狀態並寫入本機設定,不建立雲端資源。括號內出錯會停止該段,不會關閉 Cloud Shell。
export NET_LAB_PROJECT='YOUR_PROJECT_ID'
export NET_LAB_CONTEXT="$HOME/cloudon-network-labs/net04-$(date -u +%Y%m%d-%H%M%S)-$RANDOM/context.env"
(
set -eu
case "$NET_LAB_PROJECT" in
''|'YOUR_PROJECT_ID'|'(unset)') echo '請先填入自己的 Project ID。' >&2; exit 1 ;;
esac
command -v timeout >/dev/null
command -v grep >/dev/null
NET_LAB_ACCOUNT="$(gcloud config get-value account)"
case "$NET_LAB_ACCOUNT" in
''|'(unset)') echo '請先確認 Cloud Shell 的登入帳號。' >&2; exit 1 ;;
esac
gcloud projects describe "$NET_LAB_PROJECT" --format='yaml(projectId,name,projectNumber)'
NET_LAB_BILLING="$(gcloud billing projects describe "$NET_LAB_PROJECT" --format='value(billingEnabled)')"
if [ "$NET_LAB_BILLING" != 'True' ]; then
echo 'Billing 尚未啟用,請先確認練習環境。' >&2
exit 1
fi
NET_LAB_REGION='us-central1'
NET_LAB_ZONE='us-central1-a'
NET_LAB_NAME="$(basename "$(dirname "$NET_LAB_CONTEXT")")"
NET_LAB_NETWORK="$NET_LAB_NAME-net"
NET_LAB_SUBNET="$NET_LAB_NAME-subnet"
NET_LAB_ALLOW="$NET_LAB_NAME-iap"
NET_LAB_BLOCK="$NET_LAB_NAME-block"
mkdir -p "$(dirname "$NET_LAB_CONTEXT")"
(
umask 077
for field in NET_LAB_PROJECT NET_LAB_REGION NET_LAB_ZONE NET_LAB_NAME \
NET_LAB_NETWORK NET_LAB_SUBNET NET_LAB_ALLOW NET_LAB_BLOCK; do
printf 'export %s=%q\n' "$field" "${!field}"
done > "$NET_LAB_CONTEXT"
)
printf '帳號:%s\n本次設定檔:%s\n' "$NET_LAB_ACCOUNT" "$NET_LAB_CONTEXT"
)
核對帳號、專案與設定檔完整路徑。後續每段都從這份檔案讀回位置與名稱,不修改 gcloud 預設專案或 Zone。同一次練習只做一次準備。
Cloud Shell 重新連線後,如何恢復設定?
只載入自己在本篇產生的設定檔。先列出候選檔案,再把第二行換成記錄的完整路徑;檔案沒有登入權杖,但 source 會執行其內容,不要載入陌生來源的檔案。
ls -lt "$HOME/cloudon-network-labs"/*/context.env
export NET_LAB_CONTEXT="$HOME/cloudon-network-labs/替換成本次目錄/context.env"
(
set -eu
source "${NET_LAB_CONTEXT:?請先指定本次設定檔路徑}"
printf 'Project=%s\nZone=%s\nVM=%s\nBlock rule=%s\n' \
"$NET_LAB_PROJECT" "$NET_LAB_ZONE" "$NET_LAB_NAME" "$NET_LAB_BLOCK"
)若家目錄未保留,請從自己的筆記與 Console 找回舊專案、位置和名稱。不要重跑準備後用另一組名稱查詢。
步驟 1:建立 Custom VPC
(
set -eu
source "${NET_LAB_CONTEXT:?請先完成準備或恢復設定檔}"
gcloud services enable compute.googleapis.com iap.googleapis.com --project="$NET_LAB_PROJECT"
gcloud compute networks create "$NET_LAB_NETWORK" \
--project="$NET_LAB_PROJECT" --subnet-mode=custom
)
本次網路沒有自動建立的 Subnet,也不依賴 default VPC。若後面任何建立步驟失敗,前面成功建立的資源仍在,應依同一份設定清理。
步驟 2:建立 Subnet
(
set -eu
source "${NET_LAB_CONTEXT:?請先完成準備或恢復設定檔}"
gcloud compute networks subnets create "$NET_LAB_SUBNET" \
--project="$NET_LAB_PROJECT" --region="$NET_LAB_REGION" \
--network="$NET_LAB_NETWORK" --range=10.91.0.0/24 \
--enable-private-ip-google-access
gcloud compute networks subnets describe "$NET_LAB_SUBNET" \
--project="$NET_LAB_PROJECT" --region="$NET_LAB_REGION" \
--format='yaml(name,network,region,ipCidrRange,privateIpGoogleAccess)'
)
核對網路、Region、10.91.0.0/24 與 privateIpGoogleAccess: true。這證明設定已存在,尚未證明任一 API 請求成功;實際連線還受 DNS、路由、防火牆及服務支援範圍影響。
步驟 3:建立防火牆規則
先建立允許規則,再建立尚未啟用的拒絕規則。兩者都只匹配 IAP IPv4 來源、本次標記與 TCP 22;Priority 900 的拒絕規則啟用時,才會比 1000 的允許規則優先。
(
set -eu
source "${NET_LAB_CONTEXT:?請先完成準備或恢復設定檔}"
gcloud compute firewall-rules create "$NET_LAB_ALLOW" \
--project="$NET_LAB_PROJECT" --network="$NET_LAB_NETWORK" \
--direction=INGRESS --action=ALLOW --rules=tcp:22 \
--source-ranges=35.235.240.0/20 --target-tags="$NET_LAB_NAME" --priority=1000
gcloud compute firewall-rules create "$NET_LAB_BLOCK" \
--project="$NET_LAB_PROJECT" --network="$NET_LAB_NETWORK" \
--direction=INGRESS --action=DENY --rules=tcp:22 \
--source-ranges=35.235.240.0/20 --target-tags="$NET_LAB_NAME" --priority=900 --disabled
gcloud compute firewall-rules describe "$NET_LAB_BLOCK" --project="$NET_LAB_PROJECT" \
--format='yaml(name,network,direction,priority,sourceRanges,targetTags,denied,disabled)'
)
此時拒絕規則的 disabled 應為 true。target-tags 是防火牆的目標選擇器,不是 IAP IAM 授權,也不等於 Firewall Policy 使用的 Secure Tags。
步驟 4:建立沒有外部 IP 的 VM
(
set -eu
source "${NET_LAB_CONTEXT:?請先完成準備或恢復設定檔}"
gcloud compute instances create "$NET_LAB_NAME" \
--project="$NET_LAB_PROJECT" --zone="$NET_LAB_ZONE" \
--machine-type=e2-micro --image-family=debian-12 --image-project=debian-cloud \
--boot-disk-type=pd-standard --boot-disk-size=10GB \
--subnet="$NET_LAB_SUBNET" --no-address --no-service-account --no-scopes \
--metadata=block-project-ssh-keys=TRUE \
--tags="$NET_LAB_NAME" --labels="coa-lab=network04,coa-run=$NET_LAB_NAME"
gcloud compute instances describe "$NET_LAB_NAME" \
--project="$NET_LAB_PROJECT" --zone="$NET_LAB_ZONE" \
--format='yaml(name,status,zone,networkInterfaces,serviceAccounts,disks,tags)'
)
核對 VM 為 RUNNING、Zone 正確、網路介面屬於本次 Subnet、沒有外部 natIP,且沒有服務帳號。block-project-ssh-keys 阻擋專案 metadata 金鑰,不會停用組織要求的 OS Login。
沒有外部 IP 要看網路設定,不能用 curl ifconfig.me 逾時推論。 逾時也可能來自 DNS、服務故障或防火牆;有 NAT、代理或其他出口時,沒有外部 IP 的 VM 仍可能連到 Internet。
步驟 5:透過 IAP 連線
在 Cloud Shell 執行,登入後只執行 hostname 再結束連線:
(
set -eu
source "${NET_LAB_CONTEXT:?請先完成準備或恢復設定檔}"
gcloud compute ssh "$NET_LAB_NAME" \
--project="$NET_LAB_PROJECT" --zone="$NET_LAB_ZONE" \
--tunnel-through-iap --command='hostname'
)
第一次可能會提示建立/解鎖 SSH 金鑰、確認 host key,或等待 VM 的 SSH 服務就緒。依提示處理;成功輸出本次 VM 的 hostname 才能繼續拒絕測試。IAP 權限失敗、Linux 登入被拒或 VM 尚未就緒時,先排錯,不要用後面的失敗掩蓋原本就不能登入。
驗證結果
接下來會短暫啟用拒絕規則。指令使用新的 SSH 連線,並限制等待時間;EXIT trap 會嘗試停用本次拒絕規則,即使測試出錯或收到一般中斷訊號,也會先做復原。
設定傳播需要時間。 啟用後若新連線仍成功,或超過 45 秒、出現其他權限錯誤,都不算取得對照證據。待確認狀態後沿用同一份設定重試,不要改公開 SSH。強制關閉 Cloud Shell、斷線或程序被強制終止時,trap 不能保證執行,需使用下一節的獨立復原指令。
(
set -eu
source "${NET_LAB_CONTEXT:?請先完成準備或恢復設定檔}"
NET_LAB_LOG="$(mktemp)"
restore_iap() {
if ! gcloud compute firewall-rules update "$NET_LAB_BLOCK" \
--project="$NET_LAB_PROJECT" --disabled; then
echo '復原失敗:請使用下方獨立指令停用本次拒絕規則。' >&2
exit 1
fi
rm -f "$NET_LAB_LOG"
}
trap restore_iap EXIT
trap 'exit 130' INT
trap 'exit 143' TERM
trap 'exit 129' HUP
gcloud compute firewall-rules update "$NET_LAB_BLOCK" \
--project="$NET_LAB_PROJECT" --no-disabled
gcloud compute firewall-rules describe "$NET_LAB_BLOCK" --project="$NET_LAB_PROJECT" \
--format='yaml(name,priority,sourceRanges,targetTags,denied,disabled)'
set +e
timeout 45s gcloud compute ssh "$NET_LAB_NAME" \
--project="$NET_LAB_PROJECT" --zone="$NET_LAB_ZONE" \
--tunnel-through-iap --command='hostname' \
--ssh-flag='-oConnectTimeout=10' --ssh-flag='-oConnectionAttempts=1' \
> "$NET_LAB_LOG" 2>&1
NET_LAB_SSH_STATUS=$?
set -e
cat "$NET_LAB_LOG"
if [ "$NET_LAB_SSH_STATUS" -eq 0 ]; then
echo '連線仍成功,尚未觀察到拒絕;先確認規則與設定傳播。' >&2
exit 1
fi
if [ "$NET_LAB_SSH_STATUS" -eq 124 ] || \
! grep -Eiq '\[4003:|failed to connect to backend' "$NET_LAB_LOG"; then
echo '尚未取得可判讀的 IAP backend 失敗證據;請分辨逾時、IAM 與 SSH 登入錯誤。' >&2
exit 1
fi
echo '觀察到 IAP backend 連線失敗;仍需完成停用與重新連線核對。'
)
IAP 錯誤 4003 代表連線/防火牆問題,也可能是客體服務沒在監聽,不能只憑錯誤碼就宣稱規則測試通過。需要保留「變更前成功、拒絕啟用時失敗、停用後恢復」三份證據,以及這次變更的精確規則名稱與時間。
停用測試拒絕規則
這段也是失敗後的獨立復原入口。它從 Cloud Shell 呼叫控制平面,不依賴 SSH 通道;先恢復自己的設定檔路徑,再執行:
(
set -eu
source "${NET_LAB_CONTEXT:?請先完成準備或恢復設定檔}"
gcloud compute firewall-rules update "$NET_LAB_BLOCK" \
--project="$NET_LAB_PROJECT" --disabled
gcloud compute firewall-rules describe "$NET_LAB_BLOCK" --project="$NET_LAB_PROJECT" \
--format='yaml(name,disabled)'
gcloud compute ssh "$NET_LAB_NAME" \
--project="$NET_LAB_PROJECT" --zone="$NET_LAB_ZONE" \
--tunnel-through-iap --command='hostname'
)
核對 disabled: true 且 hostname 再次成功。若仍失敗,先確認設定傳播、適用政策、IAP 與登入模式;不要追加專案級 Owner、把 SSH 開給 0.0.0.0/0 或停用組織安全政策。
流程圖暫時無法顯示。可先查看下方的流程與節點文字,或重新整理頁面後再試。
查看流程與節點文字
箭頭表示流程方向;方括號與引號內是節點名稱,可搭配下方圖解閱讀。
flowchart TB A["專用 VPC、Subnet、VM<br/>只有 IAP 來源的 TCP 22"] --> B["基準:hostname 成功"] B --> C["短暫啟用 priority 900 拒絕<br/>本次標記、IAP 來源、TCP 22"] C --> D["新 SSH 連線失敗<br/>核對 backend 錯誤與變更時間"] D --> E["trap/獨立指令停用拒絕規則"] E --> F["復原:hostname 再次成功"] F --> G["依本次設定清理<br/>VM、磁碟、兩條規則、Subnet、VPC"] C -. "逾時、權限錯誤或意外成功<br/>都先復原,不算通過" .-> E
清理本次資源
在 Cloud Shell 逐段執行,先核對本次 VM 與磁碟,再於 CLI 提示時確認刪除。不要同時執行多段;不要略過確認或刪整個專案。若已加入重要資料、其他磁碟或別的工作負載,先另外評估。
(
set -eu
source "${NET_LAB_CONTEXT:?請先完成準備或恢復設定檔}"
gcloud compute instances describe "$NET_LAB_NAME" \
--project="$NET_LAB_PROJECT" --zone="$NET_LAB_ZONE" --format='yaml(name,labels,disks)'
gcloud compute instances delete "$NET_LAB_NAME" \
--project="$NET_LAB_PROJECT" --zone="$NET_LAB_ZONE" --delete-disks=boot
)
再分別刪除兩條規則、Subnet 與 VPC:
(
set -eu
source "${NET_LAB_CONTEXT:?請先完成準備或恢復設定檔}"
gcloud compute firewall-rules delete "$NET_LAB_BLOCK" --project="$NET_LAB_PROJECT"
)
(
set -eu
source "${NET_LAB_CONTEXT:?請先完成準備或恢復設定檔}"
gcloud compute firewall-rules delete "$NET_LAB_ALLOW" --project="$NET_LAB_PROJECT"
)
(
set -eu
source "${NET_LAB_CONTEXT:?請先完成準備或恢復設定檔}"
gcloud compute networks subnets delete "$NET_LAB_SUBNET" \
--project="$NET_LAB_PROJECT" --region="$NET_LAB_REGION"
)
(
set -eu
source "${NET_LAB_CONTEXT:?請先完成準備或恢復設定檔}"
gcloud compute networks delete "$NET_LAB_NETWORK" --project="$NET_LAB_PROJECT"
)
中途建立失敗或已做過部分清理時,只有查明是本次名稱的 NOT_FOUND 才跳到下一段。權限不足、查詢失敗、資源使用中都不是已刪除;記下仍待處理的完整名稱,不要忽略錯誤。
如果 VM 建立失敗,卻留下本次同名開機磁碟?
先從下方最後核對確認磁碟仍存在,再描述它。僅在名稱、Zone、用途均為本次練習,且不再附掛重要資源時執行刪除;正常刪除 VM 與 boot disk 後不必再做這一步。
(
set -eu
source "${NET_LAB_CONTEXT:?請先完成準備或恢復設定檔}"
gcloud compute disks describe "$NET_LAB_NAME" \
--project="$NET_LAB_PROJECT" --zone="$NET_LAB_ZONE" --format='yaml(name,zone,users,labels)'
gcloud compute disks delete "$NET_LAB_NAME" --project="$NET_LAB_PROJECT" --zone="$NET_LAB_ZONE"
)最後核對六個本次名稱。每個查詢必須成功且沒有剩餘項目;函式會把查詢錯誤與仍有資源分別回報,不能將空白畫面當成查詢成功。
(
set -eu
source "${NET_LAB_CONTEXT:?請先完成準備或恢復設定檔}"
require_absent() {
local remaining
if ! remaining="$(gcloud "$@")"; then
echo '查詢失敗,無法確認已清理。' >&2
return 1
fi
if [ -n "$remaining" ]; then
printf '仍有本次資源,請核對後清理:\n%s\n' "$remaining" >&2
return 1
fi
}
require_absent compute instances list --project="$NET_LAB_PROJECT" \
--zones="$NET_LAB_ZONE" --filter="name=$NET_LAB_NAME" --format='value(name)'
require_absent compute disks list --project="$NET_LAB_PROJECT" \
--zones="$NET_LAB_ZONE" --filter="name=$NET_LAB_NAME" --format='value(name)'
for rule in "$NET_LAB_ALLOW" "$NET_LAB_BLOCK"; do
require_absent compute firewall-rules list --project="$NET_LAB_PROJECT" \
--filter="name=$rule" --format='value(name)'
done
require_absent compute networks subnets list --project="$NET_LAB_PROJECT" \
--regions="$NET_LAB_REGION" --filter="name=$NET_LAB_SUBNET" --format='value(name)'
require_absent compute networks list --project="$NET_LAB_PROJECT" \
--filter="name=$NET_LAB_NETWORK" --format='value(name)'
echo '六個本次資源名稱均未列出。'
)
保留設定檔、三段連線結果與清理輸出。本篇不另外建立 NAT、保留 IP、快照或應用服務帳號,也不在清理時停用 API;若自行加過其他資源,需另外核對。停止 VM 不等於刪除磁碟;Billing 資料也可能延遲,不能以即時零元代替資源清單。
自我檢核:完成操作後,能說明這三件事嗎?
- 為何 priority 900 的 DENY 沒有一開始就擋住? 它先以
disabled建立;停用的規則不參與比對,數字小也不會生效。 - 4003 一定代表這條防火牆擋住嗎? 不一定,也可能是客體沒在監聽。要核對新連線、規則範圍、變更時間,以及前後的成功基準。
- Subnet 開了 Private Google Access,就能讀任何 bucket 嗎? 不能;還需網路條件、服務支援與該資源的授權。沒有服務帳號的 VM 也不會自動獲得物件讀取權。
若只有建立成功、尚未取得三段證據或仍有資源未清理,請保留未完成項目;不要只因為指令跑過就勾選整份實作完成。
六、做完後整理一下
這篇的主線其實只有一條:先決定資源位於哪個網路範圍,再用路由與防火牆控制資料路徑,最後替管理者提供一條不必公開 VM 的連線方式。
VPC 與 Subnet
- GCP VPC 是全球資源,Subnet 是區域資源
- Custom Mode 讓團隊自行決定 Region 與 CIDR
- Auto Mode 可以轉成 Custom Mode,但不能切回 Auto
CIDR 規劃
- GCP 會在主要範圍保留 4 個位址,估算時要另外留成長空間
- 用 RFC 1918 私有 IP 範圍(10.x.x.x、172.16.x.x、192.168.x.x)
- 為容器環境預留 Secondary IP Range
防火牆
- 防火牆有狀態,允許連線後會自動放行對應回程流量
- 在同一組匹配的 VPC rules 中比較 Priority;跨政策先查評估順序,同值衝突由 DENY 生效
- 每條規則都應有用途、擁有者與退場條件
管理連線
- OS Login 管理誰能登入,IAP 提供抵達私有 VM 的連線路徑
- 使用 IAP 仍要設定 IAM、防火牆與 VM 端登入權限
下一步學習資源
官方文件
- VPC Networks Overview
- VPC Firewall Rules
- Firewall Policy 評估順序
- Private Google Access 條件
- 建立/停用防火牆規則
- Cloud IAP TCP forwarding
實驗室實作
Qwiklabs 已經併進 Google Skills(原 Google Cloud Skills Boost),舊的 qwiklabs.com 連結大多失效或重導了。直接到 Google Skills 上搜尋對應的 hands-on lab 即可:
- 在 Google Skills 搜尋「VPC Networks」,練習建立 VPC 與 Subnet
- 搜尋「Firewall Rules」,練習設定與驗證防火牆規則
- 搜尋「Cloud IAP」或「IAP for TCP forwarding」,練習連線到沒有外部 IP 的 VM
進階主題
- VPC Peering:連接兩個 VPC
- Shared VPC:讓多個專案共用集中管理的網路
- Cloud VPN 與 Cloud Interconnect:連接地端與 Google Cloud
- Private Service Connect:透過私有 IP 使用服務
系列文章連結
常見問題 FAQ
Q1: VPC 與 Subnet 有什麼差異?
A: VPC 是全球性的虛擬網路容器,Subnet 是 VPC 內特定區域的 IP 地址範圍。一個 VPC 可包含多個跨區域的 Subnet。
Q2: 為什麼 Cloud IAP 不需要外部 IP?
A: IAP Proxy 會把通過授權的 TCP 流量轉送到 VM 的內部 IP,所以 VM 本身不必配置外部 IP。防火牆仍要允許 IAP 的來源範圍連到指定連接埠。
Q3: 防火牆規則的優先權如何運作?
A: 先確認政策評估順序,再在適用且已啟用的 VPC rules 內比較匹配規則的 Priority。數字較小者優先;同值且 ALLOW、DENY 同時匹配時由 DENY 生效。停用規則不參與比對,跨政策不能直接混排數字。團隊預留數字區間是管理慣例,不是平台限制。
Q4: Auto Mode VPC 可以轉換成 Custom Mode 嗎?
A: 可以,但只能從 Auto Mode 轉成 Custom Mode,不能再切回 Auto Mode。轉換既有網路需核對實際專案、網路與影響範圍,依核准的網路變更流程處理;本篇實作直接建立新的 Custom VPC,不轉換既有網路。
Q5: 如何監控防火牆規則是否被使用?
A: 可以先啟用 Firewall Rules Logging,再用 Firewall Insights 檢查規則的使用狀況。看到長期沒有命中的規則時,先確認擁有者與用途,再依變更流程停用或移除,不要只看一次報表就直接刪除。
Q6: GCP VPC vs AWS VPC 的主要差異是什麼?
A: GCP VPC 是全球資源,Subnet 是區域資源,可涵蓋同一 Region 內的多個 Zone;AWS VPC 則是區域資源,Subnet 位於單一 Availability Zone。哪一種較適合,要看既有架構、維運方式與跨區需求。
Q7: IAP TCP forwarding 防火牆如何設定?
A: IPv4 的 IAP TCP forwarding 需允許 35.235.240.0/20 到目標 VM 的指定 port(如 TCP 22)。可用 Network Tag 或服務帳號限定防火牆目標;操作者的 IAP IAM 與 SSH 登入權限仍需另外核對。
Q8: OS Login 是什麼?
A: OS Login 把 Linux VM 的 SSH 登入資格交給 IAM 管理,減少逐台維護 metadata SSH Key 的工作。它也可以搭配兩步驟驗證,相關管理活動則可透過稽核記錄追查。
準備 ACE 時可以怎麼記?
先掌握這幾個判斷點:
- GCP VPC 是全球資源,Subnet 是區域資源——跟 AWS 不同
- 先確認政策評估順序,再比較匹配的 VPC rules;已啟用規則中 Priority 越小越優先,同值衝突由 DENY 生效
- 隱含規則是 Ingress 拒絕、Egress 允許,不是所有專案的實際完整政策
- Cloud IAP TCP forwarding 可連到沒有外部 IP 的 VM,防火牆需允許
35.235.240.0/20 - Private Google Access 提供無外部 IP 的 VM 到支援 API 的網路路徑;仍需 DNS、路由、防火牆與資源授權
- 題目涉及成本時,要分開看網路資源本身、流量方向與是否跨區,不要只憑「用了 VPC」判斷
三個常見題型
Q:Custom VPC 可以改成 Auto Mode 嗎? A:不行。Auto Mode 可以轉 Custom(單向不可逆),但 Custom 不能轉回 Auto。
Q:同一個 VPC 的兩條已啟用規則都匹配,一條 ALLOW tcp:80 priority 1000,一條 DENY tcp:80 priority 1000,且沒有先終止評估的政策,結果是? A:DENY。同 Priority 的匹配 VPC rules 由 DENY 勝出。
Q:VM 沒有外部 IP,但需要存取 Cloud Storage API,怎麼做? A:可在 Subnet 啟用 Private Google Access,並核對支援服務、DNS、路由與防火牆;呼叫 Cloud Storage 的身分仍須具有對應資源權限。啟用 PGA 本身不會授權讀取物件。
下一篇會接著看 GCP-105:看懂身分、角色與權限繼承,把「誰可以對哪些資源做什麼」這件事拆開說清楚。
讀完後,留一個學習紀錄
試著用自己的話說出一個重點,以及你會如何運用。實作文章請先核對結果與清理資源,再標記為讀完。
文章進度以你確認讀完的標記為準,可隨時取消。舊版造訪紀錄保留,但不計入讀完;這份自評不代表已掌握內容。