Зачем нужны DKIM, SPF и DMARC
Электронная почта без аутентификации — как письмо без подписи: любой желающий может отправить сообщение от имени вашего домена, и никто это не заметит. DKIM, SPF и DMARC — три механизма, которые работают в связке и закрывают домен от подделки (spoofing), а заодно заметно улучшают доставляемость нормальной почты.
- SPF (Sender Policy Framework) — TXT-запись в DNS, в которой вы явно перечисляете IP-адреса серверов, которым разрешено слать почту от имени домена. Принимающая сторона смотрит: а этот IP вообще в списке? Если нет — письмо подозрительное.
- DKIM (DomainKeys Identified Mail) — криптографическая подпись заголовков и тела письма. Ваш сервер подписывает каждое письмо приватным ключом, получатель сверяет подпись с публичным ключом из DNS. Подделать это без приватного ключа практически невозможно.
- DMARC (Domain-based Message Authentication, Reporting & Conformance) — политика, которая говорит принимающей стороне: что делать с письмами, провалившими SPF или DKIM. Варианты три: пропустить и записать в лог (
none), отправить в карантин (quarantine) или отклонить совсем (reject). Плюс встроенный механизм отчётности — вы будете видеть, кто и что шлёт от вашего имени.
Без всего этого ваши письма рискуют уходить в спам даже у крупных провайдеров — Gmail, Outlook.com, Mail.ru. Причём с 2024 года Google прямо требует DKIM + SPF + DMARC от массовых отправителей. Не настроили — ждите проблем с доставляемостью.
Настройка SPF
SPF — самое простое из трёх. Настраивается за 10 минут: одна TXT-запись в DNS, и готово.
Создание SPF-записи
В SPF-записи перечисляете все источники, с которых уходит почта вашего домена:
# Базовая SPF-запись для домена с одним почтовым сервером
# DNS TXT запись для corp.local:
v=spf1 ip4:203.0.113.10 mx -all
# Разъяснение:
# v=spf1 — версия SPF
# ip4:... — разрешённый IP отправителя
# mx — все MX-серверы домена
# -all — отклонять всё остальное (hard fail)
# Расширенная SPF-запись
v=spf1 ip4:203.0.113.10 ip4:203.0.113.11 ip6:2001:db8::1 mx include:_spf.google.com ~all
# include: — включение SPF-записей другого домена (для SaaS)
# ~all — soft fail (рекомендуется на начальном этапе)
# -all — hard fail (рекомендуется для продакшена)
Проверяем, что SPF-запись подхватилась и выглядит правильно:
# Через dig
dig TXT corp.local +short
# Через nslookup
nslookup -type=TXT corp.local
# Онлайн-проверка через mxtoolbox (из командной строки)
curl -s "https://dns.google/resolve?name=corp.local&type=TXT" | python3 -m json.tool
Проверка SPF на стороне Postfix
Чтобы Postfix сам проверял входящую почту по SPF, нужен postfix-policyd-spf-python. Ставится в пару команд:
# Установка
sudo apt install postfix-policyd-spf-python
# Конфигурация Postfix: /etc/postfix/master.cf
# Добавьте в конец файла:
policyd-spf unix - n n - 0 spawn
user=policyd-spf argv=/usr/bin/policyd-spf
# /etc/postfix/main.cf
# Добавьте в smtpd_recipient_restrictions:
smtpd_recipient_restrictions =
permit_mynetworks,
permit_sasl_authenticated,
reject_unauth_destination,
check_policy_service unix:private/policyd-spf
# Настройка таймаута
policyd-spf_time_limit = 3600
# Перезагрузка Postfix
sudo systemctl reload postfix
Установка и настройка OpenDKIM
OpenDKIM — стандарт де-факто для связки с Postfix. Если ищете, с чего начать DKIM — берите его, не ошибётесь.
Установка OpenDKIM
Ставим пакеты и делаем начальную конфигурацию:
# Установка
sudo apt install opendkim opendkim-tools
# Создание директорий
sudo mkdir -p /etc/opendkim/keys
sudo chown -R opendkim:opendkim /etc/opendkim
sudo chmod 700 /etc/opendkim/keys
Генерация DKIM-ключей
Генерируем пару ключей — приватный и публичный — отдельно для каждого домена:
# Создание директории для домена
sudo mkdir -p /etc/opendkim/keys/corp.local
# Генерация ключей (2048 бит, селектор "mail")
sudo opendkim-genkey -b 2048 -d corp.local -D /etc/opendkim/keys/corp.local -s mail -v
# Результат: два файла
# mail.private — приватный ключ (хранить на сервере)
# mail.txt — публичный ключ (добавить в DNS)
# Установка прав
sudo chown opendkim:opendkim /etc/opendkim/keys/corp.local/mail.private
sudo chmod 600 /etc/opendkim/keys/corp.local/mail.private
# Просмотр публичного ключа для DNS
sudo cat /etc/opendkim/keys/corp.local/mail.txt
После генерации появится файл mail.txt — это и есть DNS-запись, которую надо добавить в зону. Выглядит примерно так:
mail._domainkey IN TXT ( "v=DKIM1; h=sha256; k=rsa; "
"p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA..." )
Конфигурация OpenDKIM
Главный конфиг — /etc/opendkim.conf. Вот как мы его настраиваем:
# /etc/opendkim.conf
AutoRestart Yes
AutoRestartRate 10/1h
Syslog Yes
SyslogSuccess Yes
LogWhy Yes
Canonicalization relaxed/simple
Mode sv
SubDomains no
OversignHeaders From
# Ключи и таблицы
KeyTable refile:/etc/opendkim/key.table
SigningTable refile:/etc/opendkim/signing.table
ExternalIgnoreList /etc/opendkim/trusted.hosts
InternalHosts /etc/opendkim/trusted.hosts
# Сокет для связи с Postfix
Socket local:/run/opendkim/opendkim.sock
PidFile /run/opendkim/opendkim.pid
UMask 007
UserID opendkim:opendkim
# Алгоритм подписи
SignatureAlgorithm rsa-sha256
Теперь создаём вспомогательные файлы — таблицы ключей и подписей:
# /etc/opendkim/key.table
# Формат: имя_ключа домен:селектор:/путь/к/приватному/ключу
mail._domainkey.corp.local corp.local:mail:/etc/opendkim/keys/corp.local/mail.private
# /etc/opendkim/signing.table
# Формат: паттерн_отправителя имя_ключа
*@corp.local mail._domainkey.corp.local
# /etc/opendkim/trusted.hosts
# Хосты, чья почта подписывается
127.0.0.1
::1
localhost
*.corp.local
10.0.0.0/24
Интеграция OpenDKIM с Postfix
Postfix общается с OpenDKIM через milter-интерфейс (mail filter). Прописываем это в конфиге Postfix:
# /etc/postfix/main.cf
# Настройка milter для OpenDKIM
milter_default_action = accept
milter_protocol = 6
smtpd_milters = local:/run/opendkim/opendkim.sock
non_smtpd_milters = $smtpd_milters
# Добавление пользователя postfix в группу opendkim
sudo usermod -aG opendkim postfix
# Создание директории для сокета
sudo mkdir -p /run/opendkim
sudo chown opendkim:opendkim /run/opendkim
# Запуск OpenDKIM
sudo systemctl enable opendkim
sudo systemctl restart opendkim
# Перезагрузка Postfix
sudo systemctl restart postfix
# Проверка, что сокет создан
ls -la /run/opendkim/opendkim.sock
Проверка подписи
Отправляем тестовое письмо и смотрим, появилась ли DKIM-подпись в заголовках:
# Отправка тестового письма
echo "DKIM test" | mail -s "DKIM Test $(date)" test@gmail.com
# Проверка логов
sudo tail -f /var/log/mail.log | grep -i dkim
# Должно быть: DKIM-Signature field added
# Проверка через командную строку
opendkim-testkey -d corp.local -s mail -vvv
# Результат должен содержать:
# opendkim-testkey: key OK
В заголовках письма ищите строку Authentication-Results — там должно быть dkim=pass. Если есть — всё работает.
Настройка DMARC
DMARC — это надстройка над SPF и DKIM. Она не проверяет сама, а говорит: вот что делать с письмами, которые не прошли эти проверки:
# DNS TXT запись для _dmarc.corp.local
_dmarc.corp.local. IN TXT "v=DMARC1; p=none; sp=none; rua=mailto:dmarc-reports@corp.local; ruf=mailto:dmarc-forensic@corp.local; fo=1; adkim=r; aspf=r; pct=100; ri=86400"
# Разъяснение параметров:
# v=DMARC1 — версия
# p=none — политика: none (мониторинг), quarantine, reject
# sp=none — политика для поддоменов
# rua= — адрес для агрегированных отчётов
# ruf= — адрес для forensic-отчётов
# fo=1 — генерировать отчёт при любом failure
# adkim=r — выравнивание DKIM: r(relaxed) или s(strict)
# aspf=r — выравнивание SPF: r(relaxed) или s(strict)
# pct=100 — процент писем, к которым применяется политика
# ri=86400 — интервал отчётов (секунды, 86400 = 1 день)
Рекомендуемый порядок ужесточения DMARC
Сразу ставить политику reject — плохая идея. Мы несколько раз видели, как это обрезало легитимную почту. Двигайтесь постепенно:
- Неделя 1-4:
p=none — только смотрим, ничего не блокируем, собираем отчёты - Неделя 5-8:
p=quarantine; pct=10 — в карантин уходят 10% подозрительных писем - Неделя 9-12:
p=quarantine; pct=50 — карантин уже для половины - Неделя 13-16:
p=quarantine; pct=100 — все подозрительные письма идут в карантин - После анализа:
p=reject; pct=100 — полная защита, чужие письма от вашего имени отклоняются
На каждом этапе читайте DMARC-отчёты внимательно. Если видите легитимные источники, которые не проходят проверку — не паникуйте: просто добавьте их в SPF или настройте для них DKIM. Это нормальная рабочая ситуация.
Поддержка нескольких доменов
Если один Postfix обслуживает несколько доменов — для каждого нужен свой DKIM-ключ. Вот как это настраивается:
# Генерация ключей для каждого домена
sudo mkdir -p /etc/opendkim/keys/example.com
sudo opendkim-genkey -b 2048 -d example.com \
-D /etc/opendkim/keys/example.com -s mail -v
sudo chown -R opendkim:opendkim /etc/opendkim/keys/example.com
# /etc/opendkim/key.table (добавьте строку)
mail._domainkey.example.com example.com:mail:/etc/opendkim/keys/example.com/mail.private
# /etc/opendkim/signing.table (добавьте строку)
*@example.com mail._domainkey.example.com
# Перезапуск
sudo systemctl restart opendkim
Для каждого домена добавьте в DNS три записи: SPF (TXT в корне домена), DKIM (TXT для mail._domainkey) и DMARC (TXT для _dmarc). Без любой из них защита будет неполной.
Диагностика проблем
Типичные проблемы, с которыми приходят клиенты, и как их диагностировать:
DKIM не подписывает письма
Проверяйте в таком порядке — это экономит время:
# 1. Проверка статуса OpenDKIM
sudo systemctl status opendkim
# 2. Проверка сокета
ls -la /run/opendkim/opendkim.sock
# Пользователь postfix должен иметь доступ
# 3. Проверка логов
sudo grep opendkim /var/log/mail.log | tail -20
sudo journalctl -u opendkim -n 50
# 4. Проверка конфигурации
opendkim -n # парсинг конфигурации без запуска
# 5. Проверка прав на приватный ключ
ls -la /etc/opendkim/keys/corp.local/mail.private
# Должно быть: -rw------- opendkim opendkim
# 6. Проверка signing.table
# Убедитесь, что домен отправителя совпадает с паттерном
SPF fail при отправке
Если получатели видят SPF fail в заголовках — скорее всего одна из этих причин:
# Проверка SPF-записи
dig TXT corp.local +short
# Проверка, с какого IP отправляется почта
# Посмотрите Received-заголовки письма — IP должен быть в SPF
# Проверка через spfquery
sudo apt install libmail-spf-query-perl
spfquery -ip 203.0.113.10 -sender user@corp.local -helo mail.corp.local
# Частые ошибки:
# - IP сервера не указан в SPF
# - Превышен лимит DNS-запросов (максимум 10 include/redirect)
# - Отправка через relay, не указанный в SPF
# - Опечатка в SPF-записи
Комплексная проверка
Для финальной проверки всей связки удобно использовать внешние сервисы — они сразу покажут, что не так:
# Отправка на специальные адреса для проверки
# Gmail: посмотрите заголовки через "Show original"
# Должно быть: SPF: PASS, DKIM: PASS, DMARC: PASS
# Проверка DNS-записей
dig TXT corp.local +short # SPF
dig TXT mail._domainkey.corp.local +short # DKIM
dig TXT _dmarc.corp.local +short # DMARC
# Проверка DKIM-ключа
opendkim-testkey -d corp.local -s mail -vvv
# Проверка через mail-tester.com
# Отправьте письмо на адрес, указанный на сайте mail-tester.com
# Сервис выставит оценку от 1 до 10 и покажет все проблемы
Ротация DKIM-ключей
DKIM-ключи надо менять раз в 6–12 месяцев. Если ключ утёк — злоумышленник может подписывать письма от вашего имени сколько угодно. Процедура ротации такая:
# Шаг 1: Генерация нового ключа с новым селектором
sudo opendkim-genkey -b 2048 -d corp.local \
-D /etc/opendkim/keys/corp.local -s mail202604 -v
sudo chown opendkim:opendkim /etc/opendkim/keys/corp.local/mail202604.private
# Шаг 2: Добавление нового ключа в DNS (не удаляя старый!)
# mail202604._domainkey.corp.local IN TXT "v=DKIM1; h=sha256; k=rsa; p=..."
# Шаг 3: Обновление key.table и signing.table
# /etc/opendkim/key.table:
mail202604._domainkey.corp.local corp.local:mail202604:/etc/opendkim/keys/corp.local/mail202604.private
# /etc/opendkim/signing.table:
*@corp.local mail202604._domainkey.corp.local
# Шаг 4: Перезапуск OpenDKIM
sudo systemctl restart opendkim
# Шаг 5: Через 1-2 недели (после истечения кэша DNS) удалите старый ключ из DNS
# Удалите запись mail._domainkey.corp.local
Важный момент: старый DNS-ключ не удаляйте сразу после смены. Письма со старой подписью могут сидеть в очередях получателей несколько дней — дайте им время дойти, иначе получите волну ошибок.
Оставить комментарий