WordPress «відправив» лист. Ваш клієнт його не отримав. Відділ підтримки надсилає скріншоти порожніх скриньок, а єдиний конкретний артефакт у вас — прапорець у плагіні з написом “Use PHP mail()”.
Ось неприємна правда: доставка пошти — це не функція WordPress. Це розподілена система з ідентичністю, репутацією, DNS, політикою та десятком способів мовчки зламатися. Виправлення майже завжди — SMTP, але не тоте «встановіть плагін і моліться». Виправлення — це налаштування SMTP, яке ви можете спостерігати, тестувати і експлуатувати.
Швидкий план діагностики
Якщо ви на виклику, у вас немає часу заново відкривати SMTP. Вам потрібно швидко знайти вузьке місце: WordPress? PHP? локальний MTA? мережа? віддалений релей? DNS-політика? фільтрація на боці отримувача? Використовуйте цю послідовність.
Перше: підтвердіть, чи WordPress взагалі намагається відправити
- Спровокуйте відомий лист: скидання пароля для тестового користувача, лист замовлення WooCommerce або відправка форми, яка логує подію.
- Перевірте логи застосунку: логи плагіна (якщо ваш SMTP-плагін їх підтримує), логи вебсерверу для запиту та WordPress debug log, якщо ввімкнено.
- Рішення: Якщо спроби немає, у вас проблема з додатком/налаштуванням. Якщо спроба є — продовжуйте.
Друге: ідентифікуйте шлях відправлення
- Це PHP mail() до локального MTA? Це означає «WordPress передав повідомлення серверу». Це нічого не говорить про доставку.
- Це SMTP напряму до реле? Краще: ви можете пройти автентифікацію, логувати і відстежувати помилки.
- Рішення: Якщо ви не можете описати шлях одним реченням, у вас не система — у вас відчуття.
Третє: знайдіть першу стійку помилку
- Черга локального MTA росте? Подивіться чергу Postfix/Exim і логи.
- Віддалений SMTP відхиляє? Вам потрібен віддалений код помилки (5xx/4xx) і причина.
- Прийнято, але не отримано? Питання доставлюваності і політики: SPF/DKIM/DMARC вирівнювання, репутація, контент, обмеження по швидкості або фільтрація на боці отримувача.
- Рішення: Не змінюйте п’ять речей одночасно. Зафіксуйте першу конкретну помилку, потім виправляйте її корінну причину.
Парафразована ідея (приписано): Зробіть невдачу видимою; надійність починається зі спостереження того, що система реально робить
— Charity Majors (парафраз).
Що насправді ламається, коли WordPress не може відправити пошту
«WordPress не відправляє пошту» зазвичай означає одне з наступного:
- Відсутній MTA або локальний MTA зламаний. Багато сучасних образів VPS не постачаються з налаштованим агентом передачі пошти. PHP може викликати
sendmail, але за ним може нічого розумного не стояти. - Провайдер блокує вихідний SMTP. Деякі хости блокують порт 25 або обмежують пошту з загальних IP-діапазонів. Хмарні провайдери роблять це, щоб зменшити зловживання.
- SMTP-автентифікація не пройшла. Неправильне ім’я користувача, пароль, порт, режим шифрування, неправильна ідентичність «From» або налаштування орендатора (привіт, Microsoft 365).
- Відсутня або неузгоджена ідентичність DNS. SPF занадто строгий, DKIM не налаштований, DMARC в режимі примусового застосування і вирівнювання не проходить. Пошта відхиляється або потрапляє в bulk.
- Проблеми репутації та політики. Новий домен/IP, що відправляє транзакційну пошту, виглядає підозріло. Системи отримувачів не цікавить, що це «лише скидання пароля». Їх цікавлять сигнали.
- Контент тригерить фільтри. Форми, які відправляють контент від користувачів, можуть виглядати як фішинг або містити URL у чорних списках.
- Проблеми часу і TLS. Неправильний системний час ламає перевірку TLS. Старі шифри не проходять на сучасних SMTP-ендпоінтах. «Працює на моєму ноуті», бо ваш ноутбук не сервер.
Жарт #1: Доставлюваність пошти — як дверний контролер у нічному клубі: ви можете бути в списку, але вас все одно не впустять, бо ви «виглядаєте підозріло».
У продакшні я розглядаю WordPress-пошту як конвеєр із контрольними точками:
- App checkpoint: WordPress викликає wp_mail().
- Transport checkpoint: плагін передає до SMTP або PHP mail() передає локальному MTA.
- Relay checkpoint: SMTP-реле приймає (або відхиляє) повідомлення.
- Recipient checkpoint: SMTP отримувача приймає (або відхиляє) від реле.
- Inbox checkpoint: фільтрування і політика отримувача вирішують, куди воно потрапить, або чи буде поміщено в карантин.
Ваше завдання — знайти першу контрольну точку, де реальність відхиляється від очікування. Все інше — шум вниз по потоку.
Цікаві факти (і чому вони досі важливі)
- SMTP старший за веб. Основна специфікація SMTP передує сучасному веб-хостингу, тому вона багато чого передбачає як довірене і додавала автентифікацію пізніше.
- SPF створювався для перевірки підроблених envelope-sender, а не заголовка “From:”. Багато хто очікує, що SPF перевіряє те, що бачать користувачі. Ні — вирівнювання через DMARC зв’язує це разом.
- DKIM підписує тіло повідомлення та вибрані заголовки. Це означає, що деякі «допоміжні» реле, які змінюють вміст, можуть зламати підписи і поховати доставку.
- DMARC існує, бо SPF і DKIM окремо були недостатні. DMARC додає політику та звітність і формалізує вирівнювання, щоб приймачі могли примусово застосовувати правила.
- Greylisting досі існує. Деякі отримувачі тимчасово відхиляють відправників у перший раз (4xx). Хороші MTA повторюють спроби; наївні імплементації фіксують помилку і здаються.
- IP у спільному хостингу часто має погану репутацію. Ваш сайт може бути поряд зі спам-канонією сусіда по IP.
- Порт 25 часто блокується провайдерами хмар. Не тому що вони ненавидять вас — тому що спам — це зовнішній негатив, і вони платять за це у вигляді репутації та обробки зловживань.
- Транзакційна і маркетингова пошта мають різні очікування. Скидання пароля потребує швидкої та надійної доставки; масові розсилки потребують прогріву і суворого дотримання. Змішування шкодить обом.
- Адреса “From” важить більше, ніж здається. Багато приймачів застосовують репутацію на рівні заголовка From, а не лише на рівні IP.
Виберіть архітектуру SMTP (і уникайте спокусливих помилок)
Варіант A: Використовуйте виділений SMTP-релей (рекомендовано)
Це зріле рішення для більшості WordPress-сайтів, що мають значення. Ваш хост запускає додаток, а виділене реле забезпечує доставлюваність, повторні спроби, обробку bounce, feedback loop і репутацію IP.
Плюси: найкраща доставлюваність, реальні логи, передбачувана поведінка обмежень по швидкості, легша підтримка автентифікації домену. Мінуси: коштує грошей, потребує DNS-робіт та управління обліковими даними.
Вибирайте це коли: ви надсилаєте скидання паролів, підтвердження замовлень, листи для членства або будь-що, про що користувачі почнуть кричати, якщо це перестане працювати.
Варіант B: Використовуйте SMTP вашого корпоративного поштового провайдера (іноді підходить)
Gmail/Google Workspace або Microsoft 365 може підійти для низькооб’ємної транзакційної пошти, але очікуйте обмежень: ліміти, обмеження From, зміни з OAuth проти basic auth, політики орендатора та раптові сюрпризи.
Плюси: ви вже за це платите, знайомий адмін-інтерфейс. Мінуси: обмеження, складнощі аудиту і просто налаштувати ідентичності так, щоб DMARC пройшов.
Варіант C: Запустити Postfix на сервері і відправляти напряму (рідко варто того)
Так, ви можете запустити власний вихідний MTA і відправляти безпосередньо до MX-хостів отримувачів. Якщо ви читаєте це, бо WordPress-пошта ненадійна, вам, ймовірно, не варто ще й ставати інженером з репутації пошти.
Плюси: повний контроль. Мінуси: управління репутацією, блок-листи, зворотний DNS, обробка зловживань, постійне тонке налаштування. І ще: вас звинуватять у спамі, якого ви не відправляли.
Поганий дефолт: PHP mail() в порожнечу
PHP mail() не є «неправильним», але це найменш спостережуваний транспорт. Це передача тому, що налаштовано як sendmail_path. На shared hosting це може працювати. У сучасних керованих середовищах воно часто вказує на нічого або на локальний реле без будь-якої роботи з доставлюваності.
Практичні завдання: команди, виводи, рішення (12+)
Ці завдання розраховані на виконання на хості WordPress (або хості контейнера) з доступом до shell. Кожне містить: команду, приклад виводу, що це означає та рішення, яке ви приймаєте.
Завдання 1: Підтвердіть, чи хост WordPress правильно резолвить DNS
cr0x@server:~$ resolvectl status
Global
Protocols: -LLMNR -mDNS -DNSOverTLS DNSSEC=no/unsupported
resolv.conf mode: stub
Current DNS Server: 1.1.1.1
DNS Servers: 1.1.1.1 8.8.8.8
Значення: DNS-резолюція налаштована і вказує на доступні резолвери.
Рішення: Якщо DNS зламаний або вказує на внутрішній резолвер, який не може розв’язувати публічні записи — виправте DNS першочергово. Діагностика SMTP без працюючого DNS — це мистецтво продуктивності.
Завдання 2: Перевірте, чи доступні вихідні SMTP-порти
cr0x@server:~$ nc -vz smtp.mailprovider.example 587
Connection to smtp.mailprovider.example 587 port [tcp/submission] succeeded!
Значення: Мережевий шлях до реле на порті 587 (submission) відкритий.
Рішення: Якщо це не вдається, ви маєте справу з правилами firewall, обмеженнями виходу в хмарі або політиками провайдера. Використовуйте 587/465 з автентифікацією; не боріться з блокуваннями порту 25, якщо вам не подобаються тікети abuse.
Завдання 3: Перевірте системний час (TLS залежить від нього)
cr0x@server:~$ timedatectl
Local time: Sat 2025-12-27 13:05:41 UTC
Universal time: Sat 2025-12-27 13:05:41 UTC
RTC time: Sat 2025-12-27 13:05:41
Time zone: Etc/UTC (UTC, +0000)
System clock synchronized: yes
NTP service: active
RTC in local TZ: no
Значення: Годинник синхронізований; перевірка сертифікатів TLS не впаде через системну дату 1970 року.
Рішення: Якщо не синхронізовано — виправте NTP. Випадкові TLS-помилки зіпсують вам день.
Завдання 4: Визначте, чи є локальний MTA
cr0x@server:~$ command -v sendmail; systemctl status postfix 2>/dev/null | head
/usr/sbin/sendmail
Unit postfix.service could not be found.
Значення: Бінарний файл sendmail існує (можливо від msmtp або nullmailer), але Postfix не встановлений.
Рішення: Якщо ви покладаєтеся на PHP mail(), потрібно знати, що таке /usr/sbin/sendmail насправді. Якщо його немає або він не працює — переключіться на SMTP через плагін або встановіть/налаштуйте справжній MTA.
Завдання 5: Подивіться, що PHP вважає «sendmail»
cr0x@server:~$ php -i | grep -E '^sendmail_path|^mail\.force_extra_parameters'
sendmail_path => /usr/sbin/sendmail -t -i => /usr/sbin/sendmail -t -i
mail.force_extra_parameters => no value => no value
Значення: PHP викличе /usr/sbin/sendmail -t -i.
Рішення: Якщо ви навмисно не експлуатуєте локальний MTA — припиніть використовувати цей шлях. Він за замовчуванням не логгує і дає творчі збої.
Завдання 6: Якщо існує Postfix — перегляньте чергу пошти
cr0x@server:~$ mailq
-Queue ID- --Size-- ----Arrival Time---- -Sender/Recipient-------
3F2A91234A 2213 Sat Dec 27 12:58:02 wordpress@example.com
user@gmail.com
(connect to gmail-smtp-in.l.google.com[142.250.102.27]:25: Connection timed out)
-- 1 Kbytes in 1 Request.
Значення: Повідомлення в черзі і не можуть досягти MX отримувача на порті 25 (таймаут).
Рішення: Припиніть намагатися доставляти direct-to-MX з цього хоста. Використовуйте автентифіковане реле на 587/465. Черга каже вам, що мережевий шлях заблокований.
Завдання 7: Читайте логи пошти для помилок SMTP (приклад Postfix)
cr0x@server:~$ sudo tail -n 30 /var/log/mail.log
Dec 27 12:58:02 server postfix/smtp[21877]: connect to gmail-smtp-in.l.google.com[142.250.102.27]:25: Connection timed out
Dec 27 12:58:32 server postfix/smtp[21877]: connect to gmail-smtp-in.l.google.com[2607:f8b0:400e:c06::1b]:25: Network is unreachable
Dec 27 12:59:02 server postfix/qmgr[901]: 3F2A91234A: from=<wordpress@example.com>, size=2213, nrcpt=1 (queue active)
Значення: Послідовні таймаути і IPv6 недоступний. Це не баг WordPress.
Рішення: Налаштуйте Postfix для ретрансляції через smarthost на 587, або відключіть IPv6, якщо маршрут некоректний. Краще: пропустіть локальний MTA і використовуйте SMTP-плагін напряму до реле.
Завдання 8: Протестуйте SMTP-автентифікацію і TLS через OpenSSL
cr0x@server:~$ openssl s_client -starttls smtp -connect smtp.mailprovider.example:587 -servername smtp.mailprovider.example -crlf
CONNECTED(00000003)
depth=2 C=US O=Example CA CN=Example Root CA
verify return:1
depth=1 C=US O=Example CA CN=Example Issuing CA
verify return:1
depth=0 CN=smtp.mailprovider.example
verify return:1
---
250 STARTTLS
250 AUTH PLAIN LOGIN
250 PIPELINING
250 SIZE 10485760
Значення: TLS-узгодження працює; сервер анонсує AUTH-механізми.
Рішення: Якщо перевірка сертифіката не проходить — виправте CA bundle або перехоплюючий проксі. Якщо STARTTLS не пропонується — ви на неправильному порту або провайдер вимагає implicit TLS (465).
Завдання 9: Перевірте наявність SPF-запису для домену відправника
cr0x@server:~$ dig +short TXT example.com | grep -i spf
"v=spf1 include:_spf.mailprovider.example -all"
Значення: Домен має SPF, який авторизує ваше реле.
Рішення: Якщо відсутній — додайте його. Якщо закінчується на -all і ви не включили реле — отримувачі відкинуть або помістять у спам. Якщо є кілька SPF-записів — виправте це (див. Завдання 10).
Завдання 10: Виявлення множинних SPF-записів (типова самосаботаж)
cr0x@server:~$ dig +short TXT example.com | grep -i "v=spf1" | wc -l
2
Значення: Існує два SPF-записи. Приймачі трактують це як постійну помилку (PermError) і SPF фактично не проходить.
Рішення: Об’єднайте механізми SPF в один запис. Ніколи не публікуйте кілька TXT з v=spf1.
Завдання 11: Підтвердіть наявність DKIM-записів (за селектором)
cr0x@server:~$ dig +short TXT s1._domainkey.example.com
"v=DKIM1; k=rsa; p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A..."
Значення: Публічний ключ DKIM присутній для селектора s1.
Рішення: Якщо відсутній — ввімкніть DKIM у вашого релей-провайдера і опублікуйте TXT-запис точно як надано. DKIM більше не є опцією для стабільної доставки.
Завдання 12: Підтвердіть політику DMARC і вимоги вирівнювання
cr0x@server:~$ dig +short TXT _dmarc.example.com
"v=DMARC1; p=quarantine; adkim=s; aspf=s; rua=mailto:dmarc@example.com"
Значення: DMARC встановлено з політикою quarantine і суворим вирівнюванням для DKIM та SPF.
Рішення: Суворе вирівнювання означає, що видимий заголовок From: повинен співпадати з доменами, що використовуються для автентифікації. Налаштуйте «From Email» у WordPress і ідентичність реле, або пом’якшіть вирівнювання, розуміючи наслідки.
Завдання 13: Перевірте зворотний DNS (PTR) для вашого відправного IP (якщо ви відправляєте напряму)
cr0x@server:~$ dig +short -x 203.0.113.10
mail.example.com.
Значення: PTR існує. Багато приймачів недовіряють IP без rDNS.
Рішення: Якщо ви доставляєте напряму — виправте PTR у вашого ISP/хмарного провайдера. Якщо ви релеєте через SMTP-провайдера — це важливіше для IP релея, ніж для вашого хоста.
Завдання 14: Спостерігайте помилки WordPress/PHP під час відправлення (PHP-FPM)
cr0x@server:~$ sudo tail -n 40 /var/log/php8.2-fpm.log
[27-Dec-2025 12:57:51] WARNING: [pool www] child 18234 said into stderr: "PHP Warning: fsockopen(): Unable to connect to smtp.mailprovider.example:587 (Connection timed out) in /var/www/html/wp-includes/PHPMailer/SMTP.php on line 214"
[27-Dec-2025 12:57:51] WARNING: [pool www] child 18234 said into stderr: "SMTP connect() failed."
Значення: Застосунок намагався використати SMTP, але отримав таймаут — проблема в мережі або firewall.
Рішення: Виправте egress firewall/security groups, NAT або обмеження хост-провайдера. Не варто крутити налаштування плагіна, якщо TCP-хендшейк взагалі не проходить.
Завдання 15: Швидкий end-to-end тест SMTP за допомогою swaks (якщо встановлено)
cr0x@server:~$ swaks --to user@gmail.com --from wordpress@example.com --server smtp.mailprovider.example --port 587 --auth LOGIN --auth-user wordpress@example.com --auth-password 'REDACTED' --tls
=== Trying smtp.mailprovider.example:587...
=== Connected to smtp.mailprovider.example.
<= 220 smtp.mailprovider.example ESMTP ready
=> EHLO server
<= 250-AUTH PLAIN LOGIN
=> AUTH LOGIN
<= 235 2.0.0 Authentication successful
=> MAIL FROM:<wordpress@example.com>
<= 250 2.1.0 Ok
=> RCPT TO:<user@gmail.com>
<= 250 2.1.5 Ok
=> DATA
<= 354 End data with <CR><LF>.<CR><LF>
=> .
<= 250 2.0.0 Accepted for delivery
=== Connection closed with remote host.
Значення: SMTP-реле прийняло повідомлення. Тепер ви в зоні доставлюваності, а не транспорту.
Рішення: Якщо прийнято, але не отримано — перевірте логи релея, папки спаму, вирівнювання SPF/DKIM/DMARC і переконайтеся, що «From» відповідає вашому автентифікованому домену.
Налаштування SMTP для WordPress, яке витримує продакшн
WordPress використовує PHPMailer під капотом. Класичний режим відмови — коли WordPress налаштовано «відправляти», але транспорт відсутній (не має MTA) або ненадійний (спільний IP без автентифікації). SMTP вирішує обидві проблеми, роблячи відправку явною.
Виберіть один SMTP-плагін — і ставтесь до нього як до інфраструктури
Я не збираюсь агітувати за конкретні бренди. Виберіть надійний SMTP-плагін, який:
- підтримує автентифікований SMTP з TLS
- може логувати спроби відправлення і помилки
- дозволяє встановити стабільний From name/email
- підтримує OAuth, якщо ваш провайдер вимагає
Правила конфігурації, які запобігають звичайним катастрофам
- Використовуйте порт 587 з STARTTLS, якщо провайдер явно не вимагає 465 (implicit TLS). Порт 25 — для сервер-сервер і часто блокується.
- Встановіть From Email в реальну скриньку або авторизованого відправника у тому ж домені, який ви автентифікуєте. Не використовуйте
wordpress@localhostабоno-reply@yourdomain, якщо реле не дозволяє і ваш DNS не вирівнюється. - Примусово задавайте From Email і From Name для транзакційної пошти. Плагіни і теми люблять перезаписувати заголовки; це ламає вирівнювання і створює «випадкові» проблеми доставки.
- Не використовуйте особисті облікові дані пошти для сайту. Використовуйте сервісний акаунт або API-ключ релея. Регулярно обертайте. Зберігайте в менеджері секретів, якщо він у вас є.
- Увімкніть логування плагіна, принаймні під час налаштування. Вам потрібні часові мітки і SMTP-коди помилок.
- Розділяйте транзакційну і маркетингову пошту, якщо обсяг зростає. Навіть у того самого провайдера використовуйте окремі субдомени або ідентичності відправника, щоб одне не отруїло репутацію іншого.
Ідентичність: адреса «From» — це не дизайнерський вибір
Для DMARC-узгодженої пошти видимий заголовок From: повинен вирівнюватися з:
- SPF-узгодженим доменом (envelope sender / return-path), або
- домем підпису DKIM d= (домен, що підписує повідомлення)
Якщо ви автентифікуєте SMTP як wordpress@example.com, але плагін встановлює From як wordpress@some-other-domain, DMARC може не пройти навіть якщо SMTP-автентифікація успішна. Ось чому «SMTP працює, але листи все одно зникають».
Жарт #2: Заголовок «From» — як бейджик на конференції: якщо він не відповідає вашій реєстрації, служба безпеки зацікавиться.
DNS і автентифікація домену: SPF, DKIM, DMARC
SMTP виводить лист за поріг. Автентифікація змушує його прийняти — і ставитися як до відповідального учасника. У 2025 році припускайте, що великі поштові провайдери за замовчуванням підозріливі.
SPF: авторизуйте відправників, не ускладнюйте
SPF — це TXT-запис, який каже «ці хости/IP можуть надсилати пошту від мого домену». Приймачі перевіряють підключений IP проти цієї політики.
Правила, щоб SPF залишався здоровим:
- Публікуйте рівно один SPF-запис для домену.
- Використовуйте
include:механізми для вашого релей-провайдера; уникайте перерахування десятків IP, якщо ви ними не володієте. - Слідкуйте за лімітом DNS-запитів (10). Надто багато include може спричинити SPF PermError.
- Визначте політику:
~all(softfail) під час міграції;-all(fail) коли впевнені.
DKIM: цілісність і ідентичність домену
DKIM підписує вихідну пошту приватним ключем; отримувачі перевіряють підпис за публічним ключем у DNS. Це доводить, що повідомлення не змінювалося в дорозі і пов’язує його з доменом.
Операційні нотатки:
- Використовуйте 2048-бітні ключі, де це підтримується.
- Ротуруйте селектори періодично (наприклад,
s1,s2). Залишайте старі селектори під час перекриття. - Остерігайтеся «допоміжних» плагінів або релеїв, які переписують HTML або додають футери; це може зламати DKIM, якщо підпис накладається до змін (провайдери зазвичай підписують після перепису).
DMARC: політика, вирівнювання і різниця між «відправлено» і «довірено»
DMARC каже приймачам, що робити, якщо SPF і DKIM не вирівняні з видимим доменом From, і куди надсилати звіти.
Практичний прогрес DMARC:
- Почніть з p=none, щоб вимірювати без ламання пошти.
- Перейдіть до p=quarantine, коли виправите очевидні невідповідності та сторонніх відправників.
- Використовуйте p=reject, коли впевнені, що не блокуєте легальну пошту (і перерахували всі системи, що відправляють від вашого домену).
Пастки вирівнювання саме в WordPress
- Плагіни контактних форм іноді встановлюють From на адресу відвідувача. Це гарантований DMARC-фейл. Використовуйте Reply-To для адреси відвідувача.
- Multisite налаштування можуть мати різні From-домени для підсайтів. Якщо ви не можете автентифікувати їх усі — доставка буде непослідовною.
- Сторонні маркетингові інструменти теж можуть відправляти від кореневого домену. Координуйте SPF/DKIM/DMARC або розділіть субдомени.
Реальність доставлюваності: репутація, ліміти і контент
Коли SMTP приймає повідомлення, ви потрапляєте в область евристик, систем репутації та політик проти зловживань. Це не особисто. Це математика.
Що насправді означає «accepted for delivery»
Коли ваше реле каже «250 Accepted», це означає, що реле взяло відповідальність на себе за спробу доставки. Це не гарантує попадання у вхідні. Воно навіть не гарантує, що отримувач прийняв — тільки що реле спробує.
Репутація: ваш домен і патерни відправлення
Поштові провайдери будують репутацію з таких сигналів:
- послідовна автентифікація (SPF/DKIM/DMARC вирівнювання)
- низькі рівні відскоків
- низькі скарги (користувачі натискають «спам» рідко)
- сталий обсяг відправлень (раптові сплески видаються за компрометацію)
- якість контенту та репутація посилань
Обмеження по швидкості і тимчасові помилки
Багато SMTP-помилок — це тимчасові 4xx: «спробуйте пізніше». Хороший реле повторює з backoff. Погана конфігурація позначає як помилку миттєво, і ви про це не дізнаєтеся, окрім скарг користувачів.
Контент: листи WordPress можуть виглядати як наживка для фільтрів
Поширені тригери:
- форми, що дозволяють довільний користувацький вміст, включно з підозрілими URL
- повідомлення з поганим співвідношенням тексту до HTML або дивними кодуваннями
- тематики, що виглядають як фішинг («Терміново: перевірка облікового запису»)
- відправлення «From» від домену без веб-історії (новий домен, без історії)
Якщо ваше повідомлення містить контент, створений користувачем, розглядайте його як недовірений вхід. Очищуйте. Обмежуйте посилання. Подумайте про те, щоб надсилати мінімальне повідомлення з посиланням для перегляду повідомлення в межах вашого автентизованого веб-додатку.
Три корпоративні міні-історії з практики
Міні-історія #1: Інцидент через хибне припущення
Налаштування виглядало нормально: WordPress на керованому VPS, плагін контактної форми і адреса From встановлена як support@company.example. Команда припустила, що оскільки сайт використовує домен компанії, автентифікація пошти вже налаштована. Раніше вони налаштували SPF для платформи розсилок і вирішили, що цього досить.
Потім тихо змінилася політика DMARC: з p=none на p=quarantine після аудиту безпеки. Нікому не повідомили веб-команду. Раптом листи з контактної форми перестали доходити для частини отримувачів — переважно корпоративних скриньок із суворішою фільтрацією.
Першою реакцією було звинуватити WordPress. Далі — перевстановити плагін. Потім — «просто використовувати PHP mail()». Нічого з цього не допомогло. Справжня проблема: плагін контактної форми ставив From як адресу відвідувача (щоб зручно відповідати). Це означало, що вирівнювання DMARC не проходило для кожного повідомлення, де відвідувач використовував домен з p=reject (а таких багато).
Виправлення було нудним: залишити From як support@company.example, встановити Reply-To на адресу відвідувача. Додати DKIM-підпис через правильне реле. Інцидент закінчився не героїчним патчем, а тим, що заголовок припинив «брехати».
Міні-історія #2: Оптимізація, яка відбилася боком
Інша організація мала інтернет-магазин на WooCommerce з великим трафіком. Вони платили за реле і вирішили «оптимізувати», відправляючи скидання паролів і підтвердження замовлень через власний Postfix, щоб заощадити. У них був IP, сервер і переконання, що «пошта — це просто SMTP».
Два тижні працювало. Потім доставлюваність погіршилася. Деякі великі поштові провайдери почали відкладати з 4xx через ліміти. Інші масово скидали в bulk. Черга підтримки забилася повідомленнями «Я не отримав чек». Гірше: скидання пароля зникали періодично, що створювало блокування акаунтів і повернення грошей, бо клієнти не могли отримати доступ до статусу замовлення.
Команда налаштовувала Postfix, міняла HELO, пробували інші домени. Вони ганялися за симптомами. Справжня проблема — репутація і поведінка: новий IP з різкими патернами обсягу, без встановленої довіри і інколи bounce через помилки в адресах.
Вони повернулися до провайдера-реле для транзакційної пошти і залишили Postfix лише як точку локальної підміни в релей (smarthost), а не як прямий відправник. «Оптимізація» економила гроші, поки не перестала. Проблема була не в технічній складності — а в недооцінці важливості історії відправника для приймачів.
Міні-історія #3: Нудна, але правильна практика, що врятувала ситуацію
Одна SaaS-компанія запускала кілька WordPress-інстансів для маркетингових сайтів і документації. Їх раніше вже підвели, тож вони стандартизували відправку пошти: всі WordPress використовували одного релей-провайдера, окремий домен відправника (mail.company.example) і примусове встановлення From. Логи SMTP централізувалися.
Одного понеділка скидання паролів уповільнилися. Не зупинилися — уповільнилися. Helpdesk помітив патерн: користувачі Gmail отримували листи, деякі корпоративні домени — ні. SRE на чергуванні не чіпав WordPress. Він подивився логи релея і побачив збільшення 4xx deferral від конкретної сім’ї доменів отримувачів.
Оскільки у них були DMARC-звіти і послідовне DKIM-підписання, вони швидко виключили проблему автентифікації. Відкладання були через обмеження на боці отримувача. Реле автоматично повторював спроби з backoff, і доставка наздогнала протягом кількох годин.
Порятунок не вимагав хитрощів. Він полягав у тому, що вони додали спостережуваність і послідовність у нудну інфраструктуру пошти, тож інцидент став інформаційним оновленням, а не панікою.
Поширені помилки: симптом → корінь → виправлення
1) «WordPress каже відправлено, але нічого не приходить»
Корінь: Використання PHP mail() без робочого MTA, або з локальним MTA, який не може доставити (порт 25 заблоковано, немає релея, черга застрягла).
Виправлення: Налаштуйте автентифікований SMTP до релея на 587/465. Якщо ви змушені використовувати локальний MTA — налаштуйте його як smarthost і моніторте чергу.
2) «SMTP працює у тестовому листі плагіна, але листи з контактних форм не доходять»
Корінь: Плагін контактної форми ставить From як адресу відвідувача; вирівнювання DMARC не проходить або реле відкидає спуфінг.
Виправлення: Встановіть From на ваш домен (вирівняний з DKIM/SPF). Помістіть адресу відвідувача в Reply-To. Більшість плагінів має таку опцію.
3) «Authentication failed» або «535 5.7.3 Authentication unsuccessful»
Корінь: Неправильні облікові дані, неправильний метод автентифікації, basic auth вимкнено або провайдер вимагає app password/OAuth.
Виправлення: Використовуйте метод, затверджений провайдером: app password, облікові дані SMTP релея або OAuth. Перевірте порт/шифрування. Не використовуйте особисті паролі.
4) «Connection timed out» до SMTP-хоста
Корінь: Egress firewall, security group, блокування вихідного SMTP хостом, неправильний DNS або зламаний маршрут IPv6.
Виправлення: Тестуйте за допомогою nc і openssl s_client. Дозвольте egress до релея на 587/465. Вимкніть некоректний IPv6 або виправте маршрутизацію.
5) Листи йдуть у спам у великих провайдерів
Корінь: Відсутній або некоректний DKIM, SPF PermError (декілька SPF-записів), DMARC невідповідність, або погана репутація.
Виправлення: Опублікуйте правильний SPF (один запис), увімкніть DKIM, додайте DMARC (почніть з p=none), забезпечте вирівнювання From з автентифікованим доменом. Розгляньте використання надійного релея і поступовий прогрів відправлень.
6) «Деякі отримувачі отримують пошту, інші ні»
Корінь: Фільтрація на стороні отримувача, greylisting, лімітування або блокування IP/домену.
Виправлення: Використовуйте реле з повторними спробами та логами. Перевірте лог подій релея на дефери та bounce. Не очікуйте однакової поведінки від усіх отримувачів.
7) Листи для скидання пароля перестали працювати після міграції сайту
Корінь: Репутація нового хоста/IP, відсутні DNS-записи в новій зоні DNS або відправлення з домену, неавторизованого новим релеєм.
Виправлення: Перевірте SPF/DKIM/DMARC у активній зоні DNS. Використайте ті самі облікові дані релея і домен відправника. Переконайтесь, що From не повернувся до дефолту.
8) «Працювало, поки ми не увімкнули кеш/CDN/плагін безпеки»
Корінь: Зазвичай не кеш. Часто це збіг змін: оновлення плагіна, обертання облікових даних, зміна політики провайдера, посилення фаєрволу або зупинка cron, через що черга повідомлень не надсилається.
Виправлення: Перевірте wp-cron/реальний cron, підключення SMTP і логи плагінів. Корелюйте часові мітки з деплоєм і зміною облікових даних.
Чеклісти / покроковий план
Покроково: від «немає пошти» до «надійної доставки»
- Визначте архітектуру: використовуйте виділене SMTP-реле для транзакційної пошти.
- Виберіть ідентичність відправника: наприклад,
no-reply@example.comабоsupport@example.com— але зробіть її реальною та вирівняною. - Налаштуйте SMTP-плагін WordPress: хост, порт 587, STARTTLS, автентифікація ввімкнена, примусове From.
- Опублікуйте SPF: один запис, що включає релей-провайдера.
- Опублікуйте DKIM: селекторні записи як надає реле.
- Опублікуйте DMARC: почніть з
p=noneзі звітністю, потім рухайтеся до примусового режиму, коли стабільно. - Запустіть тести з хоста:
nc+openssl s_clientдо релея. - Відправте тестовий лист: підтвердіть, що реле приймає і одержувач отримує.
- Виправте вирівнювання для форм: From = ваш домен, Reply-To = відвідувач.
- Увімкніть логування: логи плагіна + логи релея; зберігайте їх достатньо довго для діагностики.
- Налаштуйте моніторинг: алерти на стійкі відмови відправлень, ріст черги (якщо релевантно) і сплески bounce.
- Документуйте «відомо добру» конфігурацію: місце зберігання облікових даних, DNS-записи і причини вибору цього релея.
Операційний чекліст: що перевіряти під час інциденту
- Чи може сервер дістатися до релея на 587/465?
- Чи не обернулися або не закінчилися облікові дані?
- Будь-які останні оновлення WordPress/плагінів?
- Будь-які зміни DNS (SPF/DKIM/DMARC) або перемикання зони?
- Логи релея: відхилення (5xx) vs відкладання (4xx) vs прийнято.
- Чи стосуються проблеми конкретних доменів отримувачів?
Жорсткі правила (бо вам це захочеться зробити)
- Не надсилайте листи контактних форм з From як адресу відвідувача. Використовуйте Reply-To.
- Не покладайтеся на PHP mail() у середовищах, які ви не контролюєте. Якщо ви не можете читати логи пошти, у вас немає системи.
- Ніколи не публікуйте кілька SPF-записів.
- Не використовуйте спільні облікові дані поштових скриньок у продакшні. Створіть сервісну ідентичність.
ЧаПи
1) Чому WordPress «працює» на одному хості, але не на іншому?
Тому що PHP mail() залежить від MTA і мережевих політик хоста. Один хост має налаштований реле, інший — нічого за /usr/sbin/sendmail, або вихідний SMTP заблоковано.
2) Використовувати порт 465 чи 587?
Використовуйте 587 з STARTTLS, якщо провайдер прямо не вимагає 465. Обидва можуть бути захищеними; 587 — сучасний стандарт для submission і зазвичай краще проходить через фаєрволи.
3) Тест SMTP каже «успіх», але листи все одно не показуються. Що робити?
Це питання доставлюваності або фільтрації на боці отримувача. Перевірте вирівнювання SPF/DKIM/DMARC, логи релея на bounce/deferral і протестуйте відправлення до кількох провайдерів. Також перевірте папки спаму/карантину.
4) Можу я просто використовувати облікові дані Gmail або Microsoft 365?
Можете, але це крихке. Провайдери змінюють правила автентифікації, вимагають MFA і обмежують пропускну здатність. Віддавайте перевагу виділеному релею або офіційним app password/OAuth з сервісним акаунтом.
5) Яку адресу From використовувати для WooCommerce?
Використовуйте адресу в вашому домені, яку ви автентифікуєте (наприклад, orders@example.com). Примусово встановіть її в SMTP-плагіні, щоб шаблони і розширення не підміняли її і не ламали вирівнювання.
6) Чому листи з контактних форм часто не доходять тільки для певних відправників?
Якщо форма ставить From як адресу відвідувача, політика DMARC домену відвідувача може призвести до відхилення або поміщення в спам. Багато великих доменів мають суворий DMARC саме для цього.
7) Чи потрібен DKIM, якщо SPF вірний?
Так, якщо ви хочете стабільної доставлюваності. SPF ламається при пересилці, і він не підписує вміст. DKIM додає цілісність і часто підвищує довіру. DMARC працює краще, коли є обидва механізми.
8) Який найшвидший спосіб зрозуміти, чи це мережевий блок?
Запустіть nc -vz relay 587 і openssl s_client -starttls smtp з хоста WordPress. Таймаути і повідомлення «no route» краще за здогади.
9) Чи коли-небудь варто запускати власний Postfix для вихідної пошти?
Іноді: якщо у вас є поштовий відділ, стабільний IP-простір, контроль PTR і бажання керувати репутацією та зловживаннями. Для більшості WordPress-сайтів реле через провайдера економить час.
10) Як припинити попадання листів у спам без зміни контенту?
Почніть з вирівнювання автентифікації (SPF/DKIM/DMARC), потім — послідовності відправлень (сталий обсяг) і репутації (використовуйте надійний реле). Зміни контенту допомагають, але ідентичність — фундамент.
Наступні кроки, які ви можете зробити сьогодні
Якщо WordPress-пошта не працює — не сперечайтеся з нею. Інструментуйте її і дайте реальний транспорт.
- Відмовтеся від PHP mail(), якщо ви не експлуатуєте локальний MTA з логами і шляхом ретрансляції.
- Налаштуйте автентифікований SMTP до виділеного релея на 587/465 і протестуйте з хоста підключення.
- Опублікуйте і перевірте SPF/DKIM/DMARC і впевніться, що адреса From у WordPress вирівнюється з тим, що автентифікує ваше реле.
- Виправте плагіни форм, щоб адреса відвідувача ставала Reply-To, а не From.
- Зберігайте логи (плагін + реле) і використовуйте їх, щоб відрізняти проблеми транспорту від проблем доставлюваності.
Зробіть це, і «WordPress не відправляє пошту» перестане бути загадкою й перетвориться на нудну, моніторовану підсистему. Нудно — це добре. Нудно — це спосіб спати спокійно.