- фикс входящего спама: 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>
164 lines
18 KiB
Markdown
164 lines
18 KiB
Markdown
---
|
||
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 -->
|