SMTP 4xx тимчасові помилки електронної пошти: головні причини та перевірені виправлення

Було корисно?

Ви відправили лист. Або, принаймні, так вам здалося. Потім ваш телефон для on-call починає вібрувати ніби намагається втекти: «Замовлення не відправляються», «Скидання паролів відсутні», «Рахунки затримуються». Ви відкриваєте логи і бачите одне й те саме слово, написане з презирством у кожному рядку: deferred. Поруч із ним — 4xx SMTP коди.

SMTP 4xx — це всесвіт пошти, який каже: «Не зараз, спробуй пізніше.» Іноді це виправдане. Часто це сигнальна ракета, що щось у вашому стеку — або в стеку одержувача — почало піддаватися навантаженню. Хороша новина: 4xx зазвичай діагностуються дисципліною та кількома командами. Погана новина: якщо ви будете гадати, ви помилитеся, і ваша черга зросте, поки не стане другою роботою.

Що насправді означають тимчасові помилки SMTP 4xx

Відповідні коди SMTP — це грубі інструменти з оманливо ввічливою оболонкою. Відповідь 4xx — це транзитна помилка: очікується, що відправник спробує знову пізніше. Це не обіцянка, що пізніше вдасться — просто прохання, щоб ваш MTA перестав бити в ту сторону.

Практична різниця між 4xx і 5xx

  • 4xx: «Спробуйте знову». Ваш MTA ставить повідомлення в чергу, планує повторні спроби і врешті-решт зупиняється після TTL (за замовчуванням у Postfix це часто дні, але перевірте вашу конфігурацію).
  • 5xx: «Припиніть». Одержувач каже, що відмова постійна (неіснуючий отримувач, політична відмова, хард-баунс). Повторні спроби зазвичай марні, якщо відправник не виправить проблему.

Розширені коди статусу важливіші за три цифри

Сучасні MTA зазвичай додають «розширений» код статусу типу 4.7.0 або 4.4.1. Саме в цьому коді ховається зміст. Приклади:

  • 421 4.7.0: зазвичай throttling, тимчасові політики блокування або «йди геть».
  • 450 4.2.0: поштовий ящик недоступний, часто тимчасово або greylisting.
  • 451 4.3.0: локальна помилка обробки; може бути виснаження ресурсів.
  • 452 4.3.1: недостатньо системного сховища; або одержувач каже «перевищена квота».
  • 454 4.7.0: TLS тимчасово недоступний (або політичні переговори).

Операційне правило: тримайте 4xx як сигнал про ємність і коректність. Навіть якщо «інша сторона» винна, саме ваша система накопичує deferred-пошту, шум алертів і ризик репутації.

Перефразована ідея, приписувана Gene Kranz: Fail fast, be calm, and act from the data. Це не поезія, але виграє інциденти.

Жарт 1: SMTP 4xx — це як запрошення на зустріч зі статусом «tentative» — вас не відкинули, ви просто застрягли в календарному чистилищі.

Швидкий план діагностики (перший/другий/третій)

Коли черга зростає, у вас немає часу медитувати над RFC. Потрібно знайти вузьке місце послідовністю дій, що мінімізує блукання.

Перший: визначте патерн помилок (на боці отримувача чи у вас)

  1. Одна доменна зона чи багато? Якщо це один великий провайдер — думайте про throttling/greylisting/політику. Якщо багато — перевіряйте DNS, мережу, локальні ресурси, зламану конфігурацію або спільну залежність.
  2. Один відправний хост чи всі MTA? Якщо постраждав лише один сервер — підозрюйте репутацію IP того хоста, маршрутизацію або виснаження локальних ресурсів.
  3. Чи корелюється по часу? Піки на початку години? Схоже на пакетні джоби та обмеження швидкості. Піки під час бекапів? Схоже на I/O і затримки.

Другий: читайте точний SMTP-текст, а не свої відчуття

Витягніть приклади рядків логів і згрупуйте за рядком відповіді віддаленого сервера. Безкоштовні бали даються за помітку «4.7.0 try again later» проти «4.4.1 connection timed out» проти «451 4.3.0 internal error». Кожне вказує на інший шар.

Третій: перевіряйте стан черги та системи паралельно

Сам лише розмір черги — не проблема; це симптом. Ви маєте відповісти на питання:

  • Чи ми намагаємось доставляти з нормальною швидкістю, чи застрягли (DNS поламаний, мережева проблема, процес завис)?
  • Чи ми отримуємо defer через політику (throttling/greylisting), що вимагає backoff або warmup?
  • Чи ми обмежені ресурсами (диск переповнений, виснаження inode, затримки I/O, тиск пам’яті)?

Найшвидша матриця триажу

  • 4.4.x timeouts → мережа, DNS, маршрутизація, firewall, віддалений outage.
  • 4.7.x policy/throttling → ліміти швидкості, репутація, аутентифікація, патерни контенту.
  • 4.3.x local processing → сховище, права, корупція черги, здоров’я процесу MTA.
  • 4.2.x mailbox → проблеми отримувача або greylisting; часто домен-залежні.

Найпоширеніші причини помилок SMTP 4xx (та реальні виправлення)

1) Throttling отримувача та обмеження швидкості (421/450/451/4.7.x)

Великі провайдери захищають себе лімітами. Вони не хочуть, щоб ви надсилали занадто швидко, з занадто багатьох з’єднань або з патернами, що нагадують спам. Результат часто — 421 4.7.0, 451 4.7.x або розмите «Try again later».

Виправлення, що працюють:

  • Зменшіть concurency до конкретного домену: менше паралельних з’єднань, менше отримувачів на одне з’єднання.
  • Прогрівайте нові IP, замість того щоб відправляти повний обсяг з першого дня.
  • Розділіть класи трафіку (transactional vs bulk). Нехай bulk страждає від throttling, а не скидання паролів.
  • Використовуйте розумний retry/backoff. Агресивні повторні спроби можуть виглядати як зловживання.

2) Greylisting (450 4.2.x / 451 4.7.x)

Greylisting — навмисна тактика «йди й повернися пізніше». Вона ґрунтується на припущенні, що легітимні MTA повторно спробують, а багато спам-ботів — ні. Ви побачите тимчасову відмову при першій спробі; пізніші спроби зазвичай успішні.

Виправлення, що працюють:

  • Не боріться з цим панікою. Переконайтеся, що ваш графік повторних спроб правильний і не вимкнений.
  • Зберігайте стабільний IP-відправник. Ключі greylisting часто включають IP.
  • Переконайтеся, що ваш MTA не поводиться як бот: коректні HELO/EHLO, валідний зворотний DNS, послідовна поведінка TLS.

3) Проблеми DNS: таймаути, SERVFAIL, поламані резолвери (451 4.4.3, “Temporary lookup failure”)

SMTP сильно залежить від DNS: MX-запити, A/AAAA записи, PTR, SPF, DKIM-селектори, іноді RBL та політичні перевірки. Якщо ваш резолвер повільний, неправильно налаштований або заблокований, ви отримуєте транзитні помилки, що виглядають як віддалені проблеми, але насправді локальні.

Виправлення, що працюють:

  • Використовуйте надійні резолвери локально (systemd-resolved часто поводиться підозріло).
  • Моніторте латентність DNS і частку SERVFAIL, а не тільки «DNS доступний/не доступний».
  • Кешуйте відповідально. Не кешуйте поламані відповіді вічно.

4) Проблеми переговорів TLS (454 4.7.0, handshake failures, оппортунистичні TLS кейси)

TLS зазвичай нудний, поки ним не стане. Тимчасові TLS-помилки можуть виникати через невідповідність шифрів, проблеми валідації сертифікатів (для примусового TLS), баги SNI або middlebox’и, що «оптимізують» і ламають трафік.

Виправлення, що працюють:

  • Логируйте деталі SMTP TLS у MTA і зніміть один невдалий транзакційний трейс.
  • Віддавайте перевагу сучасним версіям TLS, але збережіть сумісність, якщо потрібно говорити зі старими кінцями.
  • Якщо ви примушуєте TLS для певних доменів, переконайтеся, що ваш CA-store і обробка SNI коректні.

5) Проблеми зі сховищем та файловою системою черги (451 4.3.0, 452 4.3.1, “cannot write file”)

Ваш MTA — це система зберігання, одягнена у поштову шкіру. Черга — фактично база повідомлень, а бази ненавидять повільні диски, заповнені диски, виснаження inode і неграмотні права.

Виправлення, що працюють:

  • Перевірте вільне місце на диску, inode і латентність I/O.
  • Розмістіть чергу на надійному сховищі. Якщо ви ділите том з «шумними сусідами», очікуйте проблем.
  • Слідкуйте за знімками резервних копій, що блокують I/O або заповнюють томи.

6) Вичерпання процесів/ресурсів (451 4.3.0, “out of memory,” too many open files)

MTA не величезні, але під навантаженням вони можуть досягати лімітів дескрипторів файлів, тиску пам’яті або обмежень таблиці процесів. Симптоми: тимчасові відмови через локальні помилки, повільні доставки і дивна переривчаста поведінка.

Виправлення, що працюють:

  • Підніміть ulimit -n та системні ліміти відповідно.
  • Перестаньте вважати swap продуктивністю.
  • Підійміть правильно concurency. Додавання потоків до насиченого диска лише погіршить ситуацію.

7) Репутація / політичні тимчасові блоки (421/451 4.7.0, “temporarily deferred”)

Одержувачі можуть тимчасово блокувати вас через підозрілий сплеск трафіку, скарги на спам, неправильні отримувачі або неузгоджену аутентифікацію. Іноді отримувач не хоче казати «ваша пошта погана», тому каже «спробуйте пізніше».

Виправлення, що працюють:

  • Вирівняйте SPF, DKIM та DMARC для тієї пошти, яку ви відправляєте.
  • Зменшіть рівень бортів, очищаючи списки і фіксуючи валідацію отримувачів.
  • Стабілізуйте обсяг. Сплески трафіку — це податок на репутацію.

8) Мережеві шляхи: таймаути, втрата пакетів, MTU-особливості (4.4.x)

Якщо ви таймаутите до багатьох доменів, не дивіться годинами тільки на конфіги Postfix. Подивіться на мережу. Втрата пакетів, асиметрична маршрутизація, неправильно налаштовані firewall або зламаний IPv6 можуть перетворити SMTP на повільну трагедію.

Виправлення, що працюють:

  • Тестуйте v4 і v6 окремо. Помилки dual-stack знамениті своєю плутаниною.
  • Перевірте стани таблиць firewall і ємність NAT.
  • Не ігноруйте PMTUD/MTU-проблеми, якщо TLS-handshake зависає.

9) Збої залежних сервісів: сканування контенту, латентність milter, відмови антивірусу (451 4.3.0)

Багато налаштувань прокачують пошту через milters, фільтри контенту, DLP-движки або «security appliances». Коли вони деградують, ваш MTA чекає, блокує, а потім відкладає. SMTP-помилка може вказувати на фільтр; може й не вказувати.

Виправлення, що працюють:

  • Вимірюйте латентність і відмови milter явно.
  • Використовуйте таймаути і політику fail-open/fail-closed свідомо, залежно від класу пошти.
  • Плануйте ємність фільтрів як для production-сервісів. Бо такими вони і є.

Жарт 2: Якщо ваш «шлюз безпеки пошти» впав, вітаємо: ви побудували дуже дорогий генератор пакетної втрати.

Практичні завдання: команди, виводи та рішення (12+)

Це польові завдання. Кожне включає команду, приклад виводу, що це означає, та рішення. Використовуйте їх, щоб перетворити «пошта застопорилася» на конкретну діагностику.

Task 1: Count deferred vs active queue (Postfix)

cr0x@server:~$ mailq | egrep -c "^[A-F0-9]"
1842

Що це означає: Приблизний розмір черги (ID повідомлень). Якщо це число росте швидше, ніж падає, у вас проблема пропускної здатності.

Рішення: Якщо черга > нормального базового рівня і росте, ізолюйте за доменом і текстом помилок перед перезапуском будь-чого.

Task 2: Identify top deferred reasons from logs (Postfix)

cr0x@server:~$ sudo awk '/status=deferred/ {print $0}' /var/log/mail.log | tail -n 2000 | sed -n 's/.*said: //p' | sort | uniq -c | sort -nr | head
  421 4.7.0 Try again later
  198 451 4.4.2 Timeout while waiting for server greeting
   74 450 4.2.0 Greylisted, please try again
   41 451 4.3.0 Error: queue file write error
   22 454 4.7.0 TLS not available due to temporary reason

Що це означає: Це «топ-токери» інциденту. Підказує, який рівень розслідувати насамперед.

Рішення: Оберіть 1–2 топ-повідомлення і ганяйте їх. Не розпорошуйте увагу на п’ять різних сімейств помилок.

Task 3: Find which recipient domains dominate the queue

cr0x@server:~$ mailq | awk '/@/ {print $NF}' | sed 's/.*@//' | tr -d '>,' | sort | uniq -c | sort -nr | head
  912 gmail.com
  376 outlook.com
  211 example-corp.com
   94 yahoo.com
   51 proton.me

Що це означає: Якщо один домен домінує, ймовірно throttling, репутація або політика провайдера.

Рішення: Застосуйте обмеження за доменом і перевірте вирівнювання аутентифікації для трафіку цього домену.

Task 4: Inspect a single queued message’s last error (Postfix postcat)

cr0x@server:~$ sudo postcat -vq 3F2A91C02B | sed -n '/^*** ENVELOPE RECORDS/,/^*** MESSAGE CONTENTS/p' | head -n 30
*** ENVELOPE RECORDS ***
message_size:           48213              2812               1               0            48213
message_arrival_time: Wed Jan  3 11:02:19 2026
sender: noreply@yourdomain.tld
*** RECIPIENT RECORDS ***
original_recipient: user@gmail.com
recipient: user@gmail.com
offset: 2812
dsn_orig_rcpt: rfc822;user@gmail.com
dsn_notify: failure
dsn_orcpt: rfc822;user@gmail.com
orig_to: user@gmail.com
recipient_status: 421 4.7.0 Try again later

Що це означає: Підтверджує відповідь отримувача, прив’язану до цього запису черги (не тільки те, що ви бачили в логах).

Рішення: Якщо помилка — політика/тротлінг, налаштуйте concurency та стратегію повторів, а не перезапускайте Postfix.

Task 5: Show Postfix concurrency/rate settings that influence throttling

cr0x@server:~$ sudo postconf | egrep 'default_destination_concurrency_limit|smtp_destination_concurrency_limit|smtp_destination_rate_delay|smtp_destination_recipient_limit|maximal_queue_lifetime'
default_destination_concurrency_limit = 20
smtp_destination_concurrency_limit = 20
smtp_destination_rate_delay = 0s
smtp_destination_recipient_limit = 50
maximal_queue_lifetime = 5d

Що це означає: Висока concurency і відсутність rate delay — класичний шлях до отримання throttling від великих провайдерів.

Рішення: Якщо бачите 4.7.x throttling, знизьте concurency на напрямок (почніть з 2–5) і додайте невеликий rate delay для важких доменів.

Task 6: Confirm DNS resolution for MX and A/AAAA

cr0x@server:~$ dig +time=2 +tries=1 MX gmail.com
;; ANSWER SECTION:
gmail.com.              300     IN      MX      10 alt1.gmail-smtp-in.l.google.com.
gmail.com.              300     IN      MX      20 alt2.gmail-smtp-in.l.google.com.

cr0x@server:~$ dig +time=2 +tries=1 A alt1.gmail-smtp-in.l.google.com
;; ANSWER SECTION:
alt1.gmail-smtp-in.l.google.com. 300 IN A 142.250.102.26

Що це означає: Якщо це повільно, дає SERVFAIL або таймаут, у вас проблема DNS, що проявиться як 4.4.x або «temporary lookup failure».

Рішення: Якщо DNS ненадійний, виправте резолвери першочергово. Доставка пошти залежить від правильного DNS.

Task 7: Check resolver health (systemd-resolved)

cr0x@server:~$ resolvectl status | sed -n '1,40p'
Global
       Protocols: -LLMNR -mDNS -DNSOverTLS DNSSEC=no/unsupported
resolv.conf mode: stub
Current DNS Server: 127.0.0.53
       DNS Servers: 10.0.0.2 10.0.0.3
        DNS Domain: corp.local

Що це означає: Ви використовуєте локальний stub-резолвер; зазначені upstream-сервери. Якщо upstream неправильні або недоступні, очікуйте переривчастих збоїв.

Рішення: Якщо upstream — внутрішні і вони перевантажені, переключіться на відомі надійні резолвери або запустіть локальний кешуючий резолвер з моніторингом.

Task 8: Test outbound SMTP connectivity (TCP and banner)

cr0x@server:~$ nc -vz alt1.gmail-smtp-in.l.google.com 25
Connection to alt1.gmail-smtp-in.l.google.com 25 port [tcp/smtp] succeeded!

cr0x@server:~$ timeout 5 bash -lc 'exec 3<>/dev/tcp/alt1.gmail-smtp-in.l.google.com/25; head -n 1 <&3'
220 mx.google.com ESMTP

Що це означає: Якщо TCP-connect падає або читання банера таймаутиться — підозрюйте firewall, маршрутизацію, втрату пакетів або віддалений outage.

Рішення: Якщо це падає масово — ескортуйте до мережі. Якщо тільки для одного провайдера — перевіряйте блеклисти або репутацію/політику.

Task 9: Verify IPv6 isn’t silently breaking outbound delivery

cr0x@server:~$ getent ahosts alt1.gmail-smtp-in.l.google.com | head
2607:f8b0:4004:c06::1a STREAM alt1.gmail-smtp-in.l.google.com
2607:f8b0:4004:c06::1a DGRAM
2607:f8b0:4004:c06::1a RAW
142.250.102.26 STREAM
142.250.102.26 DGRAM
142.250.102.26 RAW

Що це означає: Якщо IPv6 присутній, ваш MTA може обирати його першим. Якщо маршрут IPv6 зламаний — будете бачити таймаути і відкладення.

Рішення: Якщо шлях v6 ненадійний — виправте його або віддайте перевагу IPv4 для SMTP, поки він не стане довіреним.

Task 10: Check disk space and inode exhaustion (queue writes)

cr0x@server:~$ df -h /var/spool/postfix
Filesystem      Size  Used Avail Use% Mounted on
/dev/sda2        40G   39G  620M  99% /var

cr0x@server:~$ df -i /var/spool/postfix
Filesystem      Inodes   IUsed   IFree IUse% Mounted on
/dev/sda2      2621440 2620101   1339  100% /var

Що це означає: Простір або inode на 99–100% спричинять помилки запису файлів черги і відкладення 451/452.

Рішення: Звільніть місце/inode негайно (rotate логи, видаліть старі файли), потім сплануйте розширення файлової системи для черги та форматування з адекватною кількістю inode.

Task 11: Check I/O latency (a common hidden villain)

cr0x@server:~$ iostat -xz 1 3
avg-cpu:  %user   %nice %system %iowait  %steal   %idle
          3.01    0.00    1.24   18.55    0.00   77.20

Device            r/s     w/s   rkB/s   wkB/s  await  svctm  %util
sda              5.12   92.40   164.0  8120.3  98.40   1.12  99.60

Що це означає: await близько 100ms і %util близько 100% — насичений диск. Черги пошти ненавидять це.

Рішення: Знизьте concurency, перемістіть чергу на швидше сховище або зупиніть I/O-«козиря» (бекапи, AV-сканування, snapshot-шторми).

Task 12: Confirm Postfix processes are alive and not stuck

cr0x@server:~$ sudo systemctl status postfix --no-pager
● postfix.service - Postfix Mail Transport Agent
     Loaded: loaded (/lib/systemd/system/postfix.service; enabled)
     Active: active (exited) since Wed 2026-01-03 10:58:01 UTC; 10min ago
    Process: 1123 ExecStart=/bin/true (code=exited, status=0/SUCCESS)

cr0x@server:~$ ps -ef | egrep 'postfix/(master|qmgr|smtp|pickup)' | head
root      1180     1  0 10:58 ?        00:00:00 /usr/lib/postfix/sbin/master -w
postfix   1182  1180  0 10:58 ?        00:00:00 pickup -l -t unix -u
postfix   1183  1180  0 10:58 ?        00:00:00 qmgr -l -t unix -u

Що це означає: Postfix виглядає живим. Якщо черга не спадає, зосередьтеся на помилках доставки та залежностях, а не на автоматичному рестарті.

Рішення: Перезапускайте лише за наявності доказів завислого процесу або зміни конфігурації; рестарти можуть посилити хвилю черги.

Task 13: Measure queue age and “how bad is it”

cr0x@server:~$ mailq | awk 'BEGIN{old=0} /^[A-F0-9]/{id=$1} /^[[:space:]]*[A-Z][a-z]{2}[[:space:]]/{print}' | tail -n 5
     Wed Jan  3 08:41:22  user@outlook.com
     Wed Jan  3 08:41:23  user@gmail.com
     Wed Jan  3 08:41:24  user@yahoo.com
     Wed Jan  3 08:41:25  user@proton.me
     Wed Jan  3 08:41:26  user@example-corp.com

Що це означає: Старі записи черги означають тривалу неспроможність доставки. Це вже не просто тимчасовий спалах.

Рішення: Якщо найстаріші листи — годинної давності для transactional-трафіку, почніть пом’якшення: змініть throttle за доменом, відокремте пули, перенаправте через альтернативний MTA або призупиніть bulk-відправку.

Task 14: Check for too many open files (classic 451 local errors)

cr0x@server:~$ cat /proc/$(pgrep -n master)/limits | egrep 'open files|Max processes'
Max processes             127528               127528               processes
Max open files            1024                 1048576              files

Що це означає: Якщо Max open files низький (наприклад, 1024), висока concurency може влучити у виснаження FD під навантаженням.

Рішення: Підвищте ліміти для Postfix через systemd overrides і налаштуйте concurency відповідно до дискових/мережевих реалій.

Task 15: Validate TLS from your host to a target (debug handshake failures)

cr0x@server:~$ openssl s_client -starttls smtp -connect alt1.gmail-smtp-in.l.google.com:25 -servername alt1.gmail-smtp-in.l.google.com -brief < /dev/null | head -n 12
CONNECTION ESTABLISHED
Protocol version: TLSv1.3
Ciphersuite: TLS_AES_256_GCM_SHA384
Peer certificate: CN=mx.google.com
Verification: OK
250 SMTPUTF8

Що це означає: TLS працює end-to-end з цього хоста. Якщо Postfix рапортує 454, можлива невідповідність політики, проблема CA-store або втручання milter.

Рішення: Якщо це падає, виправте системний CA-bundle, налаштування SNI/шифрів або мережеві middlebox’и перед зміною маршрутизації пошти.

Task 16: Spot milter/filter delays (symptom: local tempfail)

cr0x@server:~$ sudo journalctl -u postfix --since "30 min ago" | egrep -i 'milter|timeout|warning' | tail -n 20
Jan 03 11:10:12 server postfix/smtpd[2841]: warning: milter inet:127.0.0.1:8891: can't read response packet: Connection timed out
Jan 03 11:10:12 server postfix/smtpd[2841]: warning: milter inet:127.0.0.1:8891: aborting milter conversation
Jan 03 11:10:12 server postfix/smtpd[2841]: warning: milter inet:127.0.0.1:8891: unavailable: temporary failure

Що це означає: Ваша залежність-фільтр таймаутиться, штовхаючи SMTP у тимчасові відмови.

Рішення: Або відновіть потужність фільтра, обійдіть для критичного трафіку, або встановіть таймаути/фейлоувер-політику свідомо.

Три корпоративні міні-історії з продакшену

Міні-історія 1: Аутейдж через неправильне припущення («4xx означає, що інша сторона впала»)

Компанія мала пару Postfix relay перед флотом застосунків. Все було «добре», поки в один вівторок вранці скидання паролів не почали відставати. On-call бачив 451 4.4.2 Timeout while waiting for server greeting і вирішив, що великий провайдер має інцидент. Це припущення купило для всіх дві години очікування.

Тим часом черга росла. Не лише для великого провайдера — для майже всіх. Підказка була захована в логах: таймаути траплялися для доменів, які нічого спільного не мали. Команда продовжувала звинувачувати «інтернет», що означає брак ідей.

Мережевий інженер нарешті зробив прямий тест банера і помітив дивину: TCP connect проходив швидко, але читання SMTP-банера зависало. Це не «віддалений впав». Це «пакети їдять». Причина — оновлення stateful firewall, яке зменшило розмір таблиці connection tracking. За нормального навантаження все було ок; під піком воно починало скидати нові та деякі встановлені потоки непередбачувано.

Виправлення було буденним: відновили capacity connection tracking і тимчасово зменшили SMTP concurency, поки backlog не спустів. Постмортем дія була важливішою за сам поворот у firewall: «Коли бачите 4.4.x таймаути по багатьох несумісних доменах, ставте ставку на свою мережу, поки не доведено протилежне.»

Міні-історія 2: Оптимізація, що повернулася бумерангом (черга на «швидкому» спільному сховищі)

Інша організація вирішила «модернізувати» свої mail relay. Вони перемістили Postfix чергу з локального SSD на спільну мережеву файлову систему, бо це здавалося «надійним» і «легше керувати». Зміна пройшла гладко, бо звучала як підвищення надійності.

Спочатку працювало. Потім ввели завдання бекапу, що робило консистентні snapshots цього ж спільного сховища. Кожну годину в точний час процес знімку спричиняв сплеск латентності. SMTP-доставки уповільнювалися, потім відкладалися, і черга росла. Помилки були міксом 451 4.3.0 локальних помилок обробки і випадкових таймаутів, бо коли менеджер черги стоїть довго, все інше починає здаватися поламаним.

Команда відповіла стандартним поганим ритуалом: перезапустити Postfix. Тимчасово «допомагало», переважно створюючи ілюзію дії. Але кожний рестарт уповільнював відновлення, бо збільшував churn з’єднань і примусив більше TLS-handshake.

Кінцеве виправлення — перестати ставитися до черги як до каталогу логів. Вони повернули її на локальний SSD, увімкнули моніторинг латентності диску та визнали спільне сховище місцем для бекапів, а не для гарячих записів черги. Урок оптимізації: доставка пошти чутлива до I/O, і «надійне спільне сховище» може виявитися пасткою продуктивності, якщо латентність не контролюється жорстко.

Міні-історія 3: Нудна, але правильна практика, що врятувала день (сепарація класів трафіку)

Одне підприємство зробило непопулярну, але правильну річ: вони відокремили transactional-пошту від bulk-маркетингу. Два логічні sender-ідентитети, два пулі IP, різні черги, різні ліміти швидкості. Здавалося бюрократією, тож було не в пошані — поки не стало в нагоді.

Пішла кампанія з опечаткою в сегменті, що спричинила сплеск невалідних отримувачів. Рівень bounce зріс, і великий отримувач почав повертати тимчасові політичні відмови (421 4.7.0). Bulk-черга швидко накопичилася, як снігова заметіль біля дверей.

Але transactional-пошта надходила. Скидання паролів і рахунки йшли через transactional-пул зі стрішими правилами list-hygiene і стабільним профілем обсягу. Цей пул мав окремі per-domain concurency limits і іншу політику повторів. Він майже не відчував тротлінгу.

Інцидент-реакція була майже нудною: призупинити bulk-відправку, виправити сегмент, дати bulk-черзі повільно стікати, і тримати критичну пошту здоровою. Постмортем читався як казка на ніч: «Нудна сепарація турбот врятувала доставку, що впливає на дохід.» Це не зробило нікого знаменитим, що зазвичай показник гарної інженерії.

Цікаві факти та історичний контекст (корисне, не тривіальне)

  • SMTP старший за сучасну епоху спаму. Він був спроектований у більш довірливій мережі, тому багато політик сьогодні прикручені зверху.
  • Тимчасові відмови стали одночасно зброєю і щитом. Greylisting популяризував ідею використання 4xx, щоб змусити спамерів марнувати час, сподіваючись, що легітимні MTA повторять спробу.
  • Розширені коди статусу (наприклад, 4.7.0) додали точності понад трицифрові відповіді, бо «451» сам по собі вже не виражав сучасних політик.
  • Черги пошти навмисно персистентні. SMTP припускає, що мережі падають; механізм queue-and-retry — сенс існування. Ваше завдання — не допустити, щоб черга перетворилася на сміттєзвалище.
  • Історично деякі MTA повторювали протягом тижня чи більше. Це мало сенс за нестабільних лінків; сьогодні це може перетворити короткий outage на дні затримок.
  • RBL/RHSBL і DNS-політики вибухнули з поширенням спаму. Надійність DNS стала критичною для пошти, тому збої резолверів виглядають як «пошта впала».
  • TLS для SMTP починався як оппортунистичне шифрування. Воно покращило приватність без координації, але також створило дивні кейси, коли «іноді TLS працює» стає змінною доставки.
  • Великі поштові провайдери працюють як мішені DDoS. Їхні троттлери — частина виживання; якщо ви відправляєте у великому масштабі, ви ведете переговори з їхніми антиабуз-системами.
  • Навіть «тимчасові» блоки можуть стати ефективно постійними, якщо ваша поведінка повторних спроб викликає додаткове політичне посилення (наприклад, висока concurency повторів, що виглядає як молотіння).

Типові помилки: симптом → корінна причина → виправлення

«Усе відкладено» і черга росте по багатьох доменах

Симптом: Багато 4.4.x таймаутів або «temporary lookup failure», що зачіпає різноманітних отримувачів.

Корінна причина: Проблеми локального DNS-резолвера, виснаження firewall/NAT, втрата пакетів або зламаний IPv6.

Виправлення: Перевірте DNS за допомогою dig, тестуйте банери з nc//dev/tcp, ізолюйте v4/v6. Виправляйте мережу перед тюнінгом Postfix.

Один домен домінує в деферах з «Try again later»

Симптом: Provider-specific 421 4.7.0 або подібне, переважно один домен.

Корінна причина: Throttling через concurency, сплеск обсягу або сигнали репутації.

Виправлення: Знизьте per-destination concurency, додайте rate delay, розділіть класи трафіку і стабілізуйте обсяг. Не повторюйте агресивно.

Переривчасті 451 4.3.0 локальні помилки під навантаженням

Симптом: 451 4.3.0 «internal error» / помилки запису черги, часто корелюють з іншими джобами.

Корінна причина: Диск повний/inode вичерпано, або латентність I/O від бекапів/snapshots/AV-сканів; іноді FD-вичерпання.

Виправлення: Перевірте df -h, df -i, iostat та ліміти дескрипторів файлів. Перемістіть чергу на низьколатентне сховище і зупиніть шумних сусідів.

454 4.7.0 TLS недоступний, тільки для деяких отримувачів

Симптом: Оппортунистичний TLS працює для більшості, але підмножина тимчасово падає.

Корінна причина: Невідповідність шифрів, поламаний middlebox, SNI-особливості, проблеми CA-store або неправильна політика примусового TLS.

Виправлення: Відтворіть за допомогою openssl s_client -starttls smtp з хоста-відправника; відкоригуйте TLS-настройки або обійдіть middlebox’и.

Greylisting сприймають як аварію

Симптом: Перша спроба доставки дає 450, пізніше — успіх, але люди все одно панікують.

Корінна причина: Greylisting працює як задумано, а ваш алертинг надто наївний.

Виправлення: Налаштуйте алерти на пороги за віком/швидкістю, а не на одиничний 450. Переконайтеся, що інтервали повторних спроб не надто довгі для критичної пошти.

Черга довго стікає навіть після «виправлення проблеми»

Симптом: Одержувач знову приймає пошту, але ви все ще заблоковані на години.

Корінна причина: Ваші власні ліміти пропускної здатності MTA, латентність диска або per-domain concurency надто малі для відновлення backlog.

Виправлення: Тимчасово обережно збільште пропускну спроможність (додаткові worker-процеси, трохи вищі concurency), спостерігайте диск і рівень помилок, потім відкотіть.

Контрольні списки / покроковий план

Покроково: від першого алерту до стабільної доставки

  1. Зніміть знімок стану. Розмір черги, топ-тексти помилок, топ-домени отримувачів, вік найстарішого повідомлення.
  2. Класифікуйте домінантне сімейство помилок. 4.4.x таймаути vs 4.7.x політика vs 4.3.x локальні помилки.
  3. Підтвердіть або спростуйте локальні DNS/мережеві проблеми. DNS-запити, TCP-connect, читання банера, sanity v4/v6.
  4. Перевірте здоров’я сховища. Місце, inode, латентність I/O, файлкова система черги.
  5. Перевірте залежності. Milters/фільтри контенту, outbound proxies, NAT/firewalls.
  6. Застосуйте найменше безпечне пом’якшення. Обмеження за доменом, пауза bulk-трафіку або reroute критичної пошти.
  7. Моніторте швидкість спуску черги і рівень помилок. Не оголошуйте перемогу, поки черга не зменшується і нова пошта не доставляється нормально.
  8. Після стабільності: жорстке закріплення. Кращі пороги алертів, розділення трафіку, більш великі резерви ємності.

Операційний чекліст: що налаштовувати (а що ні)

  • Робіть тюнінг per-domain concurency і rate delay для великих провайдерів.
  • Робіть розділення transactional і bulk, ідеально на рівні IP/ідентичності та черги.
  • Робіть моніторинг латентності DNS, латентності диску і віку черги.
  • Не «виправляйте» backlog збільшенням concurency наосліп; часто це призведе до більшого throttling і гіршої репутації.
  • Не перезапускайте MTA як першу лінію відповіді. Це крайній засіб; поганий діагностичний інструмент.
  • Не ігноруйте IPv6. Або працюйте з ним правильно, або явно віддавайте перевагу IPv4 для SMTP до моменту довіреної роботи IPv6.

Чекліст для алертів (щоб уникнути хибних інцидентів «пошта впала»)

  • Алерт на вік найстаршої черги для критичних класів, а не лише на розмір черги.
  • Алерт на швидкість відкладень за доменом (раптовий сплеск 4.7.0).
  • Алерт на частоту SERVFAIL/таймаутів DNS з поштових хостів.
  • Алерт на iowait і заповнення файлової системи для томів черги.
  • Алерт на латентність/таймаути milter, якщо у вас є milters.

FAQ

1) Чи безпечно ігнорувати 4xx SMTP помилки, бо вони ж повторять спробу?

Ні. Повторні спроби — це механізм, а не рішення. Спалах 4xx — це або сигнал політики (throttle), або сигнал надійності (DNS/мережа/сховище). Ставтеся до нього як до зростаючої латентності в будь-якій production-системі.

2) Як швидко відрізнити throttling від мережевої відмови?

Подивіться на розширені коди і розподіл. 4.7.x скупчення на одному провайдері вказує на throttling/політику. 4.4.x таймаути по багатьом доменам вказують на мережу/DNS/локальні проблеми.

3) Чому я бачу «Try again later» без корисних деталей?

Отримувачі навмисно залишають політику непрозорою, щоб не допомагати спамерам. Найкращий сигнал — це поведінка: які домени, які обсяги, які патерни з’єднань і чи недавно змінилася ваша IP-ідентичність.

4) Як довго мені продовжувати повторювати deferred-повідомлення?

Достатньо довго, аби пережити реальні outages, і досить коротко, щоб не доставляти застарілі сповіщення. Багато організацій встановлюють коротші TTL для transactional-повідомлень, ніж для низькоцінного bulk. Узгодьте TTL з бізнес-цінністю.

5) Чи можуть проблеми SPF/DKIM/DMARC викликати 4xx, а не 5xx?

Так. Деякі отримувачі відкладають, поки оцінюють репутацію, чекають DNS або застосовують тимчасову політику. Також ваші власні системи (наприклад, milters) можуть тимчасово відмовляти під час DNS-перевірок.

6) Чи варто відключити greylisting на приймальному боці (якщо я його контролюю)?

Якщо можете, краще віддати перевагу сучаснішим anti-abuse-контролям. Greylisting затримує легітимну пошту і створює операційний шум. Якщо залишаєте його, білуйте критичних відправників і забезпечте розумні вікна повторних спроб.

7) Чому перезапуск Postfix іноді «фіксує» проблему?

Бо він скидає стан, очищує завислі процеси або тимчасово зменшує concurency під час підняття сервісу. Це також може погіршити ситуацію, бо збільшує churn з’єднань і TLS-handshakes. Використовуйте його з доказами, а не як магічний ритуал.

8) Який правильний спосіб обробляти масивний backlog, коли корінь проблеми усунуто?

Спускайте чергу деліберативно. Пріоритезуйте критичний трафік, пом’якшуйте домени, які карають за сплески, і збільшуйте пропускну здатність лише настільки, наскільки ваш диск/мережа витримають. Інакше ви викличете нові тротли і подовжите відновлення.

9) Чи завжди 452 означає заповнений диск?

Ні. 452 може означати, що отримувач перевищив квоту, або що відправник не може виділити ресурси. Перевірте, чи текст згадує «insufficient system storage» локально, і провалідуйте свої диски/inode.

10) Як запобігти тому, щоб 4xx будили мене о 3:00 ранку?

Розділіть класи трафіку, моніторте вік черги й причини defer, тримайте сховище черги швидким і просторим, і розглядайте DNS як залежність першого класу з власним SLO.

Висновок: наступні кроки, щоб уникнути повторень

SMTP 4xx помилки рідко містять містику. Це просто розподілені системи в краватці. Ваше завдання — перестати гадати і почати класифікувати: політика vs мережа vs локальні ресурси vs залежності.

Наступні кроки, що одразу окупаються:

  1. Додайте панель «топ причин відкладень» (текст помилки + розширені коди) і алерт на раптові зрушення.
  2. Алертуйте за віком найстарішої черги для transactional-пошти; припиніть трактувати усю пошту однаково.
  3. Забезпечте розділення трафіку: transactional vs bulk, бажано з окремими чергами та політиками швидкості.
  4. Зробіть DNS нудним: швидкі резолвери, моніторинг і протестоване фейловер.
  5. Захистіть файлову систему черги: низька латентність, достатньо місця/inode і ні несподіваних snapshot-шторми.
  6. Документуйте швидкий план діагностики у ваших runbooks і потренуйте його один раз, поки нічого не горить.

Якщо ви це зробите, «тимчасові помилки» знову стануть тим, чим вони мали бути: інколи турбулентністю, але не постійним способом життя.

← Попередня
Пошук WordPress повільний: прискорте його без дорогих сервісів
Наступна →
Виправлення MySQL-помилок WordPress «Server Has Gone Away» та «Too Many Connections»

Залишити коментар