導入:Pi-holeがローカルネットワークの「ブラックボックス」になっていませんか?
ホームラボの運用者や小規模オフィスのネットワーク管理者にとって、Pi-holeはDNSトラッキングや広告をブロックするお馴染みの防御壁です。Pi-holeの標準Webダッシュボードは非常にシンプルで見やすく設計されています。しかし、それは主要な基本メトリクスをざっと確認する程度の場合に限られます。IPカメラ、スマートテレビ、テストラボの仮想マシンなど、管理対象が40〜50台規模に膨らむと話は一変します。
最大のデメリットは、I/O負荷によるボトルネックを防ぐため、Pi-holeがログをRAMやローカルのSQLiteファイルに保持する期間を制限している点です。マルウェアに感染したネットワークカメラがDNSリクエストを乱発してネットワークが不安定になった際、クエリ量とCPU負荷やルーターの帯域幅を突き合わせて調査するのは至難の業です。年単位でログを長期保存し、多角的なグラフで詳細に分析するには、Pi-holeをPrometheus + Grafanaの鉄板構成に統合するのが最適なアプローチです。
コアコンセプト:PrometheusがPi-holeからメトリクスを収集する仕組み
Pi-holeはPrometheus標準の/metricsエンドポイントをネイティブサポートしていません。提供されているのは、FTLエンジンを介して未加工のJSONデータを返すREST APIのみです。
そこで仲介役として必要になるのがpihole-exporterです。データフローは以下のようになります:
- pihole-exporter: 15秒ごとに認証トークンを用いてPi-holeのAPIを呼び出します。取得したJSONを解析し、OpenMetrics標準フォーマットのテキスト形式メトリクスへと変換します。
- Prometheus: exporterのポート
9617から定期的にデータをスクレイピング(収集)します。収集されたすべての指標は圧縮され、時系列データベース(TSDB)に直接書き込まれます。 - Grafana: PromQL経由でPrometheusからデータを取得します。これにより、ブロック率、秒間クエリトラフィック、DNSリクエストを最も消費しているTopクライアント一覧などを可視化するダッシュボードを構築できます。
実践編:ゼロから完成ダッシュボードまでの構築手順
ステップ1:Pi-holeからAPIトークンを取得する
exporterがFTLメトリクスを読み取るには、APIトークンが必要です。取得手順は以下の通りです:
- Pi-hole管理画面にアクセス > Settings > API / Web interface タブを開きます。
- Show API tokenをクリックし、警告ダイアログを確認後、
WEBPASSWORDのハッシュ文字列をコピーします。
ステップ2:Docker Composeでpihole-exporterを起動する
Docker経由でexporterを立ち上げることで、ホスト環境をクリーンに保ち、管理も容易になります。docker-compose.ymlファイルは、Pi-holeが稼働しているRaspberry Pi上に直接配置しても、独立した監視サーバー上に配置しても構いません:
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
イメージを取得してサービスを起動します:
docker compose up -d
exporterが実際にデータを取得できているか確認します:
curl -s http://localhost:9617/metrics | grep pihole_
ターミナルにpihole_dns_queries_today 18450のようなメトリクスが返ってくれば、正常に連携できています。
ステップ3:PrometheusにScrape Jobを登録する
監視サーバー上のprometheus.ymlを開き、スクレイプ設定を追加します:
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'
Prometheusプロセスを再起動せずに設定を再読み込みします:
curl -X POST http://localhost:9090/-/reload
ステップ4:Grafanaダッシュボードのインポートと実戦的なPromQL
すぐに洗練された画面を使いたい場合は、ダッシュボードID 10176(または13565)をインポートするのが手軽です。Grafana > Dashboards > New > Importへ進み、IDを入力してデータソースにPrometheusを指定します。
ただし、パネルを手動で細かくカスタマイズする方が、データを正確に把握するには最適です。押さえておくべき主要なPromQLクエリを3つ紹介します:
1. 当日のブロック率(%):
(pihole_ads_blocked_today / pihole_dns_queries_today) * 100
2. 平均クエリレート(queries/秒):
rate(pihole_dns_queries_total[2m])
3. 直近5分間でリクエストが急増したTop 10クライアント:
topk(10, sum by (client) (rate(pihole_queries_by_client_total[5m])))
運用のコツ:アラートの閾値設定で「アラート疲弊」を回避する
システム構築当初、筆者自身もひどいアラート疲弊(Alert Fatigue)に悩まされました。クエリが一時的にスパイクしたり、ブロック率が35%を超えたりするたびにTelegram Botが鳴り響いていましたが、調査してみるとソニー製スマートテレビのバックグラウンドファームウェア更新やMacBookのiCloud同期が原因だったというオチでした。
誤検知アラートで夜間に起こされる日々を経て、以下の2つの重要な原則にたどり着きました:
- 瞬間的なスパイク値でアラートを飛ばさない: メトリクスは必ず10〜15分の時間枠で
rate()やincrease()関数を使って平滑化してください。ユーザーがブラウザで20個のタブを一気に開けば、わずか5秒間に数百件のリクエストが発生するのはごく自然な挙動です。 - 全体トラフィックではなく個別IPの異常値を検知する: 単一のIPが15分間にネットワーク全体のクエリ総量の50%以上を占めた場合にアラートを設定します。これはMiraiなどのボットネットに感染したIoT機器や、DNS名前解決の無限ループ(DNS retry storm)に陥ったアプリケーションを検知する上で最も信頼性の高い兆候です。
まとめ
Pi-hole、Prometheus、Grafanaの3要素を組み合わせることで、単なるDNSシンクホールが本格的なネットワーク監視レーダーへと進化します。プリンターの外部ログ送信から不審なスキャン挙動に至るまで、トラフィックの変動を鮮明に捉えられるようになります。ぜひ今すぐexporterコンテナを立ち上げ、無駄な通知に悩まされないようアラート閾値を適切にチューニングしてみてください。

