WireGuard VPNをマスターする:Prometheusによる帯域幅と接続の監視

Monitoring tutorial - IT technology blog
Monitoring tutorial - IT technology blog

現実の課題:VPNが「ブラックボックス」になる時

約1年前、私は30人のリモート開発チームのためにWireGuard VPNクラスターを管理していました。WireGuardは軽量で高速なため、最初はすべてが非常にスムーズに動作していました。しかし、チームメンバーから「ネットワークが重い」「Pingが500msに跳ね上がる」「時々接続が完全に切れる」といった不満が出始めたことで問題が発生しました。

当時、私にできたのはサーバーにSSHでログインし、wg showを連打することだけでした。黒い画面上で乱数のように動く数値を見つめながら、私は完全に行き詰まっていました。なぜなら、以下のことが分からなかったからです。

  • 現在の総トラフィック量は?1Gbpsのネットワークカードがボトルネックになっていないか?
  • どのユーザーがトレントをダウンロードしたり、重いデータを同期したりして他者に影響を与えているのか?
  • そのユーザーが最後にアクティブだったのはいつか?退職したユーザーのキーを回収し忘れていないか?
  • 過去24時間の使用履歴に異常な変動はないか?

データが不足していたため、トラブルが発生するたびに原因を特定するだけで午前中を丸々潰していました。私はシステムを「勘」で管理していることに気づきました。

なぜ wg show コマンドだけでは不十分なのか?

WireGuardはミニマリズムの哲学に基づいて設計されているため、付属のツールも非常に基本的です。wgコマンドは瞬時のデータ(スナップショット)しか表示せず、主に3つの弱点があります。

  1. 履歴の追跡ができない: リソースをスケールさせるために、午前3時のピーク帯域幅がどれくらいだったかを知ることができません。
  2. 集中管理が困難: 3〜5台のVPNサーバーがある場合、それぞれにSSHでログインして確認するのはまさに苦行です。
  3. アラート機能の欠如 1日に50GB以上のデータを使用したピアがある場合に、Telegramで自動通知を飛ばす方法がありません。

プロフェッショナルな管理を行うには、これらの数値をPrometheusのような時系列データベース(Time-series database)に取り込み、簡単に監視やグラフ化ができるようにする必要があります。

監視ソリューションの検討

私が検討した一般的な3つのアプローチを以下に示します。

  • 方法1:自作スクリプト。 wg show dumpの出力をパースしてログに送るPythonスクリプトを書く方法。手っ取り早いですが、出力フォーマットが変わると壊れやすく、メンテナンスが非常に困難です。
  • 方法2:Netdata。 非常に美しいダッシュボードで、1秒ごとのリアルタイム表示が可能です。しかし、NetdataはRAMを消費し、複数のサーバーからデータを1か所に集約するのが少し面倒です。
  • 方法3:WireGuard Exporter + Prometheus。 これが業界標準(クラウドネイティブ)です。収集、保存、表示が分離されており、大規模なシステムでも非常に安定しています。

WireGuard Exporter + Prometheusの構築

私はモジュール性が高いPrometheus – Grafanaのコンボを選択しました。以下は、VPNサーバーを「可視化」されたシステムに変える手順です。

ステップ1:WireGuard Exporterのインストール

WireGuard Exporterは通訳のような役割を果たします。WireGuardからデータを読み取り、Prometheusが理解できる形式に変換します。Dockerを使用するのが最も簡単です。

以下の docker-compose.yml ファイルを作成します:

version: '3'
services:
  wireguard-exporter:
    image: mindflavor/prometheus-wireguard-exporter
    container_name: wireguard-exporter
    privileged: true # ネットワークインターフェース情報を読み取るために必須
    network_mode: "host"
    restart: always
    volumes:
      - /etc/wireguard:/etc/wireguard:ro

ヒント: /etc/wireguardをマウントすることで、exporterが公開鍵とユーザー名(エイリアス)を自動的に照合してくれます。ダッシュボードには、無意味な文字列の代わりにユーザー名が表示されるようになります。

docker-compose up -d コマンドでexporterを起動します。http://IP-SERVER:9586/metrics で確認できます。wireguard_sent_bytes_total といった行が表示されていればOKです。

ステップ2:Prometheusの設定

監視サーバー側で、Prometheusが定期的にVPNサーバーからデータを取得するように設定する必要があります。prometheus.yml ファイルに以下のジョブを追加します:

scrape_configs:
  - job_name: 'wireguard-vps'
    static_configs:
      - targets: ['<IP_SERVER_VPN>:9586']
    scrape_interval: 15s

15秒の間隔は、サーバーのCPUに負荷をかけずにトラフィックを監視するのに十分な頻度です。

ステップ3:Grafanaでダッシュボードを表示する

自分でダッシュボードを作成する時間を無駄にしないでください。コミュニティが既に優れたテンプレートを作成しています。テンプレートID 11280 をお勧めします。

  1. Grafanaにログインし、Importを選択します。
  2. 検索ボックスにID 11280 を入力します。
  3. データソースとして、先ほど設定したPrometheusを選択します。

これで、イン/アウトの総容量、オンライン中のユーザーリスト、各ユーザーの消費量などが視覚的に表示されます。

ステップ4:自動アラートの設定

画面を凝視し続ける代わりに、Prometheusにその仕事を任せましょう。私は通常、トラフィックが5分間連続で80Mbpsを超えた場合にアラートを設定しています。これは、不適切な利用やサーバーへの攻撃の兆候である可能性があります。

Prometheusのアラートルール例

groups:
- name: wireguard_alerts
  rules:
  - alert: HighVPNTraffic
    expr: sum(rate(wireguard_sent_bytes_total[5m])) > 10000000 # ~80Mbps
    for: 2m
    labels:
      severity: warning
    annotations:
      summary: "{{ $labels.instance }} でVPN帯域幅が急増しました"

導入後の成果

このシステムを導入してから、運用業務は非常に楽になりました。レスポンスが遅いという報告があれば、ダッシュボードをちらっと見るだけで済みます。CPU使用率は低いのにトラフィックが高い場合は、誰かが大きなファイルをダウンロードしていることがすぐに分かります。ピアの latest_handshake が古すぎる場合は、そのクライアントの設定に問題があることが即座に判断できます。

監視は単にバグを修正するためだけではありません。ユーザーが増えた際に、自信を持ってサーバーのアップグレードを提案するための実データを提供してくれます。皆さんの構築が成功することを願っています!

Share: