
DNSの計測、トラブルシューティング、およびセキュリティ監査ツールセット
[](https://pypi.python.org/pypi/dnsdiag/) []() [](https://pepy.tech/project/dnsdiag) [](https://pepy.tech/project/dnsdiag) []() [](https://hub.docker.com/r/farrokhi/dnsdiag) [](https://github.com/farrokhi/dnsdiag/stargazers)
DNS 測定、トラブルシューティング、セキュリティ監査ツールセット
===============================================================
あなたの ISP が [DNS トラフィックを傍受している](https://medium.com/decentralize-today/is-your-isp-hijacking-your-dns-traffic-f3eb7ccb0ee7)のではないかと考えたことはありませんか?
DNS 応答に異常な挙動を感じたり、誤ったアドレスにリダイレクトされて DNS に何か問題があるのではないかと疑ったことはありませんか?私たちは、DNS リクエストと応答に対して基本的な監査を実行し、DNS が期待通りに機能していることを確認するためのツールスイートを提供しています。
`dnsping` を使えば、任意のクエリに対する任意の DNS サーバーの応答時間を測定できます。通常の ping ユーティリティと同様に、dnsping は DNS リクエストに対して同等の機能を提供し、サーバーの応答性を監視するのに役立ちます。
また、`dnstraceroute` を使って DNS リクエストの宛先までの経路を追跡し、リダイレクトや傍受が行われていないことを確認できます。同じサーバーに送信された DNS クエリを比較することで、`dnstraceroute` は経路の違いを観察でき、潜在的な問題に気付くことができます。
`dnseval` は複数の DNS リゾルバを評価し、ネットワークに最適な DNS リゾルバを選択するのに役立ちます。サードパーティの DNS リゾルバへの依存を避けるために独自の DNS リゾルバを使用することを推奨しますが、必要な場合には `dnseval` が最適な DNS リゾルバの選択を支援します。パフォーマンス(レイテンシ)と信頼性(パケットロス)に基づいて DNS サーバーを比較でき、情報に基づいた意思決定のための包括的な視点を提供します。
# インストール
このツールセットを使用する方法はいくつかありますが、最適な柔軟性と制御のためにソースコードから直接実行することを推奨します。ソースからの実行または pip でのインストールには Python 3.11 以降が必要です。
## ソースコード
1. git リポジトリをチェックアウトし、依存関係をインストールします:
```
git clone https://github.com/farrokhi/dnsdiag.git
cd dnsdiag
pip3 install -r requirements.txt
```
2. あるいは、pip を使ってパッケージをインストールすることもできます:
```
pip3 install dnsdiag
```
## uv の使用(推奨)
[uv](https://docs.astral.sh/uv/) は、インストールせずにツールを直接実行できる高速な Python パッケージマネージャーです:
```bash
# インストールせずに dnsping を直接実行
uvx --from dnsdiag dnsping google.com
# 特定のオプションを指定して実行
uvx --from dnsdiag dnsping -c 5 --tls -s 8.8.8.8 example.com
# dnstraceroute を実行
uvx --from dnsdiag dnstraceroute cloudflare.com
# dnseval を実行
uvx --from dnsdiag dnseval -f public-servers.txt github.com
```
dnsdiag を永続的にインストールするには:
```bash
# dnsdiag ツールをインストール
uv tool install dnsdiag
# 最新バージョンにアップグレード
uv tool upgrade dnsdiag
```
## バイナリパッケージ
時折、Windows、Mac OS X、Linux 向けのバイナリパッケージがリリースされます。最新リリースは [releases ページ](https://github.com/farrokhi/dnsdiag/releases)から入手できます。
### 対応プラットフォーム
ビルド済みバイナリは以下で利用可能です:
- Linux (x86_64, ARM64)
- macOS (Intel, Apple Silicon)
- Windows (x86_64)
Windows ARM64 は現在サポートされていません。これは、ビルド依存関係が容易には入手できないネイティブコンパイルツールチェーンを必要とするためです。ARM 上の Windows を使用している場合は、Windows Subsystem for Linux (WSL2) を使って dnsdiag を実行するか、ソースから直接インストールできます。
## Docker
ローカルマシンに `dnsdiag` をインストールしたくない場合は、Docker イメージを使ってコンテナ化された環境でツールを実行できます。例えば:
```
docker run --network host -it --rm farrokhi/dnsdiag dnsping.py
```
# dnsping
`dnsping` は、任意の DNS クエリを複数回送信することで DNS リゾルバを「ping」できます。サポートされているコマンドラインオプションの完全なリストは `--help` を使用してください。以下はいくつかの主要なフラグです:
- `--tcp`、`--tls`、`--doh`、`--quic`、`--http3` を使ってトランスポートプロトコルを選択します(デフォルトは UDP)。これらのオプションは相互排他的で、コマンドごとに指定できるプロトコルは 1 つだけです。
- `--flags` を使って、各応答の応答フラグ(EDNS フラグを含む)を表示します。
- `--dnssec` を使って、利用可能な場合は DNSSEC 検証を要求します。
- Extended DNS Error メッセージ([RFC 8914](https://www.rfc-editor.org/rfc/rfc8914))は存在する場合に自動的に表示されます。
- `--nsid` を使って、利用可能な場合は Name Server Identifier (NSID) を表示します([RFC 5001](https://www.rfc-editor.org/rfc/rfc5001))。
- `--ecs` を使って、地理的ルーティング最適化のための EDNS Client Subnet 情報を含めます。
- `--cookie` を使って、応答に存在する場合に DNS クッキー([RFC 7873](https://www.rfc-editor.org/rfc/rfc7873))を表示します。
```shell
./dnsping.py -c 5 --dnssec --flags --tls -t AAAA -s 8.8.8.8 brokendnssec.net
```
```
dnsping.py DNS: 8.8.8.8:853, hostname: brokendnssec.net, proto: TLS, class: IN, type: AAAA, flags: [RD]
75 bytes from 8.8.8.8: seq=1 time=73.703 ms SERVFAIL [QR RD RA -- DO] [EDE:10("For brokendnssec.net/soa")]
75 bytes from 8.8.8.8: seq=2 time=69.523 ms SERVFAIL [QR RD RA -- DO] [EDE:10("For brokendnssec.net/soa")]
75 bytes from 8.8.8.8: seq=3 time=58.058 ms SERVFAIL [QR RD RA -- DO] [EDE:10("For brokendnssec.net/soa")]
75 bytes from 8.8.8.8: seq=4 time=54.235 ms SERVFAIL [QR RD RA -- DO] [EDE:10("For brokendnssec.net/soa")]
75 bytes from 8.8.8.8: seq=5 time=57.806 ms SERVFAIL [QR RD RA -- DO] [EDE:10("For brokendnssec.net/soa")]
--- 8.8.8.8 dnsping statistics ---
5 requests transmitted, 5 responses received, 0% lost
min=54.235 ms, avg=22.665 ms, max=69.523 ms, stddev=38.202 ms
```
`dnsping` は、最小、最大、平均応答時間に加えて、ジッター(標準偏差)やパケットロスなどの統計も提供します。
`dnsping` のいくつかの興味深いユースケースを以下に示します:
- 異なるトランスポートプロトコル(例:UDP と DoH)間の応答時間の比較。
- ジッターとパケットロスを測定することによる DNS サーバーの信頼性の評価。
- `--dnssec` フラグを使って DNSSEC を有効にした応答時間の測定。
- 地理位置情報を考慮した応答のための EDNS Client Subnet の挙動のテスト:
```shell
./dnsping.py -c 3 --ecs 203.0.113.0/24 -s 94.140.14.14 google.com
```
```
dnsping.py DNS: 94.140.14.14:53, hostname: google.com, proto: UDP, class: IN, type: A, flags: [RD]
66 bytes from 94.140.14.14: seq=1 time=31.407 ms NOERROR [ECS:203.0.113.0/24/24]
66 bytes from 94.140.14.14: seq=2 time=29.156 ms NOERROR [ECS:203.0.113.0/24/24]
66 bytes from 94.140.14.14: seq=3 time=30.892 ms NOERROR [ECS:203.0.113.0/24/24]
--- 94.140.14.14 dnsping statistics ---
3 requests transmitted, 3 responses received, 0% lost
min=29.156 ms, avg=30.485 ms, max=31.407 ms, stddev=1.176 ms
```
- NSID オプションを使った DNS サーバーの識別:
```shell
./dnsping.py -c 2 --nsid -s 8.8.8.8 google.com
```
```
dnsping.py DNS: 8.8.8.8:53, hostname: google.com, proto: UDP, class: IN, type: A, flags: [RD]
68 bytes from 8.8.8.8: seq=1 time=36.399 ms NOERROR [NSID:gpdns-ams]
68 bytes from 8.8.8.8: seq=2 time=32.156 ms NOERROR [NSID:gpdns-ams]
--- 8.8.8.8 dnsping statistics ---
2 requests transmitted, 2 responses received, 0% lost
min=32.156 ms, avg=34.278 ms, max=36.399 ms, stddev=2.122 ms
```
- セキュリティ強化とキャッシュ最適化のための DNS クッキーのテスト:
```shell
./dnsping.py -c 2 --cookie -s anyns.pch.net quad9.net
```
```
dnsping.py DNS: anyns.pch.net:53, hostname: quad9.net, proto: UDP, class: IN, type: A, flags: [RD]
82 bytes from anyns.pch.net: seq=1 time=30.552 ms NOERROR [COOKIE:27f609c017bb2ec4ea70de5c68eec3fc39f6a53ee49c55f8]
82 bytes from anyns.pch.net: seq=2 time=24.794 ms NOERROR [COOKIE:719631dd9fcce722d3ac859b68eec3fd2e5430b5c8a7f8cf]
--- anyns.pch.net dnsping statistics ---
2 requests transmitted, 2 responses received, 0% lost
min=24.794 ms, avg=27.673 ms, max=30.552 ms, stddev=4.072 ms
```
## DNSSEC およびセキュリティ関連フラグの解釈
`--dnssec` と `--flags` を使用すると、`dnsping` は DNS セキュリティ検証に直接関連する DNS プロトコルフィールドを公開します。これらの値は、リゾルバが DNSSEC を検証できるかどうか、および応答が正常に検証されたかどうかを示します。
一般的なフラグ:
- **DO (DNSSEC OK)**
クライアントが DNSSEC 関連のレコードを要求していることを示します。この存在は、リゾルバが DNSSEC クエリをサポートしていることを示します。
- **AD (Authenticated Data)**
応答が DNSSEC を使用して暗号学的に検証された場合に、検証を行うリゾルバによって設定されます。これは DNSSEC 検証が有効で成功していることを示す強いシグナルです。
典型的なパターン:
| 結果 | 意味 |
|-------|--------|
| `AD` フラグ付きの `NOERROR` | DNSSEC 検証が成功 |
| `DO` フラグ付きの `SERVFAIL` | DNSSEC 検証が失敗(多くの場合、壊れた署名や設定ミスが原因) |
| `AD` フラグが存在しない | リゾルバが DNSSEC 検証を実行していない |
Extended DNS Errors (EDE, RFC 8914) は、DNSSEC 検証が失敗したときに追加の診断情報を提供します。例えば:
- **EDE:10** – *DNSSEC Bogus*(無効または壊れた DNSSEC データ)
- **EDE:6** – *DNSSEC Signature Expired*
- **EDE:7** – *DNSSEC Signature Not Yet Valid*
これらの指標により、`dnsping` はパフォーマンステストだけでなく、リゾルバが DNSSEC を正しく適用しているかどうかの検証や、DNSSEC 展開の問題の診断にも役立ちます。
# dnstraceroute
`dnstraceroute` は、DNS リクエストの宛先までの経路を追跡するユーティリティです。実際のネットワーク traceroute と比較して、DNS トラフィックが望ましくない経路を通っていないことを確認したい場合に役立ちます。
`dnstraceroute` は複数のトランスポートプロトコルをサポートしています(相互排他的):
- UDP(デフォルト) - 従来の DNS クエリ
- TCP (`--tcp`) - DNS over TCP
- DoQ (`--quic`) - DNS over QUIC(AdGuard DNS でサポート)
- DoH3 (`--http3`) - DNS over HTTP/3(Google DNS と Cloudflare でサポート)
```shell
./dnstraceroute.py --expert --asn -C -t A -s 8.8.4.4 facebook.com
```
最新の DNS プロトコルをテストすることもできます:
```shell
# AdGuard DNS で DNS over QUIC をテスト
./dnstraceroute.py --quic -s 94.140.14.14 -c 3 google.com
# Google DNS で DNS over HTTP/3 をテスト
./dnstraceroute.py --http3 -s 8.8.8.8 -c 3 google.com
```
```
dnstraceroute.py DNS: 8.8.4.4:53, hostname: facebook.com, rdatatype: A
1 192.168.0.1 (192.168.0.1) 1 ms
2 192.168.28.177 (192.168.28.177) 4 ms
3 192.168.0.1 (192.168.0.1) 693 ms
4 172.19.4.17 (172.19.4.17) 3 ms
5 dns.google (8.8.4.4) [AS15169 GOOGLE, US] 8 ms
=== Expert Hints ===
[*] public DNS server is next to a private IP address (possible hijacking)
```
`dnstraceroute` で `--expert` フラグを使用すると、潜在的な DNS トラフィックハイジャックに関する警告を含むエキスパートヒントの表示が有効になります。
# dnseval
`dnseval` は、指定された DNS サーバーのリストに任意の DNS クエリを送信する一括 ping ユーティリティで、応答時間を同時に比較できます。
`dnseval` を使用して、`--tcp`、`--tls`、`--doh`、`--quic`、`--http3` フラグをそれぞれ使うことで、UDP(デフォルト)、TCP、DoT (DNS over TLS)、DoH (DNS over HTTPS)、DoQ (DNS over QUIC)、DoH3 (DNS over HTTP/3) を含む異なるトランスポートプロトコル間で応答時間を評価できます。これらのプロトコルオプションは相互排他的で、コマンドごとに 1 つだけ指定できます。
## プロトコルサポートの概要
| ツール | UDP | TCP | TLS (DoT) | DoH | DoQ | DoH3 |
|------|-----|-----|-----------|-----|-----|------|
| `dnsping` | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
| `dnstraceroute` | ✓ | ✓ | - | - | ✓ | ✓ |
| `dnseval` | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
*DoQ: DNS over QUIC、DoH3: DNS over HTTP/3*
```shell
./dnseval.py --skip-warmup --dnssec -c10 -f public-servers.txt ripe.net
```
```
server avg(ms) min(ms) max(ms) stddev(ms) lost(%) ttl flags response
---------------------------------------------------------------------------------------------------------------------
1.0.0.1 29.01 14.15 45.36 8.60 %0 300 QR -- -- RD RA AD -- DO NOERROR
1.1.1.1 23.90 18.14 42.07 7.83 %0 300 QR -- -- RD RA AD -- DO NOERROR
1.0.0.2 25.90 21.36 31.58 4.26 %0 300 QR -- -- RD RA AD -- DO NOERROR
1.1.1.2 22.68 18.36 32.15 3.96 %0 300 QR -- -- RD RA AD -- DO NOERROR
1.0.0.3 22.53 18.98 32.52 3.94 %0 300 QR -- -- RD RA AD -- DO NOERROR
1.1.1.3 21.70 20.25 22.97 0.77 %0 299 QR -- -- RD RA AD -- DO NOERROR
2606:4700:4700::1001 21.70 19.13 27.50 2.28 %0 299 QR -- -- RD RA AD -- DO NOERROR
2606:4700:4700::1111 22.63 20.42 30.18 3.13 %0 299 QR -- -- RD RA AD -- DO NOERROR
2606:4700:4700::1002 24.97 20.89 44.63 7.16 %0 299 QR -- -- RD RA AD -- DO NOERROR
2606:4700:4700::1112 23.24 21.37 25.87 1.48 %0 298 QR -- -- RD RA AD -- DO NOERROR
2606:4700:4700::1003 21.68 19.28 24.88 1.65 %0 298 QR -- -- RD RA AD -- DO NOERROR
2606:4700:4700::1113 22.61 19.86 26.09 1.73 %0 299 QR -- -- RD RA AD -- DO NOERROR
195.46.39.39 25.56 16.42 55.37 15.37 %0 300 QR -- -- RD RA -- -- -- NOERROR
195.46.39.40 19.08 16.51 23.86 2.24 %0 300 QR -- -- RD RA -- -- -- NOERROR
2a05:d014:939:3300::39 0.00 0.00 0.00 0.00 %100 N/A -- -- -- -- -- -- -- -- No Response
2a05:d014:939:3300::40 0.00 0.00 0.00 0.00 %100 N/A -- -- -- -- -- -- -- -- No Response
208.67.220.220 30.60 14.54 120.64 31.88 %0 300 QR -- -- RD RA AD -- DO NOERROR
208.67.222.222 21.78 17.42 36.45 6.06 %0 50 QR -- -- RD RA AD -- DO NOERROR
2620:0:ccc::2 29.48 19.23 98.29 24.22 %0 299 QR -- -- RD RA AD -- DO NOERROR
2620:0:ccd::2 22.36 17.90 30.18 3.98 %0 299 QR -- -- RD RA AD -- DO NOERROR
216.146.35.35 172.53 114.46 360.87 71.47 %0 299 QR -- -- RD RA AD -- DO NOERROR
216.146.36.36 187.36 118.21 324.32 59.08 %0 110 QR -- -- RD RA AD -- DO NOERROR
209.244.0.3 46.49 25.23 115.86 28.19 %0 300 QR -- -- RD RA -- -- DO NOERROR
209.244.0.4 58.33 28.09 109.18 29.20 %0 299 QR -- -- RD RA -- -- DO NOERROR
4.2.2.1 64.58 30.21 86.79 30.19 %25 299 QR -- -- RD RA -- -- DO NOERROR
4.2.2.2 40.54 22.69 74.80 20.76 %0 70 QR -- -- RD RA -- -- DO NOERROR
4.2.2.3 90.62 90.62 90.62 0.00 %50 70 QR -- -- RD RA -- -- DO NOERROR
4.2.2.4 31.53 23.80 70.93 14.51 %0 294 QR -- -- RD RA -- -- DO NOERROR
4.2.2.5 24.11 24.05 24.18 0.09 %33 294 QR -- -- RD RA -- -- DO NOERROR
80.80.80.80 0.00 0.00 0.00 0.00 %100 N/A -- -- -- -- -- -- -- -- No Response
80.80.81.81 0.00 0.00 0.00 0.00 %100 N/A -- -- -- -- -- -- -- -- No Response
8.8.4.4 28.35 20.85 39.14 7.24 %0 300 QR -- -- RD RA AD -- DO NOERROR
8.8.8.8 21.22 16.22 24.93 2.39 %0 299 QR -- -- RD RA AD -- DO NOERROR
```
結果を JSONL 形式で保存して、さらに処理することもできます。出力ファイルの各行は、1 つの DNS サーバーの完全な測定結果を含む有効な JSON オブジェクトです。
```shell
./dnseval.py -c 5 -j results.jsonl -f public-servers.txt example.com
```
出力は `jq` のような標準的な JSON ツールで 1 行ずつ解析できます。
```shell
cat results.jsonl | jq -r 'select(.data.r_lost_percent == 0) | .data.resolver'
```
### 作者
Babak Farrokhi
- github: [github.com/farrokhi](https://github.com/farrokhi/)
- website: [farrokhi.net](https://farrokhi.net/)
- mastodon: [@[email protected]](https://unix.family/@farrokhi)
- twitter: [@farrokhi](https://twitter.com/farrokhi)
### ライセンス
dnsdiag は 2 条項 BSD ライセンスの下でリリースされています。