Postfix + Rspamd: как мы вытащили письма из спама для маркетингового агентства «МаркетМейл»

Ситуация: 70% писем уходит в спам

Маркетинговое агентство «МаркетМейл» обратилось к нам в itfresh.ru с критической проблемой: их email-рассылки практически не доходят до клиентов. Из 5000 писем в день — 70% попадает в спам у Gmail, 50% у Mail.ru, 40% у Yandex.

Исходная инфраструктура:

  • VPS на Hetzner (новый IP, без истории)
  • Postfix — установлен из пакетов, конфигурация по умолчанию
  • DNS — есть MX-запись, но нет SPF, DKIM и DMARC
  • Рассылка — 5000 писем/день через один IP без warm-up
  • Антиспам — отсутствует (ни входящий, ни исходящий контроль)

Диагностика через mail-tester.com показала оценку 2.1/10. Основные проблемы:

  1. ❌ SPF: отсутствует
  2. ❌ DKIM: письма не подписаны
  3. ❌ DMARC: отсутствует
  4. ❌ IP 65.x.x.x в 3 чёрных списках (Spamhaus SBL, SORBS, Barracuda)
  5. ❌ Нет reverse DNS (PTR)
  6. ⚠️ HTML без text/plain альтернативы
  7. ⚠️ Отсутствует List-Unsubscribe заголовок

SPF, DKIM и DMARC: базовая аутентификация email

Три технологии аутентификации — абсолютный минимум для доставляемости. Без них письма автоматически получают штрафные баллы у всех почтовых провайдеров.

SPF (Sender Policy Framework) — DNS-запись, указывающая, какие серверы имеют право отправлять почту от имени домена:

# DNS TXT-запись для marketmail.ru
marketmail.ru.  IN  TXT  "v=spf1 ip4:65.21.xxx.xxx ip4:65.21.xxx.yyy include:_spf.google.com ~all"

# Разбор:
# v=spf1          — версия SPF
# ip4:65.21.x.x   — IP нашего почтового сервера
# include:...      — доверяем Google (если используется Gmail для корпоративной почты)
# ~all             — soft fail для остальных (рекомендуется на старте)
# Позже меняем на -all (hard fail) после проверки, что всё работает

DKIM (DomainKeys Identified Mail) — цифровая подпись каждого письма. Настраиваем через Rspamd (подробнее в следующем разделе):

# Генерация DKIM-ключа
sudo mkdir -p /var/lib/rspamd/dkim
sudo rspamadm dkim_keygen -s mail2026 -d marketmail.ru -b 2048 \
  -k /var/lib/rspamd/dkim/marketmail.ru.mail2026.key

# Команда выдаёт DNS-запись, которую нужно добавить:
# mail2026._domainkey.marketmail.ru. IN TXT (
#   "v=DKIM1; k=rsa; p=MIIBIjANBgkqhki..."
# )

# Права на ключ
sudo chown _rspamd:_rspamd /var/lib/rspamd/dkim/marketmail.ru.mail2026.key
sudo chmod 600 /var/lib/rspamd/dkim/marketmail.ru.mail2026.key

DMARC (Domain-based Message Authentication, Reporting & Conformance) — политика, указывающая получателям, что делать с письмами, не прошедшими SPF/DKIM:

# DNS TXT-запись DMARC
_dmarc.marketmail.ru.  IN  TXT  "v=DMARC1; p=none; rua=mailto:dmarc@marketmail.ru; ruf=mailto:dmarc-forensic@marketmail.ru; fo=1; adkim=r; aspf=r; pct=100"

# Разбор:
# p=none     — на старте только мониторинг (не блокировать)
# rua=       — агрегированные отчёты (XML, раз в день)
# ruf=       — forensic-отчёты (каждое подозрительное письмо)
# fo=1       — отправлять forensic при любом fail
# pct=100    — политика для 100% писем

# Через 2 недели мониторинга (убедившись, что всё корректно):
# p=quarantine — помечать подозрительные как спам
# Через месяц:
# p=reject — отклонять полностью

PTR-запись (Reverse DNS) — обязательна. IP-адрес должен резолвиться обратно в hostname сервера:

# Проверка текущей PTR
dig -x 65.21.xxx.xxx +short
# Должно вернуть: mail.marketmail.ru

# PTR настраивается у хостинг-провайдера (Hetzner Robot → Servers → IP → rDNS)
# Значение: mail.marketmail.ru

# Проверка прямого и обратного соответствия:
dig mail.marketmail.ru A +short       # 65.21.xxx.xxx
dig -x 65.21.xxx.xxx +short           # mail.marketmail.ru
# Оба должны совпадать!

Rspamd: интеграция с Postfix и настройка

Rspamd — современный антиспам-фильтр, заменяющий SpamAssassin. Быстрее в 10 раз, написан на C, имеет web-интерфейс и встроенную DKIM-подпись.

# Установка Rspamd на Rocky Linux 9
sudo dnf install -y rspamd redis
sudo systemctl enable --now redis rspamd

# Интеграция с Postfix через milter-протокол
# /etc/postfix/main.cf — добавляем:
smtpd_milters = inet:127.0.0.1:11332
non_smtpd_milters = inet:127.0.0.1:11332
milter_protocol = 6
milter_mail_macros = i {mail_addr} {client_addr} {client_name} {auth_authen}
milter_default_action = accept

Настройка DKIM-подписи исходящих писем:

# /etc/rspamd/local.d/dkim_signing.conf
enabled = true;

# Путь к ключам: /var/lib/rspamd/dkim/..key
path = "/var/lib/rspamd/dkim/$domain.$selector.key";
selector = "mail2026";

# Подписываем все домены, для которых есть ключ
try_fallback = true;
use_domain = "header";
use_redis = false;
allow_hdrfrom_mismatch = false;
allow_username_mismatch = false;
sign_authenticated = true;
sign_local = true;

Настройка RBL (Real-time Blackhole Lists) — проверка IP отправителя по чёрным спискам:

# /etc/rspamd/local.d/rbl.conf
# Стандартные RBL включены по умолчанию, добавляем дополнительные:
rbls {
  spamhaus_sbl {
    symbol = "RBL_SPAMHAUS_SBL";
    rbl = "sbl.spamhaus.org";
    returncodes {
      RBL_SPAMHAUS_SBL = "127.0.0.2";
      RBL_SPAMHAUS_CSS = "127.0.0.3";
    }
  }
  barracuda {
    symbol = "RBL_BARRACUDA";
    rbl = "b.barracudacentral.org";
  }
}

Greylisting — временный отказ для новых отправителей (спамеры обычно не повторяют):

# /etc/rspamd/local.d/greylist.conf
enabled = true;
timeout = 300;        # 5 минут задержка
expire = 86400;       # помним отправителя 24 часа
whitelist_symbols = ["WHITELIST_DKIM", "WHITELIST_SPF_DKIM"];

# Белый список — крупные провайдеры не грейлистятся
whitelist_domains_url = [
  "https://maps.rspamd.com/freemail/free.txt.zst"
];

Postfix: rate limiting, bounce handling и заголовки

Postfix — основа почтовой инфраструктуры. Мы полностью переписали конфигурацию для оптимальной доставляемости.

Rate limiting — ограничение скорости отправки, чтобы не попасть в rate-limit крупных провайдеров:

# /etc/postfix/main.cf

# Общий rate limit: не более 50 писем в минуту
smtpd_client_message_rate_limit = 50
default_destination_rate_delay = 2s

# Ограничения для конкретных доменов (transport maps)
transport_maps = hash:/etc/postfix/transport

# /etc/postfix/transport
gmail.com       smtp-gmail:
mail.ru         smtp-mailru:
yandex.ru       smtp-yandex:
ya.ru           smtp-yandex:

# /etc/postfix/master.cf — отдельные транспорты с rate limits
smtp-gmail unix - - n - 2 smtp
  -o smtp_destination_rate_delay=5s
  -o smtp_destination_concurrency_limit=2
  -o smtp_extra_mime_headers=

smtp-mailru unix - - n - 3 smtp
  -o smtp_destination_rate_delay=3s
  -o smtp_destination_concurrency_limit=3

smtp-yandex unix - - n - 3 smtp
  -o smtp_destination_rate_delay=3s
  -o smtp_destination_concurrency_limit=3

Bounce handling — обработка возвратов:

# /etc/postfix/main.cf

# Максимальное время попытки доставки
maximal_queue_lifetime = 3d      # hard bounce через 3 дня
bounce_queue_lifetime = 3d
delay_warning_time = 4h          # предупреждение через 4 часа

# Bounce notification
notify_classes = bounce, delay, policy, protocol, resource, software
bounce_notice_recipient = postmaster@marketmail.ru

# Header checks — удаляем лишнюю информацию из заголовков
header_checks = regexp:/etc/postfix/header_checks

# /etc/postfix/header_checks
/^Received:.*127\.0\.0\.1/    IGNORE
/^X-Mailer:/                  IGNORE
/^User-Agent:/                IGNORE
/^X-Originating-IP:/          IGNORE

Обязательные заголовки для рассылок:

# В приложении рассылки (Python/PHP) обязательно добавляем:
List-Unsubscribe: , 
List-Unsubscribe-Post: List-Unsubscribe=One-Click
Precedence: bulk
Feedback-ID: campaign123:marketmail.ru

# MIME: всегда отправляем multipart/alternative с text/plain
Content-Type: multipart/alternative;
  -- text/plain (обязательно!)
  -- text/html

List-Unsubscribe-Post — новое требование Gmail с февраля 2024. Без него массовые рассылки (>5000/день) автоматически блокируются.

IP reputation и мониторинг через Google Postmaster Tools

IP reputation — ключевой фактор доставляемости. Новый IP без истории по умолчанию не доверенный, а IP из чёрных списков — практически заблокирован.

Шаг 1: Делистинг из чёрных списков.

# Проверка IP во всех основных RBL
# Используем mxtoolbox.com или командную строку:
for rbl in sbl.spamhaus.org bl.spamcop.net b.barracudacentral.org \
  dnsbl.sorbs.net zen.spamhaus.org; do
  result=$(dig +short $( echo 65.21.xxx.xxx | awk -F. '{print $4"."$3"."$2"."$1}').$rbl)
  if [ -n "$result" ]; then
    echo "LISTED in $rbl: $result"
  else
    echo "clean: $rbl"
  fi
done

# Процесс делистинга:
# Spamhaus: https://check.spamhaus.org/ → Request Removal
# Barracuda: https://www.barracudacentral.org/lookups → Request Removal
# SORBS: https://www.sorbs.net/cgi-bin/db → Request Delisting

Шаг 2: Google Postmaster Tools — обязательный инструмент для мониторинга доставляемости в Gmail:

# 1. Зарегистрироваться на https://postmaster.google.com/
# 2. Добавить домен marketmail.ru
# 3. Подтвердить владение через DNS TXT-запись:
# google-site-verification=XXXXXXXXXXXXXXXXX

# Google Postmaster показывает:
# - Domain reputation (High/Medium/Low/Bad)
# - IP reputation
# - Spam rate (должен быть < 0.1%)
# - Authentication (SPF/DKIM/DMARC pass rate)
# - Encryption (TLS usage)
# - Delivery errors

Шаг 3: Feedback loops — подписка на уведомления о жалобах:

# Mail.ru FBL: https://postmaster.mail.ru/ → Feedback Loop
# Yahoo FBL: подписка через Complaint Feedback Loop
# Microsoft SNDS: https://sendersupport.olc.protection.outlook.com/snds/

# Обработка FBL в Postfix — скрипт для автоматического удаления жалобщиков:
#!/bin/bash
# process_fbl.sh — парсит ARF-отчёты и удаляет email из базы рассылки
while read line; do
  email=$(echo "$line" | grep -oP 'Original-Rcpt-To: \K.*')
  if [ -n "$email" ]; then
    echo "Unsubscribing $email due to spam complaint"
    curl -X POST "https://api.marketmail.ru/unsubscribe" \
      -d "email=$email&reason=fbl_complaint"
  fi
done < /var/spool/fbl/incoming

Warm-up: постепенное наращивание объёма

Нельзя отправлять 5000 писем/день с нового IP — это гарантированный путь в спам. Warm-up — постепенное наращивание объёма в течение 4-6 недель.

Наш график warm-up для «МаркетМейл»:

НеделяПисем/деньЦелевая аудитория
150-100Самые активные подписчики (открывали последние 3 письма)
2200-500Активные (открывали хотя бы 1 из 5 последних)
3500-1000Умеренно активные
41000-2500Все, кроме неактивных >90 дней
52500-5000Вся база, кроме заведомо мёртвых
6+5000+Полный объём
# warm-up-scheduler.py — автоматический контроль объёма
import datetime
import redis

r = redis.Redis()

WARMUP_SCHEDULE = {
    1: 100,
    2: 500,
    3: 1000,
    4: 2500,
    5: 5000,
}

def get_daily_limit():
    start_date = datetime.date(2026, 4, 1)  # дата начала warm-up
    week = (datetime.date.today() - start_date).days // 7 + 1
    return WARMUP_SCHEDULE.get(week, 10000)  # после 5 недели — полный объём

def can_send():
    today = datetime.date.today().isoformat()
    sent_count = int(r.get(f'sent:{today}') or 0)
    limit = get_daily_limit()
    if sent_count >= limit:
        return False, f'Limit reached: {sent_count}/{limit}'
    r.incr(f'sent:{today}')
    r.expire(f'sent:{today}', 86400 * 2)
    return True, f'OK: {sent_count + 1}/{limit}'

Критически важные правила warm-up:

  • Начинать с самых лояльных — подписчики, которые открывают и кликают. Высокий engagement = позитивные сигналы для почтовых провайдеров
  • Мониторить bounce rate — если bounce > 3%, остановить и почистить базу
  • Мониторить spam complaints — если > 0.1%, остановить и пересмотреть контент
  • Не превышать лимиты провайдеров: Gmail — 500/час для нового IP, Mail.ru — 300/час

Тестирование доставляемости

Перед каждой рассылкой мы проверяем доставляемость тестовым письмом:

# Тест через mail-tester.com
# 1. Заходим на https://www.mail-tester.com/
# 2. Получаем адрес вида test-xxx@srv1.mail-tester.com
# 3. Отправляем тестовое письмо
echo "Test email for deliverability check" | mail -s "Test $(date)" \
  test-xxx@srv1.mail-tester.com
# 4. Проверяем результат на сайте (оценка 1-10)

# Автоматическая проверка через скрипт:
#!/bin/bash
# check_deliverability.sh
set -e

# Проверяем SPF
SPF=$(dig TXT marketmail.ru +short | grep spf)
[ -z "$SPF" ] && echo "FAIL: SPF record missing" && exit 1
echo "OK: SPF = $SPF"

# Проверяем DKIM
DKIM=$(dig TXT mail2026._domainkey.marketmail.ru +short)
[ -z "$DKIM" ] && echo "FAIL: DKIM record missing" && exit 1
echo "OK: DKIM selector found"

# Проверяем DMARC
DMARC=$(dig TXT _dmarc.marketmail.ru +short)
[ -z "$DMARC" ] && echo "FAIL: DMARC record missing" && exit 1
echo "OK: DMARC = $DMARC"

# Проверяем PTR
PTR=$(dig -x 65.21.xxx.xxx +short)
[ -z "$PTR" ] && echo "FAIL: PTR record missing" && exit 1
echo "OK: PTR = $PTR"

# Проверяем RBL
REVERSE=$(echo 65.21.xxx.xxx | awk -F. '{print $4"."$3"."$2"."$1}')
for rbl in sbl.spamhaus.org bl.spamcop.net; do
  result=$(dig +short $REVERSE.$rbl)
  if [ -n "$result" ]; then
    echo "FAIL: Listed in $rbl"
    exit 1
  fi
done
echo "OK: Not listed in any RBL"

echo "All checks passed!"

Результаты и выводы

Через 6 недель работы (включая warm-up) для «МаркетМейл»:

МетрикаДоПосле
Оценка mail-tester.com2.1/109.4/10
Inbox rate Gmail~30%92%
Inbox rate Mail.ru~50%95%
Inbox rate Yandex~60%97%
SPF/DKIM/DMARC pass rate0%100%
Чёрные списки (RBL)30
Open rate рассылки8%24%
Spam complaint rateне отслеживался0.04%

Email deliverability — это не разовая настройка, а постоянный процесс. SPF/DKIM/DMARC — базовый фундамент, без которого не стоит даже начинать. Но даже с идеальной технической настройкой плохой контент или грязная база подписчиков отправят вас в спам. Ключевой показатель: spam complaint rate должен быть ниже 0.1% — это требование Google для отправителей более 5000 писем/день. Если ваши письма попадают в спам — обращайтесь к нам в itfresh.ru.

Часто задаваемые вопросы

Да. С февраля 2024 Google и Yahoo требуют DMARC для отправителей более 5000 писем в день. Даже для малых объёмов DMARC с p=none даёт ценные отчёты о том, кто отправляет почту от имени вашего домена. Настройка занимает 5 минут — одна DNS-запись.
Rspamd — в большинстве случаев. Он в 10 раз быстрее (написан на C, а не Perl), имеет встроенную DKIM-подпись, Redis-интеграцию, web-интерфейс и Lua-скриптинг для кастомных правил. SpamAssassin оправдан только если у вас уже есть множество кастомных правил, которые сложно мигрировать.
Минимум 4 недели для объёмов до 5000 писем/день, 6-8 недель для 10 000+. Ускорить нельзя — попытка отправить большой объём с нового IP немедленно испортит репутацию. Исключение: если вы мигрируете с другого IP и можете попросить почтовых провайдеров перенести репутацию (Google поддерживает это для крупных отправителей).
Три способа: 1) проверка через mxtoolbox.com/blacklists.aspx — сканирует 80+ RBL; 2) мониторинг через Google Postmaster Tools — показывает reputation drop; 3) автоматическая проверка скриптом через DNS-запросы к основным RBL (Spamhaus, Barracuda, SORBS). Рекомендуем настроить ежедневную автоматическую проверку с Telegram-уведомлением.
Настоятельно рекомендуем. Транзакционные письма (подтверждения заказов, сброс пароля) должны доставляться мгновенно. Если маркетинговые рассылки испортят репутацию IP — транзакционные тоже пострадают. Два IP с раздельной репутацией — страховка от взаимного влияния. В Postfix это настраивается через sender_dependent_default_transport_maps.

Нужна помощь с проектом?

Специалисты АйТи Фреш помогут с архитектурой, DevOps, безопасностью и разработкой — 15+ лет опыта

📞 Связаться с нами
#Postfix#Rspamd#SPF#DKIM#DMARC#email deliverability#антиспам#IP reputation
Комментарии 0

Оставить комментарий

загрузка...