Запуск почтового сервера в Docker (traefik + mailserver)
Настройка и запуск почтового сервера в Docker-контейнере
Электронная почта, несмотря на бурное развитие мессенджеров и социальных сетей, остается довольно популярным способом коммуникации. Кроме того email в большинстве случаев является выбором номер один в плане доставки чувствительных данных, например таких как пароли. В связи с чем, довольно часто стоит задача поднять свой собственный почтовый сервер, и данный материал попытается ответить на вопрос, как это сделать.
В предыдущем посте я рассказывал как использовать Traefik в качестве реверс-прокси для контейнеров Docker. Сейчас же мы рассмотрим связку Traefik с одним из популярных почтовиков Postfix. Почтовый сервер, как вы уже скорее всего догадались, будем так же запускать в докере. Для это возьмем вот эту реализацию - docker-mailserver.
КОНФИГУРИРОВАНИЕ TRAEFIK
Так как подключаться к нашему почтовому серверу мы планируем посредством шифрованного соединения с обязательным требованием аутентификации, то наш прокси-сервер должен уметь перенаправлять запросы со следующих портов 465 и 993:
- 465 порт необходим для отправки почты по протоколу
ESMTP
; - 993 порт необходим для получения почты по протоколу
IMAP4
;
Теперь когда мы определились с необходимыми портами, первым делом добавим две новые точки входа в наш прокси. Для этого внесем следующие изменения в файл traefik.yaml. Так же необходимо помнить, что порты, через которые мы
будем осуществлять коммуникации, должны быть добавлены в секцию ports
файла docker-compose
traefik.
entryPoints:
...
smtp-ssl:
address: :465
imap-ssl:
address: :993
После перезапуска контейнера с traefik, в дашборде должны появиться новые точки входа:
Соответственно должны появиться открытые порты:
# netstat -tulpn | grep docker-proxy
tcp6 0 0 :::465 :::* LISTEN 700540/docker-proxy
tcp6 0 0 :::443 :::* LISTEN 700552/docker-proxy
tcp6 0 0 :::993 :::* LISTEN 700528/docker-proxy
tcp6 0 0 :::80 :::* LISTEN 700564/docker-proxy
В моем случае, открытых портов я не увидел. Может быть из-за того, что я добавил соответствующие правила в iptables и перегрузил файрвол, или же traefik просто не подхватил порты. Но после перезагрузки демона Docker и перезапуска контейнера traefik, все завелось.
Запуск и настройка mailserver
И так, чтобы запустить наш почтовый сервер в докере, согласно документации нам необходимо четыре файла: docker-compose.yml
, compose.env
, mailserver.env
, setup.sh
.
Скачаем их все:
# mkdir mailserver && cd ./mailserver
# curl -O https://raw.githubusercontent.com/tomav/docker-mailserver/master/setup.sh
# curl -O https://raw.githubusercontent.com/tomav/docker-mailserver/master/docker-compose.yml
# curl -O https://raw.githubusercontent.com/tomav/docker-mailserver/master/mailserver.env
# curl -o .env https://raw.githubusercontent.com/tomav/docker-mailserver/master/compose.env
Добавим разрешения на запуск bash-скрипта:
# chmod a+x ./setup.sh
В файле .env необходимо указать HOSTNAME
и DOMAINNAME
Вашего почтового сервера.
В файле mailserver.env необходимо выставить значение SSL_TYPE
в letsencrypt, так как ssl-сертификаты мы планируем получать именно от данного поставщика.
Файл setup.sh оставляем без изменений, а вот в файл docker-compose.yml внесем наибольшее кол-во изменений.
Так как ssl-сертификаты мы будем использовать от Let’s Encrypt, то добавим следующий сервис:
whoami:
image: containous/whoami
restart: always
labels:
- "traefik.enable=true"
- "traefik.http.routers.whoami.entrypoints=https, http"
- "traefik.http.routers.whoami.rule=Host(`your_host.your_domain_name`)"
- "traefik.http.routers.whoami.tls=true"
- "traefik.http.routers.whoami.tls.certresolver=letsEncrypt"
Это позволит автоматически получать и продлевать ssl-сертификаты для домена нашего почтового сервера. Более подробно связку traefik и Let’s Encrypt я описывал в предыдущей статье.
Traefik и контейнеры, в которые проксируется трафик, должны находиться в одной сети, поэтому добавим следующие строки:
networks:
default:
external:
name: traefik_net
Имейте ввиду, у меня эта сеть называется traefik_net, и она является сетью по-умолчанию для всех моих контейнеров. У Вас же может быт совсем другая конфигурация. Более подробную информацию можете найти здесь.
Так как traefik выступает в роли прокси-сервера, то в секции ports
сервиса mail
оставим только 25й порт. Так же зададим необходимые значения для hostname
, domainname
и container_name
.
В секцию volumes
добавим файл, где traefik сохраняет данные о полученных сертификатах:
- /home/traefik/config/acme.json:/etc/letsencrypt/acme.json:ro
Последний штрих добавим метки, чтобы traefik знал, куда именно проксировать трафик:
labels:
- "traefik.enable=true"
- "traefik.tcp.routers.mail-smtp.rule=HostSNI(`your_host.your_domain_name`)"
- "traefik.tcp.routers.mail-smtp.entrypoints=smtp-ssl"
- "traefik.tcp.routers.mail-smtp.tls.passthrough=true"
- "traefik.tcp.routers.mail-smtp.service=mail-smtp"
- "traefik.tcp.services.mail-smtp.loadbalancer.server.port=465"
- "traefik.tcp.routers.mail-imap.rule=HostSNI(`your_host.your_domain_name`)"
- "traefik.tcp.routers.mail-imap.entrypoints=imap"
- "traefik.tcp.routers.mail-imap.tls.passthrough=true"
- "traefik.tcp.routers.mail-imap.service=mail-imap"
- "traefik.tcp.services.mail-imap.loadbalancer.server.port=993"
После запуска, в дашборде traefik можно наблюдать, два наших сервиса:
Выполним запуск контейнера и произведем первоначальную конфигурацию:
# docker-compose up -d
# ./setup.sh email add <user@domain> [<password>]
# ./setup.sh alias add postmaster@<domain> <user@domain>
# ./setup.sh config dkim
Теперь, когда почтовый сервер настроен, рассмотрим варианты, как сделать его более безопасным.
Защита от спуфинга с помощью SPF и DKIM
Спамеры могут сфальсифицировать ваше доменное имя, рассылая поддельные письма якобы от вашего почтового ящика. Это называется спуфингом. Чтобы этого избежать рекомендуется, использовать следующие методы аутентификации электронной почты в домене:
- SPF позволяют проверить, было ли письмо с указанным исходным доменом действительно отправлено с сервера, авторизованного владельцем этого домена;
- DKIM добавляет цифровую подпись к каждому сообщению. Это позволяет принимающему серверу проверить, не было ли сообщение подделано или изменено при доставке;
Чтобы включить SPF у регистратора домена, необходимо добавить DNS запись TXT для SPF, следующего содержания:
v=spf1 a mx:mail.your_domain ip4:xxx.xxx.xx.xxx/32 ip6:xxxx:xxx:xxxx:xxx::1 ~all
Теги, которые используются для создания записи TXT для SPF, называются механизмами. Ниже приведен список механизмов, которые определены в строке выше:
Механизм | Описание |
---|---|
v | Версия SPF. Необходимое значение: spf1. Этот тег является обязательным, и он должен быть первым тегом в записи. |
a | Указывает один или несколько почтовых серверов с помощью доменного имени. |
mx | Указывает почтовый сервер по ссылке на запись MX. |
ip4 | Указывает один или несколько почтовых серверов с помощью адреса IPv4 или диапазона. |
ip6 | Указывает один или несколько почтовых серверов с помощью адреса IPv6 или диапазона. |
all | Этот тег обычно указывается в конце записи. Проверки SPF игнорируют любые механизмы после all. |
При инициализации почтового сервера мы выполняли следующую команду:
# ./setup.sh config dkim
Данная команда сформирует цифровую подпись для всех исходящих писем нашего почтового сервера. Кроме этого она создаст файл mail.txt
c ключем DKIM, который необходимо добавить как DNS запись типа TXT.
Найти данный файл можно по пути ./config/opendkim/keys/your-domain-name/
относительно скрипта setup.sh
.
На этом все. Подключившись с помощью почтового клиента к домену your_host.your_domain_name
мы можем безопасно получать и отправлять сообщения.