VPC Firewall Rules — Stateful Engine & Connection Tracking
Tại sao quan trọng trong production
VPC firewall rules là lớp L3/L4 enforcement đầu tiên trong data path của GCP. Mọi packet đến hoặc rời một VM instance đều phải đi qua lớp này trước khi chạm đến bất kỳ tầng application nào. Sai cấu hình ở đây có hai loại hậu quả: expose service không đáng (ingress quá rộng), hoặc block traffic hợp lệ (deny egress không tính đến return traffic).
Điểm mà hầu hết engineer hiểu sai nhất là tính stateful. VPC firewall rules không phải packet filter thuần túy theo kiểu iptables --state. Andromeda — network stack của GCP — duy trì một connection tracking table riêng, và quyết định allow/deny của một packet có thể phụ thuộc vào lịch sử của connection đó. Hiểu sai điều này dẫn đến hàng loạt lỗi configuration không thể debug nếu chỉ nhìn vào rules.
Mô hình nội tại — Stateful Connection Tracking Engine
Vị trí trong data path
VPC firewall rules không chạy trên một thiết bị tập trung. Chúng được enforce bởi Andromeda hypervisor trực tiếp tại Virtual Network Interface (vNIC) của mỗi VM. Không có "firewall appliance" hay "security group" trung gian nào nằm giữa hai VM trong cùng subnet. Điều này có nghĩa:
- Đánh giá firewall xảy ra tại nguồn egress và tại đích ingress của packet.
- Latency gần như zero vì tất cả là software trong hypervisor.
- Không có single point of failure — mỗi VM tự enforce cho chính mình.
Connection tracking table
Khi một connection được phép qua firewall (ingress hoặc egress rule match), Andromeda tạo một connection tracking entry trong bộ nhớ của hypervisor. Entry này lưu trữ:
- 5-tuple ban đầu: source IP, destination IP, source port, destination port, protocol
- 5-tuple đảo ngược (cho return traffic): destination IP ↔ source IP, destination port ↔ source port
- Trạng thái connection: established, time-wait, etc.
- Timestamp của packet cuối cùng
Khi return packet đến (ví dụ: TCP ACK từ server về client), Andromeda kiểm tra connection table trước khi đánh giá firewall rules. Nếu tìm thấy matching entry, packet được allow tự động mà không cần một egress rule riêng cho phép return traffic.
Theo tài liệu GCP: "When a connection is allowed through the firewall in either direction, return traffic matching this connection is also allowed."
Đây là điểm cốt lõi: một ingress allow rule không yêu cầu một egress allow rule tương ứng để return traffic đi được. Connection table xử lý điều đó.
Timeout và eviction
Connection tracking entry không tồn tại vĩnh viễn. Andromeda sẽ xóa entry nếu không có packet nào trên connection trong một khoảng thời gian nhất định:
- TCP established: ~1200 giây (20 phút) cho connections đã established
- TCP half-open/time-wait: ngắn hơn nhiều
- UDP: ~30 giây (UDP stateless nên timeout nhanh hơn)
Theo tài liệu GCP: "Connection tracking remains active if at least one packet transmits every 10 minutes."
Thực tế production: nếu bạn có một long-lived TCP connection (ví dụ: database connection pool), nhưng không có traffic trong hơn timeout period, connection sẽ bị xóa khỏi tracking table. Khi next packet đến, nó bị treat như một connection mới và phải match một explicit rule.
Eviction khi hết dung lượng
Connection tracking table có giới hạn kích thước phụ thuộc vào machine type của VM:
| Machine Type | Số kết nối tối đa |
|---|---|
| Shared-core (e2-micro, f1-micro, ...) | 130,000 |
| 1–8 vCPUs | 130,000 × số vCPU |
| Hơn 8 vCPUs | 1,040,000 (cố định) |
Khi table đầy, Andromeda evict các entry có idle time lâu nhất (LRU - Least Recently Used). Đây là nguồn gốc của một failure mode khó debug:
Scenario: VM với 2 vCPU (tối đa 260,000 connections) chạy application tạo nhiều short-lived connections (ví dụ: scraper hoặc API gateway). Dưới tải cao, connection table đầy. Connections mới phải qua full rule evaluation, nhưng do eviction đang xảy ra liên tục, một số established connections bị mất tracking entry và bị drop khi return packet đến, gây ra TCP RST bất ngờ.
Triệu chứng: connection reset không predictable, xảy ra chỉ dưới tải cao, không có lỗi firewall rõ ràng trong logs vì rule vẫn allow, nhưng return packet không match existing entry nữa.
Fragmented packets
Fragmented packets có handling đặc biệt trong connection tracking:
- Fragment đầu tiên (chứa TCP/UDP header): được evaluate theo firewall rules bình thường
- Fragment tiếp theo: chỉ được allow nếu fragment đầu tiên đã được allow (connection table track theo IP/protocol/fragment ID)
Điều này ngụ ý: cấu hình firewall chặn ICMP nhưng không tính đến IP fragmentation có thể vô tình block large packets bị fragment.
Cấu trúc của một firewall rule
Các thành phần bắt buộc
Mỗi VPC firewall rule là một object với các thuộc tính sau:
Direction: INGRESS hoặc EGRESS. Một rule không thể vừa ingress vừa egress.
INGRESS: áp dụng cho traffic đến VM (packets đang đi vào vNIC)EGRESS: áp dụng cho traffic ra từ VM (packets đang rời khỏi vNIC)
Action: ALLOW hoặc DENY. Không có action nào khác (không có LOG, REDIRECT, v.v. — những tính năng đó nằm ở Cloud NGFW và hierarchical policies).
Priority: số nguyên từ 0 đến 65535. Số nhỏ hơn có độ ưu tiên cao hơn. Khi có nhiều rules match, rule có priority thấp nhất thắng.
Lưu ý quan trọng: priority
0là cao nhất,65535là thấp nhất. Đây là nguồn gốc của nhiều hiểu nhầm.
Target: xác định VM nào rule này áp dụng:
- All instances in the network: rule apply cho mọi VM
- Specified target tags: chỉ VM có network tag cụ thể
- Specified service accounts: chỉ VM dùng service account cụ thể
Match criteria:
- Cho ingress: source IP ranges, source tags, source service accounts
- Cho egress: destination IP ranges
- Protocol và port: TCP, UDP, ICMP, ESP, AH, SCTP, IPIP, hoặc protocol number theo IANA
Ingress vs Egress là hai quyết định độc lập
Đây là điểm quan trọng nhất cần hiểu đúng. Khi VM A gửi request đến VM B:
- Trên VM A: Andromeda evaluate egress rules của VM A
- Trên VM B: Andromeda evaluate ingress rules của VM B
Cả hai đánh giá xảy ra độc lập. Traffic chỉ đến được VM B nếu cả hai đều allow:
- Egress rules của VM A cho phép traffic ra destination IP của VM B
- Ingress rules của VM B cho phép traffic từ source IP của VM A
Điều này tạo ra security model mạnh hơn: ngay cả khi VM A có egress allow-all, traffic vẫn bị chặn ở ingress của VM B nếu không có matching ingress rule.
VM A (10.0.0.2) ─── egress evaluate ───► VM B (10.0.0.3)
◄─── ingress evaluate ───Priority resolution algorithm
Khi nhiều rules cùng match một packet:
- Tìm tất cả rules match packet (direction, target, protocol/port, source/destination IP)
- Chọn rule có priority thấp nhất (số nhỏ nhất)
- Nếu có tie (cùng priority), GCP documentation không đảm bảo ordering — trong thực tế nên tránh same-priority conflicting rules
- Thực thi action của rule thắng
Không có "first match" hay "last match" logic. Chỉ có lowest priority number wins.
Implied rules — Rules không thể xóa
Mọi VPC network đều có hai implied rules không hiển thị trong console nhưng luôn được enforce:
Implied deny ingress (priority 65535):
direction: INGRESS
action: DENY
priority: 65535
source: 0.0.0.0/0Block tất cả ingress traffic không được explicitly allow.
Implied allow egress (priority 65535):
direction: EGRESS
action: ALLOW
priority: 65535
destination: 0.0.0.0/0Cho phép tất cả egress traffic không được explicitly deny.
Điều này có nghĩa: mô hình mặc định của GCP là allow-all outbound, deny-all inbound. Khác hoàn toàn với on-prem firewall thường deny cả hai chiều theo mặc định.
Hệ quả bảo mật: nếu bạn không có egress deny rules, mọi VM trong VPC đều có thể kết nối ra internet. Để kiểm soát egress, bạn phải explicit add egress deny rules với priority thấp hơn 65535.
Exemption bắt buộc của GCP
Có một số loại traffic luôn được bypass firewall rules, bất kể bạn cấu hình gì:
Metadata server: Andromeda luôn allow traffic giữa VM và metadata server 169.254.169.254. Không thể block bằng firewall rules. Đây là cơ chế để VM lấy instance metadata, service account tokens, và cấu hình.
Loopback: traffic đến địa chỉ loopback (127.0.0.0/8) không đi qua network stack, nên không bị evaluate bởi firewall.
DHCP: Andromeda thực hiện IP allocation qua DHCP. Traffic DHCP (port 67/68) được handled ở hypervisor layer, không đi qua firewall evaluation.
Theo tài liệu GCP: "Google Cloud always allows communication between a VM instance and its corresponding metadata server at
169.254.169.254regardless of firewall configuration."
Thực tế quan trọng: ngay cả với một deny-all rule ở priority 0, metadata server vẫn accessible. Điều này là thiết kế có chủ đích — VM cần metadata để bootstrap.
Targeting: Network Tags vs Service Accounts
VPC firewall rules có thể target VM theo hai cơ chế:
Network Tags
Network tags là string labels gán cho VM instances. Chúng không có access control — bất kỳ IAM principal nào có compute.instances.setTags permission đều có thể thêm/bỏ tags.
# Firewall rule targeting by tag
targetTags:
- "web-server"
- "backend-api"Vấn đề bảo mật: nếu developer có quyền tạo VM, họ có thể tự gán network tags và bypass hoặc gain access mà không qua approval. Network tags không provide strong security boundary.
Service Accounts
Khi rule target theo service account, chỉ VM chạy với service account đó mới bị ảnh hưởng. Service account assignment có separate IAM controls (cần iam.serviceAccountUser role).
# Firewall rule targeting by service account
targetServiceAccounts:
- "backend@project.iam.gserviceaccount.com"Lợi thế: service account là một strong identity với clear IAM controls. Không ai có thể tự "claim" identity một service account trừ khi được explicitly granted.
Giới hạn: không thể mix network tags và service accounts trong cùng một rule — phải chọn một trong hai.
Khi nào dùng gì
- Production workloads với security requirements: dùng service accounts. Đặc biệt cho east-west traffic giữa microservices.
- Legacy systems hoặc đội không control được VM provisioning: network tags với cơ chế governance bên ngoài (org policies hạn chế ai được setTags).
- Đừng dùng cả hai trong cùng VPC cho cùng policy — sẽ rất khó reason về effective policy.
Constraints & Failure Modes
Giới hạn số lượng rules
Mỗi VPC network có giới hạn mặc định là 300 firewall rules (có thể tăng qua quota request, nhưng có giới hạn). Ở scale lớn (nhiều team, nhiều service), con số này có thể đạt rất nhanh.
Đây là một trong những lý do chính để migrate sang Hierarchical Firewall Policies và Network Firewall Policies — chúng có giới hạn rule cao hơn nhiều và được share across networks.
Không có rule "log-only"
VPC firewall rules không hỗ trợ action "log only" hay "monitor". Rule chỉ có thể ALLOW hoặc DENY. Để logging, bạn enable Firewall Rules Logging trên từng rule, nhưng logging không thay đổi action.
Khi cần "thử một rule trước khi enforce", phải dùng hierarchical firewall policies với action goto_next hoặc VPC Service Controls với dry-run mode.
Không có FQDN hoặc L7 matching
VPC firewall rules hoàn toàn không hiểu DNS names, HTTP headers, hay application-layer content. Nếu bạn muốn allow traffic đến api.example.com nhưng block admin.example.com, đó là việc của Cloud NGFW Enterprise với FQDN/URL filtering — không phải VPC firewall rules.
Connection tracking và asymmetric routing
Nếu traffic đi vào qua một path nhưng return traffic đi qua path khác (asymmetric routing), connection tracking sẽ fail. Entry được tạo khi packet đầu tiên đến qua interface A. Khi return packet đến qua interface B, không có tracking entry nào trên interface B, và packet phải match explicit rules.
Đây xảy ra trong một số cấu hình hybrid connectivity (VPN + Interconnect cùng lúc) hoặc khi dùng multiple NICs trên VM.
Best Practices từ góc độ security
Không liệt kê pattern, nhưng có một mental model quan trọng:
Firewall rules không phải policy-as-documentation. Chúng là enforcement mechanism. Mỗi rule tồn tại nên có lý do rõ ràng và được review định kỳ. Dùng Firewall Insights (Chương 27.7) để tìm rules không có traffic hit — đó là candidates cho removal.
Không dựa vào "VPC firewall là firewall duy nhất". Với hybrid connectivity, traffic từ on-premises đến GCP phải qua VPC firewall. Nhưng traffic giữa hai VM trong cùng subnet vẫn phải qua firewall. Đây khác với on-prem switch — trong GCP, mọi L3 traffic đều bị evaluate.
Default egress allow là rủi ro. Implied egress allow (priority 65535) nghĩa là mọi VM đều có thể kết nối ra internet nếu không có explicit block. Trong production, luôn thêm deny egress rules và chỉ allow specific destinations.