Свой Mail Server на Docker за 10 минут +7


Предисловие

В Интернетах много разных очень крутых сервисов, которые позволяют сделать свой почтовый сервис с собственными адресами. Однако, захотелось приключений и появилась тяга к созданию чего-нибудь своего. Зачем что-то делать просто, если можно причудливо?

Предпосылки, что и зачем описал тут: статья

Постановка задачи

Захотелось сделать собственный почтовый сервис, чтобы письма отправлял/получал, рассылки делал и интегрировался с другими сервисами (чтобы клубная платформа Vas3k могла отправлять письма). Плюс имел бы веб-интерфейс для администрирования.

Описание проекта

В GitHub создал проект, с помощью которого можно создать собственный почтовый сервис за 10 минут, используя Docker. Посмотреть все исходники можно тут: MyDockerMailserver

Что же оно умеет:

  • Поддержка POP3, IMAP, SMTP с авторизацией. А еще могут быть ящики, которые только отправляют письма, но не умеют получать.

  • TLS enforced: использование SSL-сертификатов. Как самоподписанных (self-signed, так и кастомных).

  • Веб-интерфейс для доступа в почту (Roundcube).

  • Возможность задания правил фильтрации почты через веб-интерфейс (RSPADM).

  • Защита от спама и вирусов в почтовых сообщениях :) Спам-фильтр сам тренируется при переносе сообщений в спам! А еще есть Real Time Black Hole Lists (RBL) для блокировки известных спамеров.

  • Поддержка универсальных почтовых адресов (Aliasing).

  • Поддержка квот на почтовые ящики пользователей. С уведомлениями о превышении.

  • Поддержка DKIM подписи.

  • Веб-интерфейс для администрирования всего этого добра.

  • Поддержка отправки почты через RELAY HOST.

  • и т. д.

Приступим к настройке

Итак, если вы хотите создать свой почтовый сервис, но не обладаете достаточными знаниями в администрировании различных систем, то дальнейшая информация будет крайне полезна.

Необходимые средства для развертывания почтового сервиса:

  • Сервер с Ubuntu и установленным Docker. Например, можно развернуть в Yandex.cloud, AWS, Azure, Digital Ocean.

  • Доменное имя. (далее, для примера, будет использоваться несуществующее доменное имя domain.my).

  • Wildcard SSL-сертификат для домена, либо выделенные сертификаты для sub-домена.

В статье предполагается, что почтовый сервис будет доступен по адресу https://mail.domain.my. При этом, на основном адресе будет развернут основной веб-сайт.

Автор использует обратный прокси jwilder/nginx-proxy для маршрутизации запросов туды-сюды по тому или иному адресу.

ШАГ 0

Почтовый сервер должен отправлять почту. А это позволено лишь не всем, а не каким-то там спамерам. По умолчанию, свой почтовый сервер не сможет отправлять сообщения популярным почтовым серверам.

Чтобы обойти это недоразумение есть разные способы (наверное). Простой способ - это использовать Relay сервис по отправке сообщений. Автор остановился на сервисе SendInBlue, который на момент написания этих строк по бесплатному тарифу предлагает отправку 300 сообщений в день.

https://www.sendinblue.com

Настройка SendInBlue не должно быть какой-то проблемой. Важно это сделать для вашего домена. В итоге, на странице https://account.sendinblue.com/advanced/api будут доступным необходимые данные для настройки RelayHost.

Вот тута, в целом, написано неплохо: как настраивать SendInBlue.

ШАГ 1

Подключаемся на сервер через SSH любым удобным доступным способом.

На сервере нужен какой-нибудь редактор текстовых файликов. Т.к. автор не смог выйти из VIM, то он использует Nano.

ШАГ 2

  • На сервере переходим в необходимую директорию

mkdir mailserver
cd mailserver
  • Клонируем репозитарий в директорию (которую создали, но предыдущий шаг - необязателен).

git clone https://github.com/TopTuK/docker-mailserver.git
  • Переходим в директорию, куда клонирован репозитарий

ШАГ 3

  • Копируем файл .env.dist в .env и открываем его

cp .env.dist .env
nano .env
  • Редактируем файл .env

Если будем использовать RelayHost, то обязательно указываем соответствующие поля. Иначе, оставляем пустым. В целом, название переменных говорят сами за себя.

MYSQL_DATABASE=mailserver # Название mysql базы. Оставляем как есть
MYSQL_USER=mailserver # Имя пользователя. Оставляем как есть
MYSQL_PASSWORD=changeme # Пароль от базы. Меняем на свой
MYSQL_ROOT_PASSWORD=changeme # Пароль от базы. Меняем на свой
MAILNAME=mail.domain.my # Меняем на свой домен, где доступен mailserver
POSTMASTER=postmaster@domain.my # Меням постмастера
RELAYHOST= # указываем relayhost. Если используется sendinblue, то '[smtp-relay.sendinblue.com]:587'
RELAY_PASSWD_KEY= # В случае sendinblue, то будет что-то вида 'user@domain.my:QQQYYYZZZ'
RELAY_OPTIONS=noanonymous # Для работы Relayhost
HEADER_SIZE_LIMIT=4096000 # Для работы Relayhost
FILTER_MIME=false
FILTER_VIRUS=true
ENABLE_IMAP=true
ENABLE_POP3=true
ENABLE_FTS=true
CONTROLLER_PASSWORD=changeme # Меняем на свой для доступа в RSPADM
WAITSTART_TIMEOUT=2m
RECIPIENT_DELIMITER=-
FTS_ARGS="partial=3 full=20 verbose=0 lowmemory=256"
FTS_VSZ_LIMIT=256M

ШАГ 4

Настраиваем использование своих SSL сертификатов

  • Переходим в директорию certs: cd certs

  • Создаем файлы сертификатов. Например, путем копирования их содержимого

Примечание: я сделал путем копирования содержимого файлов сертификатов, т.е. через Ctrl-C -> Ctrl-V. Название файлов с сертификатами может быть произвольным.

rm domain.*
touch mail.domain.my.crt
touch mail.domain.my.key
# Копируем содержимое сертификатов в созданные файлики. Например, через nano
cd ..

ШАГ 5

Конфигурируем файлы docker-compose.*

  • Открываем на редактирование файл docker-compose.yml

  • Редактируем docker-compose.yml

# Либо комментируем, либо удаляем
# ssl:
  # image: jeboehm/mailserver-ssl:latest
  # build: ./ssl
  # env_file: .env
  # volumes:
  # - data-tls:/media/tls:rw
  • Добавляем свои сертификаты (для сервисов mda и mta)

...
# - data-tls:/media/tls:ro
# Uncomment lines below and change left part for using your own certificates
- ./certs/mail.domain.my.crt:/media/tls/mailserver.crt:ro
- ./certs/mail.domain.my.key:/media/tls/mailserver.key:ro
...
  • Добавляем возможность интеграции с обратным прокси (jwilder/nginx-proxy)

...
# For use with jwilder/nginx-proxy. Uncomment this if you are using jwilder/nginx-proxy
environment:
  - VIRTUAL_HOST=mail.domain.my
...
  • Удаляем или комментируем "лишний" volume, т.к. используем "свои" сертификаты

...
volumes:
  data-db:
  data-dkim:
  ...
  # Comment line below if you are using your own certificates
  # data-tls:
  data-filter:
  ...
...

ШАГ 6

На данном шаге требуется сделать последние шаги перед запуском почтового сервиса. Сконфигурировать production параметры. Редактируем параметры docker-compose.production.yml

  • Комментируем раздел для сервиса web, т.к. используем обратный прокси

...
# Remove this block if you are using jwilder/nginx-proxy reverse proxy
# web:
  # ports:
    # - "0.0.0.0:81:80"
...
  • Объединяем все почтовые сервисы в единую сеть

...
# Uncomment next block if you use jwilder/nginx-proxy reverse proxy
networks:
  default:
  # Set your network name
    name: mynetwork
...

ШАГ 7

Конфигурирование сделано. Настало время запустить почтовый сервис и убедиться, что все работает.

  • Запускаем сервисы и дожидаемся выполнения каждой команды без ошибок.

./bin/production.sh pull
./bin/production.sh build
./bin/production.sh up -d
  • Проверяем, что сервисы запущены и инициализированы. Выполняем команду docker ps. В результате, что-то должно быть похоже на:

ШАГ 8

На этом шаге требуется создать первого пользователя администратора

Выполняем команду ниже, а потом отвечаем на простые вопросы, следуя инструкции.

./bin/production.sh run --rm web setup.sh

ШАГ 9: Оно работает!

В результате выполнения всех шагов выше все сервисы должны заработать в PROD.

  • Админка (при обращении к mail.domain.my -> потом авторизация администратора).

  • Веб-интерфейс почтового клиента (mail.domain.my/webmail)

  • Настройка спам-фильтра (mail.domain.my/rspadm). Пароль для доступа указывали в параметре CONTROLLER_PASSWORD.

Заключение

Вот так, с помощью нехитрых приобщений можно превратить буханку черного (или белого) хлеба в троллейбус построить свой почтовый сервер буквально за 5-10 минуты имея манипулятор типа мышь и клавиатуру.

Считается, что если начать утро с прочтения данной статьи, то день сложится удачно и без хитростей. В доме будет царить благополучнее и любовь! Если остались вопросы, прошу в комменты.




Комментарии (11):

  1. MAXH0
    /#24477670 / +2

    Очень милый троллейбус. Не то что баба с КДПВ.

  2. SlyFoxMan
    /#24477836 / +1

    Почему бы просто не использовать mailcow?

    • Cydoor
      /#24477894 / +2

      Пробовал, не получилось подружить с обратным прокси :( Выбирал, собственно, из следующих решений:

      • mailu; // не подружил с reverse proxy. Пробовал траефик - сдался на настройке конфета.

      • mallcow; // не подружил с обратным прокси, что-то не вышло свои сертификаты добавить. Хотел какое-то однокнопочное решение. Хотя moo было наиболее близко.

      • docker-mailserver (https://github.com/jeboehm/docker-mailserver). Из коробки это не умеет:

        • Нормально интегрироваться с sendinblue. (см. PR https://github.com/jeboehm/docker-mailserver/pull/129 - его так и не закоммитили в мастер).

        • rspadm из коробки не поддерживает ч/б списки ip, доменов и адресов.

      С docker-mailserver случилась кракозябра, что 100 лет не коммитит внешние PR :(

      • DirectX
        /#24480448

        Веб интерфейс mailu можно проксировать через Nginx, с этим нет проблем. Очень удобный вариант. Некоторые тонкости настройки раскрыты в этой статье.

  3. smartpunter
    /#24478162 / +4

    Poste.io ~ complete mail server

    Вот же есть давно уже такое, больше тролейбусов, хороших и разных.

    • Johan_Palych
      /#24480800

      Ай спасибо. Будем посмотреть.

      container=$(buildah from docker.io/analogic/poste.io)

  4. devzona
    /#24478240

    Согласен с @smartpunter Posteo прекрасный сервис, эксплуатирую уже более 3 лет. Есть API, все работает из коробки включая SSL. Есть платная версия, если хотите большего, но бесплатной версии хватит по самые уши. Успешно детектирует всякие шуданы, которые все норовят прощупать на уязвимости. В отличие от инструкции автора поста, запускается всего одной строкой со всеми плюшками. И весь вопрос, зачем? Только испортил буханку хлеба, а хлебом играться нельзя.

  5. 13werwolf13
    /#24478768 / +2

    мне всегда казалось что вебморда это последнее что надо почтовому серверу, а скорее даже первое что НЕ надо ему..

    • Cydoor
      /#24478818

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

      На работе - другое дело. Веб морда у эксченжа - это здорово, но чота сложна и выглядит ненадежно. Поэтому, используем аутлук.

      • 13werwolf13
        /#24478892 / +2

        ладно массовые почтопомойки типо мылору или гмыло.. но если речь идёт о личном или корпоративном почтовом сервисе то вебморда это:
        1) медленнее чем нативный клиент
        2) ИМХО неудобнее чем нативный клиент (особенно на мобилках и прочих устройствах с тачскрином)
        3) ещё один вектор атаки
        4) нефункционально (например для работы с gpg есть только пара весьма упоротых плагинов прибитых гвоздями к конкретному почтовому сервису)

        большинству скорее всего пофиг, секретарше дусе плевать, ей привычно.. но я потому и написал что это ИМХО.