Когда я расположил приложение в Docker-контейнере и попробовал отправить email на почтовый сервер в другом Docker-контейнере, столкнулся с непредвиденной проблемой. Почтовый сервер postfix по умолчанию отправляет почту на произвольный домен получателя только от локального клиента. Все остальные домены нужно прописывать в параметре relay_domains, и если параметр mynetwors настроен правильно, то почта будет отправляться на перечисленные в параметре relay_domains домены с клиента из mynetwors.
В принципе, мне этого было достаточно, т.к. приложение теоретически должно было отправлять почту на ровно один корпоративный почтовый сервер. Но такое решение меня не очень устраивало, потому что задача может поменяться в любой момент. Поэтому, я попытался настроить sasl-авторизацию, которая позволяет отправять почту авторизованным пользователям на произвольный домен.
Результирующий файл Dockerfile достаточно прост, хотя при поиске решения пришлось повозиться, в основном с правами пользователей, о чем я расскажу немного подробнее.
FROM ubuntu:xenial
ARG UID
RUN
useradd -u $UID www-arc &&
apt-get update && apt-get install tzdata &&
echo Europe/Kiev | tee /etc/timezone &&
dpkg-reconfigure --frontend noninteractive tzdata &&
apt-get install -y postfix rsyslog sasl2-bin &&
postconf -e "mydestination = localhost" &&
postconf -e "myhostname = example.com" &&
postconf -e "always_bcc = www-arc@localhost" &&
postconf -e "smtpd_sasl_auth_enable=yes" &&
postconf -e "broken_sasl_auth_clients=yes" &&
postconf -e "smtpd_recipient_restrictions=permit_sasl_authenticated,reject_unauth_destination" &&
postconf -e "smtpd_client_restrictions = permit_sasl_authenticated,reject_unauth_destination" &&
postconf -e "smtpd_sasl_security_options = noanonymous" &&
echo 123456 | saslpasswd2 -c -p -u example.com postfix &&
ln /etc/sasldb2 /var/spool/postfix/etc/sasldb2 &&
adduser postfix sasl &&
touch /var/log/mail.log
COPY ./smtpd.conf /etc/postfix/sasl/smtpd.conf
CMD service rsyslog start && service postfix start && tail -f /var/log/mail.log
ln /etc/sasldb2 /var/spool/postfix/etc/sasldb2
По умолчанию postfix работет с файловой системой в «песочнице» /var/spool/postfix/. Там он будет искать файл с логинами /etc/sasldb2. Поэтому, задаем ссылку на файл /etc/sasldb2 из песочницы на реальный файл. Ссылка должны быть только жесткой (без параметра -s).
adduser postfix sasl
вполне понятное и очень важно действие позволяет работать postfix с файлом /var/spool/postfix/etc/sasldb2.
Правило postconf -e "smtpd_recipient_restrictions=permit_sasl_authenticated,reject_unauth_destination"
как раз и позволяет отправлять почту на произвольный домен всем прошедшим авторизацию sasl клиентам.
Конфигурация авторизации sasl в файле ./smtpd.conf:
log_level: 3
pwcheck_method: auxprop
auxprop_plugin: sasldb
mech_list: PLAIN LOGIN CRAM-MD5 DIGEST-MD5 NTLM
Параметр postconf -e "mydestination = localhost"
говорит о том, что почту для этого домена не отправлять дальше а принимать на этом хосте. Как показывает опыт, почтовые сервера, которые должны принимать почту, очень часто настроены неверно, теряют почту. Иногда это критично т.к. может вредить бизнесу, если почтовое сообщение содержит заявку клиента на приобретение товара или услуги. Поэтому данная конфигурация настроена на отправку копии локальному получателю postconf -e "always_bcc = www-arc@localhost"
. Это получатель создается с идентификатором текущего пользователя useradd -u $UID www-arc
.
Текущий пользователь определяется в конфигурации docker-compose:
postfix:
build:
context: ./docker/postfix
args:
- UID
volumes:
- ./docker/postfix/mail:/var/mail
При билде текущий пользователь передается из окружения env UID=$UID docker-compose build
.
Для подключения из другого контейнера docker к этому сервису, необходимо в качестве хоста указать postfix (название сервиса из docker-compose.yml), а имя с учетом домена (postfix@example.com) и пароль. Во всех случаях имя postfix не является обязательным инастраивается в конфигурации.
apapacy@gmail.com
8 апреля 2018 года
Автор: apapacy