
Набор инструментов для измерения 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
===============================================================
Вы когда-нибудь задумывались, не [перехватывает ли ваш провайдер DNS-трафик](https://medium.com/decentralize-today/is-your-isp-hijacking-your-dns-traffic-f3eb7ccb0ee7)? Замечали ли вы необычное поведение в ответах DNS или перенаправление на неверный адрес и подозревали, что с вашим DNS что-то не так? Мы предлагаем набор инструментов для базового аудита ваших DNS-запросов и ответов, помогающий убедиться, что DNS работает должным образом.
С помощью `dnsping` вы можете измерить время отклика любого DNS-сервера для произвольных запросов. Подобно обычной утилите ping, dnsping предоставляет аналогичную функциональность для DNS-запросов, помогая отслеживать отзывчивость сервера.
Вы также можете отследить маршрут вашего DNS-запроса до пункта назначения с помощью `dnstraceroute`, убедившись, что он не перенаправляется и не перехватывается. Сравнивая 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. Вы можете скачать последний релиз со [страницы релизов](https://github.com/farrokhi/dnsdiag/releases).
### Поддерживаемые платформы
Готовые бинарные файлы доступны для:
- Linux (x86_64, ARM64)
- macOS (Intel, Apple Silicon)
- Windows (x86_64)
Windows ARM64 в настоящее время не поддерживается из-за зависимостей сборки, требующих нативных инструментальных цепочек компиляции, которые не всегда доступны. Если вы используете Windows на ARM, вы можете запускать dnsdiag с помощью подсистемы Windows для Linux (WSL2) или установить напрямую из исходного кода.
## Docker
Если вы предпочитаете не устанавливать `dnsdiag` на свою локальную машину, вы можете использовать образ Docker для запуска инструментов в контейнеризованной среде. Например:
```
docker run --network host -it --rm farrokhi/dnsdiag dnsping.py
```
# dnsping
`dnsping` позволяет «пинговать» DNS-резолвер, отправляя произвольный DNS-запрос несколько раз. Для полного списка поддерживаемых параметров командной строки используйте `--help`. Вот несколько ключевых флагов:
- Используйте `--tcp`, `--tls`, `--doh`, `--quic` или `--http3` для выбора транспортного протокола (по умолчанию UDP). Эти параметры взаимоисключающие; в одной команде можно указать только один протокол.
- Используйте `--flags` для отображения флагов ответа, включая флаги EDNS, для каждого ответа.
- Используйте `--dnssec` для запроса валидации DNSSEC, если она доступна.
- Расширенные сообщения об ошибках DNS ([RFC 8914](https://www.rfc-editor.org/rfc/rfc8914)) отображаются автоматически при наличии.
- Используйте `--nsid` для отображения идентификатора сервера имён (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
```
- Идентификация DNS-серверов с помощью опции NSID:
```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 активна и успешна.
Типичные шаблоны:
| Результат | Значение |
|-------|--------|
| `NOERROR` с флагом `AD` | Валидация DNSSEC прошла успешно |
| `SERVFAIL` с флагом `DO` | Валидация DNSSEC не удалась (часто из-за повреждённых подписей или неверной конфигурации) |
| Флаг `AD` отсутствует | Резолвер не выполняет валидацию DNSSEC |
Расширенные ошибки DNS (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
# Тестирование DNS over QUIC с AdGuard DNS
./dnstraceroute.py --quic -s 94.140.14.14 -c 3 google.com
# Тестирование DNS over HTTP/3 с Google DNS
./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)
```
Использование флага `--expert` с `dnstraceroute` включает отображение экспертных подсказок, включая предупреждения о возможном перехвате DNS-трафика.
# dnseval
`dnseval` — это утилита массового пинга, которая отправляет произвольные DNS-запросы указанному списку DNS-серверов, позволяя одновременно сравнивать их время отклика.
Вы можете использовать `dnseval` для оценки времени отклика по разным транспортным протоколам, включая UDP (по умолчанию), TCP, DoT (DNS over TLS), DoH (DNS over HTTPS), DoQ (DNS over QUIC) и DoH3 (DNS over HTTP/3), используя флаги `--tcp`, `--tls`, `--doh`, `--quic` и `--http3` соответственно. Эти параметры протоколов взаимоисключающие; в одной команде можно указать только один.
## Сводка поддержки протоколов
| Инструмент | 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 для дальнейшей обработки. Каждая строка в выходном файле — это корректный JSON-объект, содержащий полные результаты измерений для одного DNS-сервера.
```shell
./dnseval.py -c 5 -j results.jsonl -f public-servers.txt example.com
```
Вывод можно разбирать построчно стандартными инструментами JSON, такими как `jq`.
```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 выпускается под лицензией BSD с 2 пунктами.