Ваш сайт WordPress показує «Повідомлення надіслано». Логи додатку кажуть «Лист додано в чергу». Клієнти стверджують, що нічого не отримували.
Маркетинг допікає кожні 30 хвилин. Ви перевіряєте папки «Спам». Нічого. Ви пересилаєте повторно. Все одно нічого.
Це найгірший тип відмови: безшумний, що псує репутацію, і достатньо правдоподібний, щоб усі думали «мабуть, все в порядку».
Зробімо так, щоб це не було в порядку. Зробімо це нудним. Нудне — добре в доставці пошти.
Що насправді ламається, коли листи з WordPress/додатку «не надсилаються»
Коли хтось каже «лист не надсилається», зазвичай вони мають на увазі одну з чотирьох різних відмов:
1) Додаток ніколи не передав лист у реальний механізм
Класична проблема WordPress/PHP: mail() повертає успіх, бо передав вміст локальному інтерфейсу MTA,
а не тому, що повідомлення покинуло сервер. Якщо локального MTA немає або він неправильно налаштований, ви отримуєте ілюзію успіху.
Саме тому «у мене на ноуті працює» — не стратегія для пошти.
2) Повідомлення виходить з хосту, але гине на наступному хопі
Часті причини: провайдер хостингу блокує порт 25; вихідний SMTP заборонений брандмауером; або ваш MTA намагається доставити прямо
і отримує ліміти, greylist або відмову з політичною помилкою. Лист може годинами стояти в черзі, потім відскочити,
або його можуть прийняти, а потім фільтрувати пізніше. Що приводить до…
3) Отримувач приймає, а потім фільтри спаму ховають лист
Це «доставлено, але не видно» відмова. Також найнеприємніша політична ситуація: ваша система каже «відправлено»,
сервер одержувача каже «прийнято», а користувач каже «ні». Всі три можуть бути правдою.
Відповідальними за це часто є відсутність SPF/DKIM/DMARC, погана репутація, некоректний зворотний DNS і «From»-домен, яким ви не володієте.
4) Ви надсилаєте легітимний трафік, що виглядає нелегітимним
Транзакційна пошта (скидання пароля, чеки, форми контакту) має характерні патерни: сплески під час подій, однакові шаблони,
схожі теми й посилання. Це може виглядати як спам, якщо ви не автентифікуєтесь або IP ретранслятора «новий» у світі.
Доставляємість — це не мораль. Це поєднання аналізу патернів і репутації.
Виправлення — не «спробуй інший плагін». Виправлення — це встановлення правильного шляху SMTP-ретранслятора з автентифікацією,
послідовною ідентичністю, DNS-вирівнюванням і логами, які ви можете підшукати у своїх системах.
Цікаві факти та коротка історія (щоб сучасні відмови стали зрозумілі)
- SMTP старіший за веб. Він був стандартизований на початку 1980-х і досі припускає переважно довірчу мережу.
- Раніше порт 25 був «поштовим трубопроводом інтернету». Тепер його часто блокують для клієнтських серверів, бо скомпрометовані хости розсилають спам.
- SPF виник, щоб «зупинити підробку адреси в конверті». Він перевіряє, хто може відправляти пошту для домену через DNS, але покриває лише один рівень ідентичності.
- DKIM створили, щоб вижити при пересиланні. Він підписує вміст повідомлення, щоб одержувачі могли перевірити, що його не змінювали в дорозі (або «допоміжні» шлюзи).
- DMARC — це політика та вирівнювання, а не магія. Він каже одержувачам, що робити, коли SPF/DKIM не проходять, і вимагає узгодження ідентифікаторів зі видимим «From».
- Greylisting спеціально дратує. Деякі сервери тимчасово відхиляють перші спроби, щоб побачити, чи ви повторите — як справжній MTA. Додатки «відправив і забув» програють.
- «Прийнято» — це не те саме, що «в папці «Вхідні»». Прийняття по SMTP означає «ми взяли відповідальність», а не «ми показали його людині».
- Зворотний DNS — це досі перевірка репутації. Багато одержувачів недовіряють IP без rDNS або з невідповідним rDNS, бо це типово для ботнетів.
- Великі провайдери запускають машинне навчання на поштових потоках. Ваше повідомлення оцінюють за репутацією домену, IP, взаємодією та ознаками вмісту.
Швидкий план діагностики (перші/другі/треті перевірки)
Коли пошта «не надсилається», швидкість має значення. Потрібно визначити вузьке місце за хвилини, а не після наради.
Ось порядок триажу, який я використовую в продакшені.
Перше: визначте, чи взагалі пошта покидає хост додатку
- Надішліть один тестовий лист з унікальною темою.
- Перевірте локальні логи або чергу (Postfix/Exim) на хості. Якщо немає черги і нема логів, додаток ніколи не передав лист.
- Підтвердьте, що ви не залежите від PHP
mail()без локального MTA за ним.
Друге: визначте, чи досяжний і приймає наступний SMTP-хоп
- Перевірте вихідну підключеність до вашого ретранслятора на порті 587 (і 465, якщо потрібно). Не припускайте, що порт 25 працює.
- Спробуйте автентифіковану SMTP-сесію. Якщо автентифікація не вдається, це не «проблеми доставлюваності», а «проблеми входу».
- Шукайте миттєві відмови з явними SMTP-кодами (5xx) проти тимчасових відмов (4xx).
Третє: визначте, чи повідомлення відкидають пізніше (політика, репутація, автентифікація)
- Проаналізуйте заголовки повідомлення, що дійшло кудись (навіть у тестову скриньку), щодо результатів SPF/DKIM/DMARC.
- Підтвердьте вирівнювання домену From і те, що ви не відправляєте від домену, яким не керуєте.
- Перевірте, чи не йдуть відскоки кудись, де ви не дивитесь (класика: адреса для відскоків веде в нікуди).
Мета цього плану — відсортувати відмову в одну з категорій: передача від додатку, мережа/автентифікація або політика доставлюваності.
Кожна категорія має своє виправлення. Змішування їх забирає дні.
Архітектура, що реально доставляє (і чому)
Надійний патерн простий: ваш додаток використовує SMTP submission до ретранслятора, ретранслятор обробляє доставку.
Ретранслятор автентифікований, логований, має контроль швидкості і вирівнювання з вашою доменною ідентичністю.
Що вам варто робити (думка автора)
- Використовуйте SMTP submission (587) з автентифікацією від WordPress/додатку до ретранслятора.
- Відправляйте з домену, яким ви керуєте, і правильно налаштуйте DNS (SPF/DKIM/DMARC).
- Централізуйте відправлення пошти, щоб ви могли застосовувати політики й бачити логи в одному місці.
- Розділяйте транзакційні й маркетингові потоки, якщо обсяги різняться; різна репутація — різні режими відмов.
- Віддайте перевагу керованому SMTP-ретранслятору, якщо у вас немає причин самостійно вести вихідну репутацію.
Чого слід уникати
- Прямої доставки до MX із випадкових веб-серверів. Працює доти, поки не перестане — тоді ви отримаєте репутацію, ліміти й блок-листи.
- Використання «From: yourbrand.com», але фактично надсилання через «somethingelse.com». Це ламає вирівнювання й довіру.
- Розкидання різних SMTP-плагінів/конфігів по серверах. У вас буде 12 тонко поламаних варіантів.
Один жарт на додачу: Доставляємість пошти схожа на знайомства — якщо ви приходите з фальшивим ім’ям і без рекомендацій, вам не передзвонять.
Вибір SMTP-ретранслятора: що важливо, а що — шум
Ви можете керувати власним ретранслятором (Postfix), користуватися реле вашого хмарного провайдера або купити спеціалізований сервіс для транзакційної пошти.
«Найкраще» залежить від вимог відповідності, обсягу та того, чи подобається вам дебажити репутаційні показники як хобі.
Що важливо
- Опції автентифікації: SMTP AUTH поверх TLS, бажано з обліковими даними для кожного застосунку.
- Підтримка DKIM: ретранслятор має підписувати або ви маєте підписувати; але це має бути послідовно.
- Обробка відскоків: потрібна видимість. Щонайменше — поштовий ящик для відскоків; краще — подієві логи.
- Контроль швидкості: щоб захистити вашу репутацію і уникнути випадкових сплесків від зламаних систем.
- Управління репутацією IP/домену: кому вона належить і як швидко відновлюється після інциденту.
- Доступ до логів: потрібні результати доставки з ID повідомлень. «Ми відправили» — це не доказ.
Що в основному — шум
- Обіцянки «необмеженої» відправки без плану репутації.
- Гарні дашборди, якщо ви не можете експортувати або зіставити ID повідомлень.
- «Один клік інтеграція з WordPress», що приховує реальну SMTP-ідентичність і ламає вирівнювання.
Практичні завдання (команди, очікуваний вивід і рішення)
Ці завдання припускають Linux-сервер з Postfix як локальним MTA або ретранслятором, плюс хост WordPress/додатку, що відправляє пошту.
Навіть якщо ви використовуєте керований ретранслятор, багато з цих перевірок все одно застосовні (мережа, TLS, DNS і трасування повідомлень).
Завдання 1 — Переконайтеся, що Postfix встановлено і працює
cr0x@server:~$ systemctl status postfix
● postfix.service - Postfix Mail Transport Agent
Loaded: loaded (/lib/systemd/system/postfix.service; enabled)
Active: active (running) since Mon 2026-01-04 08:11:02 UTC; 2h 13min ago
Docs: man:postfix(1)
Main PID: 1327 (master)
Tasks: 3 (limit: 4567)
Memory: 12.3M
CGroup: /system.slice/postfix.service
├─1327 /usr/lib/postfix/sbin/master -w
├─1331 qmgr -l -t unix -u
└─1332 tlsmgr -l -t unix -u
Що це означає: Якщо він не active (running), ваш «SMTP-ретранслятор» — уявний.
Рішення: Якщо неактивний, запустіть його та перевірте конфігурацію перед тим, як чіпати WordPress.
Завдання 2 — Перевірте, чи щось застрягло в черзі пошти
cr0x@server:~$ postqueue -p
-Queue ID- --Size-- ----Arrival Time---- -Sender/Recipient-------
A1B2C3D4E5 3120 Mon Jan 4 09:22:14 no-reply@example.com
user@gmail.com
(connect to gmail-smtp-in.l.google.com[142.250.102.27]:25: Connection timed out)
Що це означає: Postfix прийняв пошту, але не може дістатися до віддаленого MX (таймаут). Це мережа або вихідний порт 25.
Рішення: Якщо бачите таймаути — припиніть доставку напряму до MX і використовуйте ретранслятор через submission (587) до провайдера.
Завдання 3 — Проаналізуйте останні логи пошти на предмет відмов/відкладень
cr0x@server:~$ sudo tail -n 50 /var/log/mail.log
Jan 4 10:05:12 server postfix/smtp[24518]: A1B2C3D4E5: to=<user@gmail.com>, relay=gmail-smtp-in.l.google.com[142.250.102.27]:25, delay=67, delays=0.1/0.02/67/0, dsn=4.4.1, status=deferred (connect to gmail-smtp-in.l.google.com[142.250.102.27]:25: Connection timed out)
Jan 4 10:05:45 server postfix/smtpd[24544]: warning: unknown[203.0.113.50]: SASL LOGIN authentication failed: authentication failure
Jan 4 10:05:45 server postfix/smtpd[24544]: disconnect from unknown[203.0.113.50] ehlo=1 auth=0/1 rset=1 quit=1 commands=3/4
Що це означає: У вас дві різні проблеми: таймаути вихідної доставки (direct-to-MX) і відмови автентифікації вхідних клієнтів (клієнти неправильно налаштовані або шкідливі).
Рішення: Заблокуйте submission доступ тільки для довірених клієнтів і виправте шлях ретрансляції, щоб ви не доставляли на порт 25 із випадкових веб-нод.
Завдання 4 — Перевірте вихідну підключеність до вашого ретранслятора (порт 587)
cr0x@server:~$ nc -vz smtp.relay.local 587
Connection to smtp.relay.local 587 port [tcp/submission] succeeded!
Що це означає: Мережевий шлях існує. Якщо це не вдається — винні брандмауер/групи безпеки/DNS.
Рішення: Виправте маршрутизацію/брандмауер перед зміною налаштувань додатку.
Завдання 5 — Перевірте TLS handshake і деталі сертифіката
cr0x@server:~$ openssl s_client -starttls smtp -connect smtp.relay.local:587 -servername smtp.relay.local -brief
CONNECTION ESTABLISHED
Protocol version: TLSv1.3
Ciphersuite: TLS_AES_256_GCM_SHA384
Peer certificate: CN = smtp.relay.local
Verification: OK
Що це означає: TLS працює і сертифікат валідний. Якщо перевірка не проходить, багато клієнтів відмовляться відправляти.
Рішення: Виправте сертифікати (або сховище довіри), а не «відключайте перевірку» в додатку.
Завдання 6 — Спробуйте автентифіковану SMTP-сесію (ручна, швидка перевірка)
cr0x@server:~$ swaks --to user@example.net --from no-reply@example.com --server smtp.relay.local --port 587 --auth LOGIN --auth-user app-smtp --auth-password 'REDACTED' --tls
=== Trying smtp.relay.local:587...
=== Connected to smtp.relay.local.
=== TLS started with cipher TLS_AES_256_GCM_SHA384
<= 220 smtp.relay.local ESMTP Postfix
=> EHLO server
<= 250-smtp.relay.local
<= 250-AUTH PLAIN LOGIN
<= 250 STARTTLS
=> AUTH LOGIN
<= 235 2.7.0 Authentication successful
=> MAIL FROM:<no-reply@example.com>
<= 250 2.1.0 Ok
=> RCPT TO:<user@example.net>
<= 250 2.1.5 Ok
=> DATA
<= 354 End data with <CR><LF>.<CR><LF>
=> .
<= 250 2.0.0 Ok: queued as 9F8E7D6C5B
=== Message sent.
Що це означає: Ви можете успішно подати пошту. Ідентифікатор у черзі відслідковується в логах ретранслятора.
Рішення: Якщо це працює, а WordPress — ні, проблема в плагіні/конфігурації додатку, а не в мережі.
Завдання 7 — Прослідкуйте ID повідомлення в логах (припиніть гадати)
cr0x@server:~$ sudo grep '9F8E7D6C5B' /var/log/mail.log
Jan 4 11:14:22 server postfix/cleanup[27102]: 9F8E7D6C5B: message-id=<20260104111422.9F8E7D6C5B@smtp.relay.local>
Jan 4 11:14:22 server postfix/qmgr[1331]: 9F8E7D6C5B: from=<no-reply@example.com>, size=1023, nrcpt=1 (queue active)
Jan 4 11:14:23 server postfix/smtp[27105]: 9F8E7D6C5B: to=<user@example.net>, relay=mx.example.net[198.51.100.20]:25, delay=1.1, delays=0.1/0.02/0.4/0.6, dsn=2.0.0, status=sent (250 2.0.0 OK)
Що це означає: Доставлення до MX одержувача пройшло успішно.
Рішення: Якщо користувачі все ще не бачать листа — ви в зоні «фільтрація спаму або правила скриньки»; переходьте до аналізу заголовків і перевірок автентифікації.
Завдання 8 — Переконайтеся, що hostname сервера і FQDN адекватні
cr0x@server:~$ hostnamectl
Static hostname: smtp.relay.local
Icon name: computer-vm
Chassis: vm
Machine ID: 2b3f4c5d6e7f8a9b
Boot ID: 0a1b2c3d4e5f6a7b
Operating System: Ubuntu 22.04.4 LTS
Kernel: Linux 5.15.0-91-generic
Architecture: x86-64
Що це означає: Послідовний hostname допомагає уникати дивних невідповідностей HELO/EHLO.
Рішення: Якщо у вас localhost або ім’я змінюється, виправте це і обновіть myhostname в Postfix.
Завдання 9 — Перевірте DNS на предмет SPF (і інтерпретуйте результат)
cr0x@server:~$ dig +short TXT example.com
"v=spf1 include:_spf.relayvendor.net -all"
Що це означає: SPF присутній і жорсткий (-all). Добре — якщо вірно.
Рішення: Якщо ви фактично не відправляєте через _spf.relayvendor.net, виправте SPF або ваша пошта провалюватиме SPF-перевірки.
Завдання 10 — Перевірте публікацію DKIM-ключа (селектор)
cr0x@server:~$ dig +short TXT s1._domainkey.example.com
"v=DKIM1; k=rsa; p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A..."
Що це означає: Публічний DKIM-ключ існує для селектора s1.
Рішення: Якщо відсутній — підписування може відбуватися, але не буде валідоване; опублікуйте правильний ключ або налаштуйте підписування на ретрансляторі.
Завдання 11 — Перевірте політику DMARC і адреси для звітів
cr0x@server:~$ dig +short TXT _dmarc.example.com
"v=DMARC1; p=quarantine; rua=mailto:dmarc-reports@example.com; ruf=mailto:dmarc-forensics@example.com; adkim=s; aspf=s"
Що це означає: DMARC наказує поміщати в карантин і вимагає строгого вирівнювання.
Рішення: Якщо ви ще впроваджуєте ретранслятор, розгляньте p=none тимчасово під час перевірки вирівнювання — потім посильніше.
Завдання 12 — Перевірте зворотний DNS для вашого вихідного IP
cr0x@server:~$ dig +short -x 198.51.100.10
smtp.example.com.
Що це означає: rDNS існує. Якщо він дивний або відсутній, деякі одержувачі будуть вам недовіряти.
Рішення: Якщо ви оперуєте власними IP — налаштуйте rDNS на стабільний hostname, який розумно відповідає прямому DNS.
Завдання 13 — Перевірте, чи блокують egress на порт 25 (реальна перевірка direct-to-MX)
cr0x@server:~$ nc -vz gmail-smtp-in.l.google.com 25
nc: connect to gmail-smtp-in.l.google.com (142.250.102.27) port 25 (tcp) failed: Connection timed out
Що це означає: Ви не можете доставляти напряму до Gmail на порт 25 з цього хоста (заблоковано або фільтрується).
Рішення: Використовуйте submission-ретранслятор на 587. Не намагайтесь обійти політику еґресу провайдера «хитрими» методами.
Завдання 14 — Переконайтеся, що хост WordPress не намагається запускати «sendmail» без MTA
cr0x@server:~$ command -v sendmail || echo "sendmail not found"
sendmail not found
Що це означає: PHP mail() ймовірно не працюватиме або мовчки не виконуватиметься в залежності від конфігурації.
Рішення: Налаштуйте WordPress на явну відправку через SMTP submission; не покладайтеся на відсутній локальний бінарник.
Завдання 15 — Спостерігайте логи в реальному часі під час тесту (реальна правда)
cr0x@server:~$ sudo tail -f /var/log/mail.log
Jan 4 11:29:17 server postfix/smtpd[28110]: connect from web01[203.0.113.11]
Jan 4 11:29:18 server postfix/smtpd[28110]: 1A2B3C4D5E: client=web01[203.0.113.11], sasl_method=LOGIN, sasl_username=app-smtp
Jan 4 11:29:18 server postfix/cleanup[28113]: 1A2B3C4D5E: message-id=<6f9d2a3c9e1b@web01>
Jan 4 11:29:18 server postfix/qmgr[1331]: 1A2B3C4D5E: from=<no-reply@example.com>, size=1845, nrcpt=1 (queue active)
Jan 4 11:29:19 server postfix/smtp[28115]: 1A2B3C4D5E: to=<user@example.net>, relay=mx.example.net[198.51.100.20]:25, delay=1.2, dsn=2.0.0, status=sent (250 2.0.0 OK)
Що це означає: Ви бачите, як клієнт підключається, автентифікується, додає до черги і доставляє. Ось і вся історія.
Рішення: Якщо підключення ніколи не з’являється — WordPress не використовує ваш ретранслятор. Виправте налаштування плагіна та облікові дані.
Завдання 16 — Перевірте конфігурацію Postfix на очевидні пастки
cr0x@server:~$ sudo postconf -n
myhostname = smtp.relay.local
mydestination = $myhostname, localhost.localdomain, localhost
inet_interfaces = all
smtpd_tls_security_level = may
smtp_tls_security_level = may
smtpd_sasl_auth_enable = yes
smtpd_recipient_restrictions = permit_sasl_authenticated,reject_unauth_destination
Що це означає: Ключові рядки: SASL увімкнено, і reject_unauth_destination запобігає відкритому ретранслятору.
Рішення: Якщо ви не бачите reject_unauth_destination, зупиніться й виправте це перед тим, як виставляти сервер у мережу.
Другий жарт (і останній): Відкритий ретранслятор — як залишити машину незамкненою з ключами всередині — тільки штрафи приходять на адресу вашого начальника.
Продуктивне налаштування Postfix як ретранслятора (з запобіжними заходами)
Є дві поширені ролі «ретранслятора», які плутають:
(1) сервер submission, що приймає автентифіковану пошту від ваших додатків,
та (2) smart host, що пересилає вихідну пошту через upstream-провайдера.
Ви можете поєднати обидві ролі на одному інстансі Postfix, але потрібно бути явним.
Патерн A: Postfix як submission-сервер, що ретранслює до керованого провайдера
Це те, що я рекомендую більшості команд: додатки надсилають до вашого Postfix на 587 з SMTP AUTH, Postfix пересилає провайдеру на 587.
Ви отримуєте централізовані логи і політику, і не володієте IP-репутацією.
Встановлення пакетів (приклад для Debian/Ubuntu)
cr0x@server:~$ sudo apt-get update
Hit:1 http://archive.ubuntu.com/ubuntu jammy InRelease
Reading package lists... Done
cr0x@server:~$ sudo apt-get install -y postfix libsasl2-modules mailutils
Reading package lists... Done
Building dependency tree... Done
Setting up postfix (3.6.4-1ubuntu1.3) ...
Рішення: Якщо у вас уже є Exim або інший MTA в середовищі, не ставте кілька MTA. Виберіть один.
Налаштуйте Postfix для автентифікованого submission і безпечного ретрансляції
Редагуйте /etc/postfix/main.cf (тут наведено суть, не всі значення за замовчуванням). Значення — приклади; підлаштуйте хости/домени.
cr0x@server:~$ sudo postconf -e "myhostname = smtp.example.com"
cr0x@server:~$ sudo postconf -e "myorigin = example.com"
cr0x@server:~$ sudo postconf -e "mydestination = \$myhostname, localhost.localdomain, localhost"
cr0x@server:~$ sudo postconf -e "inet_interfaces = all"
cr0x@server:~$ sudo postconf -e "mynetworks = 127.0.0.0/8 [::1]/128"
cr0x@server:~$ sudo postconf -e "smtpd_recipient_restrictions = permit_sasl_authenticated, reject_unauth_destination"
cr0x@server:~$ sudo postconf -e "smtpd_sasl_auth_enable = yes"
cr0x@server:~$ sudo postconf -e "smtpd_tls_security_level = may"
cr0x@server:~$ sudo postconf -e "smtpd_tls_auth_only = yes"
cr0x@server:~$ sudo postconf -e "smtp_tls_security_level = may"
Що це робить:
Сервер не є відкритим ретранслятором; лише автентифіковані користувачі можуть ретрансльовувати.
TLS використовується для автентифікації (щоб ви не передавали паролі в простому тексті).
Увімкніть службу submission на порту 587
У /etc/postfix/master.cf переконайтеся, що submission увімкнено і вимагає шифрування.
Можна додати безпечно та переглянути вручну. Після редагування перевірте postfix check.
cr0x@server:~$ sudo grep -n '^submission' -A6 /etc/postfix/master.cf
submission inet n - y - - smtpd
-o syslog_name=postfix/submission
-o smtpd_tls_security_level=encrypt
-o smtpd_sasl_auth_enable=yes
-o smtpd_recipient_restrictions=permit_sasl_authenticated,reject
-o milter_macro_daemon_name=ORIGINATING
Рішення: Якщо ви не можете примусити TLS на submission, не запускайте submission у недовіреному сегменті мережі.
Налаштуйте Postfix так, щоб ретранслювати вихід через upstream smart host
Якщо провайдер дає вам smtp.provider.tld:587 з обліковими даними — встановіть relayhost і карту паролів SASL.
cr0x@server:~$ sudo postconf -e "relayhost = [smtp.provider.tld]:587"
cr0x@server:~$ sudo postconf -e "smtp_sasl_auth_enable = yes"
cr0x@server:~$ sudo postconf -e "smtp_sasl_security_options = noanonymous"
cr0x@server:~$ sudo postconf -e "smtp_sasl_password_maps = hash:/etc/postfix/sasl_passwd"
cr0x@server:~$ sudo postconf -e "smtp_tls_security_level = encrypt"
cr0x@server:~$ sudo bash -c 'cat > /etc/postfix/sasl_passwd <<EOF
[smtp.provider.tld]:587 relay-user:relay-password
EOF'
cr0x@server:~$ sudo postmap /etc/postfix/sasl_passwd
cr0x@server:~$ sudo chmod 600 /etc/postfix/sasl_passwd /etc/postfix/sasl_passwd.db
Рішення: Якщо ви додаєте /etc/postfix/sasl_passwd у Git — перестаньте. Зберігайте облікові дані в сховищі секретів і шаблонуйте їх під час деплою.
Перезапустіть і перевірте конфігурацію
cr0x@server:~$ sudo postfix check
cr0x@server:~$ sudo systemctl restart postfix
cr0x@server:~$ sudo systemctl is-active postfix
active
Що це означає: Postfix прийняв конфіг і працює.
Рішення: Якщо postfix check каже про помилки — виправте їх спочатку; не «перезапускайте, поки не запрацює».
Основи жорсткої політики, які не варто пропускати
- Брандмауер: відкривайте 587 лише для мереж додатків/VPN, а 25 — тільки якщо дійсно потрібно (багатьом не потрібно).
- Обмеження швидкості: обмежте по клієнту, щоб уникнути масових розсилок у випадку скомпрометованої WordPress.
- Розмежування облікових даних: різні SMTP-логіни для prod/stage/dev і по можливості для кожного додатку.
- Збереження логів: тримайте достатньо довго для розслідувань; але не логувати тіла повідомлень, якщо політика це забороняє.
Один інженерний вислів для чесності: «Сподівання — не стратегія.» — перефразована ідея з операційної культури (часто повторюється в SRE-командах).
DNS-автентифікація, що впливає на доставлю (SPF, DKIM, DMARC, rDNS)
Доставка пошти — це наполовину SMTP і наполовину ідентичність. Потрібні обидва аспекти.
Автентифікація не гарантує попадання в папку «Вхідні», але її відсутність гарантує проблеми.
SPF: хто має право відправляти
SPF перевіряє відправника в конверті (Return-Path / MAIL FROM). Одержувачі роблять запит до DNS за TXT-записом домену.
Якщо ви відправляєте через ретранслятора-провайдера, ваш SPF має включати його.
Що робити: опублікуйте один SPF-запис, тримайте його в межах обмежень DNS-пошукових запитів (практична реальність),
і використовуйте -all, коли впевнені.
Чого уникати: кількох SPF-записів (приймається як permerror), і «просто поставте +all» (що знецінює сенс).
DKIM: підпис вмісту
DKIM підписує заголовки й тіло; одержувачі перевіряють підпис за публічним ключем у DNS.
Він чутливий до модифікацій повідомлення — деякі «захисні» шлюзи й футери можуть ламати DKIM.
Що робити: нехай саме один компонент підписує (або ваш ретранслятор, або провайдер), робіть ротацію ключів і тримайте селектори стабільними для кожного потоку.
DMARC: політика і вирівнювання
DMARC додає дві ключові ідеї:
(1) кажіть одержувачам, що робити при невдачі автентифікації, і
(2) вимагає вирівнювання між доменом у видимому заголовку From і доменами, що проходять SPF/DKIM.
Рекомендоване впровадження: почніть з p=none для спостереження, потім переходьте до quarantine, а потім до reject.
Якщо в організації кілька відправників (helpdesk, CRM, маркетинг) — зробіть інвентар перш ніж посилювати політику, інакше зламаєте легітимні листи.
Зворотний DNS (rDNS): ідентичність IP
Якщо ви керуєте вихідним IP — налаштуйте rDNS. Якщо ви використовуєте провайдера, зазвичай це роблять вони.
Одержувачі використовують rDNS як індикатор достовірності. Це не завжди обов’язково, але відсутність rDNS схожа на прихід на співбесіду без документів.
Реальність вирівнювання: «From» має бути вашим
Найпоширеніша самошкодна помилка: WordPress відправляє «From: wordpress@hostname-server» або «From: info@gmail.com»
в той час як відправник конверта — зовсім інший домен. DMARC бачить невідповідність і одержувачі ставляться до вас підозріло.
Виправте домен у From. Володійте ним.
Схеми конфігурації WordPress/додатків, що вам не саботують
Сам WordPress — не злочинець; злочинець — непослідовна конфігурація.
Ваше завдання — змусити WordPress поводитися як ввічливий клієнт: автентифікована SMTP submission, стабільна ідентичність, адекватні заголовки.
Виберіть один шлях відправки й примусово його застосовуйте
Якщо ви запускаєте внутрішній Postfix submission, усе має йти через нього. Якщо ви використовуєте керований ретранслятор прямо з WordPress,
робіть це послідовно. Чого не хочеться:
- деякі листи — через PHP
mail(), - деякі — через плагін SMTP A,
- а скидання паролю — через плагін B, бо він «виправив» щось минулого року.
Використовуйте виділену адресу відправника для транзакційної пошти
Використовуйте щось на кшталт no-reply@yourdomain або notifications@yourdomain.
Тримайте її послідовною. Одержувачі вчаться патернам. Люди теж.
Розумно встановлюйте Reply-To
Якщо користувачі мають відповідати — встановіть Reply-To на моніторовану адресу. Якщо не повинні — все одно розгляньте моніторовану скриньку для обробки відскоків.
Беззвучні відмови часто ховаються в відскоках, які ви ніколи не читаєте.
Не відправляйте від домену, яким не керуєте
Відправляти «From: yourbrand@gmail.com» з вашого сервера — це самонаносна шкода для доставляємості. Це також ускладнює аудит.
Використовуйте свій домен, автентифікуйте його й маршрутуйте відповіді туди, куди потрібно.
Додатки: віддавайте перевагу SMTP-бібліотекам з явною обробкою помилок
Чи то PHP, Node, Python або Java: налаштуйте SMTP-клієнт, щоб він явно повідомляв про помилки і логував SMTP-відповіді.
Якщо ваш додаток «ковтає» виключення — ви будете дізнаватися про збої в пошті від сердитих клієнтів. Це жорстка система моніторингу.
Моніторинг, оповіщення та докази: припиніть здогадки
Надійна пошта — це не «налаштував і забув». Це налаштував, спостерігай і забезпечуй виконання.
Вам потрібно щонайменше три рівні: здоров’я сервісу, здоров’я черги та сигнали доставлюваності.
Здоров’я сервісу
- Оповіщення, якщо Postfix не працює.
- Оповіщення, якщо диск майже заповнений (черги й логи потребують місця; повний диск породжує креативні відмови).
- Оповіщення про закінчення строку дії TLS-сертифікатів, якщо ви термінуєте TLS самі.
Здоров’я черги
Зростаюча поштові черга — не «звичайний фоновий шум». Це видимий симптом відмов upstream, проблем мережі,
збою облікових даних або тротлінгу.
cr0x@server:~$ postqueue -p | tail -n 5
-- 2 Kbytes in 1 Request.
Рішення: Якщо вона постійно ненульова і зростає — оповістіть і розслідуйте SMTP-коди у логах.
Сигнали доставлюваності
Мінімум: зберігайте зразки заголовків доставлених листів і перевіряйте, що SPF/DKIM/DMARC проходять стабільно.
Краще: збирайте коди відскоків і категоризуйте (автентифікація, політика, поштова скринька повна, відмова як спам).
Корелюйте за ID повідомлень
Ваш ретранслятор має логувати ID черги та upstream-ID. Ваш додаток має логувати кореляційний ID для «наміру відправки».
Якщо ви не можете простежити «користувач натиснув скидання пароля» → «повідомлення прийняте ретранслятором» → «доставлено або відскочило»,
у вас не система пошти. У вас — відчуття.
Три корпоративні міні-історії з практики
Міні-історія 1: Інцидент через хибне припущення
Компанія середнього розміру використовувала WordPress для маркетингових сторінок і кастомний додаток для продукту.
Скидання пароля «надсилалися» (за логами додатку). Форми контакту «надсилались» (за WordPress).
Кількість звернень у підтримку зросла: користувачі не могли увійти.
Хибне припущення було тонким: всі вірили, що успішний виклик API мейлера означає успішну доставку.
Насправді додаток був налаштований використовувати локальний інтерфейс sendmail, який просто передавав повідомлення в локальну чергу. Ця черга існувала — ледь.
Образ ВМ мав MTA, встановлений місяці тому, але ніхто ним не опікувався. Ніхто не моніторив його. Ніхто не читав логи пошти.
Під час рутинного оновлення ОС хост перезавантажився і повернувся з іншим hostname та відсутнім конфігом резолвера (cloud-init «підсобив»).
Postfix стартував, але не міг вирішити віддалені MX. Повідомлення скупчилися в черзі. Додаток продовжував повертати успіх.
Тим часом кілька листів проривались після відновлення DNS і приходили з годинною затримкою, ще більше збиваючи всіх з пантелику.
Виправлення не було героїчним. Вони перейшли на SMTP submission до одного ретранслятора, записували ID черги в лог аплікації
і поставили оповіщення для розміру черги > невеликого порогу більше кількох хвилин.
Наступного разу при проблемі DNS вони побачили її одразу. Ніяких здогадок. Ніякої археології по клієнтах.
Міні-історія 2: Оптимізація, що обернулася проти
Інша компанія вирішила, що їхній керований провайдер транзакційної пошти «занадто дорогий».
У них був блискучий кластер Kubernetes, розумна SRE-команда і достатньо впевненості, щоб бути небезпечними.
План: відправляти пошту напряму з подів додатків легковаговою SMTP-бібліотекою на MX одержувачів.
На папері виглядало ефективно: менше залежностей, ніякого прив’язування до провайдера і «SMTP — це просто протокол».
В реальності вони відкрили, чому вихідна пошта — це спеціалізований сервіс.
Хмарний провайдер блокує порт 25 з нод. Вони попросили виняток і отримали його — частково.
Деякі egress-шляхи працювали; інші мовчки тротлилися. Доставка стала недетермінованою між подами.
Потім з’явилась репутація. Їхні вихідні IP змінювалися при ротації нод.
DKIM-підписування було непостійним, бо різні деплойменти мали трохи різні секрети.
Деякі листи проходили, деякі — ні. DMARC вирівнювання було нестабільним. Одержувачі почали тротлити й відправляти в спам.
«Оптимізація» не просто коштувала часу; вона навчила провайдерів недовіряти їхньому домену.
Вони відкотили зміни. Нудне рішення: централізований ретранслятор зі стабільною ідентичністю, послідовним DKIM та провайдером, що справді управляє репутацією.
Команда SRE не втратила обличчя; вони отримали урок операційної практики: найдешевша пошта — та, яку вам не треба пояснювати.
Міні-історія 3: Нудна, але правильна практика, що врятувала день
Великий підприємець мав звичку, яку я по-справжньому поважаю: кожен транзакційний лист мав trace ID у заголовку,
і кожен SMTP-хоп його логував. Не «іноді». Кожного разу.
Це було затверджено в CI: якщо ваш мейлер не додавав заголовок — build падав.
Одного ранку фінанси повідомили про відсутні листи із рахунками. Продажі підняли паніку. Почалась звична буря:
«Чи впав додаток?» «Чи мережа?» «Хтось змінив DNS?» Люди почали складати теорії як груповий проєкт.
Натомість on-call дістав trace ID з логів додатку, прогнав його в логах ретранслятора і знайшов чисте SMTP 250 прийняття від ретранслятора,
за яким пішли повторювані 4xx від upstream-провайдера: тимчасовий політичний тротлінг.
Черга росла, але в межах налаштованих значень. Повтори відбувалися. Нічого не було «зламано», просто повільно.
Завдяки доказам вони зробили єдине розумне: повідомили зацікавлених про затримку, тимчасово зменшили швидкість сплеску
і дали черзі відкачатися. Ніякої паніки. Ніяких хаотичних змін конфігурації.
Нудна практика — нудний день. Оце мрія.
Типові помилки: симптом → корінна причина → виправлення
«WordPress каже надіслано, але нічого не приходить» → PHP mail() передає локально → використайте SMTP submission
Симптом: плагін WordPress повідомляє успіх; немає відскоків; нема логів пошти.
Корінна причина: PHP mail() не гарантує доставку; локальний MTA відсутній або зламаний.
Виправлення: Налаштуйте WordPress на SMTP (587) до вашого ретранслятора; перевірте за допомогою логів ретранслятора і тесту, наприклад swaks.
«Пошта в черзі годинами» → direct-to-MX заблоковано або відкладено → ретрансльовуйте через провайдера на 587
Симптом: postqueue -p показує багато відкладених повідомлень; логи показують таймаути на порт 25.
Корінна причина: вихідний порт 25 заблоковано; greylisting без повторів; мережеве фільтрування.
Виправлення: Маршрутуйте вихід через upstream smart host на 587 з автентифікацією; зберігайте логіку повторів у Postfix, а не в додатку.
«Gmail приймає, але повідомлення в спамі» → слабка автентифікація/вирівнювання → виправте SPF/DKIM/DMARC
Симптом: повідомлення приходять у спам; заголовки показують SPF softfail/neutral або DKIM fail; DMARC fail.
Корінна причина: домен відправника не вирівняний; відсутній DKIM; SPF вказує на неправильних відправників.
Виправлення: вирівняйте домен у From з автентифікованими доменами; опублікуйте SPF include(и), увімкніть DKIM-підписування, налаштуйте DMARC після валідації.
«Деякі листи йдуть, інші — ні» → кілька шляхів відправки → примусьте один маршрут
Симптом: скидання пароля працює; контактна форма не працює; або навпаки.
Корінна причина: різні плагіни/функції використовують різні MTA або різні облікові дані.
Виправлення: Стандартизуйте: уся пошта через один SMTP submission endpoint; вимкніть застарілі плагіни й локальні шляхи.
«Аутентифікація не пройшла» → неправильні облікові дані або невідповідність TLS → виправте SMTP AUTH і валідацію сертифікатів
Симптом: логи показують SASL невдачі; додаток каже «Не вдалося автентифікуватися».
Корінна причина: неправильний логін/пароль; використання порту 25 без submission; TLS вимагається, але не використовується.
Виправлення: Підтвердьте через swaks; примусьте TLS на 587; ротуйте облікові дані й використовуйте секрети для додатків.
«Відскоки ніколи не приходять» → Return-Path веде в нікуди → налаштуйте обробку відскоків
Симптом: користувачі скаржаться на недоставку; у вас немає поштової скриньки для відскоків.
Корінна причина: envelope sender не моніториться; ретранслятор переписує Return-Path; або ви взагалі не налаштували bounce-домен.
Виправлення: Переконайтеся, що відскоки надходять у моніторовану скриньку/систему; логувати й категоризувати DSN.
«Після ввімкнення DMARC reject легітимні листи ламаються» → забуті відправники → спочатку інвентар
Симптом: листи від helpdesk/CRM/legacy систем зникають.
Корінна причина: застосовано DMARC enforce без відображення всіх джерел; деякі системи не підписують DKIM.
Виправлення: Почніть з p=none, перегляньте звіти, потім посилюйте; перемістіть сторонні відправники на ретранслятор або налаштуйте підписування правильно.
Чеклісти / покроковий план
План A (рекомендовано): WordPress/додаток → Postfix submission → керований провайдер ретрансляції
- Виберіть домен відправника для транзакційної пошти (приклад:
example.com). - Запустіть endpoint submission (Postfix на 587) доступний лише з ваших серверів додатків.
- Налаштуйте upstream relayhost у Postfix до провайдера на 587 з SMTP AUTH.
- Налаштуйте WordPress/додаток на SMTP до вашого Postfix submission-хоста з TLS і обліковими даними для кожного додатку.
- Опублікуйте SPF для домену з включенням провайдера (і лише того, що ви дійсно використовуєте).
- Увімкніть DKIM-підписування (на боці провайдера або ретранслятора) і опублікуйте ключі селекторів.
- Впровадьте DMARC як p=none спочатку; перевірте вирівнювання; потім перейдіть до quarantine/reject.
- Налаштуйте обробку відскоків (Return-Path) і моніторинг DSN.
- Додайте моніторинг: сервіс Postfix, розмір черги, лог-оповіщення по повторюваних 4xx/5xx.
- Прогрійте матрицю тестів: відправте до кількох великих провайдерів; проаналізуйте заголовки; підтвердіть проходження перевірок.
Аварійний чекліст «змусити відправляти зараз» (без створення майбутнього боргу)
- Припиніть direct-to-MX з веб-серверів, якщо порт 25 ненадійний.
- Спочатку налаштуйте SMTP submission через
swaks; потім вкажіть туди WordPress/додаток. - Використовуйте From-адресу на вашому домені (не з безкоштовного поштового сервісу).
- Опублікуйте SPF і DKIM перед масовими розсилками.
- Увімкніть логування і зберігайте ID повідомлень.
«Ми хочемо самі керувати вихідною доставкою» чекліст (податок реальності)
- Підтвердіть, що egress на порт 25 дозволений і стабільний по всіх шляхах egress.
- Налаштуйте rDNS і прямий DNS; утримуйте стабільні IP.
- Реалізуйте DKIM-підписування і ротацію ключів.
- Впровадьте обробку feedback loop, де доступно (скарги і відскоки).
- Поступово прогрівайте IP і домени (плавне збільшення трафіку).
- Побудуйте моніторинг для подій у блок-листах і патернів відмов.
Якщо цей список звучить як друга робота — так воно і є.
Питання та відповіді (що питають о 2-й ночі)
1) Чому WordPress каже «надіслано», коли нічого не приходить?
Бо багато шляхів лише підтверджують локальну передачу (до PHP mail або локального MTA),
а не остаточну доставку. «Надіслано» часто означає «я кинув у трубу».
2) Який порт SMTP використовувати: 25, 465 чи 587?
Використовуйте 587 для submission з автентифікацією і TLS. Порт 25 — для сервер-сервер доставлення і часто блокується для клієнтів.
Порт 465 — застарілий «implicit TLS», його ще використовують, але 587 — сучасний стандарт.
3) Чи можна просто використовувати Gmail SMTP для сайту?
Можна для малого обсягу, але це зазвичай погано в довгостроковій перспективі: ліміти, управління обліковими даними і проблеми вирівнювання.
Також використання персональної скриньки як продакшн-залежності — шлях до відлагодження пошти в аеропорту.
4) Який мінімум DNS для доставлюваності?
Мінімум: SPF і DKIM, з додаванням DMARC швидко. Якщо ви керуєте власними IP — додайте rDNS.
Без цього ви ставитеся проти базової скептичності одержувачів.
5) Що означає вирівнювання DMARC на практиці?
Це означає, що домен, який бачить людина в заголовку From:, має збігатися (або бути батьківським, залежно від жорсткості)
з доменами, що автентифікуються через SPF і/або DKIM. Невідповідність — часта причина попаданнь у спам.
6) Чому я бачу «deferred» повідомлення в черзі?
Deferred — це тимчасові помилки (4xx). Причини: greylisting, ліміти, тимчасові політичні блоки або мережеві проблеми.
Deferred не «нормально», якщо вони накопичуються; нормальні лише якщо вони повторюються і черга прогнозовано вимивається.
7) Як довести, що електронний лист доставлено?
Ви можете довести, що ваш SMTP-сервер отримав 250 «sent/accepted» від MX одержувача.
Ви не можете довести, що людина прочитала його. Якщо потрібен доказ на рівні людини — це продуктове питання (вбудовані повідомлення, квитанції тощо).
8) Чи має мій сервер WordPress запускати Postfix локально?
Іноді так. Але зазвичай краще тримати WordPress як клієнт і централізувати пошту через ретранслятор/submission-хост.
Веб-сервери можуть бути скомпрометовані; не хочете, щоб скомпрометовані веб-сервери мали прямий вихідний поштовий доступ.
9) Чому листи для скидання пароля відмовляють частіше, ніж розсилки?
Вони не завжди відмовляють частіше — люди їх помічають більше. Також скидання часто тригериться під час інцидентів (сплески трафіку),
і їхній час критичний. Будь-яка затримка в черзі відчувається як відмова.
10) Чи нормально відключити перевірку TLS у SMTP-плагіні?
Ні, не в продакшені. Це «виправляє» симптом, прибираючи безпеку й ускладнюючи дебаг потім.
Виправте сертифікати й довіру правильно. Потрібна безпечна й відтворювана поведінка.
Підсумок: наступні кроки, що працюють
Надійна пошта — це не про ідеальний плагін. Це про наявність реального шляху ретрансляції, послідовну ідентичність і логи, які кажуть правду.
Побудуйте endpoint submission, ретрансльовуйте через провайдера, якщо вам не потрібно самостійно вести репутацію, і вирівняйте SPF/DKIM/DMARC.
Зробіть це цього тижня
- Прогоніть швидкий план діагностики і класифікуйте відмову (передача від додатку vs мережа/автентифікація vs політика доставлюваності).
- Стандартизуйте на SMTP submission (587) від WordPress/додатку до одного ретранслятора.
- Опублікуйте/перевірте SPF, DKIM і DMARC-вирівнювання для домену From, який ви фактично використовуєте.
- Додайте моніторинг черги й логів, щоб ви дізнавалися раніше за клієнтів.
Зробіть це далі
- Розділіть транзакційні й маркетингові потоки, якщо ви обидва надсилаєте.
- Ротуйте облікові дані, розділіть prod/stage і тримайте SMTP-ключі як інші продакшн-секрети.
- Документуйте трасу: намір додатку → ID черги ретранслятора → upstream-результат і зробіть це частиною реагування на інциденти.
Зробіть пошту нудною. Ваше майбутнє «я» подякує, мабуть тихо, бо зможе нарешті зайнятися чимось іншим.