VPC Flow Logs — Observability Mạng và Network Forensics
Flow Logs Không Capture Tất Cả Packets
Một hiểu lầm phổ biến về VPC Flow Logs: không phải mọi packet đều được log. GCP dùng hai tầng sampling:
Primary sampling (dynamic, không configurable): GCP tự động áp dụng sampling rate biến đổi dựa trên load của physical host đang chạy VM. Traffic càng cao, sampling rate càng cao (để đảm bảo coverage); host đang yên tĩnh có rate thấp hơn. Bạn không thể control tầng này.
Secondary sampling (configurable): Sau primary sampling, GCP áp dụng một lần filter thứ hai với rate bạn chọn. Default là 50% (giữ lại 50% samples từ primary). Bạn có thể set từ 0 (tắt hoàn toàn) đến 1.0 (giữ tất cả từ primary).
Hệ quả: Ngay cả khi secondary sampling = 1.0, bạn vẫn không thấy 100% traffic — vì primary sampling đã loại bỏ một phần. Flow Logs là representative sample, không phải complete traffic dump.
Điểm Thu Thập: Trước Hay Sau Firewall?
Điểm này ảnh hưởng trực tiếp đến cách dùng Flow Logs cho debugging:
Ingress packets: Được sample SAU khi firewall rules đã evaluate. Điều này có nghĩa là packets bị DENY bởi ingress firewall không xuất hiện trong Flow Logs.
Egress packets: Được sample TRƯỚC khi egress firewall rules evaluate. Packets bị DENY bởi egress firewall xuất hiện trong Flow Logs (với disposition DENY).
Packet đến VM (Ingress flow):
[External Source] → [Andromeda ingress firewall check] → [VM]
↓ DENY here ↑ not reached
Không có log SAU đây mới có log
Packet ra từ VM (Egress flow):
[VM] → [Sample TẠI ĐÂY] → [Andromeda egress firewall check] → [Destination]
↑ Log được tạo ↓ nếu DENY ↑ không tới
Log có disposition=DENYHệ quả cho debugging: Nếu bạn không thấy inbound connection trong Flow Logs, có hai khả năng:
- Traffic chưa bao giờ đến VPC (blocked upstream)
- Ingress firewall đã drop traffic (nên check firewall logs thay vì flow logs)
Structure Của Một Flow Log Entry
Mỗi flow log entry đại diện cho một aggregated flow trong một aggregation interval (5 giây đến 15 phút, default 5 giây):
{
"connection": {
"src_ip": "203.0.113.5",
"dest_ip": "10.0.0.5",
"src_port": 54321,
"dest_port": 443,
"protocol": 6
},
"reporter": "DEST",
"start_time": "2025-01-15T10:00:00Z",
"end_time": "2025-01-15T10:00:05Z",
"bytes_sent": 15234,
"packets_sent": 23,
"rtt_msec": 5,
"src_location": {
"country": "US",
"region": "California"
},
"dest_instance": {
"project_id": "my-project",
"vm_name": "web-server-1",
"region": "us-west1",
"zone": "us-west1-a"
}
}Reporter field: Quan trọng nhất:
SRC: Flow được report bởi VM nguồn (egress flow)DEST: Flow được report bởi VM đích (ingress flow đến VM trong GCP)
Nếu destination là external (internet), chỉ có SRC reporter. Nếu cả source và destination đều là VMs trong GCP, có thể có cả hai reporters — tránh count double khi analyze.
Metadata Fields (Optional)
Có thể enable thêm metadata:
- Source/destination VM names, VPC, subnet
- Source/destination geographic location
- VPC project information
- Latency measurements (RTT)
Enable metadata tăng storage cost nhưng cần thiết cho serious forensics.
Aggregation Interval: Trade-off Visibility vs Cost
Flow Logs aggregate packets trong một interval thành một entry:
Aggregation = 5 seconds (default):
[1000 packets từ 203.0.113.5:54321 → 10.0.0.5:443 trong 5 giây]
→ Một log entry với bytes_sent=sum, packets_sent=1000
Aggregation = 5 minutes:
[Cùng flow, aggregate thành 1 entry per 5 phút]
→ Ít entries hơn, tiết kiệm cost nhưng kém visibilityDefault 5 giây phù hợp cho incident response và forensics. 5-15 phút phù hợp cho capacity planning và cost analysis.
Enable Flow Logs
# Enable cho subnet
gcloud compute networks subnets update prod-us-west1 \
--region=us-west1 \
--enable-flow-logs \
--logging-aggregation-interval=INTERVAL_5_SEC \
--logging-flow-sampling=0.5 \
--logging-metadata=INCLUDE_ALL_METADATA
# Disable (khi không cần nữa - cost savings)
gcloud compute networks subnets update prod-us-west1 \
--region=us-west1 \
--no-enable-flow-logsFlow Logs được viết vào Cloud Logging automatically. Từ Cloud Logging có thể route đến BigQuery (analytics), Cloud Storage (long-term retention), hoặc Pub/Sub (real-time processing).
Cost Analysis: Khi Nào Flow Logs Quá Tốn Kém?
Flow Logs billing: $0.50/GB ingested vào Cloud Logging (tại thời điểm viết, kiểm tra pricing page để verify).
Với traffic volume cao:
Web server xử lý 10,000 requests/second:
Mỗi flow entry: ~500 bytes
Primary sampling: ~50% (estimate)
Secondary sampling: 50%
Ước tính entries/second: 10,000 × 0.5 × 0.5 = 2,500 entries/sec
Ước tính data: 2,500 × 500 bytes = 1.25 MB/sec = 108 GB/ngày
Cost: 108 × $0.50 = $54/ngày per subnet
→ $1,620/tháng chỉ cho flow logs của một subnet!Với production high-traffic environments, phải cân nhắc:
- Giảm secondary sampling: 0.1 (10%) thay vì 0.5 giảm cost 5×
- Tăng aggregation interval: 60 giây thay vì 5 giây
- Disable metadata: Chỉ enable khi cần
- Enable chỉ cho critical subnets: Không cần cho tất cả subnets
- Export sang BigQuery với lifecycle policy: Giữ Cloud Logging logs ngắn hạn, long-term analysis ở BigQuery storage tier rẻ hơn
Dùng Flow Logs Cho Debugging
Use Case 1: Tìm Nguồn Gốc Của Traffic Tăng Bất Thường
-- Query BigQuery: Top source IPs trong 1 giờ qua
SELECT
jsonPayload.connection.src_ip,
SUM(CAST(jsonPayload.bytes_sent AS INT64)) as total_bytes,
COUNT(*) as flow_count
FROM `project.dataset.compute_googleapis_com_vpc_flows_*`
WHERE
_TABLE_SUFFIX >= FORMAT_DATE('%Y%m%d', DATE_SUB(CURRENT_DATE(), INTERVAL 1 DAY))
AND jsonPayload.reporter = 'DEST'
AND jsonPayload.dest_instance.vm_name = 'web-server-1'
GROUP BY 1
ORDER BY total_bytes DESC
LIMIT 20Use Case 2: Kiểm Tra Connectivity (Outbound)
-- Check xem VM có kết nối đến destination IP không
SELECT
jsonPayload.connection.src_ip,
jsonPayload.connection.dest_ip,
jsonPayload.connection.dest_port,
jsonPayload.start_time,
jsonPayload.bytes_sent
FROM `project.dataset.compute_googleapis_com_vpc_flows_*`
WHERE
jsonPayload.reporter = 'SRC'
AND jsonPayload.src_instance.vm_name = 'app-server-1'
AND jsonPayload.connection.dest_ip = '10.50.0.5'
ORDER BY start_time DESC
LIMIT 100Use Case 3: Lateral Movement Detection (Security)
-- Tìm VMs kết nối đến nhiều internal IPs (potential port scan)
SELECT
jsonPayload.connection.src_ip,
jsonPayload.src_instance.vm_name,
COUNT(DISTINCT jsonPayload.connection.dest_ip) as unique_dests,
COUNT(DISTINCT jsonPayload.connection.dest_port) as unique_ports
FROM `project.dataset.compute_googleapis_com_vpc_flows_*`
WHERE
jsonPayload.reporter = 'SRC'
AND TIMESTAMP(jsonPayload.start_time) > TIMESTAMP_SUB(CURRENT_TIMESTAMP(), INTERVAL 1 HOUR)
AND NET.IP_IN_NET(jsonPayload.connection.dest_ip, '10.0.0.0/8')
GROUP BY 1, 2
HAVING unique_dests > 50
ORDER BY unique_dests DESCLimitation Quan Trọng
Flow Logs không log traffic bị firewall drop (cho ingress). Nếu bạn cần biết packets bị drop, phải enable Firewall Rules Logging (riêng biệt với Flow Logs):
gcloud compute firewall-rules update deny-ssh \
--enable-loggingFirewall Rules Logging log mỗi connection được allow hoặc deny bởi rule đó. Dùng kết hợp Flow Logs (connectivity patterns) và Firewall Logs (allow/deny decisions) cho complete visibility.
References
- VPC Flow Logs Overview — Tài liệu chính thức
- Sampling và Aggregation — Chi tiết về sampling mechanism
- Analyze Flow Logs with BigQuery — Phân tích với BigQuery
- Flow Logs Pricing — Chi phí