Перейти к содержанию

Почему домены уходят от собственной почты — и что чинить, если письма всё-таки не доходят

Опубликовано
  • Админы
Доля доменов с собственным почтовым сервером за десять лет сократилась вдвое
Доля доменов с собственным почтовым сервером за десять лет сократилась вдвое

Два американских провайдера сегодня принимают почту почти для сорока процентов доменов из первого миллиона по Tranco. Собственный почтовый узел остался у 22,4 % — против 44,6 % десятью годами ранее. Цифры взяты из работы Артёма Березина на RIPE Labs: публикация от 30 июля 2026 года, срез от 18 июля, исходные данные — ежедневные снимки DNS проекта OpenINTEL.

Читать это как эпитафию самохостингу было бы поспешно. Разберём сначала, что именно посчитано, а дальше пойдёт практическая часть: какие команды запускать и какие строки править, когда письма не доходят.

Сухой остаток исследования

  • Типичный день выборки — примерно 659 000 доменов с MX-записями и 618 000 с SPF.
  • На Google Workspace приходится 21,8 % доменов с MX, на Microsoft 365 — 16,8 %; суммарно 38,6 %.
  • Идущий третьим Proofpoint набирает лишь 1,9 % — отрыв второго места от третьего почти девятикратный.
  • DMARC-запись есть у 458 467 доменов, но реально что-то предписывают (p=quarantine либо p=reject при pct=100) всего 46,9 % из них.
  • Абсолютный чемпион по частоте — строка v=DMARC1; p=none; ровно в таком виде: 58 064 домена. Ещё 32 682 публикуют её же без завершающей точки с запятой.

ℹ️ Справка

Что здесь считается «своим сервером». Провайдер определяется по основной MX-записи — с наименьшим значением preference — и сверяется со словарём известных сервисов. Не совпавшее ни с одним шаблоном автоматически уезжает в корзину «самостоятельные». Значит, доля в 22,4 % вобрала в себя помимо настоящих самохостеров ещё и небольших региональных хостеров, корпоративные шлюзы и всё прочее, до чего словарь не дотянулся. Автор приводит и встречную цифру: 36 455 уникальных MX-хостов остались неопознанными.

Корректная формулировка поэтому иная. Не «самохостинг почты умер», а «за десять лет два американских сервиса собрали 38,6 % рынка, а всё прочее раздробилось». Двадцать два с небольшим процента от 659 тысяч — это по-прежнему около 148 тысяч доменов.

Чем работать

Вся практика ниже опирается на пять утилит. Установка укладывается в одну строку:

# Debian/Ubuntu
sudo apt install dnsutils swaks openssl opendkim-tools netcat-openbsd libxml2-utils
  • dig из пакета dnsutils — показывает, что на самом деле отдаётся из DNS;
  • swaks — отправляет письмо вручную и печатает весь SMTP-диалог;
  • openssl s_client — проверка STARTTLS и сертификата;
  • opendkim-testkey — сличает приватный ключ с опубликованным публичным;
  • xmllint из libxml2-utils — чтение агрегированных отчётов DMARC.

📌 Заметка

Заведите себе по тестовому ящику на Gmail и на Outlook.com. Гонять проверки внутри собственного домена смысла нет: свой сервер доверяет себе безусловно, а нужно увидеть вердикт чужой стороны.

Справочник по симптомам

Порядок разделов примерно повторяет частоту встречаемости на практике.

Соединение висит, исходящие не уходят вовсе

Что происходит. Двадцать пятый порт закрыт хостером. Это штатное положение дел, а не поломка: Hetzner, к примеру, в своём FAQ прямо сообщает о блокировке портов 25 и 465 по умолчанию на всех облачных серверах. Снять её можно запросом лимита — но не раньше, чем пройдёт месяц обслуживания и будет оплачен первый счёт. Порт 587 при этом свободен.

Как убедиться. Три команды строго в такой последовательности.

# 1. Куда вообще надо стучаться
dig +short MX gmail.com | sort -n | head -1
#    -> 5 gmail-smtp-in.l.google.com.

# 2. Пускают ли нас туда с этого сервера
timeout 10 nc -vz gmail-smtp-in.l.google.com 25 ; echo "код возврата: $?"
#    успех -> "succeeded!" и код 0; блокировка -> таймаут и код 124

# 3. Что застряло в очереди и почему
postqueue -p | tail -20
journalctl -u postfix --since "1 hour ago" | grep -E "status=(bounced|deferred)"

Строка connect to ...[...]:25: Connection timed out на третьем шаге при живом канале указывает именно на блокировку провайдера, а не на кривой конфиг.

Путь первый — добиться открытия порта. Заявка в поддержку на снятие лимита. Условия у всех разные (у Hetzner — месяц обслуживания плюс оплаченный счёт), но схема одинакова. Заодно потребуйте прописать PTR: без обратной записи открытый порт почти бесполезен.

Путь второй — уходить через релей на 587. Официальная конфигурация Postfix под это:

# /etc/postfix/main.cf
smtp_sasl_auth_enable = yes
smtp_tls_security_level = encrypt
smtp_sasl_tls_security_options = noanonymous
relayhost = [mail.isp.example]:submission
smtp_sasl_password_maps = lmdb:/etc/postfix/sasl_passwd
# /etc/postfix/sasl_passwd
# destination                    credentials
[mail.isp.example]:submission    username:password
sudo postmap /etc/postfix/sasl_passwd
sudo chmod 600 /etc/postfix/sasl_passwd*
sudo systemctl reload postfix

⚠️ Осторожно

Плата за второй путь не сразу очевидна. Репутацию перед Gmail и Microsoft набирает релей, а не ваш узел. Хорошая новость: чужая репутация обычно лучше свежей собственной. Плохая: рычагов у вас не остаётся — угодит релей в чёрный список, туда же отправятся и ваши письма. Домашнему серверу с уведомлениями мониторинга такой размен подходит, рабочей переписке — уже сомнительно.

Gmail письмо берёт, но отправляет в спам либо придерживает

Что происходит. Как правило — неполный комплект аутентификации либо превышенный порог жалоб. Google в своих требованиях предельно конкретен: с 1 февраля 2024 года отправляющие более 5000 писем в сутки на адреса Gmail обязаны иметь SPF и DKIM одновременно, настроенный DMARC на отправляющем домене, корректные прямую и обратную DNS-записи, передачу по TLS и односкликовую отписку в рассылках. Длина ключа DKIM для отправки на личные адреса — от 1024 бит. Доля жалоб в Postmaster Tools обязана оставаться ниже 0,3 %, а рекомендуемый запас прочности — ниже 0,1 %.

Начинать надо с кода ответа. Молча Gmail не отказывает — код возвращается всегда, и по нему сразу ясно направление поиска.

# вытащить последние отбойники с текстом ответа принимающей стороны
grep -E "said: (4|5)[0-9]{2}" /var/log/mail.log | tail -20

# или через journald
journalctl -u postfix --since today | grep -oE "said: .*" | sort | uniq -c | sort -rn
Формулировки — из справочника Google Workspace по ошибкам SMTP и из поддержки Microsoft
Формулировки — из справочника Google Workspace по ошибкам SMTP и из поддержки Microsoft

Серия 4xx — временный отказ, письмо будет принято при повторной попытке. Серия 5xx окончательна: доставки не будет и повторов тоже.

Правим SPF. Одна запись типа TXT на корне домена:

example.com.  IN TXT  "v=spf1 mx -all"

Убеждаемся, что она видна и существует в единственном экземпляре:

dig +short TXT example.com | grep spf1

⛔ Так делать нельзя

Вторая запись SPF рядом с первой — прямая дорога к permerror: спецификация трактует набор из нескольких записей как ошибку обработки, и вместо pass вы получите отказ. Обслуживают домен одновременно ваш сервер и внешний сервис рассылок? Тогда всё сводится в единственную строку через include — дублировать запись нельзя.

Есть и вторая мина — исчерпание лимита обращений к DNS. По RFC 7208 механизмов и модификаторов, требующих DNS-запроса, на одну проверку допускается не более десяти; учитываются include, a, mx, ptr, exists, а также модификатор redirect. Пара-тройка вложенных include от больших сервисов выбирает этот бюджет подчистую, после чего результатом снова становится permerror.

Заводим DKIM. Ключ на 2048 бит с пометкой «только для почты»:

sudo mkdir -p /etc/dkimkeys
sudo opendkim-genkey -b 2048 -d example.com -s mail2026 -D /etc/dkimkeys -r
sudo chown opendkim:opendkim /etc/dkimkeys/mail2026.private
sudo chmod 600 /etc/dkimkeys/mail2026.private

На выходе два файла. mail2026.private — то, чем подписываются письма; mail2026.txt — готовая DNS-запись под именем mail2026._domainkey.example.com.

Скелет /etc/opendkim.conf для одного домена:

Domain              example.com
Selector            mail2026
KeyFile             /etc/dkimkeys/mail2026.private
Mode                sv
Canonicalization    relaxed/simple
Socket              inet:8891@127.0.0.1

Стыковка с Postfix:

# /etc/postfix/main.cf
smtpd_milters         = inet:127.0.0.1:8891
non_smtpd_milters     = $smtpd_milters
milter_default_action = accept

Сверка опубликованного публичного ключа с приватным:

sudo opendkim-testkey -d example.com -s mail2026 -k /etc/dkimkeys/mail2026.private -vvv
# ожидаемый финал: "key OK"

✅ Как правильно

Замкнуть цикл проверки можно одной командой — отправляем письмо на свой тестовый ящик и наблюдаем диалог целиком:

swaks --to test-inbox@gmail.com \
      --from postmaster@example.com \
      --server 127.0.0.1 \
      --helo mail.example.com \
      --header "Subject: deliverability check" \
      --body "тест"

Смотрим на код ответа в выводе. 250 2.0.0 OK подтверждает приём письма — но ещё ничего не говорит о том, попало ли оно во «Входящие». Дальше письмо открывается в Gmail через пункт «Показать оригинал», и вся правда обнаруживается в заголовке Authentication-Results.

Разбор заголовка по полям; сам формат описан в RFC 8601
Разбор заголовка по полям; сам формат описан в RFC 8601

Завершающий штрих: домен стоит зарегистрировать в Google Postmaster Tools. Иначе показатель жалоб — тот самый, которому положено держаться ниже 0,3 %, — остаётся для вас невидимым, а правки превращаются в угадайку.

⚠️ Осторожно

Порог в пять тысяч писем часто читают как «меня не касается, я отправляю двадцать штук». Касается. Базовый набор — SPF или DKIM, обратная запись, TLS, соответствие RFC 5322 — Google предъявляет всем без исключения. У массовых отправителей список просто длиннее.

Microsoft возвращает 550 5.7.515

Что происходит. Дословная формулировка Microsoft: 550 5.7.515 Access denied, sending domain <домен> does not meet the required authentication level. Смысл: домен из адреса 5322.From не дотягивает до планки, которую Outlook.com выставил отправителям от 5000 писем в сутки на свои потребительские адреса.

Что требуется. Microsoft называет три условия, выполняться они должны одновременно:

  1. опубликованы SPF и DKIM, причём обе проверки успешны;
  2. опубликована DMARC-запись — минимально хватает v=DMARC1; p=none;
  3. DMARC проходит: SPF и/или DKIM выровнены с доменом в 5322.From.

Спотыкаются обычно на третьем. Выравнивание проверяется прямо по заголовкам полученного письма:

# 1. домен, который видит человек
grep -i "^From:" message.eml

# 2. домен, которым подписан DKIM
grep -i "^DKIM-Signature:" message.eml | grep -oE "d=[^;]+"

# 3. домен конверта, по которому считался SPF
grep -i "smtp.mailfrom" message.eml

Расхождение между d= из второй команды и доменом из первой означает, что DKIM формально успешен, а DMARC — нет. Именно этот случай и порождает 5.7.515 при внешне «настроенном» DKIM.

📌 Заметка

Своя особенность есть и у Microsoft: он ощутимо чувствительнее к репутации подсети целиком, а не одного вашего адреса. Дешёвый VPS в диапазоне, откуда полгода лили спам, будет мешать при любых, даже безупречных подписях. Выданный адрес имеет смысл прогнать по публичным чёрным спискам ещё до оплаты. А когда сервер уже работает — записаться в обе программы обратной связи Microsoft: через SNDS видно статистику по адресу, через JMRP приходят сигналы о том, что кто-то пометил ваше письмо как спам.

Одни письма проходят, другие нет, логики не видно

Что происходит. Кандидатов двое. Первый — SPF, отрабатывающий при прямой отправке и рассыпающийся на пересылке: получатель настроил форвард, письмо приходит уже с чужого адреса, проверка закономерно валится. Второй — когда домен подписи DKIM и домен в From: не сходятся, из-за чего выравнивание DMARC не срабатывает. Второй сценарий особенно любит проявляться, когда часть писем уходит через сторонний сервис от имени сайта.

Снимаем полную картину. Одной пачкой по всему домену:

DOM=example.com
echo "--- MX";      dig +short MX    "$DOM"
echo "--- SPF";     dig +short TXT   "$DOM" | grep spf1
echo "--- DMARC";   dig +short TXT   "_dmarc.$DOM"
echo "--- DKIM";    dig +short TXT   "mail2026._domainkey.$DOM"
echo "--- MTA-STS"; dig +short TXT   "_mta-sts.$DOM"
echo "--- TLS-RPT"; dig +short TXT   "_smtp._tls.$DOM"
echo "--- PTR";     dig +short -x    "$(dig +short A mail.$DOM)"

Отдельно смотрим, каким именем сервер представляется при соединении: значение в HELO, имя из PTR и имя из MX обязаны совпадать.

postconf myhostname smtp_helo_name
openssl s_client -starttls smtp -crlf -connect mail.example.com:25 2>/dev/null | head -5

Что с этим делать. Против SPF, ломающегося на форварде, есть единственный работающий приём — добиться, чтобы DKIM проходил самостоятельно. Подпись остаётся в письме и пересылку переживает, чего не скажешь об SPF. Выровненный хотя бы по DKIM DMARC снимает проблему форварда полностью.

Против рассинхрона доменов: либо подписывать письма тем же доменом, что указан в From:, либо, когда отправкой занят сторонний сервис, настроить у него подпись вашим доменом. Умеют это практически все крупные сервисы — обычно просят опубликовать CNAME на свои селекторы.

DMARC стоит, отчёты идут, подделки продолжаются

Что происходит. Политика p=none ничего не предписывает принимающей стороне — это режим наблюдения. Судя по данным RIPE Labs, на нём и сидит большинство: 58 064 домена публикуют ровно v=DMARC1; p=none;, а в целом больше половины владельцев DMARC-записи не требуют от получателей ничего.

Что вообще можно указать в записи. Реально применяемые теги из RFC 7489:

ТегЗначенияПо умолчаниюЗачем
vDMARC1обязателен, идёт первым
pnone, quarantine, rejectчто делать с непрошедшими
spnone, quarantine, rejectзначение pполитика только для поддоменов
ruaсписок URIкуда слать агрегированные отчёты
rufсписок URIкуда слать отчёты о конкретных сбоях
pct0–100100к какой доле писем применять политику
adkimr, srстрогость выравнивания DKIM
aspfr, srстрогость выравнивания SPF
riсекунды86400как часто присылать агрегированные отчёты

Двигаемся ступенями, а не прыжком:

v=DMARC1; p=none; rua=mailto:dmarc@example.com; pct=100
        v  2-4 недели: собираем отчёты, опознаём все источники
v=DMARC1; p=quarantine; rua=mailto:dmarc@example.com; pct=25
        v  поднимаем pct: 25 -> 50 -> 100, наблюдая за отчётами
v=DMARC1; p=reject; sp=reject; rua=mailto:dmarc@example.com; pct=100

Чтение отчётов. Приезжают они gzip-архивом с XML внутри, глазами такое читать неудобно:

# распаковать и отформатировать
zcat report.xml.gz | xmllint --format - | less

# что интересует в первую очередь: чужие IP, у которых обе проверки провалены
zcat report.xml.gz | xmllint --format - | \
  grep -A4 "<row>" | grep -E "source_ip|count"

По каждому отправлявшему адресу отчёт показывает количество писем и результаты spf и dkim. Знакомые адреса — ваши серверы и легальные сервисы, их надо доводить до ума. Незнакомые с провалом обеих проверок — тот самый спуфинг, ради которого DMARC и придумывали.

⛔ Так делать нельзя

Выставлять p=reject сразу, не заглянув в отчёты, нельзя. Вы почти наверняка не держите в голове все системы, отправляющие письма от вашего домена: биллинг, форма обратной связи, мониторинг, забытый скрипт на соседней машине. Отбиваться они начнут в тот же час, а узнаете вы об этом от людей, а не из журналов.

Отдельная оговорка про pct: этот тег управляет применением политики, а не объёмом отчётности. Сочетание pct=25 с p=quarantine отправит в спам лишь каждое четвёртое непрошедшее письмо — но проверять будут все.

Почта ходит, но открытым текстом

Что происходит. STARTTLS выключен или предлагается, но не задействуется. С декабря 2023 года Google требует TLS от всех отправителей, так что графа «желательно» здесь закрыта.

Как проверить.

# предлагает ли ваш сервер STARTTLS входящим
openssl s_client -starttls smtp -crlf -connect mail.example.com:25 2>&1 | \
  grep -E "Verify return code|subject=|Protocol"

Как включить. Минимум по строке на каждое направление, ровно как в официальном TLS_README:

# /etc/postfix/main.cf
smtpd_tls_security_level = may
smtpd_tls_cert_file      = /etc/letsencrypt/live/mail.example.com/fullchain.pem
smtpd_tls_key_file       = /etc/letsencrypt/live/mail.example.com/privkey.pem
smtp_tls_security_level  = may
smtp_tls_loglevel        = 1

Слоем выше стоит MTA-STS: он лишает отправителя возможности откатиться на соединение без шифрования. Собирается из TXT-записи в DNS и текстового файла политики, который отдаётся вашим веб-сервером по HTTPS.

_mta-sts.example.com.  IN TXT  "v=STSv1; id=20260819120000Z;"
# https://mta-sts.example.com/.well-known/mta-sts.txt
# отдавать с Content-Type: text/plain
version: STSv1
mode: enforce
mx: mail.example.com
max_age: 604800

Плюс запись TLS-RPT, по которой вам будут приходить сводки о неудачных попытках шифрования:

_smtp._tls.example.com.  IN TXT  "v=TLSRPTv1;rua=mailto:tlsrpt@example.com"

⚠️ Осторожно

Последовательность здесь принципиальна. Держите mode: testing, пока отчёты TLS-RPT не подтвердят, что всё сходится. Опечатка в списке mx вместе с mode: enforce приведёт к тому, что соблюдающие MTA-STS отправители вообще откажутся вам писать, а max_age: 604800 означает, что помнить эту политику они будут неделю. При каждой правке политики меняйте id, иначе кэш не обновится.

Стартовый комплект

Схема на основе данных RIPE Labs и OpenINTEL, срез Tranco top-1M от 18 июля 2026
Схема на основе данных RIPE Labs и OpenINTEL, срез Tranco top-1M от 18 июля 2026

✅ Как правильно

  1. Проверить, что хостер отдаёт исходящий 25-й порт и пропишет PTR на ваш домен. Без обратной записи остальное теряет смысл.
  2. Поднять MX и A/AAAA, добиться совпадения имени в PTR, имени в MX и представления сервера в HELO.
  3. SPF: перечислить источники, закрыть строку жёстким -all (не ~all) и не выйти за десять DNS-обращений.
  4. DKIM с ключом не короче 1024 бит, а лучше 2048; сверить через opendkim-testkey.
  5. DMARC в режиме p=none с работающим rua=, две-три недели чтения отчётов, ужесточение позже.
  6. Шифрование включить в обе стороны, следом добавить TLS-RPT и MTA-STS, начиная с режима testing.
  7. Отправить пробное письмо утилитой swaks в оба тестовых ящика и разобрать Authentication-Results в каждом.

🔒 Безопасность

Пункт, о котором вспоминают последним: ящики abuse@ и postmaster@ обязаны существовать и читаться живым человеком. Это не ритуал из RFC — именно туда приходит уведомление о том, что с вашего адреса пошёл спам, и именно тишина в ответ переводит домен из категории «разбираются» в категорию «блокируем».

Вывод, который следует из цифр

Исследование RIPE Labs не призывает отказаться от собственного почтового сервера. Оно фиксирует другое: за десятилетие планка требований к отправителю поднялась настолько, что половина владельцев доменов предпочла отдать эту работу наружу, а из настроивших DMARC больше половины так и не решились его включить.

Есть время читать отчёты и следить за репутацией — свой сервер работает нормально. Поднят по принципу «настроил и забыл» — письма начнут пропадать не завтра, а через несколько месяцев, и восстановить момент поломки будет уже трудно.

💬 Вопрос к сообществу

У кого сейчас крутится собственный почтовый узел — сколько времени в месяц он съедает и какой сбой доставляемости оказался самым неочевидным? И вопрос к тем, кто съехал на Google или Microsoft: что стало последней каплей?


Источники

Featured Replies

No posts to show

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.
Примечание: Ваш пост будет проверен модератором, прежде чем станет видимым.

Гость
К сожалению, ваш контент содержит запрещённые слова. Пожалуйста, отредактируйте контент, чтобы удалить выделенные ниже слова.
Ответить в этой теме...

Последние посетители 0

  • Ни одного зарегистрированного пользователя не просматривает данную страницу
Яндекс.Метрика

Account

Navigation

Поиск

Поиск

Configure browser push notifications

Chrome (Android)
  1. Tap the lock icon next to the address bar.
  2. Tap Permissions → Notifications.
  3. Adjust your preference.
Chrome (Desktop)
  1. Click the padlock icon in the address bar.
  2. Select Site settings.
  3. Find Notifications and adjust your preference.