DNS設定ミスに気づけなかった経験から、Go製の監視ツールを作った
DNS の設定変更を見逃した経験から CLI ツールと GitHub Action を開発するまで
課題
以前、自分のドメインの DNS 設定にミスがあったことに気づけなかったことがありました。レコードが変わっていたのに、実際に問題が起きるまで気づかなかったのです。大規模な障害ではなかったものの、簡単なチェックで早期に発見できたはずの「静かな失敗」でした。
この経験から、DNS レコードが期待通りかどうかを定期的に検証できる仕組みが欲しいと思うようになりました。本格的な監視サービスではなく、自分で手軽に動かせる軽量なツールがあれば十分です。
既存ツールの検討
UptimeRobot のような監視ツールは HTTP の死活監視には優れていますが、DNS レコードレベルの検証には向いていません。特定のレコードタイプ(A、MX、TXT、NS、CNAME)をチェックし、実際の値が期待値と一致しない場合にアラートを出す、という用途には不足があります。
個人のドメイン管理で外部 SaaS に登録するのはオーバースペックです。依存自体が不要なレベルの話です。GitHub Actions の cron ジョブとして定期実行できる小さなツールがあれば、それで十分だと判断しました。
なぜ Go か
当初は TypeScript で作ることを想定していました。しかし、配布のしやすさを考えると Go が最適だという結論に至りました:
- 1. シングルバイナリ - ランタイム不要、node_modules 不要、インストール手順なし。ダウンロードしてすぐ実行できる。
- 2. クロスプラットフォーム - Go のクロスコンパイルで Linux、macOS、Windows に簡単に対応。GoReleaser でマルチプラットフォームリリースも自動化。
- 3. ゼロ依存 - 外部依存は設定ファイル解析用の
gopkg.in/yaml.v3のみ。それ以外は Go の標準ライブラリで完結。
信頼性が求められ、デプロイが簡単であるべき監視ツールにとって、これらの特性は開発者の慣れよりも重要です。機能的には TypeScript でも問題ありませんが、Go の配布モデルの方がこの用途に合っています。
設計のポイント
DNS-over-HTTPS
OS のリゾルバを使わず、Google Public DNS に HTTPS 経由(dns.google)でクエリを行います。これにはいくつかのメリットがあります:
- ポート 53 をブロックするファイアウォール環境でも動作
- OS の DNS 設定に依存しない
- 実行環境(ローカル、CI、Docker)に関わらず一貫した結果
2種類のマッチモード
DNS レコードはすべて同じ形式ではありません。A レコードは予測可能な形式ですが、TXT レコードは SPF レコードやドメイン検証トークンなど、可変的な内容を含みます。これに対応するため、2つのマッチモードを用意しました:
expected(完全一致)
DNS レスポンスが指定した値と完全に一致する必要あり。A、MX、NS、CNAME レコード向き。
contains(部分一致)
返されたレコードのいずれかが指定文字列を含んでいればマッチ。SPF などの TXT レコードに便利。
Slack 通知
チェックが失敗すると、Slack の incoming webhook を通じて通知を送ります。webhook URL は環境変数で渡すため、設定ファイルにシークレットを書く必要がありません。1つの webhook、1つのメッセージ、複雑なインテグレーションは不要です。
GitHub Actions での運用
dns-watchdog をスケジュール実行する最も簡単な方法は、GitHub Action として使うことです。cron トリガーでワークフローを追加するだけ:
name: DNS Watchdog
on:
schedule:
- cron: "0 */6 * * *" # 6時間ごと
workflow_dispatch:
jobs:
check:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: daigotanaka0714/dns-watchdog@v1
env:
SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}
DNS_WATCHDOG_CONFIG: ./config.yml 設定ファイルはリポジトリに配置し、Slack の webhook URL は GitHub の secret に保存します。6時間ごとに DNS レコードをチェックし、異常があれば Slack に通知します。
GitHub Action として公開しているので、他の人も簡単に使えます。daigotanaka0714/dns-watchdog@v1 を参照して設定ファイルを用意するだけです。
設定ファイル
設定ファイルは YAML 形式でシンプルです:
domain: example.com
checks:
- type: A
name: "@"
expected:
- "93.184.216.34"
- type: MX
name: "@"
expected:
- "10 mail.example.com."
- type: TXT
name: "@"
contains: "v=spf1"
- type: NS
name: "@"
expected:
- "ns1.example.com."
- "ns2.example.com."
- type: CNAME
name: "www"
expected:
- "example.com."
notify:
slack_webhook_env: "SLACK_WEBHOOK_URL"
template: "default"
各チェックはレコードタイプ、クエリ名、そして expected(完全一致の値リスト)か contains(検索する部分文字列)を指定します。全チェック成功で終了コード 0、いずれかが失敗すると 1 で終了します。
まとめ
dns-watchdog は実際のニーズから生まれた小さなツールです。フル機能の監視スタックの代わりにはなりませんが、自分のドメインを管理していて安心感が欲しい個人にとっては、実用的なソリューションです。期待するレコードを YAML で定義し、cron で実行し、変更があれば通知を受ける。それだけです。