В последнее время подключить почту к домену не составляет особого труда: сервисы Yandex, Google, Mail.ru и т.п. предоставляют широкие возможности для работы с почтой на своём домене. Там можно создавать ящики, заводить пользователей, настраивать учётные записи, принимать и отправлять почту через популярные клиенты. Но есть одно большое НО — ограничения на отправку писем. Если отправлять много однотипных писем, например через Яндекс, то рано или поздно это заблокируют. Причём решения принимает не человек, а бездушная машина, которой абсолютно без разницы, отсылаете ли вы письма себе или своим коллегам, или добропорядочным клиентам.
Но можно ли сделать так, чтобы письма с сайта отправлять прямо с сервера сайта, а принимать на Yandex или Google? Да, можно!
Прежде чем настраивать почтовый сервер убедитесь, что хостинг-провайдер разрешает использовать SMTP-порты (25, 465 и другие). Многие провайдеры по умолчанию блокируют эти порты и открывают при обращении в службу поддержки. Уточните у своего хостера требования для того, чтобы безбоязненно рассылать письма, а также требования к самим письмам, чтобы они не подпадали под определение SPAM.
Быстрая проверка доступности SMTP через консоль:
telnet smtp.yandex.ru 25
Если появится примерно такой текст, то порты открыты:
Trying 77.88.21.158...
Connected to smtp.yandex.ru.
Escape character is '^]'.
220 sas1-27140bb19246.qloud-c.yandex.net ESMTP (Want to use Yandex.Mail for your domain? Visit https://pdd.yandex.ru
А вот так выглядит сообщение, если порты закрыты и придётся обращаться в поддержку хостера:
Trying 77.88.21.158...
Trying 2a02:6b8::19d...
telnet: Unable to connect to remote host: Network is unreachable
DMARC — это набор правил и протоколов для авторизации почты. Если перевести на общечеловеческий, то это будет означать "делай вот так и письма не будут сразу падать в спам".
Дело в том, что протоколы электронной почты разрабатывались в те славные времена, когда люди доверяли друг другу. И если на сервер приходило письмо, то оно сразу падало в ящик получателя. Сам протокол отправки писем не предполагает авторизацию сервера, который отправляет письмо, а это значит, что любое устройство в сети Интернет может слать письма от кого угодно и куда угодно. Да-да, именно от кого угодно и куда угодно!
DMARC позволяет:
То есть DMARC не решает проблемы спама на 100%, но позволяет понимать, что письмо было отправлено и доставлено с добросовестного сервера, а не с кофеварки бабы Маши. Если не выполнять требования DMARC, то вероятность того, что ваше письмо отправится в спам, будет примерно 100%.
Помимо DMARC существует ещё один способ проверить, что сервер, который отправляет письмо, это настоящий сервер, а не кофеварка. Надо всего лишь получить его PTR-запись по IP-адресу:
# Получаем IP-адрес по домену
$ host mta-6.email2.gog.com
mta-6.email2.gog.com has address 188.114.82.45
# Получаем домен по IP-адресу
$ host 188.114.82.45
45.82.114.188.in-addr.arpa domain name pointer mta-6.email2.gog.com.
К сожалению, самостоятельно задать PTR-запись нельзя, этим занимаются хостинг-провайдеры. Если для вашего сервера PTR-запись не указана или там неверное значение, обратитесь в поддержку хостинг-провайдера для уточнения этого момента.
Без PTR-записи некоторые сервера не будут даже и пытаться принимать вашу почту, сразу обрывают соединение. Лучше уточните этот вопрос заранее.
Все команды необходимо выполнять в консоли от суперпользователя.
Для удобства сделаем алиасы для замены доменов из примеров на ваши значения:
alias my_smtp_host='sed "s/smtp.example.com/ВАШ_ХОСТ/g"'
alias my_mail_domain='sed "s/example.org/ВАШ_ПОЧТОВЫй_ДОМЕН/g"'
ВАШ_ХОСТ
— домен вашего сервера, где будет работать POSTFIX. Если на этом сервере у вас размещён сайт, то можно указать
домен сайта.ВАШ_ПОЧТОВЫй_ДОМЕН
— домен, с которого будет приходить почта (@mydomain.tld).Дальше будут приводиться конфиги с smtp.example.com
и example.org
, а фильтры будут заменять их на правильные значения.
Все команды оптимизированы для копирования и вставки в консоль БЕЗ редактирования (кроме тех мест, где встречается ВАШ_...
,
там нужно вставлять ваши значения).
Задаём имя хоста
echo smtp.example.com | my_smtp_host > /etc/hostname
echo 127.0.0.1 smtp.example.com | my_smtp_host >> /etc/hosts
Теперь следующая команда должна выводить ВАШ_ХОСТ
:
hostname --fqdn
Если выводится ошибка или значение отличное от вашего хоста, проверьте /etc/hostname
и /etc/hosts
.
Устанавливаем и настраиваем POSTFIX
apt install postfix mailutils
Создаём конфиг (предполагается, что сервер будет только отправлять письма, а принимать будет кто-нибудь другой):
(cat | my_smtp_host > /etc/postfix/main.cf) <<EOF
# Настройки доменов
myhostname = smtp.example.com
mydomain = smtp.example.com
myorigin = smtp.example.com
# Тут что-то на эльфийском
compatibility_level = 2
command_directory = /usr/sbin
daemon_directory = /usr/lib/postfix/sbin
milter_default_action = accept
# Подсети, на которых будет работать постфикс
inet_interfaces = 127.0.0.1
mynetworks = 127.0.0.0/8
inet_protocols = ipv4
# Ограничение на попытки отправить письмо (30 минут, чтобы не забивать очередь)
maximal_queue_lifetime = 30m
bounce_queue_lifetime = 30m
# Добавляем некоторые важные заголовки, если их нет (например Date, Message-ID)
always_add_missing_headers = yes
# Папка для писем
data_directory = /var/lib/postfix
EOF
Перезапускаем POSTFIX:
service postfix stop; service postfix start
Устанавливаем OpenDKIM:
apt install opendkim opendkim-tools net-tools
Создаём конфиг:
mv /etc/opendkim.conf /etc/opendkim.conf.orig
(cat | my_mail_domain > /etc/opendkim.conf) <<EOF
AlwaysAddARHeader Yes
SubDomains Yes
RemoveARAll Yes
RemoveOldSignatures Yes
SendReports Yes
Canonicalization relaxed/relaxed
Mode sv
UserID opendkim:opendkim
Syslog Yes
SyslogSuccess Yes
LogWhy Yes
KeyTable /etc/opendkim/KeyTable
SigningTable refile:/etc/opendkim/SigningTable
## Настройки для работы внурисети (определяют сети/хосты, с которых письма должны подписываться)
#ExternalIgnoreList refile:/etc/opendkim/TrustedHosts
#InternalHosts refile:/etc/opendkim/TrustedHosts
PidFile /run/opendkim/opendkim.pid
Socket inet:10021@localhost
ReportAddress "DKIM Error Postmaster" <postmaster@example.org>
EOF
Создаём папку для хранения ключей и таблиц:
mkdir -m 750 /etc/opendkim && chown opendkim:opendkim /etc/opendkim
Генерируем ключи для домена из настроек POSTFIX и селектора key1
:
opendkim-genkey -D /etc/opendkim --domain=$(echo example.org | my_mail_domain) --selector=key1
Селектор указывает на то, какую запись домена нужно будет использовать для хранения публичного ключа.
Задаём верные права на доступ к приватному ключу:
chown opendkim:opendkim /etc/opendkim/*.private
chmod 600 /etc/opendkim/*.private
Заполняем таблицу приватных ключей (имя_ключа домен:селектор:/путь/до/ключа
):
echo "key1 example.org:key1:/etc/opendkim/key1.private" | my_mail_domain > /etc/opendkim/KeyTable
Говорим, какой домен, каким ключом подписывать (шаблон имя_ключа
):
echo "*@example.org key1" | my_mail_domain > /etc/opendkim/SigningTable
Перезапускаем OpenDKIM:
service opendkim restart
Прописываем настройки для POSTFIX:
cat >> /etc/postfix/main.cf <<EOF
# Настройки DKIM
smtpd_milters = inet:localhost:10021
non_smtpd_milters = inet:localhost:10021
EOF
service postfix restart
Выводим конфиг TXT-записи с публичным ключом для домена:
echo $(cat /etc/opendkim/key1.txt) | sed 's/" "//g;s/[\(\)]//g;s/ *; --.*//'
Идём в панель управления DNS и добавляем TXT-запись key1._domainkey
со значением,
которое указано в кавычках (кавычки вносить не нужно).
Если всё сделано правильно, то через некоторое время запись можно получить командой:
host -t txt key1._domainkey.$(echo example.org | my_mail_domain)
Результат должен быть примерно такой:
key1._domainkey.ВАШ_ПОЧТОВЫЙ_ДОМЕН descriptive text "v=DKIM1; h=sha256; k=rsa; p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCg
KCAQEA6gsfUaFIqMgCvqiwNKQ0rlbH0JTOz1od+EuicKg8SmhtaI+W6Ro2OBI38L9slMjTRIOrwCT8FqvZ532Dgn6hyrePuy4PRUzPjx5mgW5mE1PbLOw77
bMK0vEn52Oyw1L/BNb6KpKJagQo+xffAgxCCfdB/ZBDEMZqPKeyo4IdrXNrIF89I9rask5" "wnQTAmJWt0/kWai3JwkkGFlLNEnhduNAqxH9I9ECrXyP2m
GEbTvmbjFMq8grJ9/LF4dZTmUgjmIcpyxR2ao7+edHB4y0+V4752oXL/MMc3dSbhp8+EhFE19TPKE44NZMMRS2Iv3xbNfxqjd+W1ThEZ7nHoFLMOQIDAQAB"
Необходимо перейти в панель управления доменом, с которого будет отправляться почта.
Если домен уже привязан к какой-либо почте
Находим в настройках домена TXT-запись, которая начинается с v=spf1
и добавляем в середину информацию о дополнительном
сервере, например так:
v=spf1 a:ВАШ_ХОСТ redirect=_spf.yandex.net
Запись a:ВАШ_ХОСТ
означает, что в результирующий список разрешённых адресов нужно добавить IP-адреса, которые указаны
в A-записях домена ВАШ_ХОСТ
. Запись redirect=_spf.yandex.net
и другие подобные оставляйте как есть, они нужны для
работы других служб.
Если домен не привязан к почте
Добавляем новую TXT-запись к самому домену (иногда нужно указать @ в качестве имени хоста) следующего содержания:
v=spf1 a:ВАШ_ХОСТ -all
Такая запись означает "доверять почте с сервера ВАШ_ХОСТ
и не доверять остальным".
После внесения изменений
Выполните следующую команду, чтобы проверить настройки домена:
host -t txt $(echo example.org | my_mail_domain) 8.8.8.8
Если изменения успели попасть на сервер, то результатом будет значение, которое вы внесли, а если нет, придётся
ждать. Время ожидания зависит от того, как быстро ДНС-сервер вашего провайдера применяет настройки, и сколько времени
живёт запись (TTL). И то и другое можно проверить с помощью команды dig
:
$ dig TXT anton-pribora.ru @dns1.yandex.net
; <<>> DiG 9.16.1-Ubuntu <<>> TXT anton-pribora.ru @dns1.yandex.net
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 65139
;; flags: qr aa rd; QUERY: 1, ANSWER: 1, AUTHORITY: 2, ADDITIONAL: 1
;; WARNING: recursion requested but not available
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;anton-pribora.ru. IN TXT
;; ANSWER SECTION:
anton-pribora.ru. 21600 IN TXT "v=spf1 redirect=_spf.yandex.net"
;; AUTHORITY SECTION:
anton-pribora.ru. 900 IN NS dns2.yandex.net.
anton-pribora.ru. 900 IN NS dns1.yandex.net.
;; Query time: 20 msec
;; SERVER: 213.180.204.213#53(213.180.204.213)
;; WHEN: Сб июл 31 14:05:21 +05 2021
;; MSG SIZE rcvd: 137
Ищите строчку ;; ANSWER SECTION:
, под ней будут нужные вам значения: число перед IN
, это секунды жизни записи, а строка
после TXT
— значение. Однако, если вы делегируете домен на Яндекс (как и я), то независимо от того, что показывает dig
,
изменения могут вступить в силу только спустя несколько дней (старый баг, который они постоянно обещают исправить).
Проверяем запущенные сервисы:
netstat -lp4n | grep -E '(:25|:10021)'
Должно быть две записи:
tcp 0 0 127.0.0.1:25 0.0.0.0:* LISTEN 11201/master
tcp 0 0 127.0.0.1:10021 0.0.0.0:* LISTEN 12893/opendkim
Если что-то не запустилось, смотрите /var/log/syslog
на предмет ошибок.
Теперь отправляем тестовое письмо:
echo "This is a test message" | mail -a "From: test@$(echo example.org | my_mail_domain)" -s test ВАШ_ЛИЧНЫЙ_ЯЩИК@gmail.com
И смотрим логи отправки:
tail -n100 /var/log/mail.log
Если ошибок нет, то письмо должно прийти в течение нескольких секунд. Проверяйте на всякий случай и папку спам.
Когда письмо придёт (на Google), откройте его исходный текст (Ctrl + U) и проверьте заголовок Authentication-Results
,
там будет информация о проверках сервера, откуда пришло письмо:
Authentication-Results: mx.google.com;
dkim=pass ...
spf=pass ...
Пока POSTFIX работает на 127.0.0.1, можно особо не переживать, что вас через него взломают или как-то навредят. Но как только вы измените внутренний адрес на внешний, ваш сервер может стать источником рассылки спама и целью для хакерских атак. На мой взгляд, самая безопасная схема работы — когда сервер только отправляет письма, а принимает и обрабатывает их кто-то другой. Протокол SMTP имеет слишком большие возможности для разного рода обмана и вредоносных действий. Вы с этим столкнётесь, когда откроете 25 порт для внешнего мира.
Как только POSTFIX будет настроен и сможет отправлять письма, то заработает и функция mail()
в PHP. Это значит, что
вы должны быть передельно осторожны с выбором программ, которые работают на сервере. Крайне не рекомендуется настраивать
POSTFIX на одном сервере с WordPress. Большинство атак на сайты заключаются в том, чтобы заразить сайт вирусом и рассылать
спам. Сам по себе WordPress не является чем-то опасным, угрозу представляют его плагины. Некоторые из них изначально
могут содержать вирусы, а некоторые имеют дыры и легко взламываются.
Следите за тем, куда и когда отправляются письма с вашего сервера (на основании /var/log/mail.log
). Попасть в чёрные
списки спамеров очень легко, а вот восстановить репутацию домена и IP-адреса в разы сложнее.