Не так давно начал мигрировать на Docker, слепил себе контейнер для php-fpm, но основное с чем возникли сложности - это отправка почты.
Если использовать почту в домене и авторизовываться в ящике, то можно прикрутить какой-нибудь PHPMailer, но я хотел обычный почтовик настроить, чтобы от любого емейла слать уведомления с сайта и не пользоваться услугами почтовых сервисов для этого.
Изначально пишем примерно такой скрипт
<?php
$to = 'mymail@gmail.com';
$subject = 'the subject';
$message = 'hello4';
$headers = 'From: admin2@site.ru' . "\r\n" .
'X-Mailer: PHP/' . phpversion();
mail($to, $subject, $message, $headers);
Настройка хоста
На самом хосте ставим Postfix, настраиваем его nano /etc/postfix/main.cf
#обязательно указать PTR на ваш айпи равный этому
myorigin = web.mydomain.ru
smtpd_banner = $myhostname ESMTP $mail_name (Debian/GNU)
biff = no
append_dot_mydomain = no
readme_directory = no
compatibility_level = 2
# TLS parameters
smtpd_tls_cert_file=/etc/ssl/certs/ssl-cert-snakeoil.pem
smtpd_tls_key_file=/etc/ssl/private/ssl-cert-snakeoil.key
smtpd_use_tls=yes
smtpd_tls_session_cache_database = btree:${data_directory}/smtpd_scache
smtp_tls_session_cache_database = btree:${data_directory}/smtp_scache
# See /usr/share/doc/postfix/TLS_README.gz in the postfix-doc package for
# information on enabling SSL in the smtp client.
#тут хак для подмены отправителя из докеров
sender_canonical_classes = envelope_sender
sender_canonical_maps = regexp:/etc/postfix/sender_canonical_maps
smtpd_relay_restrictions = permit_mynetworks permit_sasl_authenticated defer_unauth_destination
mydomain = $myhostname
alias_maps = hash:/etc/aliases
alias_database = hash:/etc/aliases
mydestination = localhost
#указать, если нужно слать через почтарь хостера
relayhost =
#последним подсеть докеров - допустимые доверительные подсети
mynetworks = 127.0.0.0/8 [::ffff:127.0.0.0]/104 [::1]/128 172.17.0.0/24
mailbox_size_limit = 0
recipient_delimiter = +
inet_interfaces = all
inet_protocols = ipv4
smtp_tls_security_level = may
Далее создадим файлик nano /etc/postfix/sender_canonical_maps
/.+/ postmaster@web.mydomain.ru
Настройки в докере
apk add ssmtp
И конфиг /etc/ssmtp/ssmtp.conf
rewriteDomain=web.mydomain.ru
FromLineOverride=YES
mailhub=172.17.0.1
#hostname=web.mydomain.ru
UseTLS=YES
UseSTARTTLS=YES
В чем был подвох?
ssmtp это минималистичный мейлер из докера, в нем прописан адрес нашего хоста 172.17.0.1 и прописан домен, которым он должен прикидываться, в postfix вся подсеть из докера в доверенной зоне.
Если на этом остановиться, то почта по идее ходила, но она была от имени root, т.е. From не работал, после того, как я прописал FromLineOverride=YES
- у меня адекватно заработал From и отправитель отображался корректно, но при этом почта попадала в спам на gmail. Но при этом с самого хоста почта работала хорошо и досылалась и в спам не попадала.
Оказывается в smtp есть сам заголовок в теле письма и есть еще заголовки при общении почтарей, это smtp.from, утилита ssmtp подменяла всё и сразу из заголовка From, а гугл проверял домен @... и говорил что ваш сервер не имеет права от него слать и письмо в спам улетало.
Вот тут и помогла подмена отправителя следующей конструкцией
sender_canonical_classes = envelope_sender
sender_canonical_maps = regexp:/etc/postfix/sender_canonical_maps
Обратите внимание! nslookup <ip> должен возвращать тот домен, который везде фигурирует, в моем примере это web.mydomain.ru