no-style

Почтовый сервер на основе Mailu в Docker контейнере

docker-compose + mailu
Хотябы 1 раз в жизни админ сталкивается с настройкой своего почтового сервера. Настраивать всё по старинке, довольно долгое занятие и требует тщательного внимания. Сегодня поднимем всё необходимое в докер контейнере что избавит нас от лишних телодвижений.


Необходимые требования

Чтобы всё получилось нам понадобится:

  • Сервер с Root доступом. Рекомендую вот этот
  • На хостинге должна быть предусмотрена возможность менять PTR запись для своего домена
  • Доменное имя. Можно бесплатный домен или поддомен
  • Установленный Docker + Docker-Compose
  • 30 - 60 минут времени






Предыстория

Какое то время назад мы с другом затеяли поднять игровой сервер Lineage 2. Разумеется что серверу был необходим форум. А для регистрации пользователей свой SMTP сервер. Ведь все письма отсылаются по протоколу SMTP. А получаются при помощи IMAP/POP. Тут то я и озадачился вопросом как поднять свой почтовый сервер. Я как раз тогда изучал Docker и наткнулся на интересный проект mailu, который позволял поднять свой почтовый сервер с нуля, буквально за пол часа.

Разобравшись с его настройкой я сохранил всю необходимую информацию, но долгое время не мог написать этот пост т.к. не было времени. Спустя какое то время всё же появилась возможность структурировать и добавить всю эту информацию сюда.







В двух словах про Mailu

  • Open Source. Причём именно в том смысле в котором его принято видеть полностью бесплатен.
  • Прост в эксплуатации.
  • Есть веб-интерфейс для приёма и отправки почты.
  • Работает с SSL сам получит необходимые сертификаты, либо есть возможность задать свои.
  • Сгенерирует все необходимые DNS записи SPF, DMARC, DKIM. Которые потом просто добавить в виде DNS записей для своего домена.






Особенности почтового сервера

Установка почтового сервера предусматривает что Вы будете добавлять PTR запись, что в свою очередь приведёт к деанону ip адреса сервера из за специфики работы почтовых протоколов. Настоятельно рекомендуется ставить почтовый сервер на отдельной впске или сервере.







Предварительная настройка (PTR, DNS, ETC)

Первым делом нам понадобиться поменять PTR запись для домена, на котором мы планируем держать mailu. Это делается в интерфейсе вашего хостинга. В каждом хостинге это делается по разному, покажу как это сделано у меня.

PTR 1

В настройках сервера вписываем желаемый домен, для которого будет установлена PTR запись.



PTR запись может обновляться долгое время, зависит от хостинга и DNS. Проверить что она установилась корректно можно двумя способами


Первый способ nslookup

nslookup -type=PTR ip-адрес-вашего-сервера

ptr nslookup

Второй способ dig

dig -x ip-адрес-вашего-сервера

ptr dig 1



Также обязательно стоит внести необходимые изменения в DNS зону вашего домена, если это ещё не сделано. Я почти все свои домены леплю на cloudflare, покажу как это сделано у меня

DNS 1



Желательно установить hostname для Вашего сервера. Впишите свой домен

sudo hostnamectl set-hostname mymailu.cf

hostname 2

Дополнительно добавим наш домен в /etc/hostname

sudo nano /etc/hostname

hostname 3



Как и в предыдущих статьях про докер контейнеры мы будем придерживаться правила - хранить все контейнеры в одном месте. Создаём необходимые директории для mailu

sudo mkdir -p /app/mail/mailu


Сделаем нашего пользователя (не root !) владельцем этой директории

sudo chown -R $USER:$USER /app/mail/mailu

На этом предварительная настройка завершена







Конфигурация mailu

Нам необходимо получить рабочий конфиг docker-compose.yml под свой сервер, поэтому отправляемся на страницу конфигурации mailu, выбираем что мы будем использовать compose и начинаем постепенно вводить свои данные.

mailu configuration 1

Далее необходимо вписать данные для своего сервера, я приведу пример как это сделано у меня

Step 2 - Initial configuration

Mailu storage path:
/app/mail/mailu

Main mail domain and server display name
mymailu.cf

Postmaster local part
admin

Choose how you wish to handle security
выбираем letsencrypt

Authentication rate limit per IP for failed login attempts or non-existing accounts
по умолчанию

Opt-out of statistics
Включаем, если не хотим отсылать телеметрию

Website name
mail.mymailu.cf

Linked Website URL
https://mail.mymailu.cf

Enable the admin UI (and path to the admin UI)
Включаем и оставляем по умолчанию.

mailu configuration  2





Step 3 - Pick some features

Enable Web email client (and path to the Web email client)
если хотим отдельный веб интерфейс для почты выбираем roundcube. Путь /webmail можно оставить по умолчанию.

Enable the antivirus service
по желанию можно включить антивирус, но он будет есть нехило ресурсов, если у Вас мощный сервер можно включить. Я предпочитаю его не включать.

Enable the webdav service
по желанию можно включить, для того чтобы была возможность использовать календари. У себя включаю.

Enable fetchmail
по желанию, включаю.

mailu configuration  3





Step 4 - expose Mailu to the world

IPv4 listen address
вписываем ip адрес сервера.

Subnet of the docker network.
по умолчанию.

Enable IPv6
Я предпочитаю не включать.

Enable an internal DNS resolver (unbound)
Включаем.

Public hostnames
mail.mymailu.cf

mailu configuration  4





Database preferences

Дабы слишком не усложнять этот и без того большой пост - выбираем sqlite

mailu configuration  5

Наконец нажимаем Setup Mailu







Установка mailu

В результате конфигурации mailu нас перебрасывает на специальную страницу с нашими уникальными конфигами.

mailu install  1

Отправляемся в директорию

cd /app/mail/mailu


И скачиваем наши уникальные сгенерированные конфиги

wget https://setup.mailu.io/1.9/file/ваш-уникальный-id/docker-compose.yml
wget https://setup.mailu.io/1.9/file/ваш-уникальный-id/mailu.env


mailu install  2



Следующий шаг предполагает ревью кода из конфигов. Кстати тут можно заменить SECRET_KEY в фаиле mailu.env на состоящую из 16 рандомно последовательных символов. Для лучшей безопасности.





Третий шаг запуск контейнера

mailu install  3

Находясь в папке с mailu стартуем наш стек контейнеров

sudo docker-compose -p mailu up -d


Начнется продолжительное скачивание и распаковка образов. А после этого будут подняты все необходимые для работы mailu контейнеры.


mailu install  5

Иногда полезно сразу взглянуть на логи. Например выявить нет ли каких то проблем с letsencrypt.

sudo docker-compose logs -f front


Финализируем установку, задав пароль для учётки администратора


sudo docker-compose -p mailu exec admin flask mailu admin admin mymailu.cf PASSWORD

В ответ нам напишут что наш пользователь admin создан

Теперь можно переходить в веб панель у меня она располагается по адресу https://mail.mymailu.cf который я задавал на этапе конфигурации.

Авторизуемся вводя электронную почту admin@mymailu.cf и заданный пароль и нажимаем Войти Admin







Настройка mailu

Вся дальнейшая настройка mailu по большей части сводится к тому чтобы правильно прописать необходимые DNS записи. Но сначала я предпочитаю поменять язык на английский, чтобы было более универсально. Это делается сверху-справа наведя курсор на иконку языка.

Переходим в раздел Mail domains. Тут в разделе Actions нажимаем на кнопку гамбургер (3 полоски).

mailu settings  1



Тут необходимо сгенерировать необходимые днс записи. Для этого нажимаем на кнопку Generate keys. Нам будет выдано предупреждение с кнопкой Confirm, нажимаем её.

mailu settings  2



Мы увидим как добавились такие записи как публичный ключ DKIM, а также запись DMARC и другие. В любой момент мы можем перегенерировать эти записи нажав на кнопку Regenerate keys.

mailu settings  3

Следующим шагом будет установка всех этих данных в DNS.







Добавляем записи DNS

Раз уж мы будем работать с DNS то я рекомендую поставить пакет dnsutils, он очень пригодиться для последующих проверок.

sudo apt install dnsutils


Как я уже говорил ранее я почти для всех доменов использую cloudflare, поэтому буду показывать на его примере. Идём в настройки DNS домена и начинаем постепенно вводить свои данные. У меня домен mymailu.cf

MX запись

  • Type: MX
  • Name: @
  • Mail server: mail.mymailu.cf
  • TTL: Auto
  • Priority: 10

Проверить MX запись можно в терминале командой

dig mymailu.cf MX




SPF запись

  • Type: TXT
  • Name: @
  • TTL: Auto
  • Content: v=spf1 mx a:mail.mymailu.cf ~all

Содержимое поля content берём из графы DNS SPF entries в mailu то что содержится в кавычках.

mailu DNS SPF





DKIM запись

  • Type: TXT
  • Name: dkim._domainkey
  • TTL: Auto
  • Priority: v=DKIM1; k=rsa; p=...

Содержимое поля content берём из графы DNS DKIM entry в mailu то что содержится в кавычках. А поле Name должно быть dkim._domainkey.

mailu DNS DKIM

Проверить DKIM запись можно командой

dig dkim._domainkey.mymailu.cf TXT






DMARC запись

  • Type: TXT
  • Name: _dmarc.mymailu.cf
  • TTL: Auto
  • Priority: v=DMARC1; p=reject;...

Содержимое поля content берём из графы DNS DMARC entry в mailu то что содержится в кавычках. А поле Name должно быть _dmarc.mymailu.cf.

mailu DNS DMARC

Проверить DMARC запись можно командой

dig _dmarc.mymailu.cf TXT


В результате заполнения DNS в cloudflare я получил такую картину

cloudflare-ready  1





Добавляем пользователей / почтовые ящики

Для того чтобы добавить почтовый ящик отправляемся в пункт Mail domains и оттуда кликаем по иконке письма

mailu add mail  1

Нажимаем Add User

mailu add mail  2

Задаём:

  • Адрес почты
  • Пароль
  • Отображаемое имя
  • Комментарий
  • Состояние ВКЛ / ВЫКЛ
  • Квоту в гигабайтах
  • Возможность использования IMAP
  • Возможность использования POP3

и нажимаем Save

mailu add mail  3

Нам сообщат что почта успешно добавлена

mailu add mail  4





Добавляем Catch-All filter

Работает это так, если кто то отправил почту на несуществующий почтовый ящик вашего домена, то это письмо попадает в специальный Catch-All ящик предназначенный для таких случаев.

В mailu из коробки нет механизма catch-all. Однако можно воспользоваться хаком и тогда всё заработает. Для включения отправляемся в пункт Mail domains и оттуда кликаем по иконке символа собаки @.

mailu catchall  1

В появившемся окне пишем в поле Alias символ %.
Обязательно нажимаем галку Use SQL LIKE Syntax(без нее не будет работать).

Затем выбираем в качестве Destination специально созданную почту для catch-all. У меня это test@mymailu.cf заполняем по желанию описание

mailu catchall  2

После добавления если отправить например почту на ящик fweh3423423iuhfew@mymailu.cf то он будет попадать в test@mymailu.cf а если например отправить на admin@mymaily.cf которая существует, то почта попадёт именно туда.

А в результате после добавления, этого алиаса, мы увидим такую запись.

mailu catchall  3







Проверяем работу mailu

Настало время проверить корректность настройки mailu. Открываем сайт mail-tester.com. Этот сайт позволит нам делать 3 проверки в день так что используйте эти попытки экономно.

mailtester  1

Попав на сайт нам сразу же будет предоставлена почта, на которую мы должны отправить тестовое письмо. Копируем эту почту и переходим в веб интерфейсе mailu в раздел Webmail.

Создаём новое сообщение и вставляем адрес почты, полученный с меилтестера. И нажимаем отправить.

sendmail  1



Наконец проверяем результат

mailtester  2

Дополнительно я отправил писмо на свой gmail ящик и оно сразу зашло в инбокс

gmail-inbox  1

Кстати, если планируете отсылать письма по gmail'ам не лишним будет добавить свой домен на специальную страницу https://postmaster.google.com



Mission Completed!







Офф Сайт

Офф Github

4 Комментарии

  1. Спасибо, отличная статья, интересный инструмент. Добавил в закладки, пригодится

    ОтветитьУдалить
  2. При отправке письма, возвращается ошибка non DNSSEC destination

    ОтветитьУдалить
    Ответы
    1. Привет, попробуйте добавить как написано тут.

      Удалить
  3. Не могу его поставить, на этапе развёртывания, пишет нот резолв порт 995 и атас... Хотя все порты открыты...

    ОтветитьУдалить

Отправить комментарий