Network Tags vs Service Accounts — Hai Mô Hình Targeting Firewall và Trade-offs
Bài Toán: Làm Sao Firewall Biết Rules Áp Dụng Cho VMs Nào?
GCP VPC firewall rules được define ở cấp VPC — nhưng không phải mọi rule áp dụng cho mọi VM. Bạn cần một cách để nói "rule này chỉ áp dụng cho web servers" hoặc "chỉ VMs trong backend tier được phép kết nối database".
GCP cung cấp hai cơ chế:
- Network Tags: String labels gắn vào VM instances
- Service Accounts: IAM identities gắn với VM instances
Sự lựa chọn giữa hai cơ chế này không chỉ là preference — nó ảnh hưởng đến security model, audit trail, và khả năng của kẻ tấn công khi compromise một số thành phần trong hệ thống.
Network Tags: Cơ Chế Và Internal Model
Cách Tags Hoạt Động
Network tags là simple strings gắn vào VM's metadata. Khi Andromeda agent evaluate firewall rule:
Rule: ALLOW tcp:443 nguồn 0.0.0.0/0 đến target-tags=[web-server]
Packet đến VM:
1. Andromeda check: VM này có tag "web-server" không?
2. Tags của VM: [web-server, production, us-west1]
3. "web-server" ∈ VM tags? → YES
4. Rule match → ALLOWTags là arbitrary strings. Không có validation, không có central registry. Bất kỳ string nào đều hợp lệ làm tag.
Quản Lý Tags: Dễ Dàng Nhưng Có Rủi Ro
# Thêm tag khi tạo VM
gcloud compute instances create my-vm \
--tags=web-server,public-facing,production
# Thêm tag vào VM đang chạy (không cần restart)
gcloud compute instances add-tags my-vm \
--tags=monitoring-target
# Xóa tag khỏi VM đang chạy (không cần restart)
gcloud compute instances remove-tags my-vm \
--tags=old-tagĐiểm quan trọng: Thay đổi tags không cần restart VM. Tag change có effect gần như ngay lập tức — Andromeda agent cập nhật VM's tag set và firewall evaluation thay đổi tương ứng.
IAM Permission Để Manage Tags
Quyền cần thiết để set tags trên VM: compute.instances.setTags
Permission này thường là một phần của roles/compute.instanceAdmin.v1 và thậm chí roles/compute.instanceAdmin. Điều này có nghĩa là bất kỳ developer nào có quyền manage VMs đều có thể thêm/xóa tags.
Kịch bản tấn công bằng tag manipulation:
1. Kẻ tấn công compromise developer account (phishing, credential leak)
2. Developer account có compute.instances.setTags
3. Kẻ tấn công thêm tag "database-admin" vào VM mà họ control
4. Nếu có firewall rule allow "database-admin" đến database:
→ Kẻ tấn công có access vào database qua VM đóĐây không phải sức vẽ ra — đây là một attack vector thực sự trong GCP environments với broad compute permissions.
Source Tags vs Target Tags
Tags có hai vai trò khác nhau trong firewall rules:
Target Tags: Xác định VMs NÀO rule này govern (apply to)
gcloud compute firewall-rules create allow-https \
--target-tags=web-server # Rule này áp dụng cho VMs có tag "web-server"
--source-ranges=0.0.0.0/0
--allow=tcp:443Source Tags: Trong ingress rules, xác định traffic từ VMs có tag này
gcloud compute firewall-rules create allow-backend-to-db \
--target-tags=database # Rule áp dụng cho DB VMs
--source-tags=backend-service # Chỉ traffic từ VMs có tag "backend-service"
--allow=tcp:5432Quan trọng về Source Tags: Source tag matching chỉ hoạt động trong cùng VPC. Không thể dùng source tags để match traffic từ peered VPC hay on-premises.
Source tag "backend-service" matching:
✓ VMs trong cùng VPC có tag "backend-service"
✗ VMs trong peered VPC
✗ On-premises hosts
✗ Internet traffic
Cho cross-VPC hay external: phải dùng sourceRanges (IP CIDRs)Service Accounts: Identity-Based Targeting
Cơ Chế Của Service Account Targeting
Khi bạn dùng service account làm firewall target, Andromeda check identity của VM (service account gắn với VM) thay vì labels:
gcloud compute firewall-rules create allow-backend-to-db \
--source-service-accounts=backend-sa@project.iam.gserviceaccount.com \
--target-service-accounts=database-sa@project.iam.gserviceaccount.com \
--allow=tcp:5432Khi evaluation:
Packet: VM A → VM B, port 5432
Check source: VM A's service account = backend-sa? → YES
Check target: VM B's service account = database-sa? → YES
→ ALLOWService Account Assignment: Tại Sao An Toàn Hơn
Để VM có service account, bạn cần:
iam.serviceAccounts.actAspermission trên SA đócompute.instances.setServiceAccountpermission (hoặc create instance)
Quan trọng hơn: Thay đổi service account của VM cần restart (stop/start VM). Không thể hot-swap SA như tags.
# Gán SA khi tạo VM
gcloud compute instances create my-vm \
--service-account=backend-sa@project.iam.gserviceaccount.com \
--scopes=https://www.googleapis.com/auth/cloud-platform
# Thay đổi SA của VM đang chạy → PHẢI STOP VM TRƯỚC
gcloud compute instances stop my-vm
gcloud compute instances set-service-account my-vm \
--service-account=new-sa@project.iam.gserviceaccount.com
gcloud compute instances start my-vmRequirement restart tạo change management friction — không ai có thể silently change SA của production VM đang chạy mà không tạo ra visible downtime. Đây là intentional security property.
Một Service Account Per VM
Mỗi VM chỉ có một service account. Không thể gán nhiều SAs như có thể gán nhiều tags.
VM "api-server":
Service Account: api-sa@project.iam.gserviceaccount.com (chỉ 1)
Tags: [api-server, production, us-west1] (nhiều tùy ý)Hệ quả: Với service account targeting, VM không thể "vừa là backend vừa là frontend" với cùng một SA. Nếu cần multi-role VM, phải dùng tags cho một trong các roles.
So Sánh Toàn Diện
| Khía cạnh | Network Tags | Service Accounts |
|---|---|---|
| Số lượng per VM | Nhiều tùy ý | Tối đa 1 |
| Thay đổi runtime | Có (instant) | Không (cần restart) |
| Permission cần | compute.instances.setTags | iam.serviceAccounts.actAs |
| Cross-VPC matching | Không (chỉ same VPC) | Không (chỉ same VPC) |
| Audit trail | Compute audit logs | IAM + Compute logs |
| Security level | Thấp-trung | Cao |
| Multi-role VM | Dễ (nhiều tags) | Khó (chỉ 1 SA) |
| Debug dễ không | Dễ (gcloud instances describe) | Trung bình |
Khi Nào Dùng Tags, Khi Nào Dùng Service Accounts
Dùng Service Accounts Cho:
Critical security boundaries — các kết nối mà nếu bị bypass sẽ dẫn đến compromise dữ liệu nhạy cảm:
- Backend → Database (SA ensures chỉ legitimate backend services được phép)
- Internal services → Secret Manager
- CI/CD systems → Production deployment APIs
- Application tier → Cloud Storage buckets với sensitive data
Audit-sensitive rules — environments cần compliance audit trail rõ ràng:
- PCI DSS environments
- HIPAA workloads
- Rules liên quan đến financial data access
Long-lived stable connections — kết nối không thay đổi thường xuyên:
- Persistent database connections
- Message broker connections
- Service mesh control plane connections
Dùng Network Tags Cho:
Grouping workloads cho operational purposes:
- Cho phép monitoring agent (Prometheus) scrape metrics từ tất cả production VMs → tag
production - Cho phép bastion host SSH đến tất cả VMs → tag
ssh-allowed - Allow load balancer health checks đến backend tier → tag
backend
Dynamic environments nơi VMs thường xuyên thay đổi role:
- Blue-green deployment (blue-pool ↔ green-pool)
- Canary deployments
- A/B testing infrastructure
Multi-role VMs cần multiple identities cùng lúc:
- Một VM vừa là "web-server" vừa là "monitoring-target" vừa là "internal-service"
Anti-Patterns Phổ Biến
Anti-pattern 1: Dùng Tags Cho Security-Critical Rules Trong Multi-Team Environment
Rule: allow tcp:5432 đến database từ source-tags=backend
Vấn đề: Trong org với 10 teams chia sẻ một VPC:
- Team A: Tạo VM dev-vm-test, thêm tag "backend" để test
- dev-vm-test không phải production backend
- dev-vm-test có direct database access
- Nếu dev-vm-test bị compromise: attacker có production DB access
Giải pháp đúng: Dùng service accounts cho DB access ruleAnti-pattern 2: Một Tag Catch-All
# BAD: một tag cho nhiều mục đích
tag: internal-service
# Rules:
allow-internal-to-db: source-tags=internal-service → database
allow-internal-to-secrets: source-tags=internal-service → secret-manager
allow-internal-to-gcs: source-tags=internal-service → gcs-backend
# Vấn đề: BẤT KỲ VM nào có tag "internal-service" có access
# đến TẤT CẢ những resources trên
# Principle of Least Privilege bị vi phạm# GOOD: Granular tags hay service accounts
backend-sa → allow tcp:5432 đến database-sa
secrets-reader-sa → allow đến Secret Manager
storage-writer-sa → allow đến GCS backendAnti-pattern 3: Override Default SA Của GKE Nodes
GKE nodes có một default service account. Nếu bạn dùng default node SA trong firewall rules:
Rule: allow từ default-compute-sa@project.iam.gserviceaccount.com → database
Vấn đề: Default compute SA được dùng bởi TẤT CẢ VMs sử dụng default SA,
không chỉ GKE nodes. Bất kỳ developer VM nào không specify SA sẽ dùng default SA
→ developer VMs có unexpected database accessGiải pháp: Tạo dedicated SA cho GKE nodes, không dùng default SA cho bất kỳ production firewall rule nào.
Anti-pattern 4: Không Log Firewall Changes
Kịch bản: Production incident "tại sao DB suddenly accessible từ internet?"
→ Ai đó đã xóa firewall rule "deny-public-access-to-db"
→ Không có log nào vì không enable audit log cho Compute Network
→ Không biết khi nào xảy ra, ai thực hiệnEnable Cloud Audit Logging cho Compute:
# Trong IAM → Audit Logs, enable "Data Write" cho Compute Engine
# Hoặc qua Organization PolicyVới audit logging, mọi thay đổi firewall rule đều được ghi lại:
- Ai thực hiện (user/SA)
- Khi nào
- Rule nào bị thay đổi
- Từ config gì sang config gì
Thực Hành Tốt Nhất Cho Production
1. Naming Convention Nhất Quán
# Tags format: <tier>-<role>-<env>
web-frontend-prod
api-backend-prod
db-primary-prod
monitoring-target-prod
# SA format: <component>-sa@<project>.iam.gserviceaccount.com
backend-api-sa@prod-project.iam.gserviceaccount.com
database-reader-sa@prod-project.iam.gserviceaccount.comNaming convention giúp audit và incident response nhanh hơn.
2. Document Tag → Rule Mapping
Maintain một "Tag Registry" (có thể là spreadsheet, Confluence page, hay code):
# tag-registry.yaml
tags:
web-frontend-prod:
description: "Production web frontend servers"
firewall_rules:
- allow-https-from-internet
- allow-from-load-balancer
owner: "team-frontend"
api-backend-prod:
description: "Production API backend servers"
firewall_rules:
- allow-from-frontend-to-api
- allow-api-to-database
owner: "team-backend"Khi có incident, bạn biết ngay tag nào → rule nào → có những access gì.
3. Least Privilege: Nhiều Narrow Tags Thay Vì Ít Broad Tags
# BAD: Broad tag
backend-tier → access to: databases, message queues, secrets, internal APIs
# GOOD: Narrow, purpose-specific tags
api-to-postgres: chỉ access postgres port
api-to-redis: chỉ access redis port
api-to-pubsub: chỉ access pubsub (IAM-based anyway, không cần firewall)
api-to-internal-secrets: chỉ access secret manager proxyMỗi tag càng hẹp, blast radius khi tag bị misuse càng nhỏ.
4. Định Kỳ Audit Tags và SAs
# Tìm VMs với tag security-critical
gcloud compute instances list \
--filter="tags.items=database-admin" \
--format="table(name,zone,tags.items)"
# So sánh với danh sách VMs được approved
# Alert nếu có VM unauthorized có sensitive tagsAutomation này nên chạy daily và alert khi có unexpected tags trên VMs.
References
- VPC Firewall Rules Targeting — Tài liệu về targeting
- IAM Best Practices for Service Accounts — Thực hành tốt nhất với SAs
- Network Tags Documentation — Quản lý network tags
- Firewall Insights — Audit và optimize firewall rules