diff --git a/content/cheatsheets/git-workflow/index.md b/content/cheatsheets/git-workflow/index.md index 3541dbd..f2cc1e1 100644 --- a/content/cheatsheets/git-workflow/index.md +++ b/content/cheatsheets/git-workflow/index.md @@ -5,7 +5,6 @@ draft: false description: "Универсальная шпаргалка по работе с Hugo блогом через Git с двумя окружениями. Префиксы коммитов, откаты, типичные ошибки и решения." tags: ["git", "workflow", "hugo", "cheatsheet"] categories: ["Шпаргалки"] -showComments: true --- ## Структура проекта diff --git a/content/posts/blog-part-1-architecture/featured.png b/content/posts/blog-part-1-architecture/featured.png index 1a37bfc..e07ea2d 100644 Binary files a/content/posts/blog-part-1-architecture/featured.png and b/content/posts/blog-part-1-architecture/featured.png differ diff --git a/content/posts/blog-part-2-k8s-deployment/feature_2.png b/content/posts/blog-part-2-k8s-deployment/feature_2.png new file mode 100644 index 0000000..98268d0 Binary files /dev/null and b/content/posts/blog-part-2-k8s-deployment/feature_2.png differ diff --git a/content/posts/blog-part-2-k8s-deployment/featured.png b/content/posts/blog-part-2-k8s-deployment/featured.png deleted file mode 100644 index 53a9edb..0000000 Binary files a/content/posts/blog-part-2-k8s-deployment/featured.png and /dev/null differ diff --git a/content/posts/blog-part-3-dev-environment/feature_3.png b/content/posts/blog-part-3-dev-environment/feature_3.png new file mode 100644 index 0000000..37fe797 Binary files /dev/null and b/content/posts/blog-part-3-dev-environment/feature_3.png differ diff --git a/content/posts/blog-part-3-dev-environment/featured.png b/content/posts/blog-part-3-dev-environment/featured.png deleted file mode 100644 index c923896..0000000 Binary files a/content/posts/blog-part-3-dev-environment/featured.png and /dev/null differ diff --git a/content/posts/blog-part-4-git-workflow/feature_4.png b/content/posts/blog-part-4-git-workflow/feature_4.png new file mode 100644 index 0000000..810aa24 Binary files /dev/null and b/content/posts/blog-part-4-git-workflow/feature_4.png differ diff --git a/content/posts/blog-part-4-git-workflow/featured.png b/content/posts/blog-part-4-git-workflow/featured.png deleted file mode 100644 index 17e6599..0000000 Binary files a/content/posts/blog-part-4-git-workflow/featured.png and /dev/null differ diff --git a/content/posts/blog-part-5-debugging/feature_5.png b/content/posts/blog-part-5-debugging/feature_5.png new file mode 100644 index 0000000..94daf71 Binary files /dev/null and b/content/posts/blog-part-5-debugging/feature_5.png differ diff --git a/content/posts/blog-part-5-debugging/featured.png b/content/posts/blog-part-5-debugging/featured.png deleted file mode 100644 index 0231c89..0000000 Binary files a/content/posts/blog-part-5-debugging/featured.png and /dev/null differ diff --git a/content/posts/blog-part-6-namespace-migration/feature_6.png b/content/posts/blog-part-6-namespace-migration/feature_6.png new file mode 100644 index 0000000..04c8480 Binary files /dev/null and b/content/posts/blog-part-6-namespace-migration/feature_6.png differ diff --git a/content/posts/blog-part-6-namespace-migration/featured.png b/content/posts/blog-part-6-namespace-migration/featured.png deleted file mode 100644 index f1d2953..0000000 Binary files a/content/posts/blog-part-6-namespace-migration/featured.png and /dev/null differ diff --git a/content/posts/mailserver-part-1-intro/featured.png b/content/posts/mailserver-part-1-intro/featured.png new file mode 100644 index 0000000..caa9836 Binary files /dev/null and b/content/posts/mailserver-part-1-intro/featured.png differ diff --git a/content/posts/mailserver-part-1-intro/index.md b/content/posts/mailserver-part-1-intro/index.md new file mode 100644 index 0000000..0c906d9 --- /dev/null +++ b/content/posts/mailserver-part-1-intro/index.md @@ -0,0 +1,623 @@ +--- +title: "Почтовый сервер на Debian 12: полное руководство от установки до production. Часть 1 - Начало" +date: 2026-03-05 +draft: false +description: "Зачем поднимать свой mail-сервер вместо Gmail. Анатомия почтового сервера: Postfix, Dovecot, антиспам, антивирус. Системные требования и чек-лист готовности." +tags: ["postfix", "dovecot", "smtp", "imap", "Self-hosting"] +categories: ["Системное администрирование", "Электронная почта"] +series: ["Почтовый сервер на Debian 12"] +series_order: 1 +--- + +Решил поднять свой почтовый сервер? Отлично. Сейчас объясню, почему это одновременно лучшее и худшее решение, которое ты можешь принять для своей инфраструктуры. + +## Зачем вообще заморачиваться + +> Что говорят в интернете: +> "Gmail бесплатный и работает отлично, зачем изобретать велосипед?" + +### Как есть на самом деле: + +**Gmail и прочие публичные сервисы - это хорошо до тех пор, пока:** +- Тебя не смущает, что твою переписку читают для таргетинга рекламы +- Ты не против того, что твой домен висит на чужой инфраструктуре +- Тебе не критично, когда Google решит внезапно заблокировать аккаунт без объяснений +- Ты готов платить за каждый ящик в корпоративном тарифе +- Тебе норм, что лимиты на размер ящика устанавливает кто-то другой + +**Свой почтовый сервер дает:** +- **Полный контроль** - ты сам решаешь кто, что и как +- **Безлимитные ящики** - сколько нужно, столько и создашь +- **Любой размер** - ограничение только в железе +- **Свои правила** - никаких внезапных "обновлений политики" +- **Прозрачность** - ты знаешь где лежит твоя почта и кто к ней имеет доступ + +Но есть нюанс. + +## Реальность: во что ты ввязываешься + +### Первые 48 часов после запуска: + +`Час 1:` Сервер работает, письма ходят, ты доволен собой. + +`Час 3:` Gmail отправляет твои письма в спам. Начинаешь разбираться с SPF. + +`Час 6:` SPF настроен. Письма все равно в спаме. Погружаешься в DKIM. + +`Час 12:` DKIM работает. Половина писем доходит. Открываешь документацию DMARC. + +`Час 24:` Понимаешь, что твой IP попал в какой-то DNSBL. Гуглишь что это вообще такое. + +`Час 48:` Письма наконец-то доходят до inbox. Пользователь жалуется: "Я не получил письмо от клиента". Начинаешь копаться в логах. + +`Неделя 1:` Обнаруживаешь, что сервер стал источником спама. Как это получилось - вопрос другой. + +`Месяц 1:` Осознаешь, что забыл настроить бэкапы. Молишься, чтобы диск не "помер". + +### Это нормально + +Я не пугаю. Я готовлю к реальности. Почтовый сервер - это не "поставил и забыл". Это инфраструктура, которая требует: +- Начальной настройки (4-8 часов чистого времени) +- Отладки репутации (первые 2-4 недели) +- Регулярного мониторинга (15-30 минут в день) +- Периодического обслуживания (2-4 часа в месяц) + +Но когда оно работает - работает **как часы**. + +## Что ты получишь в итоге + +### Техническая часть: + +``` +ТВОЙ ПОЧТОВЫЙ СЕРВЕР +│ +├─ Прием и отправка почты (Postfix) +├─ Доступ к ящикам через IMAP (Dovecot) +├─ Веб-интерфейс (RoundCube) +├─ Защита от вирусов (ClamAV) +├─ Защита от спама (SpamAssassin) +├─ Защита от взлома (Fail2ban) +├─ Шифрование (Let's Encrypt) +├─ Подписи писем (DKIM) +└─ Мониторинг и логи (Pflogsumm) +``` + +### Функциональная часть: + +**Отправка почты:** +- С любого почтового клиента (Thunderbird, Outlook, Apple Mail, K-9) +- Через веб-интерфейс из любой точки мира +- С защищенным соединением (TLS) +- С цифровой подписью (твои письма не подделать) + +**Прием почты:** +- От любых отправителей +- С проверкой на вирусы +- С фильтрацией спама +- С пользовательскими правилами (Sieve) + +**Управление:** +- Неограниченное количество доменов +- Неограниченное количество ящиков +- Псевдонимы (алиасы) +- Пересылки +- Автоответчики +- Квоты на размер (если нужно) + +**Безопасность:** +- Шифрование при передаче (никто не прочитает по пути) +- Защита от подбора паролей +- Блокировка спамеров +- Проверка отправителей + +## Из чего это состоит: анатомия почтового сервера + +Почтовый сервер - это не одна программа. Это экосистема из нескольких компонентов, каждый из которых делает свою работу. + +### Postfix - почтальон + +**Что делает:** Принимает письма от отправителей и доставляет их получателям. + +**Как работает:** +1. Кто-то отправляет письмо на user@твой-домен.ru +2. Postfix принимает письмо на порт 25 +3. Проверяет: "А должен ли я вообще принимать почту для этого домена?" +4. Проверяет отправителя через кучу правил +5. Если все ОК - передает письмо дальше (Dovecot или другому Postfix) +6. Если что-то не так - отклоняет с кодом ошибки + +**Конфиг:** `/etc/postfix/main.cf` - туда ты будешь лезть чаще всего. + +### Dovecot - хранитель ящиков + +**Что делает:** Дает доступ к почтовым ящикам по протоколам IMAP/POP3. + +**Как работает:** +1. Почтовый клиент подключается к Dovecot (порт 143/993) +2. Вводит логин и пароль +3. Dovecot проверяет учетные данные +4. Открывает доступ к почтовому ящику +5. Клиент качает письма + +**Дополнительно:** +- Работает как LDA (Local Delivery Agent) - складывает письма в ящики +- Поддерживает Sieve - пользовательские фильтры +- Управляет квотами + +**Конфиг:** `/etc/dovecot/dovecot.conf` и куча подфайлов в `/etc/dovecot/conf.d/`. + +### Amavis + ClamAV - санитары + +**Что делает Amavis:** Прослойка между Postfix и антивирусом/антиспамом. + +**Что делает ClamAV:** Сканирует вложения на вирусы. + +**Как работает:** +1. Postfix получает письмо +2. Отправляет его в Amavis (порт 10024) +3. Amavis передает в ClamAV +4. ClamAV сканирует +5. Если вирус найден - письмо в карантин +6. Если чисто - Amavis возвращает в Postfix (порт 10025) +7. Postfix доставляет получателю + +**Конфиг:** `/etc/amavis/conf.d/50-user` + +### SpamAssassin - фильтр + +**Что делает:** Определяет спам по куче признаков. + +**Как работает:** +1. Анализирует заголовки письма +2. Проверяет тело письма +3. Смотрит IP отправителя в черных списках (DNSBL) +4. Применяет эвристические правила +5. Использует Bayesian фильтр (обучаемый) +6. Выставляет баллы +7. Если баллов больше порога (обычно 5) - помечает как SPAM + +**Обучение:** +- Показываешь примеры спама → он учится +- Показываешь примеры нормальной почты → он учится +- Со временем точность растет + +**Конфиг:** `/etc/spamassassin/local.cf` + +### Postgrey - вышибала + +**Что делает:** Временно отклоняет письма от новых отправителей. + +**Как работает:** +1. Письмо приходит от нового сервера +2. Postgrey: "Приходи через 5 минут" +3. Легальный почтовый сервер вернется через 5 минут +4. Спам-бот не вернется (ему некогда) +5. При повторной попытке - пропускает + +**Эффективность:** Отсекает ~70% спама вообще без анализа. + +**Конфиг:** `/etc/default/postgrey` + +### Fail2ban - охрана + +**Что делает:** Блокирует IP-адреса, которые брутфорсят(взламывают методом перебора парольных комбинаций) пароли. + +**Как работает:** +1. Следит за логами +2. Видит неудачные попытки входа +3. Считает количество попыток +4. Если больше 3-5 за короткое время - бан IP через iptables +5. Через час-два-пять(как настроишь) разбанивает (если не повторится) + +**Защищает:** +- SMTP AUTH (порт 25, 587) +- IMAP/POP3 (порт 143, 993, 110, 995) +- Веб-интерфейс RoundCube +- +**Конфиг:** `/etc/fail2ban/jail.local` + +### Let's Encrypt - замок + +**Что делает:** Выдает бесплатные SSL-сертификаты. + +**Зачем:** Шифрование соединений между клиентом и сервером. + +**Как работает:** +1. Запускаешь Certbot +2. Он доказывает, что домен принадлежит тебе +3. Let's Encrypt выдает сертификат на 90 дней +4. Certbot автоматически продлевает каждые 60 дней + +**Без этого:** Все пароли и письма идут открытым текстом по сети. + +**Конфиг:** Автоматический, сертификаты в `/etc/letsencrypt/live/` + +### OpenDKIM - печать + +**Что делает:** Подписывает исходящие письма цифровой подписью. + +**Зачем:** Доказывает, что письмо действительно от твоего домена. + +**Как работает:** +1. Генеришь пару ключей (открытый + закрытый) +2. Открытый публикуешь в DNS +3. OpenDKIM подписывает каждое исходящее письмо закрытым ключом +4. Получатель проверяет подпись открытым ключом из DNS +5. Если подпись валидна - письмо не подделано + +**Без этого:** Gmail/Outlook 100% отправят твои письма в спам. + +**Конфиг:** `/etc/opendkim.conf` + +### RoundCube - веб-морда + +**Что делает:** Веб-интерфейс для работы с почтой. + +**Зачем:** Читать/писать письма через браузер без настройки почтового клиента. + +**Возможности:** +- Чтение/отправка писем +- Адресная книга +- Настройка фильтров (через плагин Sieve) +- Смена паролей +- Управление папками +- Поиск по почте + +**Конфиг:** `/etc/roundcube/config.inc.php` + +### PostgreSQL - база данных + +**Что делает:** Хранит данные. + +**Что хранит:** +- Базу RoundCube (сессии, адресная книга, кэш) +- Опционально: список пользователей и паролей +- Опционально: псевдонимы и пересылки + +**Почему PostgreSQL, а не MySQL:** +- Строже к типам данных → меньше косяков +- Лучше работает с UTF-8 +- Проще репликация +- В Debian 12 отличная интеграция + +**Конфиг:** `/etc/postgresql/15/main/postgresql.conf` + +### Apache + PHP + +**Что делает:** Крутит RoundCube. + +**Apache:** Веб-сервер, принимает HTTP-запросы. + +**PHP:** Интерпретатор, выполняет код RoundCube. + +**Альтернатива:** Nginx + PHP-FPM (быстрее, но сложнее, может в будущем рассмотрю и такой подход). + +**Почему Apache:** Работает из коробки, тупо проще с той же эффективностью. + +**Конфиг:** `/etc/apache2/sites-available/` + +### Pflogsumm + +**Что делает:** Анализирует логи Postfix и делает отчеты. + +**Показывает:** +- Сколько писем отправлено/получено +- Сколько отклонено +- Топ отправителей/получателей +- Ошибки доставки +- Статистику по доменам + +**Использование:** +```bash +pflogsumm /var/log/mail.log +``` + +**Автоматизация:** Настроишь cron - каждый день отчет на почту. + + +### Netdata - приборная панель + +**Что делает:** Мониторинг в реальном времени. + +**Показывает:** +- Загрузка CPU, RAM, Disk +- Очереди Postfix +- Соединения Dovecot +- Запросы к PostgreSQL +- Запросы к Apache +- Температура (если есть датчики) + +**Интерфейс:** Веб на порту 19999. + +**Потребление:** ~100MB RAM. + + +## Как все это работает вместе + +### Сценарий 1: Получение письма + +``` +1. example.ru отправляет письмо на user@твой-домен.ru + ↓ +2. DNS: "MX-запись для твой-домен.ru → mail.твой-домен.ru" + ↓ +3. Письмо приходит на твой сервер (Postfix, порт 25) + ↓ +4. Postfix: "Проверю отправителя..." + - SPF проверка + - DNSBL проверка + - Greylisting (Postgrey) + ↓ +5. Postfix: "Отправлю на проверку в Amavis" + ↓ +6. Amavis → ClamAV: "Есть вирусы?" + ClamAV: "Чисто" + ↓ +7. Amavis → SpamAssassin: "Это спам?" + SpamAssassin: "3 балла из 5, норм" + ↓ +8. Amavis возвращает в Postfix: "Все ок, доставляй" + ↓ +9. Postfix → Dovecot (LMTP): "Положи в ящик user@твой-домен.ru" + ↓ +10. Dovecot кладет в /var/spool/mail/твой-домен.ru/user/ + ↓ +11. Пользователь открывает RoundCube или Thunderbird + ↓ +12. Dovecot (IMAP) отдает письмо клиенту +``` + +### Сценарий 2: Отправка письма + +``` +1. Пользователь пишет письмо в RoundCube + ↓ +2. RoundCube → Postfix (порт 587, SMTP Submission) + ↓ +3. Postfix: "Проверю авторизацию..." + - SMTP AUTH через Dovecot + ↓ +4. Postfix: "Пользователь свой, подпишу письмо" + ↓ +5. OpenDKIM добавляет DKIM-подпись + ↓ +6. Postfix отправляет письмо на mail.example.ru + ↓ +7. example.ru получает и проверяет: + - SPF (в DNS твоего домена) + - DKIM (подпись валидна?) + - DMARC (политика домена) + ↓ +8. example.ru: "Все проверки пройдены" → Inbox +``` + +## Терминология: что есть что + +### MTA (Mail Transfer Agent) +**Что:** Программа, которая передает почту между серверами. +**Пример:** Postfix, Sendmail, Exim. + +### MDA (Mail Delivery Agent) +**Что:** Программа, которая кладет письма в почтовые ящики. +**Пример:** Dovecot (в режиме LDA/LMTP). + +### MUA (Mail User Agent) +**Что:** Почтовый клиент. +**Пример:** Thunderbird, Outlook, RoundCube, K-9 Mail. + +### SMTP (Simple Mail Transfer Protocol) +**Что:** Протокол отправки почты. +**Порты:** 25 (сервер-сервер), 587 (клиент-сервер с авторизацией). + +### IMAP (Internet Message Access Protocol) +**Что:** Протокол доступа к почте (с синхронизацией). +**Порты:** 143 (открытый), 993 (с TLS). +**Особенность:** Письма хранятся на сервере. + +### POP3 (Post Office Protocol) +**Что:** Протокол доступа к почте (скачивание). +**Порты:** 110 (открытый), 995 (с TLS). +**Особенность:** Письма скачиваются и удаляются с сервера. +**Статус:** Устарел, не будем использовать. + +### TLS/SSL +**Что:** Шифрование соединения. +**Зачем:** Чтобы пароли и письма не перехватили. +**Пример:** HTTPS для почты. + +### SPF (Sender Policy Framework) +**Что:** DNS-запись, которая говорит "с этих IP можно слать почту от моего домена". +**Пример:** `v=spf1 ip4:1.2.3.4 ~all` +**Зачем:** Защита от подделки отправителя. + +### DKIM (DomainKeys Identified Mail) +**Что:** Цифровая подпись письма. +**Как:** Закрытый ключ на сервере, открытый в DNS. +**Зачем:** Доказать, что письмо не подделано. + +### DMARC (Domain-based Message Authentication) +**Что:** Политика домена: что делать, если SPF или DKIM не прошли. +**Варианты:** none (ничего), quarantine (в спам), reject (не принимать). +**Пример:** `v=DMARC1; p=quarantine; rua=mailto:dmarc@домен.ru` + +### DNSBL (DNS-based Blackhole List) +**Что:** Черные списки IP-адресов спамеров. +**Примеры:** zen.spamhaus.org, bl.spamcop.net. +**Как работает:** Postfix спрашивает DNSBL: "Этот IP спамер?" → DNSBL отвечает. + +### Greylisting +**Что:** Временная задержка писем от новых отправителей. +**Логика:** Спам-боты не повторяют попытки, легальные серверы - повторяют. +**Задержка:** 5 минут (обычно). + +### Relay +**Что:** Пересылка почты через промежуточный сервер. +**Пример:** Твой сервер → SMTP провайдера → получатель. +**Зачем:** Если твой IP в блэклистах или нет белого IP. + +### Open Relay +**Что:** Сервер, который пересылает почту от кого угодно. +**Статус:** **ЗЛО**. Мгновенно попадешь в блэклисты. +**Защита:** SMTP AUTH + правильные restrictions. + +### Maildir vs Mbox +**Mbox:** Все письма в одном файле. +**Maildir:** Каждое письмо - отдельный файл. +**Используем:** Maildir (надежнее, быстрее). + +### Sieve +**Что:** Язык для создания почтовых фильтров. +**Пример:** "Если тема содержит 'счет', переложить в папку 'Финансы'". +**Управление:** Через плагин managesieve в RoundCube. + +### Quota +**Что:** Ограничение на размер почтового ящика. +**Пример:** 5GB на пользователя. +**Наш случай:** Без ограничений (или устанавливаешь сам). + +## Системные требования + +### Минимальная конфигурация (1-50 пользователей): + +``` +CPU: 2 ядра (любой современный процессор) +RAM: 2 GB +Disk: 20 GB (система) + объем почты + SSD рекомендуется +Net: Стабильное подключение + Белый IP (желательно) + Открытые порты: 25, 587, 143, 993, 80, 443 +``` + +### Рекомендуемая конфигурация (50-200 пользователей): + +``` +CPU: 4 ядра +RAM: 4 GB +Disk: 50 GB (система) + объем почты + SSD обязательно +Net: 100 Мбит/с + Белый статический IP +``` + +### Оптимальная конфигурация (200-500 пользователей): + +``` +CPU: 8 ядер +RAM: 8 GB +Disk: 100 GB (система) + объем почты + NVMe SSD +Net: 1 Гбит/с + Резервный канал +``` + +### Расчет дискового пространства: + +``` +Средний пользователь: 1-5 GB в год +Активный пользователь: 10-20 GB в год +Очень активный: 50+ GB в год + +Пример на 100 пользователей: + 100 × 5 GB = 500 GB + + запас 20% = 600 GB + + система 50 GB = 650 GB + +Итого: диск на 1 TB с запасом +``` + +## Что нужно ДО начала установки + +### 1. Домен +Зарегистрированный домен с доступом к управлению DNS. + +**Пример:** `example.ru` + +### 2. Сервер +VPS/Dedicated с Debian 12 и белым IP. + +**Требования:** +- Root-доступ +- Чистая установка Debian 12 +- Статический IP +- Обратная DNS (PTR) настроена на твое имя хоста + +**Проверка PTR:** +```bash +host твой-IP +# Должно вернуть: mail.example.ru +``` + +### 3. DNS-записи (настроишь в процессе) + +**A-запись:** +``` +mail.example.ru. IN A твой-IP +``` + +**MX-запись:** +``` +example.ru. IN MX 10 mail.example.ru. +``` + +**SPF-запись:** +``` +example.ru. IN TXT "v=spf1 mx ~all" +``` + +**DKIM и DMARC** - настроим позже. + +### 4. Открытые порты + +**Обязательно:** +- `25 (SMTP)` - прием почты от других серверов +- `587 (Submission)` - отправка от клиентов +- `143 (IMAP)` - доступ к ящикам +- `993 (IMAPS)` - IMAP с TLS +- `80 (HTTP)` - для Let's Encrypt +- `443 (HTTPS)` - для RoundCube + +**Опционально:** +- `22 (SSH)` - для администрирования +- `19999 (Netdata)` - для мониторинга + +### 5. Время + +**Реально необходимое:** +- Установка и базовая настройка: 4-6 часов +- Отладка доставки в Gmail/Outlook: 2-4 часа +- Настройка веб-интерфейса: 1-2 часа +- Тестирование и доработка: 2-4 часа + +**Итого:** Закладывай полноценные выходные. + +## Проверка готовности + +Прежде чем начинать, убедись: + +``` +☐ Есть зарегистрированный домен +☐ Есть доступ к управлению DNS +☐ Есть VPS/Dedicated с Debian 12 +☐ Есть root-доступ к серверу +☐ Настроен PTR для твоего IP +☐ Открыты необходимые порты +☐ Есть понимание, сколько времени займет +☐ Есть план резервного копирования +☐ Есть готовность разбираться в проблемах +☐ Прочитал эту статью до конца +``` + +Если все пункты отмечены - можешь начинать. + +## Что дальше + +В следующей части разберем установку и базовую настройку Postfix + Dovecot - сердца почтового сервера. + +Ты получишь работающую систему приема и отправки почты. Без защиты, без веб-интерфейса, без красивостей - но работающую. + +А потом будем навешивать остальное: антивирус, антиспам, шифрование, подписи и все остальное, что превращает голый сервер в production-ready решение. + +Поехали. + +--- \ No newline at end of file diff --git a/content/posts/mailserver-part-2-postfix-dovecot/featured.png b/content/posts/mailserver-part-2-postfix-dovecot/featured.png new file mode 100644 index 0000000..228ada8 Binary files /dev/null and b/content/posts/mailserver-part-2-postfix-dovecot/featured.png differ diff --git a/content/posts/mailserver-part-2-postfix-dovecot/index.md b/content/posts/mailserver-part-2-postfix-dovecot/index.md new file mode 100644 index 0000000..bf05995 --- /dev/null +++ b/content/posts/mailserver-part-2-postfix-dovecot/index.md @@ -0,0 +1,1111 @@ +--- +title: "Почтовый сервер на Debian 12: полное руководство от установки до production. Часть 2 - Postfix и Dovecot" +date: 2026-03-10 +draft: false +description: "Установка и настройка Postfix и Dovecot. SMTP/IMAP, виртуальные ящики, авторизация через SASL. Первые тесты отправки и получения почты." +tags: ["postfix", "dovecot", "smtp", "imap", "lmtp", "sasl", "Self-hosting"] +categories: ["Системное администрирование", "Электронная почта"] +series: ["Почтовый сервер на Debian 12"] +series_order: 2 +--- + +# Postfix + Dovecot: установка и базовая настройка + +Сейчас поставим два ключевых компонента почтового сервера: Postfix (прием/отправка) и Dovecot (доступ к ящикам). На выходе получишь работающую систему, через которую можно отправлять и получать почту. + +Без антивируса, без антиспама, без веб-морды - голый функционал. Но работающий. + +## Перед началом + +Эта инструкция подразумевает, что у тебя: +- Debian 12 с базовой настройкой безопасности +- Настроены SSH, firewall, fail2ban +- Система обновлена + +> Если еще не настроил - сделай это сейчас: + +{{< article link="/posts/tips-debian-12-hardening/">}} + +Дальше считаем, что база готова. + +## Подготовка для почтового сервера + +### Открываем порты в firewall + +Почтовому серверу нужны специфичные порты: + +```bash +sudo ufw allow 25/tcp comment 'SMTP' +sudo ufw allow 587/tcp comment 'SMTP Submission' +sudo ufw allow 143/tcp comment 'IMAP' +sudo ufw allow 993/tcp comment 'IMAPS' +``` + +Проверь: + +```bash +sudo ufw status +``` + +Должны появиться: +- 25/tcp (SMTP) +- 587/tcp (Submission) +- 143/tcp (IMAP) +- 993/tcp (IMAPS) + +### Проверяем DNS + +Для почтового сервера DNS - **критично**. Без правильных записей письма не пойдут или улетят в спам. + +**MX-запись:** + +```bash +dig +short MX example.com +``` + +Должно вернуть: +``` +10 mail.example.com. +``` + +**A-запись:** + +```bash +dig +short mail.example.com +``` + +Должен вернуть твой IP. + +**PTR (обратная зона):** + +```bash +host твой-IP +``` + +Должно вернуть: +``` +твой-IP.in-addr.arpa domain name pointer mail.example.com. +``` + +**Если PTR не настроен** - письма будут улетать в спам. Пиши в поддержку хостера, это делается с их стороны. + +## Установка Postfix + +### Ставим пакет + +```bash +sudo apt install -y postfix +``` + +Установщик запустит конфигуратор. **Отменяй его** - настроим вручную. + +Выбери: +- **General type of mail configuration:** No configuration +- Нажми OK + +### Создаем структуру для хранения почты + +Проверяем где реальная директория +```bash +ls -ld /var/spool/mail +``` + +Если это симлинк (обычно в Debian) - работаем с /var/mail: + +```bash +sudo mkdir -p /var/mail/example.com +``` + +Замени `example.com` на свой домен. + +Создай системную группу и пользователя для виртуальных ящиков: + +```bash +sudo groupadd -g 5000 vmail +sudo useradd -g vmail -u 5000 -d /var/spool/mail -s /usr/sbin/nologin vmail +``` + +**Что сделали:** +- Создали группу `vmail` с GID 5000 +- Создали пользователя `vmail` с UID 5000 +- Домашняя директория `/var/spool/mail` +- Запрет на логин (`/usr/sbin/nologin`) + +Назначь владельца: + +```bash +sudo chown -R vmail:vmail /var/mail +sudo chmod -R 770 /var/mail +``` + +### Базовая конфигурация Postfix + +Создай главный конфиг: + +```bash +sudo nano /etc/postfix/main.cf +``` + +Вставь: + +``` +# Общие параметры +smtpd_banner = $myhostname ESMTP +biff = no +append_dot_mydomain = no +readme_directory = no +compatibility_level = 3.6 + +# Имя хоста и домен +myhostname = mail.example.com +mydomain = example.com +myorigin = $mydomain + +# Сеть +inet_interfaces = all +inet_protocols = ipv4 + +# Доверенные сети +mynetworks = 127.0.0.0/8 + +# Локальная доставка отключена +mydestination = localhost +local_recipient_maps = + +# Виртуальные домены +virtual_mailbox_domains = example.com +virtual_mailbox_base = /var/spool/mail +virtual_mailbox_maps = hash:/etc/postfix/vmailbox +virtual_alias_maps = hash:/etc/postfix/virtual +virtual_minimum_uid = 100 +virtual_uid_maps = static:5000 +virtual_gid_maps = static:5000 + +# Размер сообщений +message_size_limit = 52428800 +mailbox_size_limit = 0 + +# Очереди +queue_directory = /var/spool/postfix +``` + +**Замени** `mail.example.com` и `example.com` на свои значения. + +**Что настроили:** + +**Общие параметры:** +- `smtpd_banner` - приветствие сервера +- `biff = no` - отключили уведомления comsat +- `append_dot_mydomain = no` - не добавлять домен автоматически +- `compatibility_level = 3.6` - уровень совместимости + +**Имя и домен:** +- `myhostname` - полное имя сервера +- `mydomain` - основной домен +- `myorigin` - от какого домена идут письма + +**Сеть:** +- `inet_interfaces = all` - слушаем на всех интерфейсах +- `inet_protocols = ipv4` - только IPv4 (если есть IPv6 - используй `all`) + +**Доверенные сети:** +- `mynetworks` - только localhost (расширим позже) + +**Локальная доставка:** +- `mydestination = localhost` - только для локалхоста +- Остальное через виртуальные домены + +**Виртуальные домены:** +- `virtual_mailbox_domains` - список доменов (пока один) +- `virtual_mailbox_base` - корневая директория почты +- `virtual_mailbox_maps` - файл с ящиками +- `virtual_alias_maps` - файл с псевдонимами +- `virtual_uid_maps / virtual_gid_maps` - от имени кого хранить файлы + +**Лимиты:** +- `message_size_limit` - максимальный размер письма (50 MB) +- `mailbox_size_limit = 0` - без лимита на ящик + +### Создаем файлы для виртуальных ящиков + +**Файл vmailbox** - список почтовых ящиков: + +```bash +sudo nano /etc/postfix/vmailbox +``` + +Добавь: + +``` +admin@example.com example.com/admin/ +user@example.com example.com/user/ +``` + +Формат: `email путь_относительно_virtual_mailbox_base/` + +**Файл virtual** - псевдонимы: + +```bash +sudo nano /etc/postfix/virtual +``` + +Добавь: + +``` +postmaster@example.com admin@example.com +abuse@example.com admin@example.com +``` + +Формат: `псевдоним куда_перенаправлять` + +**Создай hash-таблицы:** + +```bash +sudo postmap /etc/postfix/vmailbox +sudo postmap /etc/postfix/virtual +``` + +Это создаст файлы `.db` - бинарные индексы для быстрого поиска. + +**Проверь конфиг:** + +```bash +sudo postfix check +``` + +Если ошибок нет - молчит. Если есть - исправляй. + +### Запускаем Postfix + +```bash +sudo systemctl enable postfix +sudo systemctl start postfix +sudo systemctl status postfix +``` + +Должен быть `active (running)`. + +### Проверяем порты + +```bash +sudo ss -tulnp | grep master +``` + +Должно быть: + +``` +tcp LISTEN 0 100 0.0.0.0:25 0.0.0.0:* users:(("master",pid=...)) +``` + +Postfix слушает порт 25. + +## Установка Dovecot + +### Ставим пакеты + +```bash +sudo apt install -y \ + dovecot-core \ + dovecot-imapd \ + dovecot-lmtpd +``` + +**Что установили:** +- `dovecot-core` - ядро +- `dovecot-imapd` - IMAP сервер +- `dovecot-lmtpd` - LMTP для приема почты от Postfix + +### Основной конфиг Dovecot + +Открой: + +```bash +sudo nano /etc/dovecot/dovecot.conf +``` + +Приведи к виду: + +``` +# Протоколы +protocols = imap lmtp + +# Слушаем на всех интерфейсах IPv4 +listen = * + +# Рабочая директория +base_dir = /var/run/dovecot/ + +# Привет от сервера +login_greeting = Dovecot ready. + +# Отключать клиентов при перезапуске +shutdown_clients = yes + +# Подключаем конфиги из conf.d/ +!include conf.d/*.conf +``` + +### Настройка аутентификации + +Открой: + +```bash +sudo nano /etc/dovecot/conf.d/10-auth.conf +``` + +Найди и измени: + +``` +# Разрешаем plaintext auth (потом включим TLS) +disable_plaintext_auth = no + +# Механизмы аутентификации +auth_mechanisms = plain login +``` + +В конце файла закомментируй: + +``` +#!include auth-system.conf.ext +``` + +И раскомментируй: + +``` +!include auth-passwdfile.conf.ext +``` + +**Что сделали:** +- Отключили системную аутентификацию (через /etc/passwd) +- Включили аутентификацию через файл паролей + +### Настройка файла паролей + +Открой: + +```bash +sudo nano /etc/dovecot/conf.d/auth-passwdfile.conf.ext +``` + +Приведи к виду: + +``` +passdb { + driver = passwd-file + args = scheme=CRYPT username_format=%u /etc/dovecot/users +} + +userdb { + driver = static + args = uid=vmail gid=vmail home=/var/spool/mail/%d/%n +} +``` + +**Что настроили:** + +**passdb** - база паролей: +- `driver = passwd-file` - из файла +- `scheme=CRYPT` - хеширование CRYPT +- `username_format=%u` - формат логина (email) +- `/etc/dovecot/users` - путь к файлу + +**userdb** - база пользователей: +- `driver = static` - статические значения для всех +- `uid=vmail gid=vmail` - от имени кого работаем +- `home=/var/spool/mail/%d/%n` - путь к ящику + +**Переменные:** +- `%u` - полный email (user@example.com) +- `%d` - домен (example.com) +- `%n` - локальная часть (user) + +### Настройка почтовых ящиков + +Открой: + +```bash +sudo nano /etc/dovecot/conf.d/10-mail.conf +``` + +Найди и измени: + +``` +# Формат и расположение почты +mail_location = maildir:/var/spool/mail/%d/%n + +# От имени кого работаем +mail_uid = vmail +mail_gid = vmail + +# Привилегированная группа +mail_privileged_group = vmail + +# Разрешенные chroot-директории +valid_chroot_dirs = /var/spool/mail +``` + +**Что настроили:** +- `mail_location` - формат Maildir, путь к ящикам +- `mail_uid / mail_gid` - UID/GID для работы с файлами +- `valid_chroot_dirs` - где можно работать + +### Настройка LMTP + +Открой: + +```bash +sudo nano /etc/dovecot/conf.d/10-master.conf +``` + +Найди блок `service lmtp` и измени: + +``` +service lmtp { + unix_listener /var/spool/postfix/private/dovecot-lmtp { + mode = 0600 + user = postfix + group = postfix + } +} +``` + +Найди блок `service auth` и добавь: + +``` +service auth { + # Postfix SMTP AUTH + unix_listener /var/spool/postfix/private/auth { + mode = 0666 + user = postfix + group = postfix + } + + # Для самого Dovecot + unix_listener auth-userdb { + mode = 0600 + user = vmail + } +} +``` + +**Что настроили:** + +**service lmtp:** +- Создали UNIX-сокет для Postfix +- Postfix будет передавать письма через него + +**service auth:** +- Сокет для SMTP AUTH (авторизация в Postfix) +- Сокет для внутренних нужд Dovecot + +### Отключаем SSL (пока) + +Открой: + +```bash +sudo nano /etc/dovecot/conf.d/10-ssl.conf +``` + +Измени: + +``` +ssl = no +``` + +Потом включим с Let's Encrypt. Пока отключаем. + +### Создаем файл пользователей + +```bash +sudo nano /etc/dovecot/users +``` + +Формат файла: + +``` +email:password_hash:5000:5000:: +``` + +Создадим пользователя `admin@example.com` с паролем `SecurePass123`: + +Генерируем хеш: + +```bash +sudo doveadm pw -s CRYPT -p SecurePass123 +``` + +Вернет что-то вроде: + +``` +{CRYPT}$6$random_salt$hash_here +``` + +Копируй только часть после `{CRYPT}`, т.е. `$6$random_salt$hash_here`. + +Запиши в `/etc/dovecot/users`: + +``` +admin@example.com:$6$random_salt$hash_here:5000:5000:: +``` + +Создай еще пользователя `user@example.com` с паролем `UserPass456`: + +```bash +sudo doveadm pw -s CRYPT -p UserPass456 +``` + +Добавь в файл: + +``` +admin@example.com:$6$hash1:5000:5000:: +user@example.com:$6$hash2:5000:5000:: +``` + +**Формат строки:** +``` +email:hash:uid:gid:gecos:home:shell +``` + +У нас `home` и `shell` пустые, т.к. используем static userdb. + +### Права на файл + +```bash +sudo chmod 640 /etc/dovecot/users +sudo chown root:dovecot /etc/dovecot/users +``` + +### Запускаем Dovecot + +```bash +sudo systemctl enable dovecot +sudo systemctl start dovecot +sudo systemctl status dovecot +``` + +Должен быть `active (running)`. + +### Проверяем порты + +```bash +sudo ss -tulnp | grep dovecot +``` + +Должно быть: + +``` +tcp LISTEN 0 100 0.0.0.0:143 0.0.0.0:* users:(("dovecot",pid=...)) +``` + +Dovecot слушает порт 143 (IMAP). + +## Интеграция Postfix и Dovecot + +Сейчас свяжем Postfix и Dovecot, чтобы: +- Postfix передавал письма в Dovecot через LMTP +- Postfix использовал Dovecot для SMTP AUTH + +### Настраиваем Postfix на LMTP + +Открой: + +```bash +sudo nano /etc/postfix/main.cf +``` + +Добавь в конец: + +``` +# Доставка через Dovecot LMTP +virtual_transport = lmtp:unix:private/dovecot-lmtp + +# SMTP AUTH через Dovecot +smtpd_sasl_type = dovecot +smtpd_sasl_path = private/auth +smtpd_sasl_auth_enable = yes +smtpd_sasl_security_options = noanonymous +broken_sasl_auth_clients = yes +``` + +**Что добавили:** + +**virtual_transport:** +- Письма для виртуальных доменов отправляем в Dovecot через LMTP + +**SMTP AUTH:** +- Используем Dovecot для проверки логинов/паролей +- `noanonymous` - запрет анонимного доступа +- `broken_sasl_auth_clients` - поддержка старых клиентов + +### Настраиваем правила приема/отправки + +Добавь туда же: + +``` +# Требовать HELO/EHLO +smtpd_helo_required = yes + +# Правила HELO +smtpd_helo_restrictions = + permit_mynetworks, + permit_sasl_authenticated, + reject_invalid_helo_hostname, + reject_non_fqdn_helo_hostname, + reject_unknown_helo_hostname + +# Правила получателя +smtpd_recipient_restrictions = + permit_mynetworks, + permit_sasl_authenticated, + reject_unauth_destination, + reject_non_fqdn_recipient, + reject_unknown_recipient_domain + +# Правила отправителя +smtpd_sender_restrictions = + permit_mynetworks, + permit_sasl_authenticated, + reject_non_fqdn_sender, + reject_unknown_sender_domain +``` + +**Что добавили:** + +**smtpd_helo_required:** +- Требуем команду HELO при подключении + +**smtpd_helo_restrictions:** +- `permit_mynetworks` - свои пропускаем +- `permit_sasl_authenticated` - авторизованных пропускаем +- `reject_invalid_helo_hostname` - отклоняем невалидные имена +- `reject_non_fqdn_helo_hostname` - отклоняем неполные имена +- `reject_unknown_helo_hostname` - отклоняем неизвестные имена + +**smtpd_recipient_restrictions:** +- Свои и авторизованных пропускаем +- `reject_unauth_destination` - отклоняем для чужих доменов (защита от relay) +- `reject_non_fqdn_recipient` - отклоняем неполные адреса получателей +- `reject_unknown_recipient_domain` - отклоняем неизвестные домены + +**smtpd_sender_restrictions:** +- Проверяем адреса отправителей + +### Настраиваем порт submission (587) + +Открой: + +```bash +sudo nano /etc/postfix/master.cf +``` + +Найди строку `submission` (должна быть закомментирована) и раскомментируй/измени: + +``` +submission inet n - y - - smtpd + -o syslog_name=postfix/submission + -o smtpd_tls_security_level=may + -o smtpd_sasl_auth_enable=yes + -o smtpd_reject_unlisted_recipient=no + -o smtpd_recipient_restrictions=permit_sasl_authenticated,reject + -o smtpd_relay_restrictions=permit_sasl_authenticated,reject +``` + +**Что настроили:** +- Порт 587 для отправки от клиентов +- Требуется авторизация +- TLS опционален (пока, потом сделаем обязательным) + +### Перезагружаем Postfix + +```bash +sudo postfix reload +``` + +Проверь статус: + +```bash +sudo systemctl status postfix +``` + +Проверь порты: + +```bash +sudo ss -tulnp | grep master +``` + +Должно быть: + +``` +tcp LISTEN 0 100 0.0.0.0:25 ... +tcp LISTEN 0 100 0.0.0.0:587 ... +``` + +## Первый тест + +Сейчас проверим, работает ли базовая функциональность. + +### Тест 1: Отправка письма через telnet + +Подключись к SMTP: + +```bash +telnet localhost 25 +``` + +Увидишь: + +``` +220 mail.example.com ESMTP +``` + +Выполни команды: + +``` +EHLO test.local +MAIL FROM: +RCPT TO: +DATA +Subject: Test mail + +This is a test message. +. +QUIT +``` + +**Пояснение:** +- `EHLO test.local` - представляемся +- `MAIL FROM` - от кого письмо +- `RCPT TO` - кому письмо +- `DATA` - начало тела письма +- `.` (точка на отдельной строке) - конец письма +- `QUIT` - завершение сессии + +Если все ОК, увидишь: + +``` +250 2.0.0 Ok: queued as 2CAB723BB4 +``` + +### Тест 2: Проверка доставки + +Проверь логи Postfix: + +```bash +sudo tail -f /var/log/mail.log +``` + +Ищи строки вроде этой: + +``` +Mar 16 19:54:34 mail postfix/lmtp[24548]: 634D423BB4: to=, relay=mail.example.com[private/dovecot-lmtp], delay=21, delays=21/0.02/0.02/0.01, dsn=2.0.0, status=sent (250 2.0.0 mPzKDMo1uGnlXwAAt3BTQQ Saved) +``` + +Проверь файловую систему: + +```bash +sudo ls -la /var/spool/mail/example.com/user/new/ +``` + +Должен появиться файл письма. + +```bash +drwx--S--- 2 vmail vmail 4096 Mar 16 19:57 . +drwx--S--- 5 vmail vmail 4096 Mar 16 19:57 .. +-rw------- 1 vmail vmail 537 Mar 16 19:52 '1773679952.M948512P24098.mail.example.com,S=537,W=554' +-rw------- 1 vmail vmail 537 Mar 16 19:54 '1773680074.M217408P24549.mail.example.com,S=537,W=554' +-rw------- 1 vmail vmail 537 Mar 16 19:57 '1773680252.M311184P24696.mail.example.com,S=537,W=554' +``` + +Посмотри содержимое: + +```bash +cat /var/spool/mail/example.com/user/new/* +``` + +Должен быть текст письма. Например: +```bash +Return-Path: +Delivered-To: user@example.com +Received: from mail.example.com + by mail.example.com with LMTP + id /8HxEHw2uGl4YAAAt3BTQQ + (envelope-from ) + for ; Mon, 16 Mar 2026 19:57:32 +0300 +Received: from test.local (localhost [127.0.0.1]) + by mail.example.com (Postfix) with ESMTP id 06AAD23BBA + for ; Mon, 16 Mar 2026 18:37:51 +0300 (MSK) +Subject: Test mail +Message-Id: <20260316153757.06AAD23BBA@mail.example.com> +Date: Mon, 16 Mar 2026 18:37:51 +0300 (MSK) +From: admin@example.com + +This is a test message. +``` + +### Тест 3: Проверка IMAP + +Подключись к Dovecot: + +```bash +telnet localhost 143 +``` + +Увидишь: + +``` +* OK [CAPABILITY IMAP4rev1 SASL-IR LOGIN-REFERRALS ID ENABLE IDLE LITERAL+ AUTH=PLAIN AUTH=LOGIN] Dovecot ready. +``` + +Выполни: + +``` +a1 LOGIN user@example.com UserPass456 +a2 SELECT INBOX +a3 FETCH 1 BODY[] +a4 LOGOUT +``` + +**Пояснение:** +- `a1 LOGIN` - авторизация (логин пароль) +- `a2 SELECT INBOX` - открыть папку INBOX +- `a3 FETCH 1 BODY[]` - получить тело первого письма +- `a4 LOGOUT` - выход + +Если авторизация прошла: + +``` +a1 OK [CAPABILITY IMAP4rev1 SASL-IR LOGIN-REFERRALS ID ENABLE IDLE SORT SORT=DISPLAY THREAD=REFERENCES THREAD=REFS THREAD=ORDEREDSUBJECT MULTIAPPEND URL-PARTIAL CATENATE UNSELECT CHILDREN NAMESPACE UIDPLUS LIST-EXTENDED I18NLEVEL=1 CONDSTORE QRESYNC ESEARCH ESORT SEARCHRES WITHIN CONTEXT=SEARCH LIST-STATUS BINARY MOVE SNIPPET=FUZZY PREVIEW=FUZZY STATUS=SIZE SAVEDATE LITERAL+ NOTIFY SPECIAL-USE] Logged in +``` + +Если письмо есть: + +``` +* 1 FETCH (FLAGS (\Seen \Recent) BODY[] {554} +Return-Path: +Delivered-To: user@example.com +Received: from mail.example.com + by mail.example.com with LMTP + id jdVeOFA1uGkiXgAAt3BTQQ + (envelope-from ) + for ; Mon, 16 Mar 2026 19:52:32 +0300 +Received: from test.local (localhost [127.0.0.1]) + by mail.example.com (Postfix) with ESMTP id 2CAB723BB4 + for ; Mon, 16 Mar 2026 18:33:46 +0300 (MSK) +Subject: Test mail +Message-Id: <20260316153352.2CAB723BB4@mail.example.com> +Date: Mon, 16 Mar 2026 18:33:46 +0300 (MSK) +From: admin@example.com + +This is a test message. + +) +``` + +### Тест 4: Отправка с авторизацией + +Для теста SMTP AUTH нужен base64 логина и пароля. + +Генерируем: + +```bash +echo -ne '\000admin@example.com\000SecurePass123' | base64 +``` + +Где: +- `\000` - нулевой байт (NULL, символ с кодом 0) +- `username` - логин (admin@example.com) +- `\000` - еще один NULL +- `password` - пароль (SecurePass123) + +Вернет что-то вроде: + +``` +AGFkbWluQGV4YW1wbGUuY29tAFNlY3VyZVBhc3MxMjM= +``` + +Подключись к порту 587: + +```bash +telnet localhost 587 +``` + +Выполни: + +``` +EHLO test.local +AUTH PLAIN AGFkbWluQGV4YW1wbGUuY29tAFNlY3VyZVBhc3MxMjM= +MAIL FROM: +RCPT TO: +DATA +Subject: Auth test + +Test with auth. +. +QUIT +``` + +Если авторизация прошла: + +``` +235 2.7.0 Authentication successful +``` + +Письмо должно быть доставлено. + +## Что получилось + +Сейчас у тебя: + +**Работает:** +- Прием почты на порт 25 +- Отправка почты через порт 587 с авторизацией +- Доступ к ящикам через IMAP на порту 143 +- Виртуальные домены и ящики +- Псевдонимы + +**Не работает:** +- Шифрование (все по открытому каналу) +- Проверка на вирусы +- Проверка на спам +- Защита от брутфорса +- Веб-интерфейс +- DKIM подписи + +Это **рабочий прототип**, но не production-ready решение. + +## Типичные проблемы + +### Postfix не стартует + +Проверь логи: + +```bash +journalctl -u postfix -n 50 +``` + +Частые причины: +- Опечатка в `main.cf` +- Порт 25 занят другим процессом +- Нет прав на директории + +Проверь конфиг: + +```bash +postfix check +``` + +### Dovecot не стартует + +Проверь логи: + +```bash +journalctl -u dovecot -n 50 +``` + +Частые причины: +- Опечатка в конфигах +- Неправильные права на `/etc/dovecot/users` +- Порт 143 занят + +Проверь конфиг: + +```bash +doveconf -n +``` + +### Письма не доставляются + +Проверь очередь Postfix: + +```bash +postqueue -p +``` + +Если письма застряли - смотри причину: + +```bash +tail -f /var/log/mail.log +``` + +Частые причины: +- Неправильный путь в `vmailbox` +- Нет прав на `/var/spool/mail` +- LMTP сокет не создан + +Проверь сокет: + +```bash +ls -la /var/spool/postfix/private/dovecot-lmtp +``` + +Должен быть. + +### Письма не доставляются: Permission denied + +Ошибка в логах: +```bash +# Permission denied (euid=5000(vmail) missing +x perm: /var/spool/mail) +``` + +Проверь владельца реальной директории +```bash +ls -ld /var/spool/mail # Может быть симлинк +ls -ld /var/mail # Реальная директория +``` + +Исправь права +```bash +sudo chown -R vmail:vmail /var/mail +sudo chmod 755 /var/mail +``` + +Проверь вложенные директории +```bash +ls -la /var/mail/ +``` + +### IMAP не работает + +Проверь авторизацию вручную: + +```bash +doveadm auth test user@example.com UserPass456 +``` + +Должно вернуть: + +``` +passdb: user@example.com auth succeeded +userdb: user@example.com +``` + +Если не работает: +- Проверь хеш пароля в `/etc/dovecot/users` +- Проверь права на файл +- Проверь логи Dovecot + +### SMTP AUTH не работает + +Проверь сокет: + +```bash +ls -la /var/spool/postfix/private/auth +``` + +Должен быть с правами `666` и владельцем `postfix:postfix`. + +Проверь логи: + +```bash +grep "sasl" /var/log/mail.log +``` + +## Следующий шаг + +В следующей части настроим защиту: +- Антивирус Amavis + ClamAV +- Антиспам SpamAssassin +- GreyListing через Postgrey +- Fail2ban против брутфорса + +После этого сервер станет безопаснее и перестанет пропускать вирусы и спам. \ No newline at end of file diff --git a/content/posts/mailserver-part-3-security/featured.png b/content/posts/mailserver-part-3-security/featured.png new file mode 100644 index 0000000..1a85d87 Binary files /dev/null and b/content/posts/mailserver-part-3-security/featured.png differ diff --git a/content/posts/mailserver-part-3-security/index.md b/content/posts/mailserver-part-3-security/index.md new file mode 100644 index 0000000..81ba580 --- /dev/null +++ b/content/posts/mailserver-part-3-security/index.md @@ -0,0 +1,1086 @@ +--- +title: "Почтовый сервер на Debian 12: полное руководство от установки до production. Часть 3 - Защита от спама и вирусов" +date: 2026-03-16 +draft: false +description: "Настройка Amavis, ClamAV, SpamAssassin и Postgrey для защиты от вирусов и спама. Fail2ban для защиты от брутфорса SMTP/IMAP. Обучение антиспама, белые списки, мониторинг." +tags: ["amavis", "clamav", "spamassassin", "postgrey", "fail2ban"] +categories: ["Системное администрирование", "Электронная почта"] +series: ["Почтовый сервер на Debian 12"] +series_order: 3 +--- + +# Защита от спама и вирусов + +Почтовый сервер без защиты - это открытые ворота для спама и вирусов. Сейчас настроим многоуровневую оборону, которая отсечет 90%+ мусора еще до попадания в ящики. + +Четыре уровня защиты: +1. **Postgrey** - отбрасывает спам-ботов на входе (greylisting) +2. **ClamAV** - проверяет вложения на вирусы +3. **SpamAssassin** - анализирует содержимое писем +4. **Fail2ban** - блокирует IP при брутфорсе паролей + +## Перед началом + +У тебя должно быть: +- Рабочий Postfix + Dovecot из предыдущей части + +{{< article link="/posts/mailserver-part-2-postfix-dovecot/">}} + +- Минимум **2GB RAM** (ClamAV прожорлив) +- Дисковое пространство для базы вирусов (~500MB) + +Проверь что Postfix работает: + +```bash +sudo systemctl status postfix +``` + +## Установка компонентов + +### Ставим все сразу + +```bash +sudo apt install -y \ + amavisd-new \ + clamav \ + clamav-daemon \ + clamav-freshclam \ + spamassassin \ + postgrey +``` + +**Что установили:** +- `amavisd-new` - прослойка между Postfix и антивирусом/антиспамом +- `clamav` - антивирусный движок +- `clamav-daemon` - демон ClamAV для фоновой работы +- `clamav-freshclam` - автообновление вирусных баз +- `spamassassin` - антиспам фильтр +- `postgrey` - greylisting демон + +### Создание необходимых файлов и директорий + +Создаем mailname (используется Amavis) + +```bash +echo "mail.example.com" | sudo tee /etc/mailname +``` +Создаем директорию для PID файла Amavis + +```bash +sudo mkdir -p /var/run/amavis +sudo chown amavis:amavis /var/run/amavis +sudo chmod 755 /var/run/amavis +``` + +Создаем tmpfiles конфиг для автоматического создания директории +```bash +sudo nano /etc/tmpfiles.d/amavis.conf +``` + +Добавь: + +``` +d /run/amavis 0755 amavis amavis - +``` + +Примени конфиг: + +```bash +sudo systemd-tmpfiles --create +``` + +**Замени** `mail.example.com` на свое полное имя хоста. + + +### Обновляем базу вирусов + +ClamAV нужна актуальная база вирусов: + +```bash +sudo systemctl stop clamav-freshclam +sudo freshclam +sudo systemctl start clamav-freshclam +``` + +Это займет 2-5 минут. Freshclam скачает ~200-300MB данных. + +Проверь статус: + +```bash +sudo systemctl status clamav-freshclam +``` + +Должен быть `active (running)`. + +## Настройка ClamAV + +### Проверяем что демон запущен + +```bash +sudo systemctl status clamav-daemon +``` + +Если не запущен(что скорее всего): + +```bash +sudo systemctl enable clamav-daemon +sudo systemctl start clamav-daemon +``` + +### Настройка сокета + +ClamAV слушает через UNIX-сокет. Проверь: + +```bash +ls -la /var/run/clamav/clamd.ctl +``` + +Должен быть сокет с правами для группы `clamav`. + +Добавь пользователя `amavis` в группу `clamav`: + +```bash +sudo adduser clamav amavis +sudo adduser amavis clamav +``` + +Перезапусти ClamAV: + +```bash +sudo systemctl restart clamav-daemon +``` + +## Настройка Amavis + +Amavis - это диспетчер, который принимает письма от Postfix, прогоняет через ClamAV и SpamAssassin, и возвращает обратно. + +### Основной конфиг + +Открой: + +```bash +sudo nano /etc/amavis/conf.d/15-content_filter_mode +``` + +Раскомментируй: + +```perl +@bypass_virus_checks_maps = ( + \%bypass_virus_checks, \@bypass_virus_checks_acl, \$bypass_virus_checks_re); + +@bypass_spam_checks_maps = ( + \%bypass_spam_checks, \@bypass_spam_checks_acl, \$bypass_spam_checks_re); +``` + +**Что сделали:** Включили проверку на вирусы и спам. + +### Настройка интеграции + +Открой: + +```bash +sudo nano /etc/amavis/conf.d/50-user +``` + +Добавь в конец: + +```perl +# Домен +$mydomain = 'example.com'; +$myhostname = 'mail.example.com'; + +# Интерфейс +$inet_socket_bind = '127.0.0.1'; + +# Порты +$inet_socket_port = 10024; + +# Политика для локальных доменов +$policy_bank{'MYNETS'} = { + originating => 1, + os_fingerprint_method => undef, +}; + +# Антиспам +$sa_tag_level_deflt = -999; # Всегда добавлять заголовки +$sa_tag2_level_deflt = 5.0; # Помечать как спам при 5+ баллах +$sa_kill_level_deflt = 10.0; # Отклонять при 10+ баллах + +# Антивирус +$virus_admin = "postmaster\@$mydomain"; + +# Уведомления +$virus_quarantine_to = "virus-quarantine\@$mydomain"; +$spam_quarantine_to = "spam-quarantine\@$mydomain"; + +# Обязательно в конце (по умолчанию уже присутствует) +1; +``` + +**Замени:** +- `example.com` на свой домен +- `mail.example.com` на свое имя хоста + +**Что настроили:** + +**Основные параметры:** +- Слушаем на localhost:10024 +- Домен и hostname для заголовков + +**Антиспам:** +- `-999` - всегда добавлять X-Spam заголовки +- `5.0` - при 5+ баллах помечать как спам (X-Spam-Flag: YES) +- `10.0` - при 10+ баллах отклонять письмо + +**Антивирус:** +- Всегда проверять через ClamAV +- Карантин для вирусов и спама + +### Права на директории + +```bash +sudo chown -R amavis:amavis /var/lib/amavis +sudo chmod 750 /var/lib/amavis +``` + +### Запуск Amavis + +```bash +sudo systemctl enable amavis +sudo systemctl start amavis +sudo systemctl status amavis +``` + +Должен быть `active (running)`. + +Проверь порт: + +```bash +sudo ss -tulnp | grep 10024 +``` + +Должно быть: + +```bash +tcp LISTEN 0 4096 127.0.0.1:10024 0.0.0.0:* users:(("/usr/sbin/amavi",pid=43480,fd=5),("/usr/sbin/amavi",pid=43479,fd=5),("/usr/sbin/amavi",pid=43456,fd=5)) +``` + +## Настройка SpamAssassin + +SpamAssassin работает через Amavis, но нужно настроить его правила. + +### Основной конфиг + +Открой: + +```bash +sudo nano /etc/spamassassin/local.cf +``` + +Добавь в самый конец: + +``` +# Требуемый балл для спама +required_score 5.0 + +# Использовать Bayesian фильтр +use_bayes 1 +bayes_auto_learn 1 + +# DNSBL проверки +use_razor2 0 +use_pyzor 0 + +# Сетевые проверки (SPF, DKIM) +use_dcc 0 + +# Автообучение +bayes_auto_learn_threshold_nonspam -0.1 +bayes_auto_learn_threshold_spam 6.0 + +# Путь к базе Bayes +bayes_path /var/lib/amavis/.spamassassin/bayes + +# Язык +ok_languages en ru +ok_locales en ru + +# Размер письма для проверки (500KB) +report_safe 0 +``` + +**Что настроили:** + +**required_score 5.0:** +- Порог для пометки спама + +**Bayesian фильтр:** +- Обучаемая модель на основе примеров +- Автообучение включено + +**DNSBL:** +- Razor/Pyzor/DCC отключены (используем встроенные DNSBL) + +**Автообучение:** +- Письма с баллами < -0.1 учатся как не-спам +- Письма с баллами > 6.0 учатся как спам + +### Создаем директорию для Bayes + +```bash +sudo mkdir -p /var/lib/amavis/.spamassassin +sudo chown -R amavis:amavis /var/lib/amavis/.spamassassin +sudo chmod 700 /var/lib/amavis/.spamassassin +``` + +### Запуск SpamAssassin + +```bash +sudo systemctl enable spamassassin +sudo systemctl start spamassassin +sudo systemctl status spamassassin +``` + +Должен быть `active (running)`. + +### Перезапуск Amavis + +```bash +sudo systemctl restart amavis +``` + +## Настройка Postgrey + +Postgrey - это greylisting("временная задержка"). Принцип: первое письмо от нового отправителя откладывается на 5 минут. Легальные серверы повторят попытку, спам-боты - нет. + +### Конфигурация + +Открой: + +```bash +sudo nano /etc/default/postgrey +``` + +Найди и измени: + +```bash +POSTGREY_OPTS="--inet=127.0.0.1:10023 --delay=300" +``` + +**Что настроили:** +- `--inet=127.0.0.1:10023` - слушать на localhost:10023 +- `--delay=300` - задержка 5 минут (300 секунд) + +### Белые списки + +Postgrey имеет встроенные белые списки для крупных отправителей (Google, Microsoft, и т.д.). + +Посмотреть: + +```bash +cat /etc/postgrey/whitelist_clients +``` + +Добавить свои (опционально): + +```bash +sudo nano /etc/postgrey/whitelist_clients.local +``` + +Формат: + +``` +/^.*\.trusted-domain\.com$/ +192.168.1.0/24 +specific-server.example.com +``` + +На примере Yandex: + +``` +/^.*\.yandex\.ru$/ +/^.*\.ya\.ru$/ +``` + +### Запуск + +```bash +sudo systemctl enable postgrey +sudo systemctl start postgrey +sudo systemctl status postgrey +``` + +Должен быть `active (running)`. + +Проверь порт: + +```bash +sudo ss -tulnp | grep 10023 +``` + +Должно быть: + +``` +tcp LISTEN 0 5 127.0.0.1:10023 ... +``` + +## Интеграция с Postfix + +Сейчас настроим Postfix для прогона всех писем через Amavis и Postgrey. + +### Настройка content_filter + +Открой: + +```bash +sudo nano /etc/postfix/main.cf +``` + +В конце секции `smtpd_recipient_restrictions`, созданную на предыдущих этапах, добавь строку: + +``` +# Postgrey для greylisting +check_policy_service inet:127.0.0.1:10023 +``` + +И добавь в конец файла: + +``` +# Content filter через Amavis +content_filter = smtp-amavis:[127.0.0.1]:10024 +``` + +**Что добавили:** + +**content_filter:** +- Все письма идут через Amavis на порт 10024 +- Amavis проверяет через ClamAV и SpamAssassin +- Возвращает обратно в Postfix на порт 10025 + +**smtpd_recipient_restrictions:** +- Добавили `check_policy_service inet:127.0.0.1:10023` - проверка через Postgrey + +### Настройка master.cf + +Открой: + +```bash +sudo nano /etc/postfix/master.cf +``` + +Добавь в конец: + +``` +# Отправка в Amavis +smtp-amavis unix - - n - 2 smtp + -o smtp_data_done_timeout=1200 + -o smtp_send_xforward_command=yes + -o disable_dns_lookups=yes + -o max_use=20 + +# Прием из Amavis обратно +127.0.0.1:10025 inet n - n - - smtpd + -o content_filter= + -o smtpd_delay_reject=no + -o smtpd_client_restrictions=permit_mynetworks,reject + -o smtpd_helo_restrictions= + -o smtpd_sender_restrictions= + -o smtpd_recipient_restrictions=permit_mynetworks,reject + -o smtpd_data_restrictions=reject_unauth_pipelining + -o smtpd_end_of_data_restrictions= + -o smtpd_restriction_classes= + -o mynetworks=127.0.0.0/8 + -o smtpd_error_sleep_time=0 + -o smtpd_soft_error_limit=1001 + -o smtpd_hard_error_limit=1000 + -o smtpd_client_connection_count_limit=0 + -o smtpd_client_connection_rate_limit=0 + -o receive_override_options=no_header_body_checks,no_unknown_recipient_checks,no_milters + -o local_header_rewrite_clients= +``` + +**Что настроили:** + +**smtp-amavis:** +- Транспорт для отправки в Amavis +- Таймаут 1200 секунд (для больших писем) +- Максимум 20 использований соединения + +**127.0.0.1:10025:** +- Прием обратно из Amavis +- Отключаем повторные проверки (content_filter пустой) +- Пропускаем только с localhost + +### Перезапуск Postfix + +Проверь конфиг: + +```bash +sudo postfix check +``` + +Если ошибок нет - перезапускай: + +```bash +sudo postfix reload +``` + +Проверь статус: + +```bash +sudo systemctl status postfix +``` + +## Тестирование защиты + +### Тест 1: Проверка антивируса + +Отправь тестовый вирус EICAR (безопасная тестовая сигнатура): + +```bash +telnet localhost 25 +``` + +``` +EHLO test.local +MAIL FROM: +RCPT TO: +DATA +Subject: Virus test + +X5O!P%@AP[4\PZX54(P^)7CC)7}$EICAR-STANDARD-ANTIVIRUS-TEST-FILE!$H+H* +. +QUIT +``` + +Проверь логи: + +```bash +sudo grep -i "eicar\|infected\|virus" /var/log/mail.log | tail -20 +``` + +Должно быть: + +``` +... mail amavis[44437]: (44437-01) Blocked INFECTED (Eicar-Signature) {DiscardedOutbound,Quarantined}, MYNETS LOCAL [127.0.0.1]:6674 -> , quarantine: virus-quarantine@example.com, Queue-ID: 6B6C425808, Message-ID: <20260317085556.6B6C425808@mail.example.com>, mail_id: fqAsJO87JdbS, Hits: -, size: 375, 454 ms +... mail postfix/smtp[47529]: 6B6C425808: to=, relay=127.0.0.1[127.0.0.1]:10024, delay=24, delays=24/0.02/0.09/0.39, dsn=2.7.0, status=sent (250 2.7.0 Ok, discarded, id=44437-01 - INFECTED: Eicar-Signature) +... mail postfix/lmtp[47533]: B34582580B: to=, relay=mail.example.com[private/dovecot-lmtp], delay=0.12, delays=0.01/0.02/0.04/0.06, dsn=5.1.1, status=bounced (host mail.example.com[private/dovecot-lmtp] said: 550 5.1.1 User doesn't exist: virus-quarantine@example.com (in reply to RCPT TO command)) +``` + +Письмо **отклонено** - антивирус работает. + +### Тест 2: Проверка антиспама + +Отправь письмо с внешнего почтового ящика (Gmail, Yandex) на свой сервер с текстом: + +``` +Subject: BUY CHEAP VIAGRA NOW!!! +Body: +CLICK HERE FOR AMAZING DEALS!!! +FREE MONEY! ACT NOW! +BUY VIAGRA CIALIS CHEAP! +100% GUARANTEED! NO PRESCRIPTION! +MAKE MONEY FAST! LIMITED TIME! +``` + +**Важно:** Тест через `telnet localhost 25` **не покажет** X-Spam заголовки, т.к. письмо будет считаться исходящим от своих (`MYNETS`). + +Проверь логи: + +```bash +sudo grep "amavis" /var/log/mail.log | tail -5 +``` + +Должна приблизительно быть строка: + +``` +... mail amavis[51765]: (51765-01) Passed SPAMMY {RelayedOutbound}, MYNETS LOCAL [127.0.0.1]:45220 -> , Queue-ID: 526902584D, Message-ID: <20260317101453.526902584D@mail.example.com>, mail_id: yUPoX6uzzm6f, Hits: 6.549, size: 375, queued_as: 9DA0D2584F, 1259 ms +``` + +- `Passed CLEAN` — не спам (баллов < 5.0) +- `Passed SPAMMY` — спам (баллов >= 5.0) +- `Hits: X.XX` — количество баллов SpamAssassin + +Если баллов >= 5.0, письмо помечено как спам и в заголовках будет: + +``` +X-Spam-Flag: YES +X-Spam-Score: 15.2 +X-Spam-Status: Yes, score=15.2 +``` + +Проверь письмо: + +```bash +sudo ls -t /var/mail/example.com/admin/new/ | head -1 | xargs -I {} sudo cat /var/mail/example.com/admin/new/{} | grep X-Spam +``` + +**Если баллов мало (< 5.0):** + +Это нормально — письмо от доверенного провайдера (Yandex, Gmail) с валидной DKIM подписью получает мало баллов. SpamAssassin работает правильно, отличая легитимную почту от спама. + +**Уточнение:** В качестве спам рассылки я использовал почту Yandex. + +Логи испытания: +``` +... mail amavis[51765]: (51765-01) Passed SPAMMY {RelayedOutbound}, MYNETS LOCAL [127.0.0.1]:45220 -> , Queue-ID: 526902584D, Message-ID: <20260317101453.526902584D@mail.example.com>, mail_id: yUPoX6uzzm6f, Hits: 6.549, size: 375, queued_as: 9DA0D2584F, 1259 ms +... mail amavis[51766]: (51766-01) Passed CLEAN {RelayedOpenRelay}, [178.154.239.223]:36200 [2a02:6b8:c42:e720:0:640:3001:0] -> , Queue-ID: AA84721409, Message-ID: <121751773743278@mail.yandex.ru>, mail_id: V5iYivtYPpbe, Hits: 1.567, size: 1912, queued_as: 948F02584F, 853 ms +``` + +Из логов видно, что в начале письмо получает Passed SPAMMY, а затем Passed CLEAN, Hits: 1.567(колличество баллов, что < 5.0). +Причины: +- Отправитель - Yandex (доверенный провайдер) +- Валидная DKIM подпись: +``` +DKIM-Signature: v=1; a=rsa-sha256; d=ya.ru; s=mail; +``` +- IP не в блэклистах + +### Тест 3: Проверка Postgrey + +Отправь письмо с другого IP (запрос с внешнего сервера): + +```bash +telnet mail.example.com 25 +``` +где, mail.example.com - полное доменное имя или IP твоего почтового сервера. + +``` +EHLO mail.google.com +MAIL FROM: +RCPT TO: +DATA +Subject: Greylisting test +. +QUIT +``` + +При первой попытке должен получить: + +``` +450 4.2.0 : Recipient address rejected: Greylisted, see http://postgrey.schweikert.ch/help/example.com.html +``` + +Подожди 5 минут и повтори - письмо пройдет. + +Проверь статус Postgrey: + +```bash +sudo grep "postgrey" /var/log/mail.log | tail -10 +``` + +Должна быть запись о Greylisted. + +## Обучение SpamAssassin + +Чем больше примеров спама и не-спама покажешь SpamAssassin, тем точнее он работает. + +### Ручное обучение + +**Пометить письмо как спам:** + +```bash +sudo sa-learn --spam /var/mail/example.com/admin/.Spam/cur/* +``` + +**Пометить как не-спам:** + +```bash +sudo sa-learn --ham /var/mail/example.com/admin/cur/* +``` + +### Проверить статистику обучения + +```bash +sudo sa-learn --dump magic +``` + +Вывод: + +``` +0.000 0 3 0 non-token data: bayes db version +0.000 0 150 0 non-token data: nspam +0.000 0 450 0 non-token data: nham +``` + +**nspam** - количество спам-писем в базе +**nham** - количество не-спам писем в базе + +**После обучения перезапусти Amavis:** + +```bash +sudo systemctl restart amavis +``` + +### Автообучение + +SpamAssassin автоматически учится на письмах с четкими признаками (настроили в `local.cf`): + +- Баллы < -0.1 → автоматически не-спам +- Баллы > 6.0 → автоматически спам + +Через неделю-две база накопится, точность вырастет. + +## Fail2ban для почтовых сервисов + +Защита от брутфорса паролей SMTP/IMAP. + +### Проверка установки + +Fail2ban должен быть установлен из статьи по базовой настройке сервера: + +{{< article link="/posts/tips-debian-12-hardening/">}} + +Проверь: + +```bash +sudo systemctl status fail2ban +``` + +### Настройка jail для почты + +Открой: + +```bash +sudo nano /etc/fail2ban/jail.local +``` + +Добавь в конец: + +```ini +[postfix-sasl] +enabled = true +port = smtp,submission,smtps +filter = postfix[mode=auth] +logpath = /var/log/mail.log +maxretry = 3 +bantime = 600 + +[dovecot] +enabled = true +port = imap,imaps,pop3,pop3s +filter = dovecot +logpath = /var/log/mail.log +maxretry = 3 +bantime = 600 +``` + +**Что настроили:** + +**postfix-sasl:** +- Защита SMTP AUTH (порты 25, 587, 465) +- Максимум 3 неудачных попытки +- Бан на 10 минут + +**dovecot:** +- Защита IMAP/POP3 (порты 143, 993, 110, 995) +- Максимум 3 неудачных попытки +- Бан на 10 минут + +### Перезапуск Fail2ban + +```bash +sudo systemctl reload fail2ban +``` + +Проверь тюрьмы: + +```bash +sudo fail2ban-client status +``` + +Должно быть: + +``` +Status +|- Number of jail: 3 +`- Jail list: dovecot, postfix-sasl, sshd +``` + +### Тест Fail2ban + +Попробуй подключиться с неправильным паролем 3 раза: + +```bash +telnet localhost 587 +``` + +``` +EHLO test.local +AUTH PLAIN dGVzdEBleGFtcGxlLmNvbQB3cm9uZ3Bhc3N3b3Jk +AUTH PLAIN dGVzdEBleGFtcGxlLmNvbQB3cm9uZ3Bhc3N3b3Jk +AUTH PLAIN dGVzdEBleGFtcGxlLmNvbQB3cm9uZ3Bhc3N3b3Jk +``` + +После 3-й попытки твой IP должен быть забанен. + +Проверь: + +```bash +sudo fail2ban-client status postfix-sasl +``` + +Должен появиться IP в `Banned IP list`. + +## Мониторинг защиты + +### Статистика Amavis + +```bash +sudo amavisd-nanny +``` +Команда выводит состояние worker-процессов в реальном времени. +Точки (.) — процесс idle, звездочки (*) — обрабатывает письмо. + +### Статистика ClamAV + +```bash +sudo clamdscan --version +sudo freshclam --version +``` + +Проверь обновление баз: + +```bash +sudo cat /var/log/clamav/freshclam.log | tail -20 +``` + +### Статистика SpamAssassin + +```bash +sudo sa-learn --dump magic +``` + +**Вывод:** + +``` +0.000 0 3 0 non-token data: bayes db version +0.000 0 234 0 non-token data: nspam +0.000 0 789 0 non-token data: nham +0.000 0 45123 0 non-token data: ntokens +0.000 0 1773745892 0 non-token data: oldest atime +0.000 0 1773831245 0 non-token data: newest atime +0.000 0 0 0 non-token data: last journal sync atime +0.000 0 0 0 non-token data: last expiry atime +0.000 0 0 0 non-token data: last expire atime delta +0.000 0 0 0 non-token data: last expire reduction count +``` +**Где:** + +nspam: 234 — количество спам-писем в обучающей базе +nham: 789 — количество не-спам писем в обучающей базе +ntokens: 45123 — количество токенов (слов) в базе + + +### Логи + +Все логи почты в одном месте: + +```bash +sudo tail -f /var/log/mail.log +``` + +Фильтруй по ключевым словам: + +```bash +# Вирусы +sudo grep "Blocked INFECTED" /var/log/mail.log + +# Спам +sudo grep "Passed SPAM" /var/log/mail.log + +# Greylisting +sudo grep "Greylisted" /var/log/mail.log + +# Fail2ban баны +sudo grep "Ban" /var/log/fail2ban.log +``` + +## Тонкая настройка + +### Увеличить порог спама + +Если много ложных срабатываний, увеличь `required_score`: + +```bash +sudo nano /etc/spamassassin/local.cf +``` + +Измени: + +``` +required_score 7.0 +``` + +Перезапусти: + +```bash +sudo systemctl restart amavis +``` + +### Добавить домен в белый список Postgrey + +```bash +sudo nano /etc/postgrey/whitelist_clients.local +``` + +Добавь: + +``` +/^.*\.important-partner\.com$/ +``` + +Перезапусти: + +```bash +sudo systemctl restart postgrey +``` + +### Отключить greylisting для авторизованных + +Если не хочешь задержек для своих пользователей, в Postfix измени: + +```bash +sudo nano /etc/postfix/main.cf +``` + +В `smtpd_recipient_restrictions` **перед** `check_policy_service` добавь: + +``` +permit_sasl_authenticated, +``` + +Чтобы получилось: + +``` +smtpd_recipient_restrictions = + permit_mynetworks, + permit_sasl_authenticated, + reject_unauth_destination, + check_policy_service inet:127.0.0.1:10023 +``` + +Перезагрузи: + +```bash +sudo postfix reload +``` + +## Типичные проблемы + +### ClamAV жрет всю память + +ClamAV требует ~500-700MB RAM. Если сервер слабый: + +Открой: + +```bash +sudo nano /etc/clamav/clamd.conf +``` + +Уменьши: + +``` +MaxThreads 10 +MaxConnectionQueueLength 15 +``` + +Перезапусти: + +```bash +sudo systemctl restart clamav-daemon +``` + +### Письма застревают в очереди + +Проверь очередь: + +```bash +sudo postqueue -p +``` + +Причина может быть в медленной проверке. Увеличь таймаут: + +```bash +sudo nano /etc/postfix/master.cf +``` + +Найди `smtp-amavis` и увеличь: + +``` +smtp_data_done_timeout=1800 +``` + +Перезагрузи: + +```bash +sudo postfix reload +``` + +### SpamAssassin не учится + +Проверь права на базу Bayes: + +```bash +ls -la /var/lib/amavis/.spamassassin/ +``` + +Должен быть владелец `amavis:amavis`. + +Исправь: + +```bash +sudo chown -R amavis:amavis /var/lib/amavis/.spamassassin +sudo chmod 700 /var/lib/amavis/.spamassassin +``` + +### Postgrey блокирует легальную почту + +Добавь отправителя в белый список: + +```bash +sudo nano /etc/postgrey/whitelist_clients.local +``` + +``` +sender-domain.com +``` + +Перезапусти: + +```bash +sudo systemctl restart postgrey +``` + +## Что получилось + +Сейчас у тебя: + +**Работает:** +- Антивирусная проверка всех входящих писем (ClamAV) +- Антиспам с обучением (SpamAssassin + Bayes) +- Greylisting для новых отправителей (Postgrey) +- Защита от брутфорса SMTP/IMAP (Fail2ban) + +**Потребление ресурсов:** +- ClamAV: ~500-700 MB RAM +- SpamAssassin: ~200-300 MB на процесс +- Amavis: ~50-100 MB +- Postgrey: ~10-20 MB +- **Итого:** +800MB-1.2GB RAM + +**Проблемы:** +- Пароли все еще передаются открытым текстом (нет TLS) +- Нет DKIM подписей (письма могут улетать в спам) +- Нет веб-интерфейса + +Это **защищенный сервер**, но еще не production-ready. + +## Следующий шаг + +В следующей части настроим шифрование и репутацию: +- TLS через Let's Encrypt (шифрование соединений) +- DKIM подписи (доверие к твоим письмам) +- SPF и DMARC записи (защита от подделки домена) + +После этого письма перестанут улетать в спам у Gmail/Outlook. \ No newline at end of file diff --git a/content/posts/tips-debian-12-hardening/featured.png b/content/posts/tips-debian-12-hardening/featured.png index 22314ef..9d1c913 100644 Binary files a/content/posts/tips-debian-12-hardening/featured.png and b/content/posts/tips-debian-12-hardening/featured.png differ diff --git a/content/posts/tips-debian-12-hardening/index.md b/content/posts/tips-debian-12-hardening/index.md index 0f9f890..5f1ffa2 100644 --- a/content/posts/tips-debian-12-hardening/index.md +++ b/content/posts/tips-debian-12-hardening/index.md @@ -1,6 +1,6 @@ --- title: "Безопасный production-сервер на Debian 12: пошаговая настройка" -date: 2026-03-12 +date: 2026-03-07 draft: false description: "Пошаговое руководство по защите Debian 12 с нуля: настройка SSH, ufw, Fail2ban, sysctl, автообновлений и мониторинга. Базовая безопасность production-сервера за один час." tags: ["debian", "linux", "security", "безопасность", "ssh", "ufw", "fail2ban", "sysctl", "linux-admin"] @@ -441,22 +441,6 @@ sudo ufw allow 2222/tcp comment 'SSH' **Замени 2222** на свой порт из `sshd_config`. -Разрешаем базовые сервисы (добавь те, что нужны): - -```bash -# HTTP/HTTPS (если будет веб) -sudo ufw allow 80/tcp comment 'HTTP' -sudo ufw allow 443/tcp comment 'HTTPS' - -# SMTP (если будет почта) -sudo ufw allow 25/tcp comment 'SMTP' -sudo ufw allow 587/tcp comment 'SMTP Submission' - -# IMAP (если будет почта) -sudo ufw allow 143/tcp comment 'IMAP' -sudo ufw allow 993/tcp comment 'IMAPS' -``` - **Не открывай порты, которые не нужны!** Добавишь потом по мере необходимости. ### Rate limiting для SSH @@ -481,9 +465,6 @@ sudo ufw show added ``` ufw allow 2222/tcp -ufw allow 80/tcp -ufw allow 443/tcp -... ``` Включаем: @@ -514,8 +495,6 @@ Default: deny (incoming), allow (outgoing), disabled (routed) To Action From -- ------ ---- 2222/tcp LIMIT Anywhere -80/tcp ALLOW Anywhere -443/tcp ALLOW Anywhere ``` Включи автозапуск: