Nền Tảng Firewall Rules — Stateful Inspection, Priority và Connection Tracking
Firewall GCP Không Phải Là Thiết Bị Vật Lý
Điều đầu tiên cần hiểu về GCP firewall: không có firewall appliance. Firewall rules được enforce tại Andromeda agent chạy trên mỗi hypervisor — distributed, per-VM, không có central enforcement point.
Điều này có ý nghĩa quan trọng:
- Traffic giữa 2 VMs trong cùng subnet vẫn phải qua firewall (không bypass)
- Không có "firewall bypass" bằng cách đặt VMs trong cùng network segment
- Performance của firewall không bị limited bởi một thiết bị trung tâm
- Mỗi VM có firewall state riêng (connection tracking table per VM)
Tài liệu GCP xác nhận: "Connections are allowed or denied on a per-instance basis" và "traffic can only be controlled and logged as it leaves or arrives at a VM."
Internal Model: Stateful Connection Tracking
GCP firewall là stateful — điều này không chỉ là một tính năng, nó thay đổi cách bạn phải nghĩ về rules.
Cơ Chế 5-Tuple Tracking
Mỗi connection được track bằng 5-tuple:
- Source IP
- Destination IP
- Source Port
- Destination Port
- Protocol (TCP, UDP, ICMP...)
Khi một connection được cho phép bởi firewall rule, GCP lưu 5-tuple này vào connection tracking table. Return traffic matching connection này được tự động cho phép mà không cần rule riêng.
Flow 1: Client (203.0.113.5:54321) → Web Server (10.0.0.5:443)
Firewall check: Có ingress rule allow tcp:443 từ 0.0.0.0/0? → YES
Action: ALLOW
Connection tracking entry: (203.0.113.5:54321 ↔ 10.0.0.5:443, TCP, ESTABLISHED)
Flow 2 (return): Web Server (10.0.0.5:443) → Client (203.0.113.5:54321)
Firewall check: Connection trong tracking table? → YES
Action: ALLOW (không cần egress rule cho return traffic)Hệ quả thiết kế: Với ingress-focused rules (allow traffic vào), không cần egress rules cho return traffic. Ngược lại, với egress-focused rules (allow traffic ra), không cần ingress rules cho return traffic.
Connection Tracking Timeout
Connection tracking entry không tồn tại mãi mãi. Nếu "at least one packet is sent every 10 minutes," connection được coi là active. Sau 10 phút không có packet, connection bị expire và entry bị xóa.
Điều này có hệ quả cho long-lived, low-traffic connections (ví dụ: database connections với long idle periods):
Kịch bản: Application giữ database connection idle trong 15 phút
→ Connection tracking entry expire sau 10 phút idle
→ Application gửi query lần tiếp theo
→ Server nhận packet với existing connection state
→ Firewall không có tracking entry → packet bị drop (hoặc RST)
→ Application thấy "Connection reset" hoặc timeoutGiải pháp: TCP keepalive trong ứng dụng hoặc database driver, hoặc application-level heartbeats. Không phải lỗi của firewall — đây là expected behavior của stateful tracking với timeout.
Connection Tracking Table: Giới Hạn Tuyệt Đối
Đây là một trong những giới hạn kỹ thuật quan trọng nhất:
| Machine type | Max tracked connections |
|---|---|
| Shared-core (f1-micro, g1-small, e2-micro, ...) | 130,000 total |
| 1-8 vCPU | 130,000 per vCPU |
| 8+ vCPU | 1,040,000 total |
Ví dụ: VM với 4 vCPUs có thể track tối đa 520,000 connections đồng thời.
Khi limit bị vượt qua:
"When limits are exceeded, tracking is stopped for the connections that have the longest idle interval."
Những connections idle nhất bị evict khỏi tracking table. Packet tiếp theo của connection đó sẽ bị firewall treat như new connection — nếu không có rule allow cho new connections, nó bị drop.
Server với 4 vCPUs, max 520K connections:
Connections hiện tại: 519,000 (98% capacity)
Tình huống 1: 1,000 connections mới đến
→ 520,000 limit hit
→ Oldest idle connections bị evict
→ Nếu evicted connection gửi packet: drop hoặc RST
Tình huống 2: Connection storm (DDoS, botnet)
→ Tracking table overflow
→ Legitimate connections bị evict
→ Service disruptionProduction implication: Workloads với connection-intensive patterns (gaming servers, real-time messaging, websockets với hàng nghìn clients) cần:
- Scale horizontally (nhiều VMs thay vì một VM lớn) để distribute connection tracking
- Monitor
connectionsmetric - Xem xét connection pooling để giảm tổng số connections
Implied Rules: Luôn Tồn Tại, Không Thể Xóa
Hai implied rules luôn tồn tại ở cuối mọi VPC firewall:
Implied Rule 1 (INGRESS DENY):
Direction: INGRESS
Priority: 65534 (evaluated cuối cùng, trước priority 65535)
Action: DENY ALL
Implied Rule 2 (EGRESS ALLOW):
Direction: EGRESS
Priority: 65534
Action: ALLOW ALLBạn không thể xóa chúng, nhưng có thể override bằng rules có priority thấp hơn:
# Override implied ingress deny với custom deny ở priority cao hơn
gcloud compute firewall-rules create explicit-deny-ingress \
--direction=INGRESS \
--priority=65000 \
--action=DENY \
--rules=all
# Override implied egress allow với explicit block
gcloud compute firewall-rules create block-all-egress \
--direction=EGRESS \
--priority=65000 \
--action=DENY \
--destination-ranges=0.0.0.0/0 \
--rules=allBất Đối Xứng Quan Trọng
Ingress: mặc định DENY (bạn phải explicitly ALLOW những gì muốn vào)
Egress: mặc định ALLOW (bạn phải explicitly DENY những gì muốn block ra)Đây là nguồn gốc của nhiều security misconfigurations:
- Nhiều team chỉ configure ingress rules, quên egress → VM bị compromise có thể exfiltrate data ra ngoài thoải mái
- Khi implement "zero-trust", phải explicitly deny egress với rules có priority cao, rồi allow specific destinations
Hệ Thống Priority 0-65535
Quy tắc cốt lõi: Số nhỏ hơn = ưu tiên cao hơn. Rule với số nhỏ nhất matching traffic sẽ được apply, tất cả rules khác bị bỏ qua.
Rules trong VPC:
Priority Direction Sources Targets Protocol Action
100 INGRESS 10.0.0.0/8 tag:internal TCP:ALL ALLOW
500 INGRESS 0.0.0.0/0 tag:web TCP:443 ALLOW
1000 INGRESS 0.0.0.0/0 tag:web TCP:80 ALLOW
65000 INGRESS 0.0.0.0/0 ALL ALL DENY
65534 INGRESS [implied] [implied] ALL DENY
Packet: TCP:443 từ 203.0.113.5 → VM với tag:web
Check priority 100: Sources match 203.0.113.5? 10.0.0.0/8 → NO
Check priority 500: Sources match? 0.0.0.0/0 → YES. Target match? tag:web → YES
→ ALLOW (stop evaluating)
Rule priority 1000, 65000, 65534 không được checkKhi Cùng Priority: Behavior Không Xác Định
Rule A: Priority 1000, ALLOW tcp:80 từ 10.0.0.0/8
Rule B: Priority 1000, DENY tcp:80 từ 10.0.0.5/32
Packet: TCP:80 từ 10.0.0.5 (match cả 2 rules)GCP documentation không guarantee behavior khi nhiều rules cùng priority match cùng traffic. Trong thực tế, Google sử dụng internal algorithm — nhưng outcome là non-deterministic từ góc nhìn người dùng.
Thực hành bắt buộc: Đừng bao giờ để hai rules cùng priority có thể match cùng traffic với actions khác nhau. Sử dụng unique priorities hoặc design rules để chúng không bao giờ conflict.
Targeting: Network Tags vs Service Accounts
Firewall rules cần biết rules này áp dụng cho VMs nào. GCP cung cấp hai cơ chế:
Network Tags
Network tags là string labels gắn vào VM. Bất kỳ ai có quyền edit VM đều có thể thêm/xóa tags.
# Thêm tag vào VM
gcloud compute instances add-tags my-vm \
--tags=web-server,public-facing
# Firewall rule target theo tag
gcloud compute firewall-rules create allow-https \
--direction=INGRESS \
--action=ALLOW \
--source-ranges=0.0.0.0/0 \
--target-tags=web-server \
--rules=tcp:443Đặc điểm:
- Tags là arbitrary strings, không có validation
- Nhiều tags per VM (không giới hạn)
- Có thể thêm/xóa tags mà không cần restart VM
- Tags có thể tùy chỉnh tên theo convention của team
Security weakness của tags: Ai có compute.instances.setTags permission có thể thêm bất kỳ tag nào vào VM. Nếu user thêm tag web-server vào một VM không phải web server, VM đó nhận được tất cả firewall rules cho web servers — có thể tạo unintended access.
Service Accounts
Service accounts là identities của VM — được gắn khi create hoặc khi update (cần restart).
# Firewall rule target theo service account
gcloud compute firewall-rules create allow-backend-to-db \
--direction=INGRESS \
--action=ALLOW \
--source-service-accounts=backend-sa@project.iam.gserviceaccount.com \
--target-service-accounts=database-sa@project.iam.gserviceaccount.com \
--rules=tcp:5432Đặc điểm:
- Tối đa 1 service account per VM
- Thay đổi SA cần restart VM (strong guarantee)
- Quản lý bởi IAM — ai có
iam.serviceAccounts.actAsmới gán được - SA không thể bị thêm tùy tiện như tags
Security của service accounts: IAM bảo vệ việc gán SA, khó bị misuse hơn tags. Tuy nhiên, sử dụng SA làm firewall target có trade-off: khó debug hơn (phải trace từ VM → SA → firewall rules), và restart requirement khi thay đổi.
Không Thể Kết Hợp Tags và Service Accounts Trong Cùng Rule
# LỖI: không thể dùng cả hai trong cùng rule
gcloud compute firewall-rules create bad-rule \
--target-tags=web-server \
--source-service-accounts=backend-sa@project.iam.gserviceaccount.com
# Error: Cannot specify both targetTags and sourceServiceAccountsĐây là hard constraint của GCP firewall engine — phải chọn một cơ chế targeting per rule.
Ma Trận Quyết Định
| Tiêu chí | Network Tags | Service Accounts |
|---|---|---|
| Flexibility | Cao (thêm/xóa runtime) | Thấp (cần restart) |
| Security | Thấp (dễ misuse) | Cao (IAM-protected) |
| Debug dễ | Dễ (visible trong VM properties) | Khó hơn |
| Scale | Tốt (nhiều tags per VM) | Khó scale (1 SA per VM) |
| Audit | Khó (tags changes ít audit trail) | Tốt (IAM logs) |
Recommendation: Dùng service accounts cho critical security boundaries (prod → prod-db access). Dùng network tags cho less-sensitive grouping (load-balancer-frontend, monitoring-agent).
Source và Destination: Các Tùy Chọn Matching
Cho Ingress Rules
Source criteria (ai được phép vào):
sourceRanges: IP CIDRs (0.0.0.0/0, 10.0.0.0/8, ...)sourceTags: VMs với tag này làm sourcesourceServiceAccounts: VMs với SA này làm source
Target criteria (rules áp dụng cho VMs nào):
- Không specify → áp dụng cho tất cả VMs trong VPC
targetTags: VMs có tags nàytargetServiceAccounts: VMs có SA này
Cho Egress Rules
Destination criteria:
destinationRanges: IP CIDRs
Target criteria (VMs nào bị rule này govern):
- Không specify → tất cả VMs
targetTagstargetServiceAccounts
Combining Sources Trong Một Rule
# Rule với multiple sources (OR logic)
sourceRanges:
- 10.0.0.0/8 # OR
- 192.168.0.0/16
# Rule với sourceTags (OR logic)
sourceTags:
- frontend-app # OR
- api-gateway
# Nhưng không thể kết hợp sourceRanges VÀ sourceTags:
# sourceRanges và sourceTags trong cùng rule là NOT ALLOWED
# (phải chọn một loại source)Firewall Logging: Visibility Và Cost
Firewall logging cho phép log mỗi connection được allow hoặc deny:
gcloud compute firewall-rules update allow-https \
--enable-logging \
--logging-metadata=INCLUDE_ALL_METADATALog entries trong Cloud Logging:
{
"jsonPayload": {
"connection": {
"src_ip": "203.0.113.5",
"dest_ip": "10.0.0.5",
"src_port": 54321,
"dest_port": 443,
"protocol": 6
},
"disposition": "ALLOWED",
"rule_details": {
"reference": "allow-https",
"priority": 500
}
}
}Cost consideration: Firewall log entries được tính phí như Cloud Logging ingestion. Với VMs có traffic cao (web servers, proxies), logging ALL connections có thể generate GBs của logs per day → significant cost.
Selective logging: Chỉ enable logging cho security-sensitive rules (access đến databases, admin ports), không phải tất cả rules.
Failure Modes Quan Trọng Ở Scale
Failure 1: Firewall Rule Drift
Trong môi trường large-scale, rule drift xảy ra khi các rules được thêm ad-hoc theo thời gian mà không có cleanup:
Sau 2 năm:
- 500+ firewall rules trong một VPC
- Nhiều rules có priority 1000 (tất cả mọi người dùng default priority)
- Rules conflict với nhau một cách không rõ ràng
- Không ai biết rule nào đang thực sự apply hay không apply
- "Delete một rule?" → Không ai dám vì sợ break productionGiải pháp: Hierarchical firewall policies với lifecycle management, regular audit bằng Firewall Insights (trong Network Intelligence Center).
Failure 2: Tag-based Security Bypass
Bạn có rule: allow tcp:5432 từ tag:backend đến tag:database
Sự cố: Developer tạo test VM và thêm tag "backend" để test query
→ Test VM không phải là legitimate backend
→ Nhưng nó có access vào database server
→ Nếu test VM bị compromise: attacker có access vào databaseĐây là fundamental weakness của tag-based firewall trong môi trường có nhiều người dùng. Giải pháp: dùng service accounts cho high-security boundaries, IAM control ai có thể gán tag.
Failure 3: Connection Tracking Table Exhaustion Under Load
Đã đề cập ở trên nhưng cần nhấn mạnh: connection tracking exhaustion không có warning — suddenly connections start failing và không có error message rõ ràng.
Monitor metric compute.googleapis.com/firewall/dropped_packets_count và compute.googleapis.com/instance/connections để detect sớm.
References
- VPC Firewall Rules Overview — Tài liệu chính thức
- Using VPC Firewall Rules — Tạo và quản lý rules
- Firewall Rules Logging — Cấu hình logging
- Firewall Insights — Phân tích và optimize rules
- Connection Tracking — Chi tiết về connection tracking limits