Инструкция по установке почтового сервера MAILCOW
| Почтовый сервер pochta.example.ru | Почтовый шлюз mail.example.ru |
| Версия ОС AlmaLinux 10 (Docker предустановлен — см. тут ). | Дата составления Апрель 2026 |
- Архитектура решения
- Схема потоков почты
- Требования к системе
- Аппаратные требования для mailcow
- Программные требования
- Настройка DNS
- Подготовка AlmaLinux 10
- Обновление системы и установка зависимостей
- Отключить или перевести SELinux в permissive
- Отключить firewalld
- Удалить postfix
- Проверить свободность портов
- Настроить своп
- Синхронизация времени
- Проверка и настройка Docker
- Проверка версий
- Убедиться что Docker запущен и включён в автозапуск
- Настройка daemon.json
- Проверка применения настроек
- Установка mailcow
- Клонирование репозитория
- Генерация конфигурации
- Редактирование mailcow.conf
- Настройка credentials для DNS-01 (reg.ru)
- Авторизация в ghcr.io
- Запуск mailcow
- Настройка Kaspersky Secure Mail Gateway
- Quick MTA Setup — интеграция с mailcow
- Маршрутизация исходящей почты через KSMG
- Создать транспорт
- Привязать транспорт к домену
- Первичная настройка
- Брандмауэр и открытые порты
- Порты на KSMG (mail.example.ru)
- Порты на mailcow (pochta.example.ru)
- Настройка iptables на mailcow
- Тестирование и проверка
- Проверка контейнеров mailcow
- Проверка портов
- Тестирование доставки
- Обновление
- Обновление mailcow
- Обновление AlmaLinux
- Обновление KSMG
- Частые проблемы и решения
- Защита почтового сервера
- Защита операционной системы
- Защита сети и Docker
- Встроенный Netfilter (Fail2Ban)
- Усиление TLS/SSL
- MTA-STS — защита транспорта
- Двухфакторная аутентификация (2FA)
- Политика паролей
- Резервное копирование
- Мониторинг
- Сводная таблица мер безопасности
- Устранение проблем при установке Docker-образов
- Диагностика
- Ошибка: network is unreachable (IPv6)
- Ошибка: denied / failed to authorize
- Ошибка: no such host
- Образы прерываются (Interrupted)
- Проверка успешного запуска
- Первичная настройка через веб-интерфейс
- Смена пароля администратора
- Добавление домена example.ru
- Получить DNS-записи
- Создание почтовых ящиков
- Исходящий транспорт через KSMG
- Добавить KSMG в whitelist Netfilter
- Проверка работы
Архитектура решения
Входящая и исходящая почта проходит через Kaspersky Secure Mail Gateway (KSMG), который выполняет антивирусную проверку, антиспам-фильтрацию и DKIM-подпись. Сервер mailcow отвечает за хранение почты, веб-интерфейс SOGo и взаимодействие с почтовыми клиентами.

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
| Компонент | Минимум | Рекомендуется |
| CPU | 2 ядра | 4 ядра |
| RAM | 4 ГБ + 1 ГБ swap | 6 ГБ + 1 ГБ swap |
| Диск | 20 ГБ SSD | 50 ГБ 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
| Тип | Имя | Значение | Назначение |
| A | mail.example.ru | IP сервера KSMG | Публичный IP |
| A | pochta.example.ru | IP сервера mailcow | Внутренний IP |
| MX | example.ru | mail.example.ru (пр. 10) | Вся почта через KSMG |
| TXT | example.ru | v=spf1 mx ~all | SPF |
| CNAME | autodiscover.example.ru | pochta.example.ru | Автонастройка клиентов |
| CNAME | autoconfig.example.ru | pochta.example.ru | Автонастройка клиентов |
| PTR | IP 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 |
| Timezone | Europe/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
| Параметр | Значение |
| Hostname | mail.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)
| Поле | Значение |
| Domain | example.ru |
| Destination | <IP сервера pochta.example.ru> |
| Port | 25 |
| 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 Port | 25 |
Привязать транспорт к домену
Путь: 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)
| Порт | Протокол | Источник | Назначение |
| 25 | TCP | Весь интернет | Приём почты от внешних серверов |
| 443 | TCP | Администраторы | Веб-интерфейс KSMG |
Порты на mailcow (pochta.example.ru)
| Порт | Протокол | Источник | Назначение |
| 25 | TCP | Только IP KSMG | Приём почты от KSMG |
| 80 | TCP | Весь интернет | HTTP → редирект на HTTPS / Let’s Encrypt |
| 443 | TCP | Весь интернет | Веб-интерфейс mailcow + SOGo |
| 587 | TCP | Весь интернет | SMTP Submission (Thunderbird, Outlook) |
| 465 | TCP | Весь интернет | SMTPS — отправка с шифрованием SSL |
| 993 | TCP | Весь интернет | IMAPS — получение почты в клиентах |
| 995 | TCP | Весь интернет | POP3S — получение почты |
| 4190 | TCP | Весь интернет | 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 блокирует Docker | setenforce 0 и SELINUX=permissive в /etc/selinux/config |
| firewalld конфликтует с Docker | systemctl disable —now firewalld |
| Порт 25 занят | Удалить postfix: dnf remove -y postfix |
| IPv6 ошибки при pull | daemon.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 time | 10 мин | 120 мин |
| Max attempts | 10 | 5 |
| Netfilter whitelist | — | 10.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 length | 14 символов |
| 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 только по ключам, порт 2222 | 10.5.5.5 | Критично |
| ОС | Автообновления безопасности | 10.5.5.5 | Критично |
| Сеть | Порт 25 только от 10.5.5.9 (KSMG) | 10.5.5.5 | Критично |
| mailcow | Netfilter whitelist: 10.5.5.9 | 10.5.5.9 | Критично |
| mailcow | 2FA для всех пользователей | 10.5.5.5 | Критично |
| mailcow | Сильная политика паролей (14+ симв.) | 10.5.5.5 | Критично |
| TLS | TLS 1.2+ min, сильные шифры в Postfix | 10.5.5.5 | Важно |
| TLS | TLS 1.2+ min, сильные шифры в Dovecot | 10.5.5.5 | Важно |
| TLS | MTA-STS для домена example.ru | DNS | Важно |
| HTTP | HSTS, CSP, CORP заголовки в Nginx | 10.5.5.5 | Важно |
| Сеть | CrowdSec + whitelist 10.5.5.9 | 10.5.5.5 | Рекомендуется |
| Резервные копии | Ежедневно + offsite хранение | 10.5.5.5 | Критично |
| Мониторинг | Проверка логов и заблокированных IP | 10.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 selector | dkim |
Квота домена должна быть больше максимальной квоты одного ящика. Например: квота ящика 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 Host | 10.5.5.9 |
| Transport Port | 25 |
Затем: 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 и выше 







