1111 lines
27 KiB
Markdown
1111 lines
27 KiB
Markdown
---
|
||
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:<admin@example.com>
|
||
RCPT TO:<user@example.com>
|
||
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=<user@example.com>, 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 <user@example.com> 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: <admin@example.com>
|
||
Delivered-To: user@example.com
|
||
Received: from mail.example.com
|
||
by mail.example.com with LMTP
|
||
id /8HxEHw2uGl4YAAAt3BTQQ
|
||
(envelope-from <admin@example.com>)
|
||
for <user@example.com>; 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 <user@example.com>; 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: <admin@example.com>
|
||
Delivered-To: user@example.com
|
||
Received: from mail.example.com
|
||
by mail.example.com with LMTP
|
||
id jdVeOFA1uGkiXgAAt3BTQQ
|
||
(envelope-from <admin@example.com>)
|
||
for <user@example.com>; 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 <user@example.com>; 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:<admin@example.com>
|
||
RCPT TO:<user@example.com>
|
||
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 против брутфорса
|
||
|
||
После этого сервер станет безопаснее и перестанет пропускать вирусы и спам. |