Skip to content

VPC Flow Logs: Packet-Level Network Visibility

Tại sao VPC Flow Logs Quan Trọng

VPC Flow Logs cung cấp khả năng quan sát mức packet (packet-level observability) vào network traffic trên GCP. Nó lưu trữ thông tin flow (gồm 5-tuple: source IP, dest IP, source port, dest port, protocol) cùng với metadata (bytes, packets, action, timestamps).

Đây là công cụ điều tra số (forensics) chính của quy trình network debugging:

  • Xác nhận traffic đang truyền hay bị drop.
  • Xác định vị trí traffic bị drop (ingress firewall, egress firewall, routing, v.v.).
  • Debug các sự cố asymmetric routing.
  • Phân tích traffic patterns để tối ưu hóa mạng.

Connectivity Tests dùng để debug ở mức cấu hình (configuration-level). VPC Flow Logs dùng để kiểm chứng thực tế ở mức packet.

Cơ chế bên trong: VPC Flow Logs Pipeline

VPC Flow Logs không chỉ đơn giản là "log mọi packet". Nó có chiến lược lấy mẫu (sampling strategy) rất tinh vi, cùng cơ chế tổng hợp (aggregation) và xử lý pipeline. Bạn cần hiểu rõ pipeline này để giải thích log một cách chính xác.

Kiến trúc: Các tầng lấy mẫu (Sampling Layers)

VPC Flow Logs áp dụng cơ chế lấy mẫu hai giai đoạn (two-stage sampling):

Packet → [Primary Sampling] → [Aggregation] → [Secondary Sampling] → [Logging]
           (dynamic)           (configurable)     (configurable)      (Cloud Logging)

Giai đoạn 1: Primary Sampling (Lấy mẫu sơ cấp - Tự động)

Định nghĩa: Packet được lấy mẫu hay không ở tầng hypervisor dựa trên tải (load) của physical host.

Cơ chế:

Tài liệu GCP ghi rõ: "Tỷ lệ primary sampling thay đổi động dựa trên lượng packet volume trên host vật lý."

Ý nghĩa:

  • Khi packet volume thấp, tỷ lệ sampling sẽ cao (thu thập được nhiều log hơn).
  • Khi packet volume cao, tỷ lệ sampling sẽ thấp (thu thập được ít log hơn để tránh quá tải).
  • Bạn không thể cấu hình giai đoạn này.

Ví dụ:

Physical Host Load: 10,000 pps
→ Primary sampling: 50% (một nửa số packet được lấy mẫu)

Physical Host Load: 100,000 pps
→ Primary sampling: 5% (chỉ 1 trong 20 packet được lấy mẫu)

Physical Host Load: 1,000 pps
→ Primary sampling: 100% (toàn bộ packet được lấy mẫu)

Tại sao cần Adaptive Sampling?

Cơ chế lấy mẫu giúp giảm tải ở control plane (thu thập, xử lý logs). Nếu lấy mẫu 100% packet trên một host 1Tbps, hệ thống sẽ quá tải và không thể scale. Adaptive sampling nghĩa là trong thời gian thấp điểm, bạn có toàn bộ thông tin. Trong thời gian cao điểm, bạn có ít thông tin chi tiết hơn nhưng vẫn ghi lại được các flow quan trọng.

Hệ quả: "Sự cố xảy ra vào giờ cao điểm, nhưng Flow Logs không hiển thị?" — Có thể do primary sampling đã bỏ sót các packet đó.

Giai đoạn 2: Aggregation (Tổng hợp)

Sau khi primary sampling, các packet được tổng hợp theo connection (5-tuple). GCP nhóm các packet từ cùng source/dest/protocol/ports vào một flow log entry duy nhất.

Aggregation Window: Có thể cấu hình, mặc định là 5 giây nhưng có thể tăng từ 1 đến 15 phút.

Ví dụ:

Aggregation Window: 5 seconds

Packets:
  T=0.1s: 10.0.1.2:12345 → 10.1.1.2:443 (100 bytes)
  T=0.3s: 10.0.1.2:12345 → 10.1.1.2:443 (200 bytes)
  T=1.2s: 10.0.1.2:12345 → 10.1.1.2:443 (150 bytes)
  T=4.9s: 10.0.1.2:12345 → 10.1.1.2:443 (50 bytes)

Kết quả (một flow entry duy nhất):
  source_ip: 10.0.1.2
  source_port: 12345
  dest_ip: 10.1.1.2
  dest_port: 443
  protocol: 6 (TCP)
  bytes_sent: 500 (100+200+150+50)
  packets_sent: 4
  start_time: 0.1s
  end_time: 4.9s
  action: ACCEPT

Hệ quả: Bạn chỉ thấy dữ liệu tổng hợp (aggregated stats), không thấy từng packet riêng lẻ. Nếu kết nối có 1000 packets/giây, bạn chỉ thấy 1 entry cho mỗi aggregation window.

Giai đoạn 3: Secondary Sampling (Lấy mẫu thứ cấp)

Các aggregated flow entries tiếp tục được lấy mẫu một lần nữa trước khi ghi log.

Điều khiển bởi: Tham số secondary_sampling_rate (mặc định là 50% cho Compute Engine API, 100% cho Network Management API).

Ví dụ:

secondary_sampling_rate = 0.5 (50%)
→ 50% số lượng aggregated flows được log, 50% còn lại bị drop

Hệ quả: Nếu đặt secondary sampling 50%, bạn sẽ mất một nửa số flow. Điều này không tốt cho việc debug. Thông thường chúng ta nên cấu hình thông số này là 100% khi debug.

Giai đoạn 4: Làm giàu Metadata & Logging

Các flow entries (sau secondary sampling) được bổ sung thêm thông tin metadata (optional):

  • Cloud Logging hỗ trợ:
    • GCP resource IDs
    • VPC names
    • Subnet info
    • Instance labels

Sau đó, log được ghi vào Cloud Logging.

Cấu trúc của Flow Log Entry

Một VPC Flow Log entry điển hình (định dạng JSON):

json
{
  "timestamp": "2026-06-26T15:30:45.123Z",
  "src_ip": "10.0.1.2",
  "src_port": 12345,
  "dest_ip": "10.1.1.2",
  "dest_port": 443,
  "protocol": 6,           // TCP
  "bytes_sent": 5000,
  "bytes_received": 3000,
  "packets_sent": 50,
  "packets_received": 30,
  "action": "ACCEPT",      // hoặc "DENY"
  "start_time": "2026-06-26T15:30:40.000Z",
  "end_time": "2026-06-26T15:30:44.999Z",
  "rule_priority": 1000,   // Priority của firewall rule được áp dụng
  "rule_name": "allow-tcp-443",
  "vpc_name": "default",
  "src_subnet": "default",
  "dest_subnet": "remote-subnet",
  "src_instance": "vm-a",
  "dest_instance": "vm-b",
  "src_zone": "us-central1-a",
  "dest_zone": "us-central1-b"
}

Các Field quan trọng để Debug:

  • action: "ACCEPT" vs "DENY" — Traffic được chấp nhận hay bị chặn?
  • bytes_sent / bytes_received — Dung lượng data truyền nhận.
  • start_time / end_time — Thời gian kéo dài của flow.
  • rule_priority — Firewall rule nào được áp dụng.
  • protocol / ports — Kiểu kết nối.
  • src/dest_instance — Tên của endpoint.

Thời điểm ghi nhận: Đánh giá Firewall Rule vs Lấy mẫu

Quan trọng: VPC Flow Logs lấy mẫu vào các thời điểm khác nhau đối với chiều ingress và egress:

Các packet Egress được lấy mẫu TRƯỚC KHI áp dụng egress firewall rules.Các packet Ingress được lấy mẫu SAU KHI áp dụng ingress firewall rules.

Ý nghĩa:

Ingress Flow Logs

  • Packet truyền đến interface đích.
  • Ingress firewall rule được đánh giá.
  • Nếu DENY: Packet bị drop, không được log.
  • Nếu ALLOW: Packet được chấp nhận, được log.

Hệ quả: Nếu bị deny ingress firewall, sẽ không xuất hiện log entry. Bạn chỉ thấy các traffic được chấp nhận ở phía đích.

Egress Flow Logs

  • Packet rời khỏi interface nguồn.
  • Được log (lấy mẫu).
  • Egress firewall rule được đánh giá.
  • Nếu DENY: Packet bị drop (nhưng thông tin đã được ghi nhận trước đó).

Hệ quả: Nếu bị deny egress firewall, vẫn xuất hiện log entry với action="DENY".

Ý nghĩa khi debug:

Kịch bản: VM A (10.0.1.2) → VM B (10.1.1.2)
VM B ingress firewall: DENY all

Flow Log trên VM B:
  → Không có entry (vì bị denied ingress, không được ghi log)

Flow Log trên VM A (egress):
  → Entry với action="DENY" và rule="default-deny-egress"
    (nếu VM A egress firewall cũng deny)
  → Hoặc action="ACCEPT" nếu VM A egress allow

Quy trình Troubleshooting:

  1. Tìm kiếm log entry deny ở phía VM A's Flow Logs.
  2. Xác nhận firewall rule nào đang chặn.
  3. Sửa firewall rule ở chiều ingress của VM B.

Sử dụng VPC Flow Logs: Thiết lập & Truy vấn

Kích hoạt VPC Flow Logs

Flow Logs có thể được kích hoạt ở mức độ subnet:

bash
# Kích hoạt flow logs cho subnet
gcloud compute networks subnets update default \
  --region=us-central1 \
  --enable-flow-logs \
  --logging-aggregation-interval=interval-5-sec \
  --logging-flow-sampling=0.5

# Tắt khi không cần thiết (để giảm chi phí)
gcloud compute networks subnets update default \
  --region=us-central1 \
  --no-enable-flow-logs

Các tham số:

  • enable-flow-logs: Bật/tắt.
  • logging-aggregation-interval: Từ 5 giây đến 15 phút (mặc định là 5 giây).
  • logging-flow-sampling: Từ 0.0 đến 1.0 (mặc định là 0.5 - 50%). Đặt 1.0 khi cần debug.

Truy vấn Flow Logs

Flow Logs được ghi nhận vào Cloud Logging. Truy vấn thông tin bằng Log Explorer:

Truy vấn cơ bản cho denied traffic:

sql
resource.type="gce_subnetflow"
action="DENY"
timestamp>="2026-06-26T15:00:00Z"

Truy vấn cho kết nối cụ thể:

sql
resource.type="gce_subnetflow"
src_ip="10.0.1.2"
dest_ip="10.1.1.2"
dest_port="443"

Truy vấn các kết nối có lượng data truyền tải lớn:

sql
resource.type="gce_subnetflow"
bytes_sent > 1000000

Quy trình phân tích Flow Logs

Quy trình debug điển hình:

1. Chạy Connectivity Tests (phân tích cấu hình)
   → Kết quả: Lẽ ra phải reachable.
   
2. Kiểm tra traffic thực tế, xác nhận kết nối bị lỗi.

3. Kích hoạt VPC Flow Logs, cấu hình sampling=100%.

4. Truy vấn Flow Logs:
   - Có tồn tại flow không?
   - action là ACCEPT hay DENY?
   - rule_priority là gì?
   
5. Nếu action=DENY:
   - Kiểm tra firewall rule tương ứng.
   - Sửa rule, test lại.
   
6. Nếu action=ACCEPT nhưng vẫn lỗi:
   - Có thể không phải lỗi ở network layer.
   - Kiểm tra DNS resolution.
   - Kiểm tra application layer.
   - Kiểm tra load balancer backends.

Các mẫu Flow Log phổ biến

Mẫu 1: Traffic bị chặn bởi Firewall

json
{
  "action": "DENY",
  "rule_name": "default-deny-all",
  "rule_priority": 65534
}

Ý nghĩa: Firewall rule đã chặn kết nối rõ ràng.

Nguyên nhân: Thiếu rule allow, hoặc rule deny quá rộng.

Cách sửa: Tạo allow firewall rule với priority thấp hơn (số priority nhỏ hơn = độ ưu tiên cao hơn):

bash
gcloud compute firewall-rules create allow-http \
  --allow=tcp:80 \
  --source-ranges=10.0.0.0/8 \
  --target-tags=web-server \
  --priority=1000

Mẫu 2: Không xuất hiện Flow Logs

Kịch bản:

  • Connectivity Test báo reachable.
  • Traffic người dùng bị lỗi.
  • Không có log entries nào (ingress denied, không được ghi log).

Ý nghĩa: Ingress firewall đã chặn traffic, do đó không được ghi nhận log.

Cách debug:

  • Kiểm tra subnet đích Flow Logs — không có entry nghĩa là destination đã nhận packet nhưng ingress firewall đã chặn.
  • Kiểm tra subnet nguồn Flow Logs — có entry với action=DENY nghĩa là ingress firewall đang chặn.
  • Khắc phục: Thêm rule Allow ở phía đích.

Mẫu 3: Traffic bất đối xứng (Asymmetric Traffic)

Flow A→B:
  bytes_sent: 50000
  bytes_received: 0
  
Flow B→A:
  (không có entry, hoặc action=DENY)

Ý nghĩa: Phía A gửi gói tin đi nhưng phía B không phản hồi. Nguyên nhân có thể do:

  • Ứng dụng ở phía B không phản hồi.
  • Traffic trả về từ B bị chặn bởi firewall.
  • Phía B không có route trả traffic về A.

Cách debug:

  • Kiểm tra ứng dụng ở B có healthy không (logs, endpoints).
  • Kiểm tra egress firewall của B có cho phép traffic phản hồi đi qua.
  • Kiểm tra routing có đối xứng không.

Mẫu 4: Thời gian kết nối cực ngắn

json
{
  "start_time": "2026-06-26T15:30:40.000Z",
  "end_time": "2026-06-26T15:30:40.001Z",  // thời gian kết nối 1ms
  "packets_sent": 1
}

Ý nghĩa: Kết nối quá ngắn, có thể connection bị reject lập tức.

Nguyên nhân: Ứng dụng từ chối kết nối, firewall từ chối, hoặc do routing loop.

Cách debug: Kết hợp phân tích logs ứng dụng.

Giới hạn của VPC Flow Logs

Việc Lấy mẫu có thể làm mất thông tin Traffic

Cơ chế primary sampling có thể drop packet, đặc biệt vào giờ cao điểm. Việc không thấy log không có nghĩa là không có traffic, mà là do sampling đã bỏ lỡ.

Giải pháp: Tăng sampling window (aggregate lâu hơn), nhưng sẽ có trễ. Hoặc cấu hình secondary_sampling=1.0.

Cơ chế tổng hợp che khuất thông tin packet riêng lẻ

Bạn không thể xem lịch sử của từng packet riêng lẻ, mà chỉ thấy số liệu tổng hợp trong window 5 giây (hoặc thời gian cấu hình).

Giải pháp: Nếu cần điều tra số ở mức độ packet, sử dụng Cloud Packet Mirroring để mirror sang công cụ phân tích file pcap.

Traffic bị deny ở chiều Ingress không được log

Bạn không thể nhìn thấy denied inbound traffic ở Flow Logs của VM đích. Nó chỉ được ghi nhận ở phía nguồn (nếu egress firewall của nguồn deny traffic).

Giải pháp: Kiểm tra Flow Logs của phía nguồn để xem action deny.

Độ trễ cập nhật Metadata

Các thông tin bổ sung (instance name, label) có thể bị trễ 1-2 phút. Hãy lưu ý khi truy vấn các log quá mới — thông tin name có thể chưa được hiển thị đầy đủ.

Chi phí

Flow Logs có thể rất tốn kém trong môi trường có traffic lớn. secondary_sampling có thể giúp giảm chi phí (đặt 0.1 thay vì 1.0) nhưng sẽ giảm khả năng hiển thị.

Tối ưu hóa chi phí: Tắt log ở các subnet không quan trọng, chỉ kích hoạt khi thực hiện troubleshooting.

Hướng dẫn Best Practices cho Production

1. Chỉ bật Flow Logs cho các đường truyền quan trọng

Không nên bật ở mọi subnet (tránh tốn chi phí). Hãy bật ở:

  • Subnet chạy production workloads.
  • Subnet thường xảy ra lỗi kết nối.
  • DMZ hoặc boundary subnets.

2. Đặt Secondary Sampling = 1.0 khi Debugging

bash
gcloud compute networks subnets update default \
  --region=us-central1 \
  --logging-flow-sampling=1.0

Việc này đảm bảo không mất mát log do secondary sampling. Hãy đưa trở lại mức 0.5 (hoặc thấp hơn) sau khi debug xong.

3. Cấu hình Log Retention Policy

Mặc định log lưu trữ 30 ngày ở Cloud Logging. Để phân tích dài hạn, hãy export sang BigQuery hoặc Cloud Storage:

bash
# Export logs sang BigQuery để phân tích
gcloud logging sinks create vpc-flow-logs-bq \
  bigquery.googleapis.com/projects/my-project/datasets/network_logs \
  --log-filter='resource.type="gce_subnetflow"'

4. Đồng bộ thời gian (Timestamps)

Khi đối chiếu Flow Logs với app logs, hãy sử dụng exact timestamps. Log ứng dụng có thể lệch vài giây so với Flow Logs timestamp.

5. Kết hợp các công cụ

Flow Logs là một mảnh ghép của bức tranh tổng thể:

Connectivity Tests (Cấu hình có OK không?) 
  + VPC Flow Logs (Packet có đi đúng đường không?)
  + Application Logs (Ứng dụng có phản hồi không?)
  + Load Balancer Logs (Backends có healthy không?)
  
= Bức tranh toàn cảnh

Ví dụ thực tế: Debug một kết nối bị Deny

Kịch bản: VM A không thể kết nối đến VM B qua cổng TCP 443.

Quy trình xử lý:

Bước 1: Chạy Connectivity Tests
  Kết quả: Phân tích cấu hình báo REACHABLE
  → Cấu hình OK, vấn đề có thể không nằm ở firewall/routes.
  
Bước 2: Chạy Live Data Plane Analysis
  Kết quả: Probe thất bại, báo timeout.
  → Đường truyền thực tế gặp sự cố hoặc ứng dụng không phản hồi.
  
Bước 3: Bật VPC Flow Logs (sampling=1.0) ở cả hai subnets.

Bước 4: Truy vấn Flow Logs của VM A (nguồn)
  Kết quả: Không thấy entry đến dest_ip="10.1.1.2" port 443.
  
  Ý nghĩa: Traffic không rời khỏi VM A (process không gửi gói tin, hoặc 
           egress firewall silent deny).
  
  Debug: Kiểm tra logs ứng dụng của VM A xem ứng dụng có gửi request đi không.
         Kiểm tra egress firewall xem có rule chặn nào không.
  
Bước 5: Truy vấn Flow Logs của VM B (đích)
  Kết quả: Không thấy entry từ src_ip="10.0.1.2".
  
  Ý nghĩa: Traffic không đến được VM B (lỗi routing hoặc bị ingress firewall chặn).
  
  Debug: Kiểm tra routes từ VM A đến 10.1.1.2.
         Kiểm tra ingress firewall của VM B.
  
Bước 6: Khắc phục và Xác nhận
  Vấn đề: Egress firewall của VM A đang chặn traffic.
  Khắc phục:
    gcloud compute firewall-rules create allow-vm-b \
      --direction=EGRESS \
      --allow=tcp:443 \
      --destination-ranges=10.1.1.2/32 \
      --target-tags=vm-a
  
  Xác nhận: Chạy lại Connectivity Tests + test kết nối thực tế.

References