Skip to content

atlorium-api/dns-lookup-api-client

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

DNS Lookup API — проверка DNS-записей домена, SPF и DMARC

Русский · English

examples license API

Готовые примеры работы с DNS Lookup API на шести языках: Python, TypeScript (Node.js), Go, Java, C#, PHP. Проверка DNS-записей домена одним HTTP-запросом: A, AAAA, MX, TXT, CNAME, NS — плюс проверка распространения записей по публичным резолверам.

Прикладной сценарий в комплекте: проверка домена на спуфинг — читаем MX, SPF и DMARC и выносим вердикт, может ли посторонний слать письма от имени домена.

Каждый пример запускается сразу — без регистрации, без ключа, без карты. В коде зашит публичный демо-ключ.

git clone https://github.com/atlorium-api/dns-lookup-api-client
cd dns-lookup-api-client/python && pip install -r requirements.txt && python main.py
Демо-ключ: ответы сгенерированы (моки), не реальные записи DNS.

DNS-записи atlorium.com (резолвер 1.1.1.1 (sandbox)):
  A      189.99.124.40  (TTL 300)
  A      148.24.116.247  (TTL 300)
  AAAA   eed8:7c4f:92b:1734:74be:4695:fad0:6339  (TTL 300)
  MX     30 mail2.atlorium.com  (TTL 3600)
  MX     20 mail2.atlorium.com  (TTL 3600)
  TXT    v=spf1 include:_spf.atlorium.com ~all  (TTL 3600)
  NS     ns1.atlorium.com  (TTL 86400)
  NS     ns2.atlorium.com  (TTL 86400)

АУДИТ ЗАЩИТЫ ОТ СПУФИНГА — atlorium.com
  MX:    mail2.atlorium.com (приоритет 30), mail2.atlorium.com (приоритет 20)
  SPF:   v=spf1 include:_spf.atlorium.com ~all
  DMARC: не найден (_dmarc.atlorium.com)

ВЕРДИКТ: УЯЗВИМ — от имени домена можно слать поддельные письма

ПРОБЛЕМЫ:
  [~] SPF ~all (softfail): подделку помечают, но письмо всё равно доставляют. Строгая политика — -all
  [!] DMARC не найден (_dmarc.atlorium.com): почтовый сервер получателя не знает, что делать с письмом, не прошедшим SPF/DKIM, — и обычно его доставляет

Это моки, а не настоящий DNS. Демо-ключ отдаёт сгенерированные записи: IP-адреса выдуманы, mail2.atlorium.com и ns1.atlorium.com не существуют, а реальные записи домена atlorium.com выглядят иначе. Подставьте боевой ключ — тот же код начнёт резолвить настоящий DNS.

Что именно возвращает песочница (чтобы не было сюрпризов)

Это важно понимать до того, как вы начнёте сверять вывод примера с dig:

Тип Что отдаёт демо-ключ
A / AAAA Два выдуманных IPv4 и один IPv6
MX Две записи вида mailN.<домен> со случайными приоритетами. Хосты могут совпасть, а приоритеты — идти не по возрастанию: в выводе выше mail2 стоит дважды. В настоящем DNS так не бывает — это артефакт генератора, а не поведение сервиса
TXT Ровно одна записьv=spf1 include:_spf.<домен> ~all, для любого домена
NS Два хоста nsN.<домен>
CNAME В песочнице не отдаётся (боевой ключ — отдаёт)

Отсюда два следствия, которые видно в выводе выше:

  1. SPF в песочнице всегда есть и всегда ~all — то есть softfail. Ветку «SPF не найден» на демо-ключе не увидеть.
  2. DMARC в песочнице не существует. На запрос _dmarc.<домен> мок отдаёт такую же SPF-запись, а не DMARC — поэтому пример честно печатает «DMARC не найден» и ставит вердикт УЯЗВИМ. Это не баг примера: он корректно показывает отсутствие записи вместо того, чтобы её выдумать.

Мок намеренно не подстраивается под красивый вывод. Хотите увидеть вердикт «ЗАЩИЩЁН» — нужен боевой ключ и домен с p=reject.


Зачем это нужно

Мониторинг доменов, проверка миграции на новый хостинг, инвентаризация DNS в инфраструктуре, антифрод и e-mail-безопасность. Вместо dig, накрученного на bash, — структурированный JSON, который сразу ложится в код.

Примеры не просто печатают записи, а применяют их: в каждом есть функция auditMailSecurity()проверка домена на спуфинг:

  1. MX — принимает ли домен входящую почту.
  2. SPF — TXT-запись v=spf1 .... Разбирается политика: -all (hard fail — строго), ~all (softfail — подделку помечают, но доставляют), ?all / +all (политики фактически нет — дыра).
  3. DMARC — TXT-запись на поддомене _dmarc.<домен>. Это отдельная зона, поэтому нужен второй запрос к API. Разбирается тег p=: none (только мониторинг), quarantine (в спам), reject (максимальная защита).

Вердикт выносится по слабейшему звену: дыра в любом из механизмов делает домен пригодным для подделки писем. Один прогон = ровно два запроса к API.

Почему это важно: SPF сам по себе проверяет технического отправителя (конверт), а адрес в поле «От кого», который видит человек, им не защищён. Инструкцию «что делать с письмом, не прошедшим проверку» даёт только DMARC. Без DMARC принимающий сервер, как правило, доставляет подделку.

Быстрый старт за 60 секунд

Проверить API вообще без клонирования:

curl -H "Authorization: Bearer ak_sandbox_demo_mockdata_v1" \
     "https://atlorium.com/api/dns/lookup?domain=example.com"
Язык Запуск Требуется
Python pip install -r requirements.txt && python main.py Python 3.10+
TypeScript / Node.js npm install && npm start Node.js 20+
Go go run . Go 1.22+
Java java Main.java JDK 17+ (без зависимостей)
C# dotnet run .NET 8+
PHP php main.php PHP 8.1+

Передать свой домен аргументом: python main.py example.com

Аутентификация

Ключ передаётся в заголовке Authorization:

Authorization: Bearer ВАШ_КЛЮЧ
Ключ Что делает
ak_sandbox_demo_mockdata_v1 Демо-ключ. Публичный, один на всех. Возвращает моки, денег не списывает, регистрации не требует. Ответы детерминированы — на них можно писать стабильные тесты.
Боевой ключ Настоящие DNS-запросы к резолверам. Получить в личном кабинете: atlorium.com

Переход на боевой ключ не требует правок в коде — все примеры читают переменную окружения:

export ATLORIUM_API_KEY="ak_ваш_боевой_ключ"

Каждый ответ песочницы помечен заголовком X-Atlorium-Sandbox: true — перепутать мок с реальными данными невозможно.

Эндпоинты

Базовый адрес: https://atlorium.com

Метод Путь Назначение
GET /api/dns/lookup Записи домена: A, AAAA, MX, TXT, CNAME, NS — за один запрос
GET /api/dns/propagation Как видят домен разные публичные резолверы (проверка распространения)

GET /api/dns/lookup

Параметр Где Тип Описание
domain query string Обязательный. Чистое доменное имя: example.com, sub.example.com. Без https://, не IP-адрес. Поддомены — тоже домены: _dmarc.example.com валиден
resolver query string IP-адрес резолвера. По умолчанию Cloudflare 1.1.1.1. Можно указать 8.8.8.8, 9.9.9.9 или корпоративный DNS

GET /api/dns/propagation

Параметр Где Тип Описание
domain query string Обязательный. Чистое доменное имя
resolvers query string Список IP резолверов через запятую: 8.8.8.8,1.1.1.1. По умолчанию — Google, Cloudflare, OpenDNS, Quad9

Пропагация нужна после смены DNS: пока резолверы отдают разные ответы, часть пользователей продолжает ходить на старый адрес. В примерах функция checkPropagation() объявлена, но не вызывается — чтобы один прогон не тратил лишний запрос из квоты.

Поля ответа

/api/dns/lookup

Поле Тип Что содержит
domain string Запрошенный домен
resolver string Резолвер, который отвечал
requestedAtUtc date-time Время запроса, UTC
records array Группы записей по типу (см. ниже)
errors array Ошибки резолвинга по отдельным типам записей. Пустой массив — всё в порядке

Записи приходят сгруппированными по типу, а не плоским списком:

Поле группы Тип Что содержит
type string A, AAAA, MX, TXT, CNAME, NS
records array Записи этого типа
Поле записи Тип Что содержит
name string Имя, к которому относится запись
value string Значение: IP для A/AAAA, хост для MX/NS/CNAME, строка для TXT
ttl int Время жизни в кэше, секунды
preference int Только у MX. Приоритет: чем меньше число, тем выше приоритет сервера. У остальных типов null
details string Дополнительные сведения, если есть. Обычно null

/api/dns/propagation

Поле Тип Что содержит
domain string Проверяемый домен
requestedAtUtc date-time Время запроса, UTC
snapshots array Срез по каждому резолверу
Поле снимка Тип Что содержит
label string Имя резолвера: Cloudflare, Google, Quad9
resolver string Его IP-адрес
durationMs int Сколько миллисекунд отвечал
success bool Ответил ли резолвер
error string Причина, если не ответил. Иначе null
records array Что он вернул — те же группы записей

Записи разошлись между резолверами — пропагация ещё не завершилась.

Обработка ошибок

Код Причина Что делать
400 Домен не передан или задан неверно Нужно чистое имя: example.com. Не URL с протоколом и не IP
401 Ключ отсутствует, просрочен или недействителен Проверьте заголовок Authorization
402 Недостаточно кредитов на балансе Пополнить на atlorium.com
429 Превышен rate-limit Повторить с задержкой. Не доверяйте Retry-After слепо — см. ниже
500 Резолвер не ответил или таймаут Повторить позже, можно с другим resolver
503 Сервис временно недоступен Повторить позже. За сбой на нашей стороне деньги не списываются

Во всех шести примерах коды разложены в человекочитаемые причины — смотрите класс AtloriumError.

Отдельно про 429: исчерпав часовую квоту, сервер честно просит подождать 40+ минут. Клиент, который слепо спит столько, сколько написано в Retry-After, зависает на все 40 минут (а в CI просто съедает бюджет джоба). Поэтому в примерах есть потолок ожидания MAX_RETRY_DELAY = 120 секунд: дольше не ждём, а честно сообщаем, что квота исчерпана.

Обратите внимание: кода 404 у этого API нет. На домен, у которого записей не нашлось, приходит 200 с пустым records и пояснением в errors («DNS-записи для домена не найдены»). Проверять надо не код ответа, а содержимое records.

И ещё одна деталь, на которой легко ошибиться: группа с нулём записей в ответ не попадает вовсе. Если у домена нет MX-записей, группы type: "MX" в массиве не будет — не будет и пустого массива внутри неё. Поэтому «нет MX» определяется отсутствием группы, а не её пустотой; во всех примерах за это отвечает хелпер recordsOf().

Цены и лимиты

Оплата pay-as-you-go, без подписки: платите только за выполненные запросы. Актуальные тарифы и лимиты — на atlorium.com/pricing.

DNS — дешёвая операция, и лимиты у неё заметно свободнее, чем у большинства других сервисов. Точные значения и цены: atlorium.com/pricing

Частые вопросы

Как через API получить MX-записи домена? Один запрос GET /api/dns/lookup?domain=example.com возвращает все типы сразу, включая MX. Отдельного «MX lookup»-эндпоинта нет и не нужно: в ответе найдите группу с type: "MX". У MX-записей заполнено поле preference — приоритет почтового сервера.

Почему проверка DMARC — это отдельный запрос? Потому что DMARC-запись лежит не на домене, а на его поддомене _dmarc.example.com. Это другая зона DNS, и достать её тем же запросом физически нельзя. SPF при этом живёт в TXT-записи самого домена — он приходит первым же запросом.

Чем -all отличается от ~all в SPF? -all (hard fail) — «письмо не от нас, отклоняйте». ~all (softfail) — «скорее всего не от нас, но доставьте, пометив». ?all и +all — политики фактически нет: разрешено кому угодно. Строгая настройка — -all, но переходить на неё стоит после того, как DMARC-отчёты покажут, что все легитимные отправители учтены.

DMARC p=none — это защита? Нет. Это режим наблюдения: нарушения только логируются в отчётах, письма не блокируются. С него правильно начинать, но останавливаться на нём — значит собирать статистику о подделках вместо того, чтобы их прекращать. Защиту дают p=quarantine (в спам) и p=reject (отбросить).

Чем это лучше dig или системного резолвера? Тем, что ответ — сразу JSON, а не текст, который надо парсить регулярками; тем, что резолвер задаётся параметром (полезно, когда локальный DNS кэширует или подменяет ответы); и тем, что из CI/serverless-окружения, где dig не установлен, работает обычный HTTP-запрос.

Можно ли проверять этим API чужие домены? Да. DNS — публичные данные, никаких особых прав для их чтения не нужно. Именно поэтому проверка чужого домена на спуфинг вообще возможна — и именно поэтому свой домен стоит закрыть DMARC-политикой раньше, чем это заметит кто-то другой.

Обязательна ли регистрация, чтобы попробовать? Нет. Демо-ключ публичный и работает без аккаунта — но возвращает моки, а не реальные DNS-записи.

Другие API Atlorium

DNS редко проверяют в одиночку. Из того же аккаунта и тем же ключом доступны:

Полный каталог — atlorium.com

Ссылки

Лицензия

MIT — берите код и используйте как хотите, в том числе в коммерческих проектах.

About

API проверки DNS-записей: A, AAAA, MX, TXT, NS, CNAME, DNS-over-HTTPS, проверка глобального распространения. Аудит SPF и DMARC — защита домена от спуфинга. Примеры на Python, TypeScript, Go, Java, C#, PHP. DNS lookup API client.

Topics

Resources

License

Stars

0 stars

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors