Giới thiệu vấn đề: Khi Pi-hole bỗng thành “hộp đen” trong mạng nội bộ
Với anh em chạy Homelab hay quản trị mạng văn phòng nhỏ, Pi-hole là chốt chặn quen thuộc để lọc DNS tracking và quảng cáo. Bảng điều khiển web mặc định của Pi-hole nhìn khá gọn. Tuy nhiên, nó chỉ tiện khi bạn lướt xem nhanh vài thông số cơ bản. Mọi chuyện sẽ khác hẳn khi hệ sinh thái phình to lên 40–50 thiết bị, từ camera IP, smart TV đến các máy ảo test lab.
Điểm trừ lớn nhất: Pi-hole giới hạn thời gian giữ log trong RAM và file SQLite cục bộ để tránh nghẽn I/O. Khi mạng chập chờn vì một con camera dính malware bắn DNS liên tục, bạn rất khó đối chiếu lượng query với CPU hay băng thông router. Để lưu log cả năm và soi biểu đồ đa chiều, ghép Pi-hole vào cặp bài trùng Prometheus + Grafana là hướng đi tối ưu nhất.
Khái niệm cốt lõi: Cách Prometheus bóc tách metrics từ Pi-hole
Pi-hole không hỗ trợ sẵn endpoint /metrics theo chuẩn Prometheus. Công cụ này chỉ cung cấp REST API qua FTL engine để trả về dữ liệu JSON thô.
Chúng ta cần một cầu nối trung gian: pihole-exporter. Luồng dữ liệu chạy như sau:
- pihole-exporter: Cứ mỗi 15 giây, container này gọi API của Pi-hole bằng token xác thực. Nó nhận JSON rồi biên dịch lại thành các dòng text metric chuẩn format OpenMetrics.
- Prometheus: Định kỳ scrape dữ liệu từ port
9617của exporter. Toàn bộ chỉ số được nén và ghi thẳng vào Time-Series Database (TSDB). - Grafana: Kéo số liệu từ Prometheus qua PromQL. Từ đây, bạn dựng dashboard theo dõi tỷ lệ block, lưu lượng truy vấn theo giây và danh sách top client ngốn DNS nhất.
Thực hành chi tiết: Triển khai từ Zero đến Dashboard hoàn chỉnh
Bước 1: Lấy API Token từ Pi-hole
Exporter cần chuỗi token này để đọc chỉ số FTL. Các bước lấy token:
- Truy cập Pi-hole Admin > vào Settings > chọn tab API / Web interface.
- Click Show API token, xác nhận popup cảnh báo rồi copy chuỗi hash
WEBPASSWORD.
Bước 2: Chạy pihole-exporter bằng Docker Compose
Dựng exporter qua Docker giúp môi trường luôn sạch và dễ quản lý. Bạn có thể đặt file docker-compose.yml trên chính chiếc Raspberry Pi đang chạy Pi-hole hoặc trên server monitor riêng:
version: '3.8'
services:
pihole-exporter:
image: eko/pihole-exporter:v0.12.0
container_name: pihole-exporter
restart: unless-stopped
ports:
- "9617:9617"
environment:
- PIHOLE_HOSTNAME=192.168.1.53
- PIHOLE_PASSWORD=b49c0d9a691234567890abcdef1234567890abcdef1234567890abcdef123456
- PORT=9617
- INTERVAL=15s
Kéo image và khởi chạy service:
docker compose up -d
Kiểm tra xem exporter đã cào được dữ liệu thực tế hay chưa:
curl -s http://localhost:9617/metrics | grep pihole_
Terminal trả về các metric như pihole_dns_queries_today 18450 tức là kết nối đã thông suốt.
Bước 3: Khai báo Scrape Job trong Prometheus
Mở file prometheus.yml trên monitoring server rồi thêm cấu hình scrape:
scrape_configs:
- job_name: 'pihole'
scrape_interval: 15s
scrape_timeout: 10s
static_configs:
- targets: ['192.168.1.53:9617']
labels:
instance: 'homelab-pihole'
environment: 'production'
Nạp lại cấu hình mà không cần restart tiến trình Prometheus:
curl -X POST http://localhost:9090/-/reload
Bước 4: Nhập Dashboard Grafana và viết PromQL thực chiến
Muốn có giao diện đẹp ngay, bạn import Dashboard ID 10176 (hoặc bản 13565). Vào Grafana > Dashboards > New > Import, gõ ID và chọn nguồn dữ liệu Prometheus.
Tuy vậy, tự tay tinh chỉnh panel vẫn là cách tốt nhất để kiểm soát số liệu. Dưới đây là 3 câu PromQL bạn nên nắm vững:
1. Tỷ lệ % request bị chặn trong ngày:
(pihole_ads_blocked_today / pihole_dns_queries_today) * 100
2. Tốc độ truy vấn trung bình (queries/giây):
rate(pihole_dns_queries_total[2m])
3. Top 10 client gửi request dồn dập nhất trong 5 phút:
topk(10, sum by (client) (rate(pihole_queries_by_client_total[5m])))
Mẹo thực chiến: Tránh bẫy Alert Fatigue khi đặt ngưỡng cảnh báo
Hồi đầu mới dựng hệ thống, mình từng dính alert fatigue khá nặng. Cứ thấy query nhảy vọt hoặc tỷ lệ chặn vượt 35% là bot Telegram réo ầm ĩ. Hóa ra thủ phạm chỉ là chiếc tivi Sony update firmware ngầm hoặc laptop đồng bộ iCloud.
Sau nhiều đêm mất ngủ vì ping ảo, mình rút ra 2 nguyên tắc quan trọng:
- Tuyệt đối không alert theo số spike tức thời: Hãy bọc metric trong hàm
rate()hoặcincrease()với khung quét 10–15 phút. Người dùng mở trình duyệt tải 20 tab cùng lúc tạo ra vài trăm request trong 5 giây là chuyện bình thường. - Bắt bất thường từ IP cá lẻ thay vì tổng lưu lượng: Thiết lập cảnh báo khi một IP duy nhất chiếm trên 50% tổng lượng query toàn mạng trong 15 phút. Đây là dấu hiệu rõ nhất của thiết bị IoT dính botnet Mirai hoặc app bị treo vòng lặp phân giải DNS (DNS retry storm).
Kết luận
Bộ ba Pi-hole, Prometheus và Grafana biến một DNS sinkhole thông thường thành radar giám sát mạng thực thụ. Bạn sẽ thấy rõ từng biến động lưu lượng, từ việc máy in gửi log ra ngoài cho tới các hành vi rà quét bất thường. Hãy dựng thử container exporter ngay hôm nay và nhớ tinh chỉnh ngưỡng alert cẩn thận để tránh làm phiền chính mình.

