Giám sát traffic và bảo mật Cloudflare tập trung với Cloudflare Exporter, Prometheus và Grafana

Vấn đề: Dữ liệu phân mảnh giữa Edge và Origin server

Đa số hệ thống hiện nay đều đặt Cloudflare làm reverse proxy ở tuyến đầu để tận dụng CDN, DNS và WAF chặn DDoS. Mọi thứ hoạt động rất êm cho đến khi có sự cố. Dashboard mặc định của Cloudflare nhìn trực quan nhưng lại hoàn toàn tách biệt với cụm server backend của bạn.

Hãy hình dung kịch bản quen thuộc: người dùng bắt đầu kêu web chậm hoặc dính lỗi 502 Bad Gateway. Bạn phải mở song song một tab Cloudflare soi request, một tab Grafana xem RAM/CPU, rồi lại mở tiếp terminal grep access log Nginx. Việc nhảy qua lại giữa 3-4 công cụ làm chậm thời gian xử lý sự cố ít nhất 10–15 phút. Chưa kể tài khoản Free chỉ giữ analytics chi tiết trong 24–72 giờ. Muốn mở lại dữ liệu tuần trước để điều tra một đợt bot cào trộm dữ liệu gần như là bất khả thi.

Giải pháp hiệu quả nhất là đưa toàn bộ metrics từ Cloudflare GraphQL Analytics API về Prometheus qua cloudflare-exporter. Khi cả chỉ số biên mạng (Edge) lẫn tài nguyên máy chủ gốc (Origin) cùng nằm trên một dashboard Grafana, bạn sẽ biết ngay lỗi do Cloudflare nghẽn hay backend quá tải chỉ sau vài cú click.

Triển khai Cloudflare Exporter

Cloudflare Exporter là service viết bằng Go, hoạt động như một adapter trung gian. Nó định kỳ gọi GraphQL API của Cloudflare lấy số liệu thống kê rồi format lại theo chuẩn Prometheus metrics tại endpoint /metrics.

Bước 1: Tạo Cloudflare API Token

Để exporter đọc được dữ liệu, bạn cần cấp một Token có quyền xem Analytics thay vì dùng Global API Key (vốn có quá nhiều quyền rủi ro):

  1. Đăng nhập Cloudflare dashboard, vào My Profile > API Tokens.
  2. Bấm Create Token > chọn template Read analytics and logs (hoặc chọn Create Custom Token).
  3. Phân quyền tối thiểu cho Token:
    • Zone > Zone > Read
    • Zone > Analytics > Read
  4. Mục Zone Resources: Chọn Include > Specific zone và chọn domain cần theo dõi để đảm bảo an toàn (hoặc All zones nếu quản lý nhiều domain).
  5. Bấm Continue to summary > Create Token rồi copy chuỗi token lưu vào password manager.

Bước 2: Chạy Cloudflare Exporter bằng Docker Compose

Dùng Docker Compose giúp quản lý container gọn gàng nhất. Tạo thư mục làm việc trên monitoring server:

mkdir -p /opt/cloudflare-exporter && cd /opt/cloudflare-exporter
nano docker-compose.yml

Dán cấu hình sau vào file docker-compose.yml:

version: '3.8'

services:
  cloudflare-exporter:
    image: ghcr.io/lablabs/cloudflare-exporter:latest
    container_name: cloudflare_exporter
    restart: unless-stopped
    ports:
      - "127.0.0.1:8080:8080"
    environment:
      - CF_API_TOKEN=your_cloudflare_token_here
      - CF_ZONES=example.com,app.example.com
      - SCRAPE_INTERVAL=60s
      - METRICS_DENYLIST=cloudflare_zone_colocation_.*

Mẹo: Dòng METRICS_DENYLIST loại bỏ metric phân tích theo từng colocation/datacenter. Thiết lập này giúp giảm tới 80% số lượng time-series không cần thiết, tránh gây phình RAM của Prometheus.

Khởi động container:

docker compose up -d

Kiểm tra exporter đã kết nối tới Cloudflare thành công chưa:

curl -s http://127.0.0.1:8080/metrics | grep cloudflare_zone_requests_total

Nếu terminal trả về các dòng dạng cloudflare_zone_requests_total{zone="example.com"} 15420 kèm số đếm tăng dần, exporter đã sẵn sàng.

Cấu hình Prometheus cào metrics

Sau khi exporter chạy ổn định, ta khai báo target mới vào Prometheus để bắt đầu lưu trữ time-series data.

Thêm scrape job vào prometheus.yml

Mở file cấu hình Prometheus:

sudo nano /etc/prometheus/prometheus.yml

Thêm job sau vào khối scrape_configs:

scrape_configs:
  - job_name: 'cloudflare'
    scrape_interval: 60s
    scrape_timeout: 30s
    static_configs:
      - targets: ['127.0.0.1:8080']
        labels:
          env: 'production'

Lưu ý kỹ thuật: Cloudflare Analytics API tổng hợp dữ liệu theo block tròn 1 phút. Đặt scrape_interval thấp hơn 60s (ví dụ 15s) vừa không có thêm dữ liệu mới, vừa dễ khiến token bị dính Cloudflare API Rate Limit (1.200 request/5 phút).

Áp dụng cấu hình mới (yêu cầu Prometheus chạy với cờ --web.enable-lifecycle):

curl -X POST http://localhost:9090/-/reload
# Hoặc restart bằng systemd nếu chưa bật lifecycle API:
# sudo systemctl reload prometheus

Danh sách metrics cốt lõi

Dưới đây là 6 metrics quan trọng nhất bạn cần quan tâm:

  • cloudflare_zone_requests_total: Tổng lượt request chạm ngưỡng Cloudflare edge.
  • cloudflare_zone_requests_status: Lưu lượng request chia theo mã phản hồi HTTP (200, 301, 403, 502…).
  • cloudflare_zone_requests_cached: Số request được trả thẳng từ CDN cache (Cache Hit).
  • cloudflare_zone_bandwidth_total: Tổng băng thông tiêu thụ (tính bằng bytes).
  • cloudflare_zone_threats_total: Số lượt truy cập độc hại bị WAF và IP Firewall chặn đứng.
  • cloudflare_zone_pool_health_status: Trạng thái origin servers nếu bạn dùng Cloudflare Load Balancing.

Dựng Dashboard trực quan trên Grafana

Số liệu đã được đẩy đều đặn vào Prometheus. Bây giờ là lúc thiết lập các biểu đồ để nắm bắt sức khỏe hệ thống theo thời gian thực.

1. Các câu truy vấn PromQL quan trọng

Vào Grafana > Explore và kiểm tra độ chính xác của 3 công thức sau:

Tỷ lệ Cache Hit (%) — Đo lường hiệu quả giảm tải cho origin server:

(
  sum(rate(cloudflare_zone_requests_cached[5m])) 
  / 
  sum(rate(cloudflare_zone_requests_total[5m]))
) * 100

Với website thương mại điện tử hoặc tin tức, tỷ lệ này nên đạt từ 70% đến 85%. Nếu chỉ số này tụt xuống dưới 40%, hãy rà soát lại Cache Rules và HTTP header Cache-Control trên Nginx.

Tần suất lỗi HTTP backend (502/504):

sum by (status) (rate(cloudflare_zone_requests_status{status=~"5.."}[5m]))

Đặt Alert rule cho query này: nếu mã 502/504 vượt ngưỡng 5 req/s liên tục trong 2 phút, gửi cảnh báo ngay về Telegram hoặc Slack để đội trực xử lý backend.

Lượng threat bị WAF chặn theo giờ:

sum by (zone) (increase(cloudflare_zone_threats_total[1h]))

Bình thường biểu đồ sẽ dao động ở mức vài chục đến vài trăm request rác. Nếu đột ngột vọt lên 50.000–100.000 trong 1 giờ, chắc chắn website đang bị tool quét lỗ hổng hoặc bị tấn công Layer 7.

2. Dựng layout Dashboard thực tế

Một layout giám sát thực chiến thường chia làm 4 panel chính:

  • Hàng trên cùng: 2 panel dạng Gauge hiển thị Cache Hit Ratio và Current RPS (Requests Per Second).
  • Hàng thứ hai: Graph so sánh Edge Bandwidth vs Origin Bandwidth để thấy rõ lượng GB băng thông Cloudflare đã gánh hộ server.
  • Hàng thứ ba: Time-series biểu diễn HTTP Status Breakdown (tách riêng dải 2xx, 4xx, 5xx).
  • Hàng dưới cùng: Bar chart liệt kê Top WAF Threats bị chặn theo domain.

Nếu không muốn tốn thời gian kéo thả từ đầu, bạn có thể import dashboard mẫu với ID 13133 trên Grafana, sau đó chọn lại data source Prometheus của mình là xong.

Khi tích hợp xong, bạn chỉ cần một màn hình duy nhất để đối chiếu ngay: lượng request Cloudflare vừa tăng vọt có khiến CPU backend tăng theo không, hay WAF đã xử lý sạch sẽ ở ngoài biên. Việc cô lập sự cố nhờ đó nhanh hơn rất nhiều.

Share: