# Mail Веб-почта + админка почтового сервера для внутренней платформы. Встраивается через iframe в основной сайт. Аналог Roundcube/Nextcloud-Mail с управлением сервером. ## Возможности - **Почта**: системные и пользовательские IMAP-папки, треды по теме, фильтры (Все/Непрочитанные/С флагом/Важные/С вложениями), пометки звезды/важности, поиск через Meilisearch, drag-drop чипов между To/Cc/Bcc, paste-файлов из буфера. - **Compose**: чипы получателей с автодополнением (контакты + DMS-mailboxes), Markdown с тулбаром и preview, подписи, вложения (drag-drop + buffer), отложенная отправка через Redis (переживает закрытие вкладки), свернуть-в-вкладку, автосейв черновиков в IMAP Drafts. - **Realtime**: IMAP IDLE → SSE → новые письма без перезагрузки + автоматическая индексация в Meilisearch. - **Админка** (`/admin/`): дашборд, ящики, алиасы, домены с DNS-визардом (3 шага: записи → проверка через `dnspython` → DKIM + первый ящик), редактируемые настройки приложения, аудит-лог, активные сессии, карточка ELK с одной кнопкой «Применить». - **Аутентификация**: логин по IMAP-паролю, server-side сессии в Postgres (Fernet-шифрованный пароль), rate-limit 5/60с, fail2ban-релакс на DMS. - **Авто-очистка**: корзина чистится в фоне раз в 6 ч (Dramatiq), retention настраивается. - **ELK-shipping**: rsyslog-конфиг отправляет логи Flask/Dramatiq/Postfix/Dovecot на удалённый Logstash. Альтернатива через Filebeat в `deploy/elk/`. - **Бэкапы**: ежедневный cron (postgres dump + redis snapshot + maildir tar.gz). - **Мониторинг**: `/api/health` с глубокими проверками (DB/Redis/IMAP/Meili/queues/postqueue). ## Стек - **Python 3.13 + Flask 3** (Jinja SSR), gunicorn + gevent - **SQLAlchemy 2 + Alembic** — `signatures`, `groups`, `shared_mailboxes`, `autoreply`, `rules`, `user_sessions`, `audit_log` - **Dramatiq** (Redis broker) — отложенная отправка, очистка корзины, realtime-индексация - **docker-mailserver v14** — Postfix + Dovecot + Rspamd - **Postgres 16**, **Redis 7**, **Meilisearch 1.x** ## Быстрая установка (production) Свежий Debian/Ubuntu, всё готово через единый installer: ```bash git clone /home/deeily/mail cd /home/deeily/mail sudo bash deploy/install.sh ``` Что делает установщик: 1. Ставит docker / python3-venv / build-essential (если нет) 2. Создаёт venv, ставит `requirements.txt` 3. Копирует `.env.example → .env` + генерирует `FLASK_SECRET_KEY` 4. Поднимает docker-compose (postgres, redis, meili, mailserver) 5. Применяет fail2ban-override для DMS (Docker bridge в whitelist) 6. Применяет `alembic upgrade head` 7. Ставит systemd-юниты `mail-flask` + `mail-dramatiq` и стартует их 8. Прописывает cron для ежедневного бэкапа в 03:30 9. Ставит sudoers-entry для UI-кнопки «Применить ELK» После установки заполнить в `/home/deeily/mail/.env`: - `ADMINS=admin@your-domain` — кто видит /admin/* - `IMAP_PASSWORD=…` — пароль системного IMAP-юзера - `MAIL_SERVER_HOSTNAME=smtp.your-domain` И перезапустить: `sudo systemctl restart mail-flask`. ## Разработка (локально) ```bash python3 -m venv .venv .venv/bin/pip install -r requirements.txt cp .env.example .env # выставить USE_MOCK_MAIL=1 для офлайн-режима cd docker && docker compose up -d postgres redis meili cd .. .venv/bin/alembic upgrade head .venv/bin/python wsgi.py ``` Открыть http://localhost:5000/, логин — `admin@mail.local` / `admin123`. ## Структура ``` app/ __init__.py # Flask factory + before_request middleware config.py # все env-параметры db.py # SQLAlchemy engine + scoped_session models.py # ORM tasks.py # Dramatiq actors (send_deferred, cleanup_trash, index_new_messages) blueprints/ mail/ # /f/?uid=… — клиент admin/ # /admin/ + /admin/audit + /admin/domains/new (визард) auth/ # /auth/login + /auth/logout api/ # /api/health, /api/search, /api/contacts, /api/mail/* settings/ # /settings/sessions, /settings/signatures, /settings/autoreply groups/, rules/, shared/ services/ imap_client.py # IMAPClient + per-user RLock + кэши imap_idle.py # IDLE-thread per (user,folder), SSE-фанаут, хук в Meili smtp_sender.py # smtplib порт 587 mail_service.py # фасад для blueprints (mock ↔ real) store.py # CRUD над Postgres-моделями sessions.py # server-side sessions + Fernet + audit_log sieve_builder.py # rules → managesieve.sieve, deploy через docker exec search.py # Meilisearch wrapper dms_config.py # обёртка над `setup` CLI DMS + verify_dns (dnspython) templates/ # Jinja static/ # styles.css + app.js docker/ docker-compose.yml # postgres, redis, meili, mailserver dms-config/ # bind-mount в DMS — postfix-main.cf, fail2ban-jail.cf, … deploy/ install.sh # единый установщик backup.sh # ежедневный бэкап systemd/ # mail-flask.service + mail-dramatiq.service + install.sh rsyslog/ # 49-mail-stack.conf + install.sh (ELK shipping) elk/ # альтернатива через Filebeat (если rsyslog не подходит) migrations/ # Alembic gunicorn.conf.py # gevent, 1 worker, 2000 connections wsgi.py # gevent monkey-patch + create_app() ``` ## Эксплуатация ```bash # Статус systemctl status mail-flask mail-dramatiq journalctl -u mail-flask -f curl localhost:5000/api/health | jq # Перезагрузка после правки .env sudo systemctl restart mail-flask mail-dramatiq # Бэкап вручную /home/deeily/mail/deploy/backup.sh # Подключить ELK # через UI: /admin/ → карточка «ELK · отправка логов» → ELK_HOST/PORT/PROTO + «Применить» # или вручную: sudo bash deploy/rsyslog/install.sh logstash.internal 5140 tcp ``` ## Лицензия Internal — не для публичного использования.