Проверка DNS и защиты почты своего домена командами dig: SPF, DKIM, DMARC, CAA, DNSSEC

Защита почтового домена и сертификатов начинается с записей DNS, а проверить их можно одной командой без онлайн-сервисов. Типичная картина у небольших организаций: есть SPF от почтового провайдера, но нет DMARC, поэтому письма от вашего имени подделываются, а получатели не знают, что с ними делать; нет CAA, и сертификат может выпустить любой центр; нет DNSSEC. Ниже набор проверок командой dig с разбором результата и скрипт, который считает DNS-запросы в SPF и находит превышение предела.
Статья опирается на логику направления «Сетевая безопасность» из методики зрелости Группы Сбер (источник); это методика для крупных компаний, мы используем её как ориентир и пересказываем своими словами. Команды выполнены на Debian 12 с публичным резолвером; примеры результатов получены на реальных записях, имена вашего домена заменены на example.com. Проверяйте только свои домены. Настройка самих записей: SPF, DKIM и DMARC.
Что должно получиться
| Уровень | Что это значит на практике |
|---|---|
| 2. Гигиенический | Публичные сервисы и домены защищены от типовых атак, конфигурация контролируется |
Критерии сформулированы нами по мотивам методики, это ориентир, а не оценка соответствия.
Что проверять
| Запись | Команда | Хороший результат |
|---|---|---|
| MX (куда идёт почта) | dig +short MX example.com |
Серверы вашего почтового провайдера |
| SPF | dig +short TXT example.com |
Ровно одна запись v=spf1 ..., не более 10 DNS-запросов |
| DKIM | dig +short TXT СЕЛЕКТОР._domainkey.example.com |
Запись v=DKIM1; k=rsa; p=... |
| DMARC | dig +short TXT _dmarc.example.com |
Запись v=DMARC1; p=quarantine или reject |
| CAA | dig +short CAA example.com |
Перечень центров, которым разрешён выпуск (например, 0 issue "letsencrypt.org") |
| DNSSEC | dig +short DS example.com и dig example.com +dnssec |
Запись DS у родительской зоны; флаг ad в ответе валидирующего резолвера |
| NS (у кого DNS) | dig +short NS example.com |
Не менее двух серверов у надёжного провайдера |
Селектор DKIM зависит от провайдера: у многих используется default, mail, selector1 или google; точное значение смотрите в настройках почтового сервиса или в заголовке DKIM-Signature (поле s=) полученного от вас письма. Запись с публичным ключом в ответе выглядит так: "v=DKIM1; k=rsa; t=s; p=MIGfMA0GCSqGSIb3...". Если для типичных селекторов ответ пуст, а письма подписываются, значит вы просто не нашли селектор, а не записи нет.
SPF: смотрим, не превышен ли предел запросов
Проверка SPF по стандарту допускает не более десяти DNS-запросов; каждый include, a, mx, exists, ptr и redirect считается как запрос, причём вложенные записи провайдеров учитываются тоже. При превышении получатель выдаёт permerror и письма могут не доставляться. Скрипт раскрывает записи рекурсивно через dig и считает запросы:
#!/usr/bin/env python3
"""Считает DNS-запросы, которые нужны для проверки SPF-записи домена (предел по RFC 7208: 10).
Раскрывает include и redirect рекурсивно; механизмы a, mx, ptr, exists и модификатор redirect считаются как запросы.
Использует команду dig. Проверяйте свои домены.
Запуск: python3 spf_lookups.py example.com [резолвер, по умолчанию 1.1.1.1]"""
import re
import subprocess
import sys
LIMIT = 10
def txt(domain, resolver):
out = subprocess.run(['dig', '+short', '+time=3', '+tries=1', 'TXT', domain, '@' + resolver],
capture_output=True, text=True).stdout
records = [''.join(re.findall(r'"([^"]*)"', line)) for line in out.splitlines() if line.strip()]
return [r for r in records if r.lower().startswith('v=spf1')]
def walk(domain, resolver, seen, depth=0):
if domain in seen or depth > 10:
return 0, [f'{domain}: повтор или слишком глубокая вложенность']
seen.add(domain)
recs = txt(domain, resolver)
if not recs:
return 0, [f'{domain}: SPF-записи нет']
if len(recs) > 1:
return 0, [f'{domain}: ошибка, найдено {len(recs)} записей SPF (должна быть одна)']
rec = recs[0]
notes = [f'{" " * depth}{domain}: {rec}']
count = 0
for term in rec.split()[1:]:
t = term.lstrip('+-~?')
low = t.lower()
if low.startswith('include:') or low.startswith('redirect='):
count += 1
target = t.split(':', 1)[1] if ':' in t else t.split('=', 1)[1]
c, n = walk(target, resolver, seen, depth + 1)
count += c
notes += n
elif low.startswith(('a:', 'mx:', 'exists:', 'ptr')) or low in ('a', 'mx'):
count += 1
return count, notes
def main():
if len(sys.argv) < 2:
sys.exit('Использование: spf_lookups.py домен [резолвер]')
domain = sys.argv[1]
resolver = sys.argv[2] if len(sys.argv) > 2 else '1.1.1.1'
count, notes = walk(domain, resolver, set())
print('\n'.join(notes))
status = 'в пределах нормы' if count <= LIMIT else 'ПРЕВЫШЕН предел, проверка SPF даст permerror'
print(f'Всего DNS-запросов для проверки: {count} из {LIMIT}: {status}')
return 0 if count <= LIMIT else 1
if __name__ == '__main__':
sys.exit(main())
python3 spf_lookups.py example.com
Пример результата для домена, который делегирует SPF почтовому провайдеру через redirect:
example.com: v=spf1 redirect=_spf.provider.example
_spf.provider.example: v=spf1 redirect=_spf.provider2.example
_spf.provider2.example: v=spf1 include:_spf-ipv6.provider2.example include:_spf-ipv4-a... ~all
_spf-ipv6.provider2.example: v=spf1 ip6:2a02:.../40 ... ~all
...
Всего DNS-запросов для проверки: 8 из 10: в пределах нормы
Результат этого скрипта на нескольких реальных доменах: домен с политикой «никому нельзя» (v=spf1 -all) требует 0 запросов; домен, использующий провайдера почты через две цепочки redirect и шесть include, укладывается в 8; крупная организация с большим числом внешних сервисов (облачная почта, поддержка, рассылки) оказалась ровно на пределе 10. Это показывает, как быстро добавление сервисов выбирает запас. Скрипт даёт оценку: он считает механизмы a и mx как один запрос каждый, не раскрывая их, и не проверяет доступность серверов. Код возврата 1, если предел превышен: удобно для регулярной проверки.
Если предел превышен, сократите список: уберите неиспользуемые сервисы, замените include явными подсетями ip4: (но следите за их актуальностью), разделите почтовые потоки по поддоменам (рассылки с отдельного поддомена с собственной записью SPF).
Что означает redirect
Запись v=spf1 redirect=_spf.провайдер означает «вся политика берётся у указанного домена»: ваша политика полностью определяется провайдером, включая его завершающий механизм (~all — мягкая неудача, -all — жёсткая). Это допустимо и удобно, но отдельно от DMARC не заменяет вашу политику: даже при мягком ~all от провайдера подделки не отклоняются, а помечаются. Поэтому нужен DMARC.
DMARC: самое частое отсутствие
Если запрос dig +short TXT _dmarc.example.com ничего не вернул, DMARC не настроен. Последствия: получатели сами решают, что делать с письмами, не прошедшими SPF и DKIM; нет отчётов о том, кто отправляет почту от вашего имени; домен проще использовать для подделок. Минимальная запись для начала сбора отчётов:
_dmarc.example.com. IN TXT "v=DMARC1; p=none; rua=mailto:dmarc-reports@example.com"
Затем ужесточайте политику по этапам, как описано в статье про SPF, DKIM и DMARC. Пример рабочей записи крупной организации: "v=DMARC1; p=quarantine; sp=reject; pct=100; rua=mailto:dmarc@...; fo=1": политика для основного домена — карантин, для поддоменов — отклонение, действует на все письма.
CAA: кто может выпускать сертификаты
Запись CAA ограничивает список центров сертификации, которым разрешено выпускать сертификаты для домена. Пример: 0 issue "letsencrypt.org". Без неё сертификат может выпустить любой центр при подтверждении владения доменом, и ошибочный или вредоносный выпуск проще. Добавляйте записи для центров, которыми вы пользуетесь, и перепроверяйте после смены поставщика сертификатов. Проверка: dig +short CAA example.com; пустой ответ означает, что ограничений нет. Дополнительно: проверка TLS.
DNSSEC: подпись записей DNS
DNSSEC защищает от подмены DNS-ответов. Признаки включённого DNSSEC: у родительской зоны есть запись DS (dig +short DS example.com возвращает строку вида 2371 13 2 32996839A6D8...), а валидирующий резолвер отдаёт ответ с флагом ad (authenticated data): dig example.com @1.1.1.1 +dnssec показывает в строке flags: значение qr rd ra ad. Если записи DS нет, DNSSEC не включён. Включение зависит от DNS-провайдера и регистратора (подписание зоны и публикация DS у регистратора); при ошибке в настройке домен перестаёт разрешаться у валидирующих резолверов, поэтому включайте по инструкции провайдера и проверяйте.
Регулярная проверка
- Раз в квартал и после смены почтового или DNS-провайдера выполняйте набор команд из таблицы.
- Добавьте в мониторинг проверку наличия и неизменности записей SPF, DMARC, CAA и NS: изменение записи без вашей заявки — признак компрометации аккаунта DNS-провайдера.
- Защитите аккаунт регистратора и DNS-провайдера: MFA, ограниченный круг лиц, блокировка переноса домена.
- Записи DNS и ответственные за них — часть реестра активов: реестр ИТ-активов.
Диагностика
| Симптом | Причина и что делать |
|---|---|
| Две записи SPF | Неправильно: допускается одна. Объедините в одну запись |
| SPF показывает 11 и более запросов | Слишком много сервисов. Сократите, разнесите потоки по поддоменам, замените часть include подсетями |
DMARC в режиме p=none месяцами |
Политика не ужесточается. Разберите отчёты, исправьте источники и перейдите на quarantine, затем reject |
| Нет ответа на DKIM | Неверный селектор. Найдите его в заголовке письма (s=) и проверьте запись |
| Разные результаты на разных резолверах | Кэш или изменения не распространились. Подождите время жизни записи (TTL) или запросите авторитетный сервер: dig @СЕРВЕР_NS example.com TXT |
Где это в модели зрелости
Материал относится к направлению «Сетевая безопасность» (материалы направления, карта зрелости). Контроль DNS-записей, защита почтового домена и ограничение выпуска сертификатов относятся к управляемому периметру, который требуется на уровне 2.
Как проверить
- У домена одна запись SPF с числом запросов не более 10, есть DKIM и DMARC (не слабее
p=quarantineдля рабочих доменов). - Для неиспользуемых доменов опубликованы
v=spf1 -allи DMARCp=reject. - Есть запись CAA с центрами, которыми вы пользуетесь; DNSSEC включён или его отсутствие осознанное решение.
- Проверки выполнены после последнего изменения провайдеров; регулярная проверка и оповещение об изменениях настроены.
Источники
- Методика оценки уровня зрелости кибербезопасности компании, Группа Сбер: sberbank.ru.
- RFC 7208 (SPF): rfc-editor.org; RFC 8659 (CAA): rfc-editor.org; RFC 4033 (DNSSEC): rfc-editor.org. Проверьте, не заменены ли документы новыми редакциями.
- Руководство
man digдля вашей версии.






















