Установка почтового сервера Mailcow на Alma Linux 10 (Docker + Docker Compose)+Kaspersky Secure Mail Gateway

Установка почтового сервера Mailcow на Alma Linux 10 в современном офисном окружении.

Инструкция по установке почтового сервера MAILCOW

Почтовый сервер pochta.example.ruПочтовый шлюз mail.example.ru
Версия ОС AlmaLinux 10 (Docker предустановлен — см. тут ).Дата составления Апрель 2026
Содержание
  1. Архитектура решения
  2. Схема потоков почты
  3. Требования к системе
  4. Аппаратные требования для mailcow
  5. Программные требования
  6. Настройка DNS
  7. Подготовка AlmaLinux 10
  8. Обновление системы и установка зависимостей
  9. Отключить или перевести SELinux в permissive
  10. Отключить firewalld
  11. Удалить postfix
  12. Проверить свободность портов
  13. Настроить своп
  14. Синхронизация времени
  15. Проверка и настройка Docker
  16. Проверка версий
  17. Убедиться что Docker запущен и включён в автозапуск
  18. Настройка daemon.json
  19. Проверка применения настроек
  20. Установка mailcow
  21. Клонирование репозитория
  22. Генерация конфигурации
  23. Редактирование mailcow.conf
  24. Настройка credentials для DNS-01 (reg.ru)
  25. Авторизация в ghcr.io
  26. Запуск mailcow
  27. Настройка Kaspersky Secure Mail Gateway
  28. Quick MTA Setup — интеграция с mailcow
  29. Маршрутизация исходящей почты через KSMG
  30. Создать транспорт
  31. Привязать транспорт к домену
  32. Первичная настройка
  33. Брандмауэр и открытые порты
  34. Порты на KSMG (mail.example.ru)
  35. Порты на mailcow (pochta.example.ru)
  36. Настройка iptables на mailcow
  37. Тестирование и проверка
  38. Проверка контейнеров mailcow
  39. Проверка портов
  40. Тестирование доставки
  41. Обновление
  42. Обновление mailcow
  43. Обновление AlmaLinux
  44. Обновление KSMG
  45. Частые проблемы и решения
  46. Защита почтового сервера
  47. Защита операционной системы
  48. Защита сети и Docker
  49. Встроенный Netfilter (Fail2Ban)
  50. Усиление TLS/SSL
  51. MTA-STS — защита транспорта
  52. Двухфакторная аутентификация (2FA)
  53. Политика паролей
  54. Резервное копирование
  55. Мониторинг
  56. Сводная таблица мер безопасности
  57. Устранение проблем при установке Docker-образов
  58. Диагностика
  59. Ошибка: network is unreachable (IPv6)
  60. Ошибка: denied / failed to authorize
  61. Ошибка: no such host
  62. Образы прерываются (Interrupted)
  63. Проверка успешного запуска
  64. Первичная настройка через веб-интерфейс
  65. Смена пароля администратора
  66. Добавление домена example.ru
  67. Получить DNS-записи
  68. Создание почтовых ящиков
  69. Исходящий транспорт через KSMG
  70. Добавить KSMG в whitelist Netfilter
  71. Проверка работы

Архитектура решения

Входящая и исходящая почта проходит через Kaspersky Secure Mail Gateway (KSMG), который выполняет антивирусную проверку, антиспам-фильтрацию и DKIM-подпись. Сервер mailcow отвечает за хранение почты, веб-интерфейс SOGo и взаимодействие с почтовыми клиентами.

Установка почтового сервера Mailcow на Alma Linux 10 (Docker + Docker Compose)+Kaspersky Secure Mail Gateway

KSMG и mailcow должны быть на разных VM. KSMG принимает весь внешний трафик на порт 25. Mailcow в интернет напрямую не смотрит.

Схема потоков почты

НаправлениеПуть
ВходящаяИнтернет → mail.example.ru:25 → KSMG фильтрация → pochta.example.ru:25
Исходящаяpochta.example.ru → KSMG mail.example.ru:25 → DKIM-подпись → Интернет:25
Клиент IMAP/POP3Напрямую к pochta.example.ru (143/993/110/995)
Клиент SMTP SubmitНапрямую к pochta.example.ru (587/465)

Требования к системе

Аппаратные требования для mailcow

КомпонентМинимумРекомендуется
CPU2 ядра4 ядра
RAM4 ГБ + 1 ГБ swap6 ГБ + 1 ГБ swap
Диск20 ГБ SSD50 ГБ SSD и более
СетьСтатический IPСтатический IP + PTR

Программные требования

  • AlmaLinux 10 — совместим с RHEL 10, поддержка до 2034 года
  • Docker Engine версии 24.0.0 и выше — уже установлен
  • Docker Compose версии 2.0 и выше — уже установлен
  • Пакеты: git, openssl, curl, gawk, coreutils, grep, jq

Запрещено устанавливать mailcow на OpenVZ, LXC и другие контейнерные платформы. Поддерживаются KVM, ESX, Hyper-V и другие полные гипервизоры.

Настройка DNS

ТипИмяЗначениеНазначение
Amail.example.ruIP сервера KSMGПубличный IP
Apochta.example.ruIP сервера mailcowВнутренний IP
MXexample.rumail.example.ru (пр. 10)Вся почта через KSMG
TXTexample.ruv=spf1 mx ~allSPF
CNAMEautodiscover.example.rupochta.example.ruАвтонастройка клиентов
CNAMEautoconfig.example.rupochta.example.ruАвтонастройка клиентов
PTRIP KSMG (обратная зона)mail.example.ruНастраивается у провайдера

DKIM-запись (dkim._domainkey.example.ru) генерируется в KSMG после настройки и добавляется в DNS отдельно.

Подготовка AlmaLinux 10

Обновление системы и установка зависимостей

dnf update -y
dnf install -y curl git openssl gawk coreutils grep jq

Отключить или перевести SELinux в permissive

SELinux в режиме enforcing конфликтует с Docker-контейнерами mailcow:

# Временно (до перезагрузки)
setenforce 0
 
# Постоянно
sed -i 's/^SELINUX=.*/SELINUX=permissive/' /etc/selinux/config
 
# Проверить
getenforce

Отключить firewalld

firewalld конфликтует с цепочкой DOCKER-USER в iptables. Управление правилами передаётся Docker:

systemctl disable --now firewalld
 
# Проверить
systemctl status firewalld

Удалить postfix

Если postfix установлен — он занимает порт 25 и помешает mailcow:

systemctl disable --now postfix 2>/dev/null
dnf remove -y postfix

Проверить свободность портов

ss -tlpn | grep -E -w '25|80|110|143|443|465|587|993|995|4190'

Все перечисленные порты должны быть свободны. Если какой-либо занят — остановить соответствующий сервис.

Настроить своп

fallocate -l 1G /swapfile
chmod 600 /swapfile
mkswap /swapfile
swapon /swapfile
echo '/swapfile none swap sw 0 0' >> /etc/fstab

Синхронизация времени

Корректное время критично для TOTP-аутентификации и других компонентов mailcow:

timedatectl set-ntp true
timedatectl set-timezone Europe/Moscow
timedatectl status

В выводе команды должны быть строки: «NTP enabled: yes» и «NTP synchronized: yes».

Проверка и настройка Docker

На сервере уже установлены Docker Engine и Docker Compose. Необходимо проверить версии, убедиться что служба запущена, и настроить daemon.json для корректной работы с mailcow.

Проверка версий

docker --version
docker compose version
 
# Ожидаемый результат:
# Docker version 27.x.x или новее
# Docker Compose version v2.x.x или новее

Убедиться что Docker запущен и включён в автозапуск

systemctl enable --now docker
systemctl status docker

Настройка daemon.json

Обязательные настройки для корректной работы mailcow на AlmaLinux 10 — отключение IPv6 и указание DNS:

cat > /etc/docker/daemon.json << 'EOF'
{
  "ipv6": false,
  "dns": ["77.88.8.1", "77.88.8.8"]
}
EOF
 
# Проверить корректность конфига
dockerd --validate --config-file /etc/docker/daemon.json
 
# Перезапустить Docker для применения настроек
systemctl restart docker

Отключение IPv6 обязательно — без этого Docker пытается подключаться к реестрам образов по IPv6 и получает ошибку ‘network is unreachable’ если IPv6 не настроен на сервере.

Проверка применения настроек

# Убедиться что Docker читает daemon.json
docker info | grep -E "IPv6|DNS"
 
# Проверить доступность реестров образов
docker run --rm alpine nslookup ghcr.io
docker run --rm alpine nslookup registry-1.docker.io

Установка mailcow

Клонирование репозитория

cd /opt
git clone https://github.com/mailcow/mailcow-dockerized.git
cd mailcow-dockerized

Генерация конфигурации

./generate_config.sh

Ответить на вопросы мастера:

ВопросОтвет
Mail server hostname (FQDN)pochta.example.ru
TimezoneEurope/Moscow
Which branch?1 — master (стабильная)

Редактирование mailcow.conf

nano /opt/mailcow-dockerized/mailcow.conf

Установить следующие параметры:

# Mailcow принимает почту от KSMG на стандартном порту 25
SMTP_PORT=25
SMTPS_PORT=465
SUBMISSION_PORT=587
IMAP_PORT=143
IMAPS_PORT=993
POP_PORT=110
POPS_PORT=995
SIEVE_PORT=4190
 
# Отключить встроенный антивирус — проверку делает KSMG
SKIP_CLAMD=y
 
# Часовой пояс
TZ=Europe/Moscow
 
# Отключить IPv6 — обязательно для AlmaLinux
ENABLE_IPV6=false
 
# Пропустить HTTP-проверку (hairpin NAT)
SKIP_HTTP_VERIFICATION=y
 
# DNS-01 challenge через reg.ru API
ACME_DNS_CHALLENGE=y
ACME_DNS_PROVIDER=dns_regru
ACME_ACCOUNT_EMAIL=admin@example.ru

SKIP_HTTP_VERIFICATION=y необходим когда сервер находится за NAT-роутером — контейнер acme не может проверить себя через внешний IP (hairpin NAT). DNS-01 challenge не требует открытого порта 80.

Настройка credentials для DNS-01 (reg.ru)

Создать файл с учётными данными reg.ru API. Важно: переменные чувствительны к регистру — Username и Password с заглавной буквой.

cat > /opt/mailcow-dockerized/data/conf/acme/dns-01.conf << 'EOF'
REGRU_API_Username=ВАШ_ЛОГИН_REGRU
REGRU_API_Password=ВАШ_ПАРОЛЬ_REGRU
EOF

Никогда не передавайте пароль от reg.ru в открытом виде — в чате, письме или документах. После создания файла убедитесь что права доступа ограничены: chmod 600 /opt/mailcow-dockerized/data/conf/acme/dns-01.conf

Авторизация в ghcr.io

Образы mailcow хранятся на GitHub Container Registry (ghcr.io). Для загрузки необходим Personal Access Token GitHub с правами read:packages.

  • Зайти на https://github.com/settings/tokens → Generate new token (classic)
  • Название: mailcow-pull, срок: 90 дней, права: только read:packages

Скопировать токен

# Авторизоваться интерактивно — токен не попадёт в историю
docker login ghcr.io
# Username: ВАШ_GITHUB_LOGIN
# Password: ВАШ_ТОКЕН

Никогда не вводите токен GitHub в командной строке с флагом -p — он сохранится в истории bash. Всегда используйте интерактивный ввод через docker login ghcr.io без параметров.

Запуск mailcow

cd /opt/mailcow-dockerized
docker compose pull
docker compose up -d

Проверить статус контейнеров — все должны быть в состоянии Up:

docker compose ps

Проверить здоровье сервисов через watchdog (подождать ~60 секунд после запуска):

sleep 60 && docker compose logs --tail=20 watchdog-mailcow

Все сервисы должны показывать health level: 100%.

Настройка Kaspersky Secure Mail Gateway

KSMG разворачивается из ISO или OVA на отдельной VM. После установки запускается мастер начальной конфигурации. Веб-интерфейс доступен по адресу: https://mail.example.ru

ПараметрЗначение
Hostnamemail.example.ru
DNS-серверы77.88.8.8, 77.88.8.1
Веб-интерфейсhttps://mail.example.ru

Quick MTA Setup — интеграция с mailcow

Путь в меню KSMG: Settings → Built-in MTA → Quick MTA Setup

Шаг 1. Локальные домены (relay_domains)

Добавить домен, для которого KSMG принимает входящую почту:

example.ru

Шаг 2. Маршрутизация (transport_map)

ПолеЗначение
Domainexample.ru
Destination<IP сервера pochta.example.ru>
Port25
MX lookupОтключить (Do not enable MX lookup)

Шаг 3. Доверенные сети (mynetworks)

Добавить IP mailcow-сервера — это разрешит ему отправлять исходящую почту через KSMG:

<IP сервера pochta.example.ru>/32

Шаг 4. DKIM-подпись исходящих

Путь в меню KSMG: Settings → Built-in MTA → DKIM

  • Создать DKIM-ключ для домена example.ru
  • Скопировать публичную часть ключа

Добавить в DNS как TXT-запись: dkim._domainkey.example.ru

Маршрутизация исходящей почты через KSMG

Войдите в веб-интерфейс mailcow: https://pochta.example.ru (admin / moohoo — сменить пароль сразу после входа).

Создать транспорт

Путь: System → Configuration → Routing → добавить транспорт:

ПолеЗначение
Transport Host<IP сервера mail.example.ru>
Transport Port25

Привязать транспорт к домену

Путь: Mail Setup → Domains → example.ru → Edit:

  • В поле Sender-dependent transport выбрать созданный транспорт

Первичная настройка

  • Добавить домен: Mail Setup → Domains → Add domain → example.ru
  • Создать почтовые ящики: Mail Setup → Mailboxes
  • DKIM-ключ берётся из KSMG — добавить его в DNS

Брандмауэр и открытые порты

На AlmaLinux 10 firewalld должен быть отключён (раздел 4.3). Docker управляет iptables напрямую через цепочку DOCKER-USER. Правила сохраняются через iptables-services

Порты на KSMG (mail.example.ru)

ПортПротоколИсточникНазначение
25TCPВесь интернетПриём почты от внешних серверов
443TCPАдминистраторыВеб-интерфейс KSMG

Порты на mailcow (pochta.example.ru)

ПортПротоколИсточникНазначение
25TCPТолько IP KSMGПриём почты от KSMG
80TCPВесь интернетHTTP → редирект на HTTPS / Let’s Encrypt
443TCPВесь интернетВеб-интерфейс mailcow + SOGo
587TCPВесь интернетSMTP Submission (Thunderbird, Outlook)
465TCPВесь интернетSMTPS — отправка с шифрованием SSL
993TCPВесь интернетIMAPS — получение почты в клиентах
995TCPВесь интернетPOP3S — получение почты
4190TCPВесь интернетSieve — управление фильтрами писем

Настройка iptables на mailcow

# firewalld отключён (раздел 4.3), Docker управляет iptables
 
# Разрешить порт 25 только с IP сервера KSMG
iptables -I DOCKER-USER -p tcp --dport 25 \
  -s 10.5.5.9 -j ACCEPT
 
# Запретить порт 25 со всех остальных IP
iptables -I DOCKER-USER -p tcp --dport 25 \
  ! -s 10.5.5.9 -j DROP
 
# Сохранить правила
dnf install -y iptables-services
service iptables save
systemctl enable iptables

Тестирование и проверка

Проверка контейнеров mailcow

cd /opt/mailcow-dockerized
 
# Статус всех контейнеров
docker compose ps
 
# Логи postfix в реальном времени
docker compose logs -f postfix-mailcow
 
# Очередь писем
docker compose exec postfix-mailcow mailq

Проверка портов

# Проверить, что mailcow слушает нужные порты
ss -tlpn | grep -E -w '25|443|465|587|993|995|4190'

Тестирование доставки

Отправить тестовое письмо для проверки SPF, DKIM и DMARC:

# Проверка аутентификации echo "Test" | mail -s "Auth test" check-auth@verifier.port25.com

Для комплексной проверки доставляемости использовать сервис mail-tester.com — стремитесь к оценке 10/10.

Проверить журнал доставки в KSMG: веб-интерфейс KSMG → Monitoring → Mail traffic.

Обновление

Обновление mailcow

cd /opt/mailcow-dockerized
docker compose pull
docker compose up -d

Команда mailcow выпускает обновления ежемесячно. Рекомендуется обновляться регулярно.

Обновление AlmaLinux

dnf update -y

Обновление KSMG

KSMG обновляется через веб-интерфейс: Settings → Update, либо через пакетный менеджер ОС виртуальной машины.

Частые проблемы и решения

ПроблемаРешение
SELinux блокирует Dockersetenforce 0 и SELINUX=permissive в /etc/selinux/config
firewalld конфликтует с Dockersystemctl disable —now firewalld
Порт 25 занятУдалить postfix: dnf remove -y postfix
IPv6 ошибки при pulldaemon.json: ipv6: false + restart docker (раздел 5.3)
Образы не скачиваются (denied)docker login ghcr.io с GitHub токеном (раздел 14.3)
Контейнеры не запускаютсяdocker compose logs <имя_контейнера>
Контейнеры падают из-за RAMОтключить ClamAV: SKIP_CLAMD=y в mailcow.conf
Почта не доходит от KSMGПроверить mynetworks в KSMG и правила iptables
DKIM не подписываетсяПроверить настройки DKIM в KSMG и TXT-запись в DNS
Время не синхронизированоtimedatectl set-ntp true (раздел 4.7)

При обращении в техническую поддержку приложите вывод команды: docker compose logs > mailcow_logs.txt

Защита почтового сервера

Защита выстраивается по нескольким уровням: операционная система, сеть, встроенные механизмы mailcow, почтовые протоколы и мониторинг.

Защита операционной системы

SSH — только ключи, без паролей

Сгенерировать ключевую пару на рабочей машине администратора и скопировать публичный ключ на сервер:

ssh-keygen -t ed25519 -C "mailcow-admin"
ssh-copy-id -i ~/.ssh/id_ed25519.pub user@10.5.5.5

Отредактировать /etc/ssh/sshd_config:

PermitRootLogin no
PasswordAuthentication no
PubkeyAuthentication yes
Port 2222
MaxAuthTries 3
LoginGraceTime 20
systemctl restart sshd

Автоматические обновления безопасности

dnf install -y dnf-automatic
 
# Настроить только security-обновления
sed -i 's/^upgrade_type =.*/upgrade_type = security/' \
  /etc/dnf/automatic.conf
sed -i 's/^apply_updates =.*/apply_updates = yes/' \
  /etc/dnf/automatic.conf
 
systemctl enable --now dnf-automatic.timer

Защита сети и Docker

Ограничить порт 25 — только от KSMG (10.5.5.9)

# Разрешить порт 25 только с IP KSMG
iptables -I DOCKER-USER -p tcp --dport 25 \
  -s 10.5.5.9 -j ACCEPT
 
# Запретить порт 25 со всех остальных IP
iptables -I DOCKER-USER -p tcp --dport 25 \
  ! -s 10.5.5.9 -j DROP
 
# Разрешить mailcow отправлять на KSMG
iptables -I OUTPUT -p tcp -d 10.5.5.9 --dport 25 -j ACCEPT
 
# Сохранить правила
dnf install -y iptables-services
service iptables save
systemctl enable iptables
# Проверить правила
iptables -L DOCKER-USER -n -v | grep 25

Ограничить доступ к веб-интерфейсу mailcow

Добавить в data/conf/nginx/includes/site-defaults.conf:

location /mailcow-admin {
    allow 10.5.5.0/24;
    deny all;
}

Встроенный Netfilter (Fail2Ban)

Настраивается в веб-интерфейсе mailcow: Configuration → Configuration & Details → Fail2ban parameters

ПараметрПо умолчаниюРекомендуется
Max ban time10 мин120 мин
Max attempts105
Netfilter whitelist10.5.5.9 (KSMG)

Обязательно добавить IP KSMG 10.5.5.9 в whitelist Netfilter — иначе KSMG может получить бан при высокой нагрузке.

CrowdSec — дополнительный уровень защиты

curl -s https://packagecloud.io/install/repositories/crowdsec/crowdsec/script.rpm.sh | bash
dnf install -y crowdsec crowdsec-firewall-bouncer-iptables

Добавить источники логов в /etc/crowdsec/acquis.yaml:

source: docker
container_name:
  - mailcowdockerized-nginx-mailcow-1
labels:
  type: nginx
---
source: docker
container_name:
  - mailcowdockerized-dovecot-mailcow-1
  - mailcowdockerized-postfix-mailcow-1
labels:
  type: syslog

Добавить whitelist для внутренних IP в /etc/crowdsec/parsers/s02-enrich/whitelists.yaml:

name: local-whitelist
description: "Whitelist internal IPs"
whitelist:
  reason: "internal network"
  ip:
    - "127.0.0.1"
    - "10.5.5.5"
    - "10.5.5.9"
  cidr:
    - "172.22.0.0/16"
systemctl restart crowdsec

Усиление TLS/SSL

ПротоколПоддержка серверамиСтатус
TLS 1.3~70–80%Современный, предпочтительный
TLS 1.2~99%Безопасный — минимальный порог
TLS 1.1УстаревшийЗапретить
TLS 1.0УстаревшийЗапретить
SSLv3Опасный (POODLE)Запрещён везде

Почему минимум TLS 1.2, а не TLS 1.3: почта — не браузер. Ваш сервер обменивается письмами с тысячами чужих серверов по всему миру. Часть из них — корпоративные Exchange-серверы, госструктуры, мелкий хостинг — поддерживают только TLS 1.2. Установка TLS 1.3 как минимума приведёт к потере легитимной почты. TLS 1.2 с современными шифрами (ECDHE + AES-GCM) криптографически безопасен. TLS 1.3 будет использоваться автоматически там, где обе стороны его поддерживают.

Postfix — data/conf/postfix/extra.cf

tls_high_cipherlist = ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256
tls_preempt_cipherlist = yes
 
smtp_tls_protocols = !SSLv2, !SSLv3, !TLSv1, !TLSv1.1
smtp_tls_ciphers = high
smtp_tls_mandatory_ciphers = high
 
smtpd_tls_protocols = !SSLv2, !SSLv3, !TLSv1, !TLSv1.1
smtpd_tls_ciphers = high
smtpd_tls_mandatory_ciphers = high

Dovecot — data/conf/dovecot/extra.conf

Минимальный протокол TLS 1.2 — безопасный баланс между совместимостью и защитой. TLS 1.3 будет предпочтён автоматически при каждом соединении, где он поддерживается обеими сторонами.

ssl_min_protocol = TLSv1.2
ssl_cipher_list = ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384

Nginx — data/conf/nginx/includes/site-defaults.conf

# HSTS
add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload";
 
# Защита от clickjacking
add_header X-Frame-Options SAMEORIGIN;
 
# Запрет сниффинга типов
add_header X-Content-Type-Options nosniff;
 
# Отключить устаревший XSS-фильтр (заменён CSP)
add_header X-XSS-Protection "0";
 
# Content Security Policy
add_header Content-Security-Policy "default-src 'none'; connect-src 'self' https://api.github.com; font-src 'self' https://fonts.gstatic.com; img-src 'self' data:; script-src 'self' 'unsafe-inline'; style-src 'self' 'unsafe-inline' https://fonts.googleapis.com; frame-ancestors 'none'; upgrade-insecure-requests; block-all-mixed-content; base-uri 'none'";
 
# Cross-Origin политики
add_header Cross-Origin-Resource-Policy same-origin;
add_header Cross-Origin-Opener-Policy same-origin;
 
# Отключить gzip — защита от BREACH-атаки
gzip off;

Применить изменения:

cd /opt/mailcow-dockerized
docker compose restart postfix-mailcow dovecot-mailcow nginx-mailcow

MTA-STS — защита транспорта

MTA-STS принуждает входящие соединения использовать TLS и предотвращает downgrade-атаки. Поддерживается в mailcow начиная с версии 2025-09.

Включить в веб-интерфейсе mailcow: Mail Setup → Domains → example.ru → Edit → MTA-STS

Добавить DNS-записи:

CNAME  mta-sts.example.ru     ->  pochta.example.ru
TXT    _mta-sts.example.ru    ->  v=STSv1; id=2026041501
TXT    _smtp._tls.example.ru  ->  v=TLSRPTv1; rua=mailto:admin@example.ru

Двухфакторная аутентификация (2FA)

Путь в меню: Configuration → Configuration & Details → Two-Factor Authentication

Включить для администратора и всех почтовых ящиков. Поддерживаются TOTP (Google Authenticator, Aegis) и аппаратные ключи FIDO2/WebAuthn.

Политика паролей

Путь в меню: Configuration → Configuration & Details → Password policy

ПараметрРекомендуется
Minimum length14 символов
Require uppercase✅ Включить
Require lowercase✅ Включить
Require numbers✅ Включить
Require special chars✅ Включить

Резервное копирование

# Резервная копия всех данных mailcow
cd /opt/mailcow-dockerized
./helper-scripts/backup_and_restore.sh backup all
 
# Автоматически каждую ночь в 2:00
echo "0 2 * * * root cd /opt/mailcow-dockerized && \
  ./helper-scripts/backup_and_restore.sh backup all" >> /etc/crontab

Хранить резервные копии на отдельном сервере, не на 10.5.5.5.

Мониторинг

# Логи в реальном времени
docker compose logs -f postfix-mailcow
docker compose logs -f dovecot-mailcow
docker compose logs -f netfilter-mailcow
 
# Заблокированные IP
docker compose logs netfilter-mailcow | grep "Banning"
 
# Проверить правила iptables
iptables -L DOCKER-USER -n -v

Сводная таблица мер безопасности

УровеньМераIP-контекстПриоритет
ОСSSH только по ключам, порт 222210.5.5.5Критично
ОСАвтообновления безопасности10.5.5.5Критично
СетьПорт 25 только от 10.5.5.9 (KSMG)10.5.5.5Критично
mailcowNetfilter whitelist: 10.5.5.910.5.5.9Критично
mailcow2FA для всех пользователей10.5.5.5Критично
mailcowСильная политика паролей (14+ симв.)10.5.5.5Критично
TLSTLS 1.2+ min, сильные шифры в Postfix10.5.5.5Важно
TLSTLS 1.2+ min, сильные шифры в Dovecot10.5.5.5Важно
TLSMTA-STS для домена example.ruDNSВажно
HTTPHSTS, CSP, CORP заголовки в Nginx10.5.5.5Важно
СетьCrowdSec + whitelist 10.5.5.910.5.5.5Рекомендуется
Резервные копииЕжедневно + offsite хранение10.5.5.5Критично
МониторингПроверка логов и заблокированных IP10.5.5.5Рекомендуется

Устранение проблем при установке Docker-образов

При первом запуске docker compose pull на серверах с российскими провайдерами возможны проблемы с загрузкой образов из ghcr.io и docker.io. Ниже описаны типичные ошибки и способы их устранения.

Диагностика

# Проверить доступность реестров
curl -4 -v https://ghcr.io 2>&1 | grep -E "Connected|TLS|HTTP"
curl -4 -v https://registry-1.docker.io 2>&1 | grep -E "Connected|TLS|HTTP"
 
# Проверить DNS изнутри Docker-контейнера
docker run --rm alpine nslookup ghcr.io 8.8.8.8
docker run --rm alpine nslookup ghcr.io 77.88.8.8
 
# Проверить IPv6
curl -6 -v https://ghcr.io 2>&1 | head -5

Ошибка: network is unreachable (IPv6)

Симптом: dial tcp [2600:1f18:…]:443: connect: network is unreachable

Причина: Docker пытается подключиться по IPv6, который не настроен на сервере.

# Отключить IPv6 в Docker
cat > /etc/docker/daemon.json << 'EOF'
{
  "ipv6": false,
  "dns": ["77.88.8.1", "77.88.8.8"]
}
EOF
 
# Отключить IPv6 в mailcow.conf
sed -i 's/^ENABLE_IPV6=.*/ENABLE_IPV6=false/' \
  /opt/mailcow-dockerized/mailcow.conf
 
# Перезапустить Docker
systemctl stop docker docker.socket
systemctl start docker.socket
systemctl start docker
 
# Проверить применение конфига
dockerd --validate --config-file /etc/docker/daemon.json

Ошибка: denied / failed to authorize

Симптом: error from registry: denied или failed to fetch anonymous token

Причина: ghcr.io требует авторизацию из-за превышения rate limit (100 pulls/6 часов для анонимных запросов с одного IP).

Решение — создать Personal Access Token на GitHub:

  • Зайти на https://github.com/settings/tokens
  • Generate new token (classic)
  • Название: mailcow-pull, права: только read:packages
  • Скопировать токен
# Авторизоваться в ghcr.io (токен вводится интерактивно)
docker login ghcr.io
# Username: <ВАШ_GITHUB_LOGIN>
# Password: <ТОКЕН>
 
# Запустить pull
cd /opt/mailcow-dockerized
docker compose pull

Никогда не передавайте GitHub-токен в открытом виде — в чате, письме или документах. Скомпрометированный токен необходимо немедленно отозвать на https://github.com/settings/tokens

Ошибка: no such host

Симптом: lookup ghcr.io on 1.1.1.1:53: no such host

Причина: Docker использует собственный DNS-резолвер который не резолвит ghcr.io. Решается прописыванием DNS в daemon.json (см. раздел 14.2).

# Проверить что Docker читает daemon.json
docker info | grep -E "IPv6|DNS"
 
# Проверить DNS изнутри контейнера
docker run --rm alpine nslookup ghcr.io

Образы прерываются (Interrupted)

Симптом: все образы показывают Interrupted за 0.1-0.8 секунды

Причина: слишком короткий таймаут клиента Docker Compose или нестабильное соединение.

# Увеличить таймауты
export DOCKER_CLIENT_TIMEOUT=300
export COMPOSE_HTTP_TIMEOUT=300
 
# Тянуть образы по одному
cd /opt/mailcow-dockerized
 
for image in \
  "ghcr.io/mailcow/nginx:1.06" \
  "ghcr.io/mailcow/postfix:3.7.11-2" \
  "ghcr.io/mailcow/dovecot:2.3.21.1-2" \
  "ghcr.io/mailcow/phpfpm:8.2.29-2" \
  "ghcr.io/mailcow/rspamd:3.14.3-1" \
  "ghcr.io/mailcow/sogo:5.12.5-3" \
  "ghcr.io/mailcow/clamd:1.71" \
  "ghcr.io/mailcow/acme:1.97" \
  "ghcr.io/mailcow/watchdog:2.11" \
  "ghcr.io/mailcow/netfilter:1.64" \
  "ghcr.io/mailcow/unbound:1.25" \
  "ghcr.io/mailcow/dockerapi:2.12" \
  "ghcr.io/mailcow/olefy:1.15" \
  "ghcr.io/mailcow/postfix-tlspol:1.8.23" \
  "mcuadros/ofelia:latest" \
  "mariadb:10.11" \
  "redis:7.4.6-alpine" \
  "memcached:alpine"; do
  echo "=== Pulling: $image ==="
  for attempt in 1 2 3 4 5; do
    docker pull "$image" && break
    echo "Attempt $attempt failed, retry in 10s..."
    sleep 10
  done
done

Проверка успешного запуска

После успешного docker compose pull и docker compose up -d все 18 контейнеров должны быть в состоянии running, а watchdog должен показывать 100% по всем сервисам.

# Статус контейнеров
docker compose ps
 
# Проверка здоровья через watchdog (подождать ~60 сек после запуска)
docker compose logs --tail=30 watchdog-mailcow

Ожидаемый вывод watchdog после запуска:

Dovecot        health level: 100%
MariaDB        health level: 100%
Postfix        health level: 100%
Rspamd         health level: 100%
Nginx          health level: 100%
SOGo           health level: 100%
Redis          health level: 100%
Clamd          health level: 100%
Unbound        health level: 100%

Первичная настройка через веб-интерфейс

Веб-интерфейс mailcow доступен по адресу: https://pochta.example.ru

Учётные данные по умолчанию: логин admin, пароль moohoo — сменить сразу после первого входа.

Смена пароля администратора

System → Configuration → Change password

Добавление домена example.ru

Mail Setup → Domains → Добавить домен

ПараметрЗначениеПримечание
Доменexample.ru 
Максимум ящиков10 (или больше)По числу пользователей
Квота ящика по умолчанию10240 МБ (10 ГБ) 
Максимальная квота ящика20480 МБ (20 ГБ)Должна быть меньше квоты домена
Квота домена409600 МБ (400 ГБ)50-70% от свободного места на диске
Длина DKIM ключа2048 битОптимально
DKIM selectordkim 

Квота домена должна быть больше максимальной квоты одного ящика. Например: квота ящика 20 ГБ, квота домена 400 ГБ.

Нажать «Добавить домен и перезапустить SOGo».

Получить DNS-записи

После добавления домена нажать кнопку DNS напротив example.ru — mailcow покажет все необходимые записи: MX, SPF, DKIM, DMARC, MTA-STS, autoconfig, autodiscover.

Добавить все показанные записи в DNS-зону домена example.ru у регистратора.

Создание почтовых ящиков

Mail Setup → Почтовые ящики → Добавить почтовый ящик

ПараметрЗначение
Имя пользователяuser (часть до @)
Доменexample.ru
Полный адресuser@example.ru
ПарольМинимум 14 символов
Квота10240 МБ (или по необходимости)

Исходящий транспорт через KSMG

Configuration → Configuration & Details → Routing → добавить транспорт:

ПолеЗначение
Transport Host10.5.5.9
Transport Port25

Затем: Mail Setup → Domains → example.ru → Изменить → в поле Sender-dependent transport выбрать созданный транспорт.

Добавить KSMG в whitelist Netfilter

Configuration → Configuration & Details → Fail2ban parameters

Добавить IP KSMG в список исключений: 10.5.5.9

Без этой настройки KSMG может быть заблокирован Netfilter при высокой нагрузке входящей почты.

Проверка работы

# Проверка SPF, DKIM, DMARC
echo "Test" | mail -s "Auth test" check-auth@verifier.port25.com
 
# Комплексная проверка доставляемости
# Зайти на https://mail-tester.com, получить адрес и отправить письмо
# Цель: оценка 9/10 и выше

Оцените статью
IT-Sierra