Свой Mail Server на Docker за 10 минут
Предисловие
В Интернетах много разных очень крутых сервисов, которые позволяют сделать свой почтовый сервис с собственными адресами. Однако, захотелось приключений и появилась тяга к созданию чего-нибудь своего. Зачем что-то делать просто, если можно причудливо?
Предпосылки, что и зачем описал тут: статья
Постановка задачи
Захотелось сделать собственный почтовый сервис, чтобы письма отправлял/получал, рассылки делал и интегрировался с другими сервисами (чтобы клубная платформа Vas3k могла отправлять письма). Плюс имел бы веб-интерфейс для администрирования.
Описание проекта
В GitHub создал проект, с помощью которого можно создать собственный почтовый сервис за 10 минут, используя Docker. Посмотреть все исходники можно тут: MyDockerMailserver
Что же оно умеет:
Поддержка POP3, IMAP, SMTP с авторизацией. А еще могут быть ящики, которые только отправляют письма, но не умеют получать.
TLS enforced: использование SSL-сертификатов. Как самоподписанных (self-signed, так и кастомных).
Веб-интерфейс для доступа в почту (Roundcube).
Возможность задания правил фильтрации почты через веб-интерфейс (RSPAMD).
Защита от спама и вирусов в почтовых сообщениях :) Спам-фильтр сам тренируется при переносе сообщений в спам! А еще есть 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 сообщений в день.
Настройка 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 минут, имея манипулятор типа мышь и клавиатуру.
Считается, что если начать утро с прочтения данной статьи, то день сложится удачно и без хитростей. В доме будет царить благополучие и любовь! Если остались вопросы, прошу в комменты.