Files
knowledge-base/projects/dttb/mailcow-dttb.md
dttb 58fd3fa17a mailcow dttb: спам-фикс, SSL, апдейт 2026-05c, BIMI+подпись, Roundcube, сбор почты
- фикс входящего спама: No-SNAT на OpenWrt (видел все письма как 10.0.0.1)
- SSL mail-портов: cert из NPM + cron-синхрон на Proxmox
- апдейт mailcow 2026-01 -> 2026-05c; урок: forward-zone unbound обязателен (RKN режет рекурсию)
- логотип UI, BIMI-SVG (Tiny PS) + хостинг, HTML-подпись
- Roundcube на /rc (bind-mount, public_html)
- внешний сбор почты Яндексом (IMAP/POP3)
- snippets: sync-mailcow-cert.sh, dttb-mail-branding/

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-28 01:43:19 +03:00

164 lines
18 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
date: 2026-03-04
type: project
tags: [dttb, mail]
---
# Mailcow dttb.ru (VM 107, 10.0.0.107)
> **Версия:** `2026-05c` (обновлено 2026-06-28 с `2026-01` через `./update.sh -f`; снапшот отката `qm snapshot 107` = `pre_update_20260627`, удалить после недели стабильной работы).
> 🚨 **УРОК АПДЕЙТА:** при апдейте откатывал tracked-правки конфигов и НЕ вернул forward-zone в unbound.conf → **почта легла** (postfix не резолвил MX/домены отправителей → reject `450 Domain not found` на всё входящее). Рекурсивный unbound на этом провайдере НЕ работает (RKN режет доступ к корневым DNS), forward-zone — **load-bearing**. Восстановлено возвратом forward-zone (см. ниже). **На будущих апдейтах unbound.conf forward-zone НЕ удалять / вернуть сразу после.** postfix-overrides (main.cf) mailcow восстанавливает сам.
## Общая информация
- **Web UI:** https://mail.dttb.ru (через NPM proxy host #25, SSL cert #106)
- **Admin:** admin / 1qaz!QAZ
- **API key:** dttb-mailcow-api-2026 (API_ALLOW_FROM: 172.22.1.1,127.0.0.1,10.0.0.0/24)
- **OS:** Ubuntu 24.04, 4 cores, 8GB RAM, 100GB disk
- **SSH:** root (ключ claude-code ed25519), cloud-init static IP
- **Клонирован с:** VM 106 НИИКН (mail.niikn.com), перенастроен 2026-03-04
## Домен и ящики
- **Домен:** dttb.ru, DKIM selector: dkim, 2048-bit
- **Ящики:**
- admin@dttb.ru (пароль: 1qaz!QAZ)
- noreply@dttb.ru (пароль: 1qaz!QAZ)
- support@dttb.ru (пароль: 1qaz!QAZ)
- (плюс codex1..8@umnybot.ru, assistant@umnybot.ru — контур Александра)
## Подключение
- **SMTP:** mail.dttb.ru:587 (STARTTLS) или mail.dttb.ru:465 (SMTPS)
- **IMAP:** mail.dttb.ru:993 (SSL)
- **POP3:** mail.dttb.ru:995 (SSL)
- **Sieve:** mail.dttb.ru:4190
## Конфигурация
- **Install dir:** /opt/mailcow-dockerized/
- **MAILCOW_HOSTNAME:** mail.dttb.ru
- **SKIP_LETS_ENCRYPT:** y (SSL через NPM)
- **SKIP_UNBOUND_HEALTHCHECK:** y
- **Unbound:** ⚠️ **ОБЯЗАТЕЛЬНА forward-zone** к 8.8.8.8/1.1.1.1 в `data/conf/unbound/unbound.conf` (в самом конце файла). Рекурсивный резолвинг на этом провайдере НЕ работает (RKN режет корневые DNS) → без forward почта не доставляется (postfix reject `450 Domain not found`). Это НЕ band-aid, а необходимость. 2026-06-28 убрал по ошибке → положил почту, вернул. Минус 8.8.8.8: Spamhaus отшивает публичные резолверы, но postscreen_dnsbl_sites завязан на конкретные коды 127.0.0.x → ложных reject не даёт. После рестарта unbound даёт резолв через ~5-10 сек (не паниковать раньше). Проверка: `docker exec ...unbound... drill gmail.com @127.0.0.1` (ANSWER:>0).
- **SSL:** web (:443) — cert NPM; mail-порты (25/465/587/993/995) — тот же LE-cert из NPM, синхронизируется cron'ом (см. ниже «SSL на mail-портах»)
- **Docker контейнеры:** 18 шт (postfix, dovecot, rspamd, nginx, mysql, redis и др.)
## OpenWrt проброс портов → 10.0.0.107
| Порт | Протокол | Назначение |
|------|----------|------------|
| 25 | TCP | SMTP (приём почты) |
| 465 | TCP | SMTPS |
| 587 | TCP | Submission (отправка) |
| 993 | TCP | IMAPS |
| 995 | TCP | POP3S |
| 4190 | TCP | Sieve |
## DNS записи (dttb.ru → Spaceweb)
| Тип | Имя | Значение |
|-----|-----|----------|
| A | mail | 176.62.183.186 |
| MX | @ | mail.dttb.ru. (приоритет 10) |
| TXT | @ | v=spf1 ip4:176.62.183.186 a mx ~all |
| TXT | _dmarc | v=DMARC1; p=quarantine; ruf=mailto:admin@dttb.ru |
| TXT | dkim._domainkey | v=DKIM1;k=rsa;t=s;s=email;p=... (2048-bit) |
## Статус проверки (2026-06-18)
Сквозная диагностика «снаружи» (без шелла на VM):
-**Приём:** порт 25 открыт из интернета, MX отвечает `250 mail.dttb.ru`, в INBOX реальное входящее от `it5870@yandex.ru`.
-**Отправка:** письмо с admin@dttb.ru через :587 доставлено на внешний сервер за секунды → **исходящий 25-й порт у Istranet НЕ заблокирован**. Письмо **DKIM-подписано** (d=dttb.ru, s=dkim), SPF/DMARC выровнены.
- ✅ IMAP :993 и SMTP-submission :587 (AUTH LOGIN) работают (admin@dttb.ru / 1qaz!QAZ).
- ⚠️ **PTR отсутствует** — единственная дыра доставляемости. Strict-провайдеры (Gmail → спам, Mail.ru → reject) штрафуют письма с IP без reverse DNS.
- ⚠️ **IP = OOO Istranet** (`netname istranet`, RU), не Spaceweb. PTR ставит Istranet (как интернет-провайдер по этому WAN-IP), не регистратор DNS.
- 🔸 В DNS висит лишний `TXT @ "mailru-domain: 09KURdxlbSVmAm4O"` — остаток попытки привязать Mail.ru для домена; на Mailcow не влияет, можно убрать.
## Брендинг писем — BIMI + подпись (2026-06-28)
**Цель:** логотип dttb при отправке писем со всех ящиков.
**BIMI** (лого-аватар у отправителя в инбоксе Apple Mail и др.; Gmail/Yahoo требуют платный VMC ~$1000/год — пока без него):
- SVG (профиль **SVG Tiny PS**, конверт без текста — шрифт `SG` для BIMI не годится): `data/web/bimi/dttb.svg` на mailcow → публично `https://mail.dttb.ru/bimi/dttb.svg` (200, image/svg+xml, проверено снаружи). Исходник в `snippets/dttb-mail-branding/dttb-bimi.svg`.
- DMARC уже `p=quarantine` — BIMI-eligible.
- **ОСТАЛОСЬ (DNS, у Олега/в Spaceweb-панели vps.sweb.ru):** TXT `default._bimi.dttb.ru` = `v=BIMI1; l=https://mail.dttb.ru/bimi/dttb.svg;`. API sweb требует сессию панели (токена в vault нет) — автоматом не добавить.
**Подпись с логотипом** (`snippets/dttb-mail-branding/signature.html`, лого-PNG `https://mail.dttb.ru/bimi/dttb-logo.png`):
- Готовый HTML-сниппет под вставку в SOGo (Preferences→Mail) и в клиенты (Thunderbird/iPhone).
- ⚠️ Серверного футера «на всех клиентов» НЕ ставил: вставка тела после DKIM-подписи Rspamd ломает DKIM. Корректный путь — footer-milter ДО Rspamd (отдельный проект, не делал).
## Внешний сбор почты (Яндекс и др.) — 2026-06-28
Чтобы внешний сервис (напр. Яндекс) **забирал** почту из ящика dttb.ru к себе. Настраивается **на стороне Яндекса** (он подключается к нам), на mailcow ничего не нужно — `:993`/`:995` открыты из интернета, cert валиден, imap/pop3 у всех ящиков dttb включены (`attributes.imap_access/pop3_access=1`).
Параметры подключения для любого сборщика:
| | IMAP | POP3 |
|---|---|---|
| Сервер | `mail.dttb.ru` | `mail.dttb.ru` |
| Порт | `993` | `995` |
| Шифрование | SSL | SSL |
| Логин | полный адрес (`support@dttb.ru`) | то же |
**Яндекс:** ⚙️ → Все настройки → «Сбор почты с других ящиков» → адрес+пароль (сервер подхватится). **Яндекс-сборщик по умолчанию IMAP** (не POP3, как было раньше). IMAP = зеркалит всю структуру папок + статусы, но нельзя выбрать целевую папку. POP3 = только Входящие, зато можно сложить в конкретную папку/метку. Первый сбор за пару минут, далее от неск. раз/час до раза в неск. дней (решает Яндекс).
Справка: https://yandex.ru/support/mail/web/preferences/collector.html
**Обратное направление** (mailcow забирает с Яндекса в ящик dttb): mailcow UI → ящик → **Sync jobs**, IMAP `imap.yandex.ru:993`, для Яндекса нужен **пароль приложения** (не основной).
## Roundcube — второй вебмейл (2026-06-28)
Поставлен рядом с SOGo, **на `https://mail.dttb.ru/rc/`** (родной nginx mailcow, без нового поддомена/DNS/NPM — wildcard *.dttb.ru НЕТ). Скин Elastic, заголовок «dttb Mail».
- Контейнер `roundcube-mailcow` (`roundcube/roundcubemail:latest-fpm-alpine`) через `docker-compose.override.yml`.
- БД `roundcube` в mysql-mailcow (юзер `roundcube` / `df8de490bea7641fd34904cc95b29428`), схема создаётся образом сама (`initdb.sh --update`).
- IMAP `ssl://dovecot:993`, SMTP `tls://postfix:587` (внутр. алиасы сети); cert CN=mail.dttb.ru ≠ имя контейнера → в `data/conf/roundcube/extra.php` выключена проверка cert (`imap/smtp_conn_options verify_peer=false`) — трафик внутри docker-бриджа.
- Файлы вебрута: **bind** `./data/web/rc``/var/www/html` (НЕ named-том: у nginx mailcow rootfs read-only, том в /web/rc не примонтировать). nginx видит их через существующий `/web`. Новый Roundcube 1.6 — вебрут в `public_html/`, поэтому в nginx alias = `/web/rc/public_html/`, SCRIPT_FILENAME = `/var/www/html/public_html/$rcfile`.
- nginx-локация: `data/conf/nginx/site.roundcube.custom` (подключается через `include site.*.custom` в sites-default). `ROUNDCUBEMAIL_REQUEST_PATH=/rc/`.
- Вход проверен (admin@dttb.ru → 302 _task=mail). Плагины: archive, zipdownload, managesieve.
- ⚠️ На апдейтах mailcow override и data/web/rc untracked — переживают; при больших обновлениях Roundcube — `docker compose pull roundcube-mailcow && up -d` (схема обновится сама).
## Логотип UI (2026-06-28)
Кастомный логотип `dttb` (монограмма) на странице входа/в шапке. Хранится в **Redis** ключами `MAIN_LOGO` + `MAIN_LOGO_DARK` как `data:image/png;base64,...` (как делает UI → Customize). Поставлен **PNG** (не SVG: в SVG текст шрифтом `SG`, который в `<img>` не доступен → ставится дефолтный). Источник: `~/Downloads/export/dttb-01-monogram.png` (ужат 2048→1024, лимит mailcow 1920). Сброс: UI → Customize → Reset, или `redis-cli DEL MAIN_LOGO MAIN_LOGO_DARK`.
## SSL на mail-портах (фикс 2026-06-27)
`SKIP_LETS_ENCRYPT=y` → ACME-контейнер mailcow ничего не делает. Cert для mail-портов владеет **NPM** (`npm-106`, ECDSA LE, авто-продление). При установке (Mar 7) его положили в `data/assets/ssl/` **вручную** и забыли про продление → **cert протух 2 июня 2026**, клиенты IMAP/SMTP ругались на сертификат.
**Решение:** авто-синхрон cert из NPM в mailcow.
- Скрипт: `/root/sync-mailcow-cert.sh` на **Proxmox** `10.0.0.250` (копия в `snippets/sync-mailcow-cert.sh`).
- Берёт `pct exec 103 -- cat /data/compose/2/letsencrypt/live/npm-106/{fullchain,privkey}.pem`, сравнивает fingerprint с `10.0.0.107:/opt/mailcow-dockerized/data/assets/ssl/cert.pem`, при отличии — бэкап + замена + reload postfix/dovecot/nginx.
- SSH Proxmox→mailcow по ключу `/root/.ssh/mailcow_sync`.
- Cron: `/etc/cron.d/mailcow-cert-sync` — ежедневно 04:30, лог `/var/log/mailcow-cert-sync.log`.
- Ручной прогон: `/root/sync-mailcow-cert.sh`.
- Cert: ECDSA P-384, LE E-series; пару проверять по pubkey (`openssl rsa` на нём врёт — даёт пустой modulus).
## ⚠️ КОРНЕВОЙ ФИКС входящего спама (2026-06-27)
Жалоба: письма на `support@dttb.ru` (новый ящик) падают в спам, на старые ящики — нет.
**Корень:** на домашнем OpenWrt (`10.0.0.1`) у LAN-зоны было `masq=1`. Входящее `WAN:25 → DNAT → 10.0.0.107` уходило в LAN-зону и **SNAT'илось в `10.0.0.1`** → postfix/rspamd видели source = `10.0.0.1` для **ВСЕХ** внешних писем.
Следствие на каждом входящем: `RDNS_NONE=2.0` + `HFILTER_HOSTNAME_UNKNOWN=8.5` (+10.5), а у строгих отправителей ещё `R_SPF_FAIL=8.0` (SPF против 10.0.0.1) → reject (так резались «Welcome to NetBird»). Бьёт по всему серверу; старый ящик спасал только обученный Bayes (ham 3..5), новый `support@` тонул.
**Фикс (UCI, не сырой nft — грабли fw4):** на `10.0.0.1` добавлено `config nat 'No-SNAT-to-Mailcow'` (src=lan, proto=tcp, dest_ip=10.0.0.107, target=ACCEPT) + `fw4 reload`. Стоит в srcnat до masquerade.
**Проверено:** тест с внешнего `89.111.140.86` → rspamd увидел реальный `89.111.140.86` (не `10.0.0.1`). Для отправителей с нормальным PTR/MX/DKIM (Яндекс/Gmail) +10.5 больше не срабатывает.
Не трогал глобальный `lan masq=1` (на нём может висеть VPN/podkop-маршрутизация) — фикс точечный и обратимый (`uci delete firewall.@nat[0]`).
- 🔸 **SSH-доступ к VM не работает ни одним ключом** (id_rsa «claude-code-matrix-project», id_ed25519, ключ Proxmox). VM клонирована с НИИКН VM 106 → несёт чужой authorized_keys. Управление возможно через web-UI (admin/1qaz!QAZ); для шелла — добавить ключ через Proxmox console.
## Вариант «почтовый шлюз через VPS» (оценка 2026-06-18)
Идея: пускать почту через статичный VPS с чистым IP+PTR, чтобы не зависеть от Istranet. Проверил исходящий :25 на всех VPS Олега:
| VPS | Провайдер | Исходящий :25 | Вывод |
|-----|-----------|---------------|-------|
| vm-nano `158.255.0.139` (в КБ = «доменный шлюз» umnybot) | NL | ❌ блок | для почты НЕ годится |
| Finland `202.71.12.186` | Hostkey EU | ❌ блок (egress после взлома 04-24) | НЕ годится |
| **swtest `89.111.140.86`** | SpaceWeb RU | ✅ открыт (достучался до gmail MX) | единственный пригодный |
⚠️ «Доменный шлюз» из КБ (vm-nano) — это HTTP-reverse-proxy (NPM), к SMTP неприменим, и его провайдер режет 25.
⚠️ swtest на 2026-06-18: **диск 100%** (9.3/9.8 ГБ), RAM свободно ~367 МБ, **PTR нет** → перед использованием нужна чистка диска + заявка в SpaceWeb на rDNS.
**Корень:** почта dttb уже работает на приём и отправку с домашнего IP; единственная дыра — PTR. Любой путь (Istranet PTR или VPS-smarthost) всё равно упирается в заявку провайдеру на PTR. VPS-вариант оправдан, только если Istranet откажет в PTR или нужно скрыть домашний IP.
## TODO
- [ ] **PTR:** запросить у OOO Istranet запись `186.183.62.176.in-addr.arpa → mail.dttb.ru` (даст FCrDNS, A mail→176.62.183.186 уже есть). Главный пункт для доставляемости. (2026-04-18, проверено 2026-06-18 — всё ещё нет)
- [ ] Добавить `rua=mailto:admin@dttb.ru` в DMARC для агрегированных отчётов (сейчас только ruf)
- [ ] Восстановить SSH-ключ на VM 107 через Proxmox console
<!-- AUTO-SYNC FROM MEMORY.MD - DO NOT EDIT BELOW -->
## Mailcow HomeLab (VM 107, 10.0.0.107)
- Web UI: https://mail.dttb.ru (через NPM proxy host #25)
- Admin: admin / 1qaz!QAZ
- API key: dttb-mailcow-api-2026
- Домен: dttb.ru (добавлен), DKIM: selector=dkim, 2048-bit
- Ящики: admin@dttb.ru, noreply@dttb.ru (пароль: 1qaz!QAZ)
- SMTP: 10.0.0.107:587, STARTTLS, LOGIN auth
- Клон с VM 106 НИИКН, MAILCOW_HOSTNAME=mail.dttb.ru
- SSH: root (ключ claude-code ed25519), cloud-init IP static
- Unbound: forward-zone к 8.8.8.8/1.1.1.1 (обязательно, иначе DNS fail)
- SSL: self-signed для mail.dttb.ru, NPM cert ID:106 для HTTPS web
- OpenWrt проброс: 25,465,587,993,995,4190 → 10.0.0.107
- DNS (Spaceweb): A mail→176.62.183.186, MX→mail.dttb.ru, SPF, DMARC, DKIM настроены
<!-- END AUTO-SYNC -->