Postfix: NOQUEUE reject в логе — как читать и исправлять
Открываете /var/log/mail.log, а там строка на полтора метра шириной: NOQUEUE: reject: RCPT from unknown[203.0.113.5]: 554 5.7.1 <...>: Relay access denied. Выглядит как заклинание, но на самом деле это структурированная запись, где каждое слово несёт смысл. Если научиться читать такие строки, 90% вопросов «почему письмо не дошло» и «кого мой сервер заблокировал» решаются за минуту без гугления. Разберём формат построчно, на реальных примерах.
Содержание
- Что вообще такое лог Postfix и где он лежит
- Анатомия строки: разбираем NOQUEUE reject по частям
- Коды ответа: что означают 5.7.1, 4.7.1 и соседи
- Где смотреть полный лог и как вытащить контекст вокруг строки
- Как отличить легитимный отказ спамеру от ошибочной блокировки своего клиента
- Практический grep для поиска повторяющихся отказов
Обсудить статью, задать вопрос или начать новую тему
Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.
Перейти в сообщество →Что вообще такое лог Postfix и где он лежит
Postfix пишет всё через syslog, а не в собственный файл — это важно понимать, потому что путь к логу зависит от дистрибутива и настройки syslog-демона:
- Debian/Ubuntu (rsyslog по умолчанию) —
/var/log/mail.log. На части свежих установок Ubuntu rsyslog может быть не настроен вовсе, и почтовые записи будут только вjournalctl. - CentOS/RHEL/AlmaLinux —
/var/log/maillog. - Если файла нет вообще — смотрите systemd journal:
journalctl -u postfix -f
Живой мониторинг лога — первая команда, которую стоит запомнить:
tail -f /var/log/mail.log
-f держит файл открытым и печатает новые строки по мере поступления — удобно, когда вы одновременно шлёте тестовое письмо и смотрите, что происходит. Для истории за прошлые дни на Ubuntu/Debian логи ротируются logrotate и старые копии лежат сжатыми: mail.log.1, mail.log.2.gz и так далее — их читают через zcat mail.log.2.gz | grep ....
Каждая строка лога Postfix — это одно события одного процесса. У почтового сервера таких процессов несколько (smtpd принимает входящие соединения, smtp отправляет исходящие, cleanup, qmgr, local и другие), и в логе они перемешаны — письма идут параллельно. Разбираемый в этой статье случай — это события процесса smtpd, то есть кто-то пытается отправить письмо вашему серверу, и Postfix отказывает ещё на входе.
Анатомия строки: разбираем NOQUEUE reject по частям
Возьмём реальный пример и пройдёмся по нему слово за словом:
Aug 29 14:02:11 mail postfix/smtpd[18421]: NOQUEUE: reject: RCPT from unknown[203.0.113.5]: 554 5.7.1 <user@yourdomain.com>: Relay access denied; from=<spammer@evil-domain.net> to=<user@yourdomain.com> proto=ESMTP helo=<evil-domain.net>
Разбор по кусочкам:
| Фрагмент | Что значит |
|---|---|
Aug 29 14:02:11 | Дата и время события на сервере (локальное время системы) |
mail | Имя хоста (hostname), на котором работает Postfix |
postfix/smtpd[18421] | Компонент Postfix (smtpd — демон приёма SMTP-соединений) и PID процесса — по нему можно вытащить все строки именно этого соединения |
NOQUEUE | Письму не присвоен ID очереди — оно отклонено до того, как Postfix успел его принять на обработку. Это самый ранний момент отказа, ещё до записи на диск |
reject | Тип события — явный отказ (в отличие от warning, error или благополучного sent) |
RCPT from unknown[203.0.113.5] | На каком этапе SMTP-диалога случился отказ (команда RCPT TO) и IP-адрес отправителя. unknown вместо имени хоста означает, что PTR-запись (обратный DNS) для этого IP не резолвится |
554 5.7.1 | SMTP-код ответа — расшифровка ниже |
<user@yourdomain.com> | Адрес получателя, на который шло письмо (именно тот, что указан в команде RCPT TO) |
Relay access denied | Человекочитаемая причина отказа — конкретный текст зависит от того, какое правило сработало |
from=<spammer@evil-domain.net> | Адрес отправителя из конверта (envelope from, команда MAIL FROM) — не путать с тем, что написано в заголовке From: письма, они могут отличаться |
to=<user@yourdomain.com> | Дублирует получателя из RCPT — для удобства grep |
proto=ESMTP | Протокол сессии |
helo=<evil-domain.net> | Имя хоста, которое отправитель назвал в команде HELO/EHLO — может быть любым, отправитель вписывает что хочет |
Если письмо было принято и поставлено в очередь, вместо NOQUEUE вы увидите шестнадцатеричный ID вроде 4B2F1C3A9, и дальнейшая судьба письма (доставлено, отложено, отброшено) будет прослеживаться по этому ID через несколько строк лога дальше. NOQUEUE — это признак того, что до этого этапа дело не дошло: Postfix отказал ещё во время SMTP-диалога, не потратив место на диске.
Нужен сервер под эту задачу?
Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.
Арендовать VPSКоды ответа: что означают 5.7.1, 4.7.1 и соседи
SMTP-код в логе — это стандартный расширенный код статуса из RFC 3463, он состоит из трёх чисел через точку: класс.подкласс.детали.
Первая цифра — класс ответа:
2xx— успех (в reject-логах не встречается по определению)4xx— временная ошибка (soft bounce). Отправляющий сервер должен повторить попытку позже. В логе выглядит как450или4215xx— постоянная ошибка (hard bounce). Отправитель получает окончательный отказ, повторных попыток от совместимого сервера не будет. В логе это550,554,553
Средняя цифра — подкласс (общая категория проблемы):
.1— проблемы с адресацией (адрес не существует, домен не принимает почту, релей запрещён).2— проблемы с почтовым ящиком (переполнен, недоступен).7— проблемы безопасности/политики (спам-фильтры, RBL-блэклисты, отсутствие SPF/PTR, требования аутентификации)
Разберём частые сочетания, которые встретятся именно в NOQUEUE:
554 5.7.1 Relay access denied— сервер отказался пересылать письмо на чужой домен от неавторизованного отправителя. Подробный разбор причин и настройкиmynetworks/SASL — в отдельной статье про Relay access denied.450 4.7.1 Client host rejected: cannot find your reverse hostname— временный отказ из-за отсутствия PTR-записи у отправителя. Часто это ваш собственный клиент шлёт с сервера без настроенного обратного DNS.554 5.7.1 Service unavailable; Client host [IP] blocked using zen.spamhaus.org— IP отправителя в блэклисте Spamhaus.550 5.1.1 <user@domain>: Recipient address rejected: User unknown— получателя с таким адресом не существует на сервере.450 4.2.0 <user@domain>: Recipient address rejected: Greylisted— временная greylisting-задержка: не блокировка, а требование прислать письмо ещё раз чуть позже (легитимные серверы делают это автоматически).
Класс 4xx в контексте reject (не warning) значит: Postfix попросил отправителя повторить позже, письмо не потеряно окончательно — если это легитимный сервер, он попробует снова в течение нескольких часов или дней согласно своей политике retry.
Где смотреть полный лог и как вытащить контекст вокруг строки
Одной строки reject часто недостаточно — полезно увидеть, что происходило в этом же SMTP-соединении до и после отказа (например, сколько команд RCPT TO перебрал отправитель — это явный признак сканирования адресов). PID процесса в квадратных скобках — ваш ключ:
grep '18421' /var/log/mail.log
Это выведет все строки именно этого TCP-соединения от установки до разрыва. Если нужно посмотреть на события чуть шире — по времени:
grep '14:0[0-5]' /var/log/mail.log | grep smtpd
Полезно также включить более подробное логирование правил smtpd_recipient_restrictions на время отладки — это добавляет в лог, какое именно правило (какая строка в main.cf) сработала:
postconf -e smtpd_recipient_restrictions
выведет текущий список правил по порядку — Postfix проверяет их сверху вниз и останавливается на первом сработавшем.
Как отличить легитимный отказ спамеру от ошибочной блокировки своего клиента
Это главный практический вопрос: сервер отклонил письмо — хорошо это или плохо? Смотрите на три признака.
1. Чей это IP. Проверьте адрес из unknown[IP]:
whois 203.0.113.5 | grep -i -E "netname|org|country"
Если IP принадлежит незнакомому хостингу за рубежом, а helo= называет случайный домен — это спам-бот, всё работает как задумано. Если IP — это ваш собственный сайт, CRM, скрипт рассылки или знакомый партнёрский сервер — это ложная блокировка, нужно чинить.
2. Какое правило сработало. Relay access denied от чужого IP на чужой домен — нормально, это защита от открытого релея. То же самое сообщение от вашего собственного веб-сервера, который пытается слать письма через основной почтовый сервер — сигнал, что его IP забыли добавить в mynetworks или не настроили SASL-аутентификацию.
3. Массовость и повторяемость. Один-два отказа за день от разных IP на разные несуществующие адреса (user@domain, admin@domain, info@domain) — это фоновый спам-шум, с ним ничего делать не нужно. А вот если один и тот же IP получает Relay access denied каждые несколько секунд — это либо агрессивный спам-бот (и всё в порядке, сервер отбивается), либо ваше собственное приложение, у которого сломалась авторизация и оно долбит сервер безуспешными попытками (тогда чинить нужно на стороне приложения).
Обратный случай — письмо, которое вы ждали, но оно не пришло. Тогда ищите не по своему адресу получателя (его может не быть в логе вовсе, если отказ случился раньше), а по IP или домену отправителя:
grep "evil-domain.net\|203.0.113.5" /var/log/mail.log
и смотрите, на каком именно правиле произошёл reject — это подскажет, что именно отключить или смягчить в main.cf, если блокировка ошибочная.
Практический grep для поиска повторяющихся отказов
Чтобы не листать лог глазами, полезно собрать топ адресов, которые чаще всего получают reject — это быстро покажет и активных спамеров, и потенциально сломанных легитимных клиентов:
grep 'NOQUEUE: reject' /var/log/mail.log \
| grep -oP 'from=<\K[^>]+' \
| sort | uniq -c | sort -rn | head -20
Команда разбирается так: grep 'NOQUEUE: reject' отбирает только строки отказов, grep -oP 'from=<\K[^>]+' вытаскивает из каждой строки только адрес отправителя (флаг -P включает Perl-совместимые регулярки, \K — "забыть всё, что было раньше, в вывод не включать"), sort | uniq -c считает повторы, sort -rn сортирует по убыванию числа, head -20 показывает топ-20.
Аналогично можно посчитать топ IP-адресов вместо адресов почты:
grep 'NOQUEUE: reject' /var/log/mail.log \
| grep -oP 'RCPT from \S+\[\K[^\]]+' \
| sort | uniq -c | sort -rn | head -20
А если интересует распределение по типам причин (сколько было Relay access denied, сколько User unknown, сколько блэклистов):
grep 'NOQUEUE: reject' /var/log/mail.log \
| grep -oP '55[04] 5\.\d\.\d [^;]*' \
| sort | uniq -c | sort -rn
Эти три команды за пару секунд превращают тысячи строк сырого лога в компактную сводку: кто ломится, откуда и почему получает отказ.
Нужен сервер под эту задачу?
Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.
Арендовать VPSОбсудить статью, задать вопрос или начать новую тему
Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.
Перейти в сообщество →Частые вопросы
Почему в логе PID процесса меняется для каждого письма?
Postfix создаёт новый процесс smtpd на каждое входящее TCP-соединение (или переиспользует из пула простаивающих), поэтому у разных писем в логе разные числа в квадратных скобках. Для отслеживания одного конкретного письма ориентируйтесь на этот PID в пределах одной сессии, а для писем, прошедших дальше стадии NOQUEUE, — на ID очереди (шестнадцатеричный код вида 4B2F1C3A9).
Что если в строке вместо unknown стоит доменное имя?
Значит, у отправителя настроена PTR-запись и она успешно резолвится в имя хоста. Это не гарантия легитимности (у спамеров тоже бывает корректный PTR), но хороший косвенный признак.
NOQUEUE — это то же самое, что письмо потерялось?
Нет. NOQUEUE значит, что письмо отклонено на этапе SMTP-диалога и никогда не попадало на диск вашего сервера — если отправитель получил 5xx, он не будет повторять попытку и, скорее всего, сформирует отказ (bounce) себе. Это принципиально отличается от письма, которое было принято (получило ID очереди), но потом застряло — такие случаи разбираются в статье про переполненную очередь Postfix.
Как понять, что причина именно в моём main.cf, а не в стороннем сервисе типа RBL?
Смотрите текст после кода ответа. Фразы со ссылкой на конкретный чёрный список (zen.spamhaus.org, b.barracudacentral.org) значат, что сработала внешняя проверка RBL. Фразы вроде Relay access denied, Recipient address rejected, Helo command rejected — это сработали ваши собственные правила smtpd_*_restrictions в main.cf.
Можно ли логировать больше деталей, не включая полный debug?
Да, точечно — добавьте в main.cf строки debug_peer_list=203.0.113.5 и debug_peer_level=2, затем postfix reload. Подробный лог включится только для этого IP, не заваливая общий лог диагностикой по всем соединениям.
Нужны сами нейросети для контента?
Генерируйте изображения, видео и озвучку нейросетями на falapi.io — десятки моделей в одном окне. Оплата картой РФ и по СБП.