Skip to content

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ế:

  1. Network Tags: String labels gắn vào VM instances
  2. 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 → ALLOW

Tags 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

bash
# 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)

bash
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:443

Source Tags: Trong ingress rules, xác định traffic từ VMs có tag này

bash
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:5432

Quan 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:

bash
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:5432

Khi 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
→ ALLOW

Service Account Assignment: Tại Sao An Toàn Hơn

Để VM có service account, bạn cần:

  1. iam.serviceAccounts.actAs permission trên SA đó
  2. compute.instances.setServiceAccount permission (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.

bash
# 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-vm

Requirement 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ạnhNetwork TagsService Accounts
Số lượng per VMNhiều tùy ýTối đa 1
Thay đổi runtimeCó (instant)Không (cần restart)
Permission cầncompute.instances.setTagsiam.serviceAccounts.actAs
Cross-VPC matchingKhông (chỉ same VPC)Không (chỉ same VPC)
Audit trailCompute audit logsIAM + Compute logs
Security levelThấp-trungCao
Multi-role VMDễ (nhiều tags)Khó (chỉ 1 SA)
Debug dễ khôngDễ (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 rule

Anti-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 backend

Anti-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 access

Giả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ện

Enable Cloud Audit Logging cho Compute:

bash
# Trong IAM → Audit Logs, enable "Data Write" cho Compute Engine
# Hoặc qua Organization Policy

Vớ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.com

Naming 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):

yaml
# 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 proxy

Mỗi tag càng hẹp, blast radius khi tag bị misuse càng nhỏ.

4. Định Kỳ Audit Tags và SAs

bash
# 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 tags

Automation này nên chạy daily và alert khi có unexpected tags trên VMs.

References