Почтовый сервер
Панель умеет отправлять письма сама: прямая доставка на MX получателя, подпись DKIM, приём входящих. Внешний SMTP-провайдер не нужен — но и ответственность за репутацию домена ложится на вас.
Включение
Настройки → Почтовый сервер → «Почтовый сервер включён», затем перезапуск контейнера. Либо через .env:
MAIL_SERVER_ENABLED=true
MAIL_INBOUND_PORT=2525
MAIL_SERVER_HOSTNAME=0.0.0.0Переменные здесь — запасной вариант: всё то же самое настраивается из интерфейса.
Домен
- Mail Server → Domains → Add Domain
- Ввести домен, например
example.com - Ключи DKIM (RSA-2048) сгенерируются сами
Дальше кнопка DNS Records покажет, что прописать у DNS-провайдера:
| Тип | Хост | Зачем |
|---|---|---|
| A | mail.example.com | адрес почтового сервера |
| MX | example.com | куда приходит входящая почта |
| TXT | example.com | SPF — кому разрешено слать от имени домена |
| TXT | rw._domainkey.example.com | DKIM — открытый ключ подписи |
| TXT | _dmarc.example.com | DMARC — что делать с неподписанными письмами |
| PTR | IP сервера | обратная зона, настраивается у хостера |
После добавления — кнопка Check DNS.
Чужие MX забирают вашу почту молча
Проверка сверяет, куда ведёт MX-запись, а не только её наличие. Если домен переехал от прежнего хостера, его MX часто остаются в зоне и продолжают принимать всю входящую почту: отправители получают отказ вроде 550 Disabled, а панель ничего об этом не знает. Удалите чужие MX перед добавлением своей.
Порты
25 — исходящий: прямая доставка на MX получателей
2525 — входящий: приём писем
587 — SMTP submissionВ docker-compose.yml входящий порт публикуется как обычный 25-й:
ports:
- "25:2525"Порт 25 у облачных провайдеров
AWS, GCP и Azure блокируют исходящий 25-й порт. Для почты берите VPS у провайдера, который этого не делает — Hetzner, OVH, DigitalOcean.
За reverse proxy идёт только HTTP API (/api/v2/mailserver/*). SMTP через HTTP-прокси не пробросить — это другой уровень: либо публикуйте порт мимо прокси, либо настраивайте stream {} в nginx или caddy-l4.
Отправка через Brevo
Если хостер режет исходящие 25 и 587, письма можно отдавать через HTTP API Brevo (ex-Sendinblue): трафик идёт по HTTPS, DKIM-подпись и доставка до MX получателя — на стороне Brevo.
- В Brevo: Senders & IP → Domains — добавить и подтвердить домен отправителя (их DKIM/DMARC-записи), SMTP & API → API Keys — создать ключ v3.
- В админке: Настройки → Почтовый сервер: «Доставка исходящих» =
brevo, «Brevo: API-ключ» = ключ (илиMAIL_DELIVERY_MODE=brevoиBREVO_API_KEY=…в.env). Домен в разделе «Почтовый сервер» остаётся — от него берутся адрес и имя отправителя. - Очередь, лимиты, вложения и заголовки ветки переписки работают как прежде; собственный DKIM и MX получателя в этом режиме не используются. Исходящий 25-й порт не нужен; приём писем (2525) и SMTP submission (587) от режима не зависят.
Ошибки API (неверный ключ, неподтверждённый домен) видны в очереди как причина неотправки.
Шифрование
На обоих почтовых портах поднимается STARTTLS:
MAIL_TLS_CERT_PATH=/app/certs/fullchain.pem
MAIL_TLS_KEY_PATH=/app/certs/privkey.pemБез указанного пути выписывается самоподписанный сертификат в том mail_certs. Для приёма почты этого хватает: чужие серверы шифруют соединение, не проверяя сертификат. А вот на 587 клиенты будут ругаться — туда лучше положить настоящий, например смонтировать сертификат reverse proxy.
Пароль до появления сертификата
Пока сертификата нет, настройка «Требовать TLS на порту 587» не действует, и логин с паролем уходят по незашифрованному соединению. AUTH PLAIN — это base64, а не шифрование. При старте об этом есть предупреждение в логах.
Входящие письма
Каждое письмо проходит SPF, DKIM и DMARC, результат виден в списке и в карточке. Набравшие порог помечаются подозрительными и в общий список не попадают — для них отдельный фильтр.
Настройка «Отклонять подозрительные письма» заставляет отказывать прямо на приёме: тогда настоящий отправитель хотя бы получит уведомление о недоставке вместо тишины.
Стоп-лист
Адреса, которым письма больше не уходят. Наполняется сам:
- жёсткий отказ доставки (
5.x.x) — адрес закрывается насовсем - мягкий (
4.x.x, переполненный ящик) — на неделю - письмо на
unsubscribe@<домен>— адрес берётся из заголовкаList-Unsubscribe, который панель ставит в каждое письмо
Это не только вежливость: настойчивая отправка в несуществующие ящики портит репутацию домена целиком, и следом начинают теряться письма живым адресатам. Снять запрет можно вручную на вкладке Стоп-лист.
DMARC-отчёты
Почтовые системы раз в сутки присылают сводку на адрес из записи _dmarc: кто слал письма от имени домена и прошли ли они проверку. Панель распаковывает вложение (.gz, .zip), разбирает XML и показывает результат на вкладке DMARC. В разделе «Отправители без подписи» видно и чужой спуфинг, и собственный сервис, забывший про DKIM.
Хранение
Входящие по умолчанию хранятся бессрочно, история отправки — 90 дней; письма, ожидающие отправки, не удаляются. Меняется в настройках, 0 означает «без ограничения».
Проверка
- Активировать домен → Compose → Send Test → посмотреть очередь, статус должен стать
sent - Если активный домен есть, система уведомлений начинает пользоваться встроенным сервером сама, с откатом на внешний SMTP-relay