💊 Диагноз: сервер молчит, письма не уходят, ты в панике
Значит, снова эта классика. Настроил рассылку, форму обратной связи, или просто переехал на новый VPS — и тишина. Письма не уходят. В логах — какая-то каша из «deferred», «relay denied» и «connection refused». Клиент уже пишет, что «не получает письма». Коллеги смотрят на тебя с немым вопросом.
Хорошая новость: это лечится. И лечится быстро, если знать, куда смотреть.
- Понимание — почему вообще не уходит почта с сервера (причины по пунктам)
- Пошаговый чеклист диагностики — от порта до DNS
- Готовые команды для Postfix, Exim, sendmail — скопировал и вставил
- Скрипт автоматической диагностики SMTP — один запуск, полный расклад
- Чеклист «что делать, если ничего не помогло»
Состав рецепта:
- Причины: почему сервер не отправляет email
- Диагностика порта 25, 587, 465
- Проверка очереди Postfix / Exim
- Проверка DNS: SPF, DKIM, DMARC, PTR
- Тест SMTP через telnet и openssl
- Скрипт комплексной диагностики
- Осложнения и их лечение
- Профилактика: как не попасть в эту ситуацию снова
🔬 Причины: почему не уходит почта с Linux-сервера
Перед тем как лезть в конфиги, давай обозначим врага. Проблемы с отправкой почты с сервера делятся на пять групп. Почти всегда это одна из них:
1. Заблокирован порт 25 провайдером или файрволом
Самая частая причина, особенно на новых VPS. AWS, Hetzner, DigitalOcean, «Selectel» и многие другие по умолчанию блокируют исходящий порт 25 — против спама. Твой Postfix исправно пытается отправить письмо, а на уровне сети его уже зарубили.
2. Неправильно настроен или сломан почтовый агент (MTA)
Postfix не запущен. Exim не слушает нужный интерфейс. Sendmail вообще не установлен, а PHP mail() шлёт в пустоту. Конфиг сломан после апдейта. Очередь завалена и заморожена.
3. Проблемы с DNS: SPF, DKIM, DMARC, PTR
Письмо уходит с сервера, но принимающая сторона (Gmail, Outlook) его отбивает или кидает в спам. SPF-запись не включает IP сервера. DKIM-подпись не совпадает. PTR-записи нет — сервер «анонимный», и это красный флаг для всех серьёзных почтовых систем.
4. IP-адрес сервера в чёрном списке (blacklist)
Предыдущий арендатор VPS с этого IP рассылал спам. Или ты сам случайно отправил пару тысяч писем в цикле. Теперь твой IP в DNSBL, и письма молча отбиваются.
5. Проблемы аутентификации SMTP
SASL auth не настроен. TLS/STARTTLS не работает. Приложение пытается подключиться без авторизации, а relay запрещён для неаутентифицированных клиентов. Итог: «relay access denied» или «authentication required».
💉 Рецепт: пошаговая диагностика SMTP-сервера
Подготовка
Тебе нужен root или sudo на сервере, и минута терпения. Дополнительно установи утилиты, если их ещё нет:
# Debian/Ubuntu apt-get install -y telnet openssl mailutils dnsutils curl # CentOS/RHEL/Rocky yum install -y telnet openssl mailx bind-utils curl
Зафиксируй IP своего сервера — он понадобится на каждом шаге:
curl -s https://api.ipify.org && echo
# Или так:
ip route get 8.8.8.8 | awk '{print $7; exit}'
Шаг 1. Проверь — вообще запущен ли почтовый сервер
Это смешно, но 20% случаев именно так и выглядит: Postfix просто не работает после перезагрузки или падал тихо в ночи.
Postfix:
systemctl status postfix # Смотри на строку "Active: active (running)" # Если нет — запускаем: systemctl start postfix systemctl enable postfix
Exim:
systemctl status exim4 # Debian/Ubuntu systemctl status exim # CentOS # Запустить, если не работает: systemctl start exim4 systemctl enable exim4
Проверь, слушает ли MTA нужный порт:
ss -tlnp | grep -E ':(25|587|465)' # Должно быть что-то вроде: # LISTEN 0 100 0.0.0.0:25 ...
Если строки нет — MTA не слушает порт. Либо не запущен, либо конфиг не тот.
Шаг 2. Проверь порты: открыты ли они для исходящего трафика
Короче, порт 25 — это классика, которую режут все подряд. Проверяй снаружи и изнутри.
Проверь исходящий 25-й порт с сервера:
# Пробуем подключиться к MX-серверу Google через порт 25 telnet aspmx.l.google.com 25 # Если "Connected to aspmx.l.google.com" — порт открыт. # Если "Connection refused" или timeout — провайдер режет.
# Альтернатива через curl (без интерактива): curl -v telnet://aspmx.l.google.com:25 2>&1 | head -20
Проверь порт 587 (submission, с авторизацией):
telnet smtp.gmail.com 587 # Для собственного сервера: telnet localhost 587
Проверь файрвол на сервере:
# UFW (Ubuntu): ufw status verbose # iptables: iptables -L -n --line-numbers | grep -E "smtp|25|587" # firewalld (CentOS/Rocky): firewall-cmd --list-all
Если порт 25 заблокирован провайдером:
Настройка Postfix для отправки через внешний relay (например, SendGrid, Mailgun, Gmail SMTP):
# /etc/postfix/main.cf — добавь или измени: relayhost = [smtp.sendgrid.net]:587 smtp_sasl_auth_enable = yes smtp_sasl_password_maps = hash:/etc/postfix/sasl_passwd smtp_sasl_security_options = noanonymous smtp_tls_security_level = encrypt header_size_limit = 4096000
# Создай файл с паролем: echo "[smtp.sendgrid.net]:587 apikey:ТУТ_ТВОЙ_API_KEY" > /etc/postfix/sasl_passwd postmap /etc/postfix/sasl_passwd chmod 600 /etc/postfix/sasl_passwd /etc/postfix/sasl_passwd.db # Перезапусти: systemctl reload postfix
Шаг 3. Проверь очередь писем
Письма могут быть застряли в очереди. «Deferred» — это не ошибка, это «попробуем позже». Смотрим:
Postfix — просмотр очереди:
# Показать всю очередь: mailq # Или: postqueue -p # Сколько писем в очереди: postqueue -p | tail -1 # Посмотреть конкретное письмо (по ID из mailq): postcat -q ИДЕНТИФИКАТОР_ПИСЬМА
Принудительно отправить всё из очереди:
postqueue -f
Удалить все письма из очереди (осторожно!):
postsuper -d ALL
Exim — просмотр и управление очередью:
# Список писем в очереди: exim -bp # Количество писем: exim -bpc # Принудительно отправить все: exim -qff # Удалить конкретное письмо по ID: exim -Mrm ИДЕНТИФИКАТОР # Удалить всё из очереди: exiqgrep -i | xargs exim -Mrm
Смотри логи — там ответ почти всегда:
# Postfix (последние 100 строк): tail -100 /var/log/mail.log # Или: tail -100 /var/log/maillog # Фильтруй только ошибки: grep -i "error\|reject\|deferred\|bounced\|failed" /var/log/mail.log | tail -50 # Exim: tail -100 /var/log/exim4/mainlog grep -i "fail\|reject\|error" /var/log/exim4/mainlog | tail -50
Шаг 4. Проверь DNS: SPF, DKIM, DMARC, PTR
Это тот раздел, который все пропускают — и потом удивляются, почему письма летят в спам или не доходят вообще.
Проверь PTR-запись (обратный DNS):
# Замени 1.2.3.4 на свой IP: dig -x 1.2.3.4 +short # Должно вернуть что-то вроде: mail.yourdomain.com. # Если пусто — иди к провайдеру и настраивай PTR.
# Проверка через nslookup: nslookup 1.2.3.4
Проверь SPF-запись:
# Замени yourdomain.com на свой домен: dig TXT yourdomain.com +short | grep spf # Должно быть что-то вроде: # "v=spf1 ip4:1.2.3.4 include:_spf.google.com ~all"
Если IP сервера не включён в SPF — Gmail и Outlook будут отбивать письма. Пример правильной SPF-записи для домена (добавляется как TXT в DNS):
v=spf1 ip4:ТУТ_IP_ТВОЕГО_СЕРВЕРА mx ~all
Проверь DKIM:
# Замени mail._domainkey.yourdomain.com на свой селектор: dig TXT mail._domainkey.yourdomain.com +short # Должна вернуться длинная строка с "p=" — это публичный ключ.
Если записи нет — DKIM не настроен. Вот быстрая установка для Postfix + opendkim:
# Установка: apt-get install -y opendkim opendkim-tools # Генерация ключей: mkdir -p /etc/opendkim/keys/yourdomain.com opendkim-genkey -b 2048 -d yourdomain.com -D /etc/opendkim/keys/yourdomain.com -s mail -v # Смотри публичный ключ для добавления в DNS: cat /etc/opendkim/keys/yourdomain.com/mail.txt
# /etc/opendkim.conf — минимальный конфиг: Domain yourdomain.com KeyFile /etc/opendkim/keys/yourdomain.com/mail.private Selector mail Socket inet:12301@localhost
# /etc/postfix/main.cf — добавь: milter_protocol = 6 milter_default_action = accept smtpd_milters = inet:localhost:12301 non_smtpd_milters = inet:localhost:12301
systemctl restart opendkim postfix
Проверь DMARC:
dig TXT _dmarc.yourdomain.com +short # Должно быть: "v=DMARC1; p=none; rua=mailto:dmarc@yourdomain.com" # p=none — только <a class="wpil_keyword_link" href="https://it-apteka.com/category/monitoring/" target="_blank" rel="noopener" title="Мониторинг" data-wpil-keyword-link="linked" data-wpil-monitor-id="1152">мониторинг</a> (для начала безопасно) # p=quarantine — спам # p=reject — жёсткий отказ
Минимальная DMARC-запись (добавь в DNS как TXT на _dmarc.yourdomain.com):
v=DMARC1; p=none; rua=mailto:postmaster@yourdomain.com
Онлайн-инструменты для быстрой проверки DNS:
| Инструмент | Что проверяет | URL |
|---|---|---|
| MXToolbox | SPF, DKIM, DMARC, Blacklist, MX | mxtoolbox.com |
| Mail-tester.com | Полный скоринг письма | mail-tester.com |
| DKIM Validator | DKIM подпись | dkimvalidator.com |
| Google Postmaster | Репутация домена у Gmail | postmaster.google.com |
Шаг 5. Проверь IP на blacklist
# Быстрая проверка через dig (замени 1.2.3.4 на свой IP): # Для проверки bl.spamcop.net: dig 4.3.2.1.bl.spamcop.net # Для zen.spamhaus.org: dig 4.3.2.1.zen.spamhaus.org # Если вернулось 127.0.0.x — ты в списке. # Если NXDOMAIN — чист.
# Скрипт для проверки по нескольким blacklist сразу:
IP="1.2.3.4" # <-- Замени на свой IP
REVERSED=$(echo $IP | awk -F. '{print $4"."$3"."$2"."$1}')
LISTS=(
"zen.spamhaus.org"
"bl.spamcop.net"
"dnsbl.sorbs.net"
"b.barracudacentral.org"
"dnsbl-1.uceprotect.net"
"psbl.surriel.com"
)
echo "Проверка IP: $IP"
echo "-----------------------------"
for LIST in "${LISTS[@]}"; do
RESULT=$(dig +short "${REVERSED}.${LIST}" 2>/dev/null)
if [ -n "$RESULT" ]; then
echo "🔴 НАЙДЕН в: $LIST ($RESULT)"
else
echo "✅ Чист: $LIST"
fi
done
Если IP в blacklist — иди на сайт конкретного листа и подай заявку на делистинг. Для Spamhaus — это spamhaus.org/removal. Для Barracuda — lookup.barracudacentral.org.
Шаг 6. Тест SMTP вручную через telnet и openssl
Это самый надёжный способ убедиться, что SMTP работает и аутентификация проходит. Делай руками.
Telnet-тест порта 25 (без шифрования):
telnet localhost 25 # После подключения введи: EHLO test.yourdomain.com MAIL FROM:<test@yourdomain.com> RCPT TO:<получатель@gmail.com> DATA Subject: Test mail Test body . QUIT
Тест STARTTLS через openssl (порт 587):
openssl s_client -starttls smtp -connect localhost:587 -crap # Или для внешнего сервера: openssl s_client -starttls smtp -connect smtp.gmail.com:587 # После подключения: EHLO yourdomain.com AUTH LOGIN # Введи base64-логин и пароль: echo -n "твой@email.com" | base64 echo -n "твой_пароль" | base64
Отправь тестовое письмо прямо из командной строки:
# Через sendmail: echo "Subject: Test\n\nTest body" | sendmail -v получатель@gmail.com # Через mail: echo "Test body" | mail -s "Test Subject" получатель@gmail.com # Через swaks (самый удобный тестировщик SMTP): apt-get install -y swaks swaks \ --to получатель@gmail.com \ --from отправитель@yourdomain.com \ --server localhost \ --port 587 \ --auth LOGIN \ --auth-user отправитель@yourdomain.com \ --auth-password "твой_пароль" \ --tls \ --header "Subject: SMTP Test from swaks" \ --body "Если это письмо пришло — сервер работает. Можно идти спать."
Шаг 7. Скрипт комплексной автодиагностики SMTP
Хватит делать всё по одному. Вот скрипт, который пробегается по всем ключевым точкам и выдаёт отчёт. Скопируй, сохрани, запусти — получишь полный расклад за 30 секунд.
#!/bin/bash
# ================================================
# smtp_diag.sh — Скрипт диагностики SMTP-сервера
# IT Аптека | Рецепт #42
# Использование: sudo <a class="wpil_keyword_link" href="https://it-apteka.com/tag/bash/" target="_blank" rel="noopener" title="Bash" data-wpil-keyword-link="linked" data-wpil-monitor-id="1149">bash</a> smtp_diag.sh yourdomain.com 1.2.3.4
# ================================================
DOMAIN="${1:-yourdomain.com}"
SERVER_IP="${2:-$(curl -s https://api.ipify.org)}"
REVERSED_IP=$(echo $SERVER_IP | awk -F. '{print $4"."$3"."$2"."$1}')
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m'
ok() { echo -e "${GREEN}✅ OK${NC} $1"; }
fail() { echo -e "${RED}🔴 FAIL${NC} $1"; }
warn() { echo -e "${YELLOW}⚠️ WARN${NC} $1"; }
echo "========================================"
echo " IT Аптека — Диагностика SMTP"
echo " Домен: $DOMAIN | IP: $SERVER_IP"
echo "========================================"
echo ""
# --- 1. Проверка MTA ---
echo "[ 1/7 ] Почтовый агент (MTA)"
for MTA in postfix exim4 exim sendmail; do
if systemctl is-active --quiet $MTA 2>/dev/null; then
ok "$MTA запущен"
break
fi
done
# --- 2. Порты ---
echo ""
echo "[ 2/7 ] Порты SMTP"
for PORT in 25 587 465; do
if ss -tlnp | grep -q ":$PORT "; then
ok "Порт $PORT слушает"
else
warn "Порт $PORT не слушает"
fi
done
# --- 3. Исходящий порт 25 ---
echo ""
echo "[ 3/7 ] Исходящий порт 25 (к Google MX)"
if timeout 5 bash -c 'echo QUIT | telnet aspmx.l.google.com 25 2>&1 | grep -q "220"'; then
ok "Исходящий порт 25 открыт"
else
fail "Исходящий порт 25 заблокирован (провайдер или файрвол)"
fi
# --- 4. PTR ---
echo ""
echo "[ 4/7 ] PTR-запись (обратный DNS)"
PTR=$(dig -x $SERVER_IP +short 2>/dev/null)
if [ -n "$PTR" ]; then
ok "PTR настроен: $PTR"
else
fail "PTR-запись отсутствует для IP $SERVER_IP"
fi
# --- 5. SPF ---
echo ""
echo "[ 5/7 ] SPF-запись"
SPF=$(dig TXT $DOMAIN +short 2>/dev/null | grep -i "v=spf1")
if [ -n "$SPF" ]; then
ok "SPF найден: $SPF"
if echo "$SPF" | grep -q "$SERVER_IP"; then
ok "IP сервера включён в SPF"
else
warn "IP $SERVER_IP может не быть в SPF — проверь вручную"
fi
else
fail "SPF-запись отсутствует для $DOMAIN"
fi
# --- 6. DKIM ---
echo ""
echo "[ 6/7 ] DKIM (селектор 'mail')"
DKIM=$(dig TXT mail._domainkey.$DOMAIN +short 2>/dev/null)
if [ -n "$DKIM" ]; then
ok "DKIM-запись найдена"
else
fail "DKIM-запись не найдена (mail._domainkey.$DOMAIN)"
fi
# --- 7. Blacklist ---
echo ""
echo "[ 7/7 ] Проверка Blacklist"
LISTS=("zen.spamhaus.org" "bl.spamcop.net" "dnsbl.sorbs.net" "b.barracudacentral.org")
CLEAN=1
for LIST in "${LISTS[@]}"; do
RESULT=$(dig +short "${REVERSED_IP}.${LIST}" 2>/dev/null)
if [ -n "$RESULT" ]; then
fail "IP найден в $LIST"
CLEAN=0
else
ok "Чист: $LIST"
fi
done
# --- Итог ---
echo ""
echo "========================================"
echo " Диагностика завершена"
echo " Домен: $DOMAIN | IP: $SERVER_IP"
echo " Время: $(date)"
echo "========================================"
Сохрани скрипт и запусти:
chmod +x smtp_diag.sh sudo bash smtp_diag.sh yourdomain.com 1.2.3.4
Шаг 8. Типичные ошибки в логах и что они значат
| Ошибка в логах | Что это значит | Что делать |
|---|---|---|
| relay access denied | Постфикс не пускает как relay неавторизованных | Проверь mynetworks в main.cf, настрой SASL auth |
| Connection refused (port 25) | MTA не слушает или провайдер режет | Проверь systemctl status postfix, откры порт у провайдера |
| Connection timed out | Файрвол режет исходящие соединения | Проверь iptables/ufw, попробуй через другой порт |
| SASL authentication failed | Неверный логин/пароль для relay | Проверь /etc/postfix/sasl_passwd, пересоздай postmap |
| mail for X loops back to myself | Неправильный mydestination или myhostname | Убери домен из mydestination если это не локальный домен |
| 550 5.7.1 SPF check failed | SPF не включает IP сервера | Добавь ip4:ТВ0Й_IP в SPF-запись |
| STARTTLS not available | TLS не настроен на сервере | Настрой SSL-сертификат в Postfix, включи starttls |
| deferred (host or domain not found) | DNS не может разрезолвить MX получателя | Проверь /etc/resolv.conf, смени DNS на 8.8.8.8 |
⚠️ Осложнения: что делать, если рецепт не помог
Чеклист «последней надежды»
Если всё вышеперечисленное сделано, а письма всё ещё не уходят — работай по этому чеклисту:
- Проверь hostname сервера. Он должен совпадать с PTR-записью и быть FQDN (полным доменным именем).
hostname -f # Должно быть: mail.yourdomain.com # Если нет — исправь в /etc/hostname и /etc/hosts
- Проверь main.cf Postfix на корректность:
postfix check # Если тихо — конфиг ок. # Если есть ошибки — они будут выведены.
- Проверь, не стоит ли SELinux / AppArmor на пути:
# SELinux: getenforce # Если "Enforcing" — попробуй временно: setenforce 0 # Смотри audit.log: grep postfix /var/log/audit/audit.log | grep denied | tail -20
- Проверь, не забит ли диск — Postfix молча падает при 100% диска:
df -h # Если /var или / под завязку — чисти логи, очередь, журналы. du -sh /var/spool/postfix/deferred/
- Проверь права на директории Postfix:
postfix set-permissions ls -la /var/spool/postfix/
- Gmail специфично отбивает письма? Проверь Google Postmaster Tools — там видна репутация домена и IP. Зарегистрируй домен на postmaster.google.com.
- Outlook / Microsoft блокирует? Подай заявку на разблокировку через Junk Mail Reporting Program: sendersupport.olc.protection.outlook.com/pm/troubleshooting.aspx
Минимальный рабочий конфиг Postfix (main.cf)
Если хочешь начать с чистого листа — вот минимальный конфиг, который работает на большинстве серверов:
# /etc/postfix/main.cf — минимальный рабочий конфиг
# Основные параметры
myhostname = mail.yourdomain.com
mydomain = yourdomain.com
myorigin = $mydomain
inet_interfaces = all
inet_protocols = ipv4
# Кому доставляем локально (убери домен, если не принимаешь почту на этот сервер):
mydestination = $myhostname, localhost.$mydomain, localhost
# Сети, которым разрешена отправка без авторизации:
mynetworks = 127.0.0.0/8
# Размер сообщений (50MB):
message_size_limit = 52428800
# TLS параметры:
smtpd_tls_cert_file = /etc/ssl/certs/ssl-cert-snakeoil.pem
smtpd_tls_key_file = /etc/ssl/private/ssl-cert-snakeoil.key
smtpd_tls_security_level = may
smtp_tls_security_level = may
smtpd_tls_session_cache_database = btree:${data_directory}/smtpd_scache
smtp_tls_session_cache_database = btree:${data_directory}/smtp_scache
# SASL auth для клиентов:
smtpd_sasl_auth_enable = yes
smtpd_sasl_type = dovecot
smtpd_sasl_path = private/auth
smtpd_sasl_security_options = noanonymous
# Ограничения:
smtpd_recipient_restrictions =
permit_sasl_authenticated,
permit_mynetworks,
reject_unauth_destination
# После изменений main.cf: postfix check && systemctl reload postfix
🩺 Прогноз: что мы сделали и чего теперь ждать
По факту, если ты прошёл все шаги — ты:
- Убедился, что MTA запущен и слушает нужные порты
- Проверил, открыт ли исходящий порт 25 (и знаешь, что делать, если нет)
- Проверил очередь и отправил застрявшие письма
- Проверил PTR, SPF, DKIM, DMARC — без них письма либо летят в спам, либо отбиваются
- Проверил IP на blacklist и знаешь, куда идти делистироваться
- Запустил авто-скрипт диагностики и получил расклад по всем пунктам
Если ты сделал всё это и почта по-прежнему не уходит — значит, проблема либо на принимающей стороне (Gmail ненавидит тебя лично), либо у провайдера жёсткие блокировки. В обоих случаях решение — переключиться на SMTP-relay через авторизованный сервис (SendGrid, Mailgun, Amazon SES, Brevo). Это быстро, дёшево и избавляет от 90% геморроя с репутацией.
Быстрый скрипт мониторинга очереди Postfix (cron)
#!/bin/bash
# Добавь в crontab: */15 * * * * /usr/local/bin/check_mailq.sh
# Отправит alert если в очереди больше 100 писем
THRESHOLD=100
ADMIN_EMAIL="admin@yourdomain.com"
QUEUE_SIZE=$(postqueue -p 2>/dev/null | tail -1 | grep -oP '^\d+')
if [ -n "$QUEUE_SIZE" ] && [ "$QUEUE_SIZE" -gt "$THRESHOLD" ]; then
echo "ALERT: В очереди Postfix $QUEUE_SIZE писем на $(hostname) в $(date)" \
| mail -s "⚠️ Postfix queue alert" $ADMIN_EMAIL
fi
# Добавь в cron: (crontab -l 2>/dev/null; echo "*/15 * * * * /usr/local/bin/check_mailq.sh") | crontab - chmod +x /usr/local/bin/check_mailq.sh
Есть вопросы по конкретной ошибке из логов? Пиши в комментарии — разберём. Если помог рецепт — поставь звёздочку или поделись с коллегой, которому тоже «не уходят письма». Экономь чужое время.
Оставайтесь на связи
Рецепты от IT-боли. Без воды, без рекламы, без маркетинговой шелухи.
Подписаться на IT-Аптеку →



