DKIM и DMARC на VPS: как настроить, чтобы письма не улетали в спам
Зачем DKIM и DMARC, если уже настроен SPF
SPF отвечает на вопрос «с каких IP-адресов разрешено слать почту от имени домена». Это только часть защиты. Почтовый сервер может проверить SPF и пропустить письмо, но у него нет способа убедиться, что содержимое письма не подменили по пути, и нет способа сказать «если проверки не прошли — вот что с этим делать». Этим занимаются DKIM и DMARC.
DKIM подписывает письмо цифровой подписью, которая привязана к домену отправителя и телу письма. Если письмо изменили в пути (например, спам-фильтр промежуточного сервера дописал в него рекламную строку) — подпись перестанет сходиться, и получатель это увидит. DMARC идёт ещё дальше: это правило, которое говорит принимающему серверу, что делать с письмом, если SPF и DKIM не сошлись — пропускать, отправлять в спам или отклонять сразу. Без DMARC-записи каждый почтовый сервис решает это по своим внутренним алгоритмам, и предсказать результат сложно.
Это не теоретическая рекомендация, а действующее правило. Gmail и Yahoo официально закрепили в своих требованиях, что для доставки почты SPF и DKIM обязательны, а DMARC настоятельно рекомендован — подробности ниже. Если вы поднимаете почтовый сервер на VPS и отправляете письма на Gmail, Yahoo, Mail.ru или любой другой крупный сервис, без DKIM и DMARC часть писем будет либо падать в спам, либо отклоняться уже на этапе SMTP-сессии.
Если SPF ещё не настроен
SPF мы подробно разбирали в статье «Что такое ресурсные записи DNS» — там есть готовый пример записи, разбор механизмов и квалификаторов. Если у вас ещё нет SPF-записи для домена, начните с неё: DKIM и DMARC работают поверх SPF, а не вместо него. Дальше в этой статье будем считать, что SPF уже настроен и работает.
Установка DKIM на VPS
Разберём настройку на примере Ubuntu 24.04 с Postfix в качестве почтового сервера. Пакет opendkim подписывает исходящие письма на лету, ещё до того, как Postfix отправит их дальше.
Ставим пакеты:
apt-get install -y opendkim opendkim-tools
Создаём директорию под ключи домена и переходим в неё:
mkdir -p /etc/opendkim/keys/домен.ru
cd /etc/opendkim/keys/домен.ru
Генерируем пару ключей длиной 2048 бит:
opendkim-genkey -b 2048 -d домен.ru -s mail -v
Флаг -s mail задаёт селектор — короткое произвольное слово, которое станет частью имени DNS-записи. Можно использовать «mail», «default» или дату генерации ключа (например, «202609») — значения нет, важно только, чтобы это же слово потом попало в конфиг opendkim. Вывод команды выглядит так:
opendkim-genkey: generating private key
opendkim-genkey: private key written to mail.private
opendkim-genkey: extracting public key
opendkim-genkey: DNS TXT record written to mail.txt
В результате появляются два файла. mail.private — приватный ключ, он должен принадлежать пользователю opendkim и иметь права 600, чтобы его не мог прочитать никто, кроме демона. opendkim-genkey сам создаёт файл с правами 600, но владелец у него будет тот, кем вы запускали команду (обычно root), так что chown всё равно нужен — заодно явно зафиксируем и права:
chown opendkim:opendkim mail.private
chmod 600 mail.private
mail.txt — готовый текст TXT-записи для DNS, который нужно добавить в зону домена.
DNS-запись DKIM: почему ключ разбит на несколько строк
Открыв mail.txt, вы увидите примерно следующее (ключ сокращён для примера, у вас он будет длиннее):
mail._domainkey IN TXT ( "v=DKIM1; h=sha256; k=rsa; "
"p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAwT8fVn28RxUu"
"Kq3ZbLxV9mYpQe7Dc4Ht1Nw0oKzXjFvS2bGcRr5eYxL8CnQaU7WdMhPz3T"
"kV9BvGxLqYcRJ8mNtDx2FhZkP4uWnCbEaXVsY6rTgQ1iSzKoM3JdHwLmIQIDAQAB" ) ; ----- DKIM key mail for domain.ru
Ключ разбит на несколько кавычек, потому что одна строка (TXT string) в DNS ограничена 255 байтами (RFC 1035), а base64-представление 2048-битного RSA-ключа этот лимит превышает. opendkim-genkey заранее режет его на куски — при вставке в зону они склеиваются в одно значение автоматически.
Разбивка на несколько строк в кавычках — это не опечатка и не ошибка генератора. По RFC 1035 одна строка внутри TXT-записи не может быть длиннее 255 байт, а публичный ключ на 2048 бит в base64-кодировке этот лимит превышает. Поэтому opendkim-genkey сам режет ключ на сегменты — при чтении записи DNS-сервер склеивает их обратно в одну строку. Как добавлять запись, зависит от того, куда вы её вставляете: если правите zone-файл BIND напрямую — можно скопировать блок из mail.txt ровно как есть, с кавычками и переносами. Если добавляете запись через панель регистратора или DNS-провайдера (Cloudflare и подобные) — там обычно одно текстовое поле для значения TXT-записи, и в него нужно вставить только сам склеенный текст между кавычками, без имени записи, IN TXT и самих кавычек-разделителей: то есть буквально v=DKIM1; h=sha256; k=rsa; p=<склеенный без пробелов base64-ключ> одной строкой. Вставить туда содержимое файла как есть — частая причина того, что запись публикуется битой (см. следующий раздел).
Имя записи в DNS: <селектор>._domainkey.<домен>, тип — TXT. Это описано в RFC 6376 (разделы 3.6.1-3.6.2.1). Для примера выше это будет mail._domainkey.домен.ru.
Связка DKIM с Postfix
Настройки opendkim хранятся в файле /etc/opendkim.conf. Пакет ставит его уже с рабочими значениями по умолчанию (включая PidFile и UserID, от которых зависит, поднимется ли демон вообще) — не заменяйте файл целиком, а допишите в конец эти строки:
Domain домен.ru
KeyFile /etc/opendkim/keys/домен.ru/mail.private
Selector mail
Mode sv
KeyTable /etc/opendkim/KeyTable
SigningTable /etc/opendkim/SigningTable
ExternalIgnoreList /etc/opendkim/TrustedHosts
InternalHosts /etc/opendkim/TrustedHosts
Socket inet:8891@localhost
Строки Domain/KeyFile/Selector здесь на самом деле избыточны при наличии KeyTable/SigningTable ниже (при обоих способах настройки одновременно opendkim использует таблицы, а эти три строки просто игнорирует) — оставлены для наглядности, мешать не будут, но полагаться стоит именно на файлы KeyTable/SigningTable.
KeyTable — связывает селектор с файлом приватного ключа:
mail._domainkey.домен.ru домен.ru:mail:/etc/opendkim/keys/домен.ru/mail.private
SigningTable — говорит, какие письма подписывать этим ключом:
*@домен.ru mail._domainkey.домен.ru
TrustedHosts — список хостов, которым opendkim доверяет без дополнительных проверок (обычно достаточно локального сервера):
127.0.0.1
localhost
Дальше нужно сказать Postfix, чтобы он пропускал исходящую почту через opendkim как milter — внешний фильтр, который подписывает письмо перед отправкой. Применяем настройки через postconf:
postconf -e "milter_default_action = accept"
postconf -e "milter_protocol = 6"
postconf -e "smtpd_milters = inet:localhost:8891"
postconf -e "non_smtpd_milters = inet:localhost:8891"
Перезапускаем оба сервиса:
systemctl restart opendkim
systemctl restart postfix
Проверить, что opendkim слушает порт, можно командой ss -tlnp — в выводе должна появиться строка со 127.0.0.1:8891 в состоянии LISTEN. Команда postfix check при этом не должна выдавать ошибок.
Проверка DKIM
После того как TXT-запись добавлена в DNS, проверить ключ можно командой:
opendkim-testkey -d домен.ru -s mail -k mail.private -vvv
Эта команда делает реальный DNS-запрос к mail._domainkey.домен.ru и сверяет то, что там опубликовано, с локальным приватным ключом. Поэтому она сработает только после того, как запись реально появится в DNS и успеет разойтись по резолверам — это может занять от нескольких минут до часа, в зависимости от TTL зоны и того, как быстро её подхватил DNS-провайдер.
Здесь важно различать два разных сообщения, которые легко перепутать:
- «record not found» — DNS-запись ещё не видна серверу: либо не успела разойтись по резолверам (обычно от нескольких минут до часа, зависит от TTL зоны), либо не добавлена вовсе. Это ожидаемо сразу после публикации — в этом случае действительно нужно просто подождать и проверить снова.
- «Revoked key» — запись УЖЕ найдена в DNS, но в ней пустое значение
p=. По RFC 6376 пустойp=формально означает «ключ отозван» — и если вы видите это сообщение, ждать бесполезно: запись реально опубликована, но битая, и нужно не ждать, а перепроверить и перезалить её содержимое (частая причина — панель DNS-регистратора приняла только первый сегмент длинной записи в кавычках, отрезав остальное). Кстати, такое можно встретить и у крупных сервисов не по ошибке, а намеренно: у части старых DKIM-селекторов gmail.com (например,20161025._domainkey.gmail.com) сейчас именно пустойp=— Google так гасит устаревшие ротированные ключи.
Отдельно есть ещё сообщение «key not secure» — оно про отсутствие DNSSEC-подтверждения записи и появляется даже при УСПЕШНОЙ проверке ключа, само по себе поводом для беспокойства не является.
Отдельно проверить саму DNS-запись, не завязываясь на приватный ключ на сервере, можно так:
dig TXT mail._domainkey.домен.ru
В ответе должна быть строка вида v=DKIM1; k=rsa; p=... с непустым значением p=.
DMARC: синтаксис и политики
DMARC-запись публикуется в DNS как TXT-запись на поддомене _dmarc. Минимальный рабочий вариант:
v=DMARC1; p=none; rua=mailto:postmaster@домен.ru
p= — политика, которая говорит принимающему серверу, что делать с письмом, не прошедшим проверку SPF и DKIM (точнее — не прошедшим выравнивание домена, но для базовой настройки достаточно понимать это как «SPF и DKIM не сошлись»).
| Значение p= | Что происходит с письмом |
|---|---|
| none | Явных требований к получателю нет — только сбор отчётов. Письмо, скорее всего, дойдёт как обычно, но собственные спам-фильтры получателя по-прежнему могут сработать независимо от DMARC. |
| quarantine | Принимающий сервер должен по возможности считать письмо подозрительным — обычно это означает папку «Спам». |
| reject | Принимающий сервер должен по возможности отклонить письмо прямо на этапе SMTP-сессии, до доставки в ящик — это рекомендация протокола (RFC 7489/9989 используют формулировку SHOULD), а не жёсткая гарантия для 100% получателей. |
rua= — адрес (или несколько через запятую), на который будут приходить агрегированные отчёты в формате XML: кто и с каких IP слал письма от имени вашего домена, прошли ли они SPF и DKIM. ruf= — необязательный адрес для forensic-отчётов по отдельным конкретным письмам, не прошедшим проверку; такие отчёты поддерживает не каждый почтовый провайдер, поэтому не все получатели их отправляют.
Как правильно внедрять DMARC: не сразу reject
Ставить p=reject сразу после настройки DKIM — плохая идея, даже если кажется, что всё уже работает. Если SPF или DKIM настроены не идеально (например, письма уходят ещё и через сторонний сервис рассылок, который не учли в SPF), домен начнёт блокировать собственную легитимную почту, и вы узнаете об этом не сразу, а когда клиенты пожалуются, что не получают писем.
Принятая индустриальная практика внедрения DMARC выглядит так:
- Настроить и проверить SPF и DKIM по отдельности.
- Опубликовать DMARC с
p=noneи указаннымrua— это ничего не меняет в доставке, но запускает сбор отчётов. - Несколько недель анализировать отчёты: кто реально шлёт письма от имени домена, все ли источники легитимны, проходят ли они SPF/DKIM.
- Если картина чистая — постепенно ужесточать политику: сначала
quarantine, затем, когда уверенность в настройке полная,reject.
Отчёты приходят в виде XML-файлов, которые неудобно читать глазами в большом объёме — для этого существуют DMARC-аналитические сервисы. Кстати, крупные компании их и используют: если посмотреть DMARC-запись Yahoo, видно, что отчёты у них уходят не на собственный домен, а на сторонний сервис:
dig TXT _dmarc.yahoo.com
→ "v=DMARC1; p=reject; pct=100; rua=mailto:d@rua.agari.com; ruf=mailto:d@ruf.agari.com;"
Для сравнения, у Google:
dig TXT _dmarc.google.com
→ "v=DMARC1; p=reject; rua=mailto:mailauth-reports@google.com"
Оба варианта рабочие — указывать в rua можно как свой почтовый адрес, так и адрес специализированного сервиса, который разбирает отчёты и показывает их в удобном виде.
Действующие требования Gmail и Yahoo к отправителям
Это не абстрактная теория, а действующие правила, которые уже применяются на практике. Google и Yahoo с февраля 2024 года ужесточили требования к аутентификации почты, и с ноября 2025 Google предупреждает, что трафик, не соответствующий требованиям, получает временные и постоянные отказы в доставке — на сегодняшний день это уже реальность, а не анонс.
| Требование | Детали |
|---|---|
| Порог «массового отправителя» | Около 5000+ писем на личные Gmail-аккаунты за 24 часа |
| SPF или DKIM для всех отправителей | Обязательно хотя бы одно, независимо от объёма рассылки |
| SPF и DKIM для массовых отправителей | Обязательны оба, плюс домен в заголовке From: должен быть выровнен минимум с одним из них |
| DMARC для массовых отправителей | Обязателен, минимум с политикой p=none |
| TLS-соединение | Gmail требует передавать почту по TLS-соединению — обычное STARTTLS, которое Postfix включает из коробки |
| Валидная PTR-запись | IP отправляющего сервера должен иметь обратную (PTR) запись, разрешающуюся в хостнейм — для VPS это отдельный вопрос к провайдеру, если провайдер выдаёт generic-PTR вида «1-2-3-4.example-provider.net» |
| Спам-рейт | Держать ниже 0.1% (рекомендация), при 0.3% и выше доставляемость заметно страдает — у Yahoo этот порог указан прямо как требование |
| One-click unsubscribe | Обязателен с 1 июня 2024 для маркетинговых писем: заголовки List-Unsubscribe и List-Unsubscribe-Post, отписка должна обрабатываться в течение 48 часов |
Последний пункт касается в основном рассылок и маркетинговых писем, а не обычной транзакционной или личной переписки, поэтому в контексте настройки почтового сервера на VPS для большинства случаев достаточно закрыть SPF, DKIM и DMARC. Но если с VPS уходят ещё и массовые рассылки — без one-click unsubscribe письма тоже будут терять в доставляемости.
Как проверить всё разом
После того как DKIM и DMARC настроены и записи разошлись по DNS, стоит проверить результат несколькими способами.
Через dig — убедиться, что записи действительно опубликованы и читаются:
dig TXT mail._domainkey.домен.ru
dig TXT _dmarc.домен.ru
Через публичные онлайн-инструменты, если хочется проверить всё со стороны получателя, а не только формально в DNS:
- mail-tester.com — сайт генерирует одноразовый адрес, на который нужно отправить тестовое письмо с вашего сервера. После отправки сайт показывает оценку и подробный разбор того, как прошли проверки SPF, DKIM и DMARC.
- mxtoolbox.com — набор отдельных проверок по домену или IP: SPF Record Check, DKIM Check, DMARC Check, а также проверка на попадание в чёрные списки (Blacklist Check).
Оба инструмента бесплатны для разовой проверки и не требуют настройки — достаточно ввести домен или отправить письмо.
Заключение
SPF, DKIM и DMARC решают разные задачи и работают только вместе. SPF говорит, кому разрешено слать почту от имени домена, DKIM подтверждает, что письмо не изменили в пути, а DMARC объясняет принимающему серверу, что делать, если первые две проверки не прошли. На VPS вся настройка DKIM сводится к генерации ключа, публикации TXT-записи в DNS и подключению opendkim как milter к Postfix. DMARC добавляется отдельной записью и внедряется постепенно — от мониторинга (p=none) к жёсткому отклонению (p=reject), а не наоборот. Учитывая, что с 2024 года и Gmail, и Yahoo требуют эту связку официально, откладывать настройку не стоит — без неё часть писем с вашего домена будет либо оседать в спаме, либо не доходить вовсе.
Похожее
Все статьи
Почему письма с VPS уходят в спам, даже если SPF, DKIM и DMARC настроены
SPF настроен, DKIM подписывает письма, DMARC не ругается — а получатели всё равно видят ваши письма в папке «Спам» или не видят вовсе. Если записи в DNS в порядке (о том, как устроены SPF, DKIM и DMARC как DNS-записи, —…
Свой почтовый сервер на VPS: установка Postfix и Dovecot с нуля
Собственный почтовый сервер имеет смысл, когда вам нужен полный контроль над доставкой писем на корпоративном домене, вы хотите разобраться, как устроена почта на уровне протоколов, или просто не хотите зависеть от стороннего почтового сервиса. Но это не разовая настройка на…