From e0e5b041f977af604900566d0a874842b02cfbc2 Mon Sep 17 00:00:00 2001 From: bvn13 Date: Tue, 30 Jun 2026 22:50:17 +0300 Subject: [PATCH] mail server --- .env | 5 + README.md | 251 ++++++++++++++++++++++++++++++++++++++ config/rspamd/milter.conf | 3 + docker-compose.yml | 64 ++++++++++ 4 files changed, 323 insertions(+) create mode 100644 .env create mode 100644 README.md create mode 100644 config/rspamd/milter.conf create mode 100644 docker-compose.yml diff --git a/.env b/.env new file mode 100644 index 0000000..5351368 --- /dev/null +++ b/.env @@ -0,0 +1,5 @@ +# Временная зона +TZ=Europe/Moscow + +# Домен (для справки — настраивается через WebAdmin Stalwart) +MAIL_DOMAIN=mail.example.com diff --git a/README.md b/README.md new file mode 100644 index 0000000..7a7250e --- /dev/null +++ b/README.md @@ -0,0 +1,251 @@ +# stalwart-mail + +Self-hosted почтовый стек: **Stalwart** (SMTP/IMAP/CalDAV/CardDAV) + **Rspamd** (антиспам, milter) + **ClamAV** (антивирус, milter). + +## Состав + +| Сервис | Образ | Роль | +|----------|------------------------------|-------------------------------------------| +| stalwart | `stalwartlabs/stalwart` | MTA + IMAP + CalDAV/CardDAV + WebAdmin | +| rspamd | `rspamd/rspamd` | Антиспам, milter на порту 11332 | +| clamav | `clamav/clamav:stable` | Антивирус, milter на порту 7357 | + +--- + +## Требования к хосту + +- Docker + Docker Compose v2 +- RAM: минимум **2 ГБ** (ClamAV держит ~500 МБ–1 ГБ на сигнатурах) +- Открытые порты: 25, 465, 587, 143, 993 (почта), 443/8080 (WebAdmin) +- Статический IP и PTR-запись (reverse DNS) — обязательно для доставки почты + +--- + +## Быстрый старт + +```bash +# 1. Клонировать / распаковать +cd stalwart-mail + +# 2. Задать домен в .env +cp .env .env.local +# отредактировать MAIL_DOMAIN + +# 3. Первый запуск — Stalwart создаст конфиг и задаст пароль admin +docker compose up -d + +# 4. Посмотреть пароль администратора (выводится при первом старте) +docker compose logs stalwart | grep -i password + +# 5. Открыть WebAdmin +# http://:8080/admin +``` + +После входа в WebAdmin: + +1. **Settings → Server → Hostname** — указать FQDN (например, `mail.example.com`) +2. **Settings → SMTP → DKIM** — сгенерировать ключи для домена +3. **Accounts** — создать почтовые ящики + +--- + +## Подключение Rspamd и ClamAV (Stalwart milters) + +После первого запуска добавить в конфигурацию Stalwart (WebAdmin → Settings → Configuration editor или напрямую в файл `data/stalwart/etc/config.toml`): + +```toml +[session.milter."rspamd"] +enable = true +hostname = "rspamd" +port = 11332 +stages = ["connect", "ehlo", "mail", "rcpt", "data"] +tls = false +allow-invalid-certs = false +tempfail-on-error = false + +[session.milter."clamav"] +enable = true +hostname = "clamav" +port = 7357 +stages = ["data"] +tls = false +allow-invalid-certs = false +tempfail-on-error = false +``` + +> Имена `rspamd` и `clamav` — это имена сервисов в Docker Compose, они резолвятся внутри сети `mail` автоматически. + +--- + +## DNS-записи + +Все записи настраиваются у регистратора домена / DNS-провайдера. Заменить `mail.example.com` и `example.com` на свои значения, `1.2.3.4` — на IP сервера. + +### 1. A-запись (адрес почтового сервера) + +``` +mail.example.com. A 1.2.3.4 +``` + +### 2. MX-запись (куда доставлять почту для домена) + +``` +example.com. MX 10 mail.example.com. +``` + +> Приоритет 10 — стандарт. Если MX несколько, меньшее число = выше приоритет. + +### 3. PTR / Reverse DNS (rDNS) + +Настраивается у хостинг-провайдера (не у DNS-регистратора). + +``` +1.2.3.4 → mail.example.com +``` + +Это обязательное условие для нормальной доставки — большинство почтовых серверов отклоняют письма с IP без PTR. + +### 4. SPF (кто имеет право отправлять от имени домена) + +TXT-запись для `example.com`: + +``` +"v=spf1 mx a:mail.example.com ~all" +``` + +- `mx` — разрешает MX-серверам домена отправку +- `a:mail.example.com` — явно разрешает A-запись почтового сервера +- `~all` — softfail для остальных (можно `-all` для строгого режима) + +### 5. DKIM (подпись исходящей почты) + +Ключи генерирует Stalwart (WebAdmin → Settings → SMTP → DKIM → Generate). + +Stalwart покажет готовую TXT-запись вида: + +``` +stalwart._domainkey.example.com. TXT "v=DKIM1; k=rsa; p=MIIBIjAN..." +``` + +Скопировать и добавить в DNS. Селектор по умолчанию — `stalwart`, можно изменить. + +### 6. DMARC (политика обработки писем без SPF/DKIM) + +TXT-запись для `_dmarc.example.com`: + +``` +"v=DMARC1; p=quarantine; rua=mailto:dmarc@example.com; ruf=mailto:dmarc@example.com; fo=1" +``` + +- `p=quarantine` — подозрительные письма в спам (начать с `p=none` для мониторинга) +- `rua` — агрегированные отчёты (раз в сутки) +- `ruf` — forensic-отчёты по каждому инциденту + +### 7. MTA-STS (принудительный TLS для входящей почты) + +Опционально, но рекомендуется. Требует HTTPS на хосте. + +TXT-запись для `_mta-sts.example.com`: +``` +"v=STSv1; id=20240101" +``` + +Файл политики по адресу `https://mta-sts.example.com/.well-known/mta-sts.txt`: +``` +version: STSv1 +mode: enforce +mx: mail.example.com +max_age: 604800 +``` + +### 8. Autodiscovery (автонастройка клиентов) + +Stalwart отдаёт `/mail/config-v1.1.xml` и `/.well-known/autoconfig/mail/config-v1.1.xml` автоматически. Для полного autodiscovery добавить CNAME: + +``` +autoconfig.example.com. CNAME mail.example.com. +autodiscover.example.com. CNAME mail.example.com. +``` + +--- + +## Сводная таблица DNS + +| Запись | Тип | Значение | Обязательно | +|-----------------------------------|------|----------------------------------------------------|-------------| +| `mail.example.com` | A | `1.2.3.4` | ✅ | +| `example.com` | MX | `10 mail.example.com` | ✅ | +| PTR для `1.2.3.4` | PTR | `mail.example.com` (у провайдера) | ✅ | +| `example.com` | TXT | `v=spf1 mx a:mail.example.com ~all` | ✅ | +| `stalwart._domainkey.example.com` | TXT | `v=DKIM1; k=rsa; p=...` (из WebAdmin) | ✅ | +| `_dmarc.example.com` | TXT | `v=DMARC1; p=quarantine; rua=mailto:dmarc@...` | ✅ | +| `_mta-sts.example.com` | TXT | `v=STSv1; id=20240101` | ☑ рекоменд. | +| `autoconfig.example.com` | CNAME| `mail.example.com` | ☑ рекоменд. | +| `autodiscover.example.com` | CNAME| `mail.example.com` | ☑ рекоменд. | + +--- + +## Проверка после настройки + +```bash +# Проверить SPF +dig TXT example.com + +# Проверить DKIM +dig TXT stalwart._domainkey.example.com + +# Проверить MX +dig MX example.com + +# Проверить PTR +dig -x 1.2.3.4 + +# Комплексный тест доставки и спам-рейтинга +# https://www.mail-tester.com — отправить тестовое письмо и получить оценку +# https://mxtoolbox.com — проверить все записи разом +``` + +--- + +## Структура файлов + +``` +stalwart-mail/ +├── docker-compose.yml +├── .env +├── config/ +│ └── rspamd/ +│ └── milter.conf # Rspamd milter bind +└── data/ + ├── stalwart/ # Конфиг и данные Stalwart (персистентные) + ├── rspamd/ # Баейс Bayes и статистика Rspamd + └── clamav/ + ├── db/ # Сигнатурные базы ClamAV (freshclam обновляет сам) + └── run/ # Unix-сокет clamd +``` + +--- + +## Обновление + +```bash +docker compose pull +docker compose up -d +``` + +ClamAV обновляет сигнатуры автоматически через встроенный `freshclamd`. + +--- + +## Порты + +| Порт | Протокол | Назначение | +|------|-----------------|-------------------------------| +| 25 | SMTP | Входящая почта (MX) | +| 465 | SMTPS | Отправка клиентами (TLS) | +| 587 | SMTP STARTTLS | Отправка клиентами (STARTTLS) | +| 143 | IMAP | Получение почты | +| 993 | IMAPS | Получение почты (TLS) | +| 4190 | ManageSieve | Управление фильтрами | +| 8080 | HTTP | WebAdmin / JMAP / autodiscovery | +| 443 | HTTPS | WebAdmin + JMAP по TLS | diff --git a/config/rspamd/milter.conf b/config/rspamd/milter.conf new file mode 100644 index 0000000..5d9dcc9 --- /dev/null +++ b/config/rspamd/milter.conf @@ -0,0 +1,3 @@ +# config/rspamd/milter.conf +# Rspamd слушает как milter на порту 11332 +bind_socket = "0.0.0.0:11332"; diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..7636d19 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,64 @@ +services: + + stalwart: + image: stalwartlabs/stalwart:latest + container_name: stalwart + restart: unless-stopped + env_file: .env + ports: + - "25:25" # SMTP (входящая почта) + - "465:465" # SMTP over TLS (SMTPS) + - "587:587" # SMTP submission (клиенты) + - "143:143" # IMAP + - "993:993" # IMAP over TLS + - "4190:4190" # ManageSieve + - "8080:8080" # HTTP: WebAdmin + JMAP + autodiscovery + - "443:443" # HTTPS (если не используется внешний reverse proxy) + volumes: + - ./data/stalwart:/opt/stalwart + environment: + - TZ=${TZ:-UTC} + depends_on: + rspamd: + condition: service_started + clamav: + condition: service_healthy + networks: + - mail + + rspamd: + image: rspamd/rspamd:latest + container_name: rspamd + restart: unless-stopped + env_file: .env + volumes: + - ./config/rspamd:/etc/rspamd/local.d + - ./data/rspamd:/var/lib/rspamd + networks: + - mail + # Milter порт 11332 доступен только внутри сети + + clamav: + image: clamav/clamav:stable + container_name: clamav + restart: unless-stopped + env_file: .env + volumes: + - ./data/clamav/db:/var/lib/clamav + - ./data/clamav/run:/run/clamav + environment: + - CLAMAV_NO_FRESHCLAMD=false + - CLAMAV_NO_MILTERD=false + - CLAMAV_MILTER_PORT=7357 + healthcheck: + test: ["CMD", "clamdcheck.sh"] + interval: 60s + retries: 3 + start_period: 120s # ClamAV долго стартует (загрузка сигнатур) + networks: + - mail + +networks: + mail: + name: mail + driver: bridge