Перейти к основному содержимому

Почтовый сервер на Debian 12: полное руководство от установки до production. Часть 2 - Postfix и Dovecot

Олег Казанин
Автор
Олег Казанин
Строю полезную инфраструктуру на Open Source стеке. Документирую грабли, чтобы вы на них не наступали.
Оглавление
Почтовый сервер на Debian 12 - Эта статья — часть серии.
Часть 2: Ты уже здесь

Postfix + Dovecot: установка и базовая настройка
#

Сейчас поставим два ключевых компонента почтового сервера: Postfix (прием/отправка) и Dovecot (доступ к ящикам). На выходе получишь работающую систему, через которую можно отправлять и получать почту.

Без антивируса, без антиспама, без веб-морды - голый функционал. Но работающий.

Перед началом
#

Эта инструкция подразумевает, что у тебя:

  • Debian 12 с базовой настройкой безопасности
  • Настроены SSH, firewall, fail2ban
  • Система обновлена

Если еще не настроил - сделай это сейчас:

Дальше считаем, что база готова.

Подготовка для почтового сервера
#

Открываем порты в firewall
#

Почтовому серверу нужны специфичные порты:

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'

Проверь:

sudo ufw status

Должны появиться:

  • 25/tcp (SMTP)
  • 587/tcp (Submission)
  • 143/tcp (IMAP)
  • 993/tcp (IMAPS)

Проверяем DNS
#

Для почтового сервера DNS - критично. Без правильных записей письма не пойдут или улетят в спам.

MX-запись:

dig +short MX example.com

Должно вернуть:

10 mail.example.com.

A-запись:

dig +short mail.example.com

Должен вернуть твой IP.

PTR (обратная зона):

host твой-IP

Должно вернуть:

твой-IP.in-addr.arpa domain name pointer mail.example.com.

Если PTR не настроен - письма будут улетать в спам. Пиши в поддержку хостера, это делается с их стороны.

Установка Postfix
#

Ставим пакет
#

sudo apt install -y postfix

Установщик запустит конфигуратор. Отменяй его - настроим вручную.

Выбери:

  • General type of mail configuration: No configuration
  • Нажми OK

Создаем структуру для хранения почты
#

Проверяем где реальная директория

ls -ld /var/spool/mail

Если это симлинк (обычно в Debian) - работаем с /var/mail:

sudo mkdir -p /var/mail/example.com

Замени example.com на свой домен.

Создай системную группу и пользователя для виртуальных ящиков:

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)

Назначь владельца:

sudo chown -R vmail:vmail /var/mail
sudo chmod -R 770 /var/mail

Базовая конфигурация Postfix
#

Создай главный конфиг:

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 - список почтовых ящиков:

sudo nano /etc/postfix/vmailbox

Добавь:

[email protected]    example.com/admin/
[email protected]     example.com/user/

Формат: email путь_относительно_virtual_mailbox_base/

Файл virtual - псевдонимы:

sudo nano /etc/postfix/virtual

Добавь:

Формат: псевдоним куда_перенаправлять

Создай hash-таблицы:

sudo postmap /etc/postfix/vmailbox
sudo postmap /etc/postfix/virtual

Это создаст файлы .db - бинарные индексы для быстрого поиска.

Проверь конфиг:

sudo postfix check

Если ошибок нет - молчит. Если есть - исправляй.

Запускаем Postfix
#

sudo systemctl enable postfix
sudo systemctl start postfix
sudo systemctl status postfix

Должен быть active (running).

Проверяем порты
#

sudo ss -tulnp | grep master

Должно быть:

tcp   LISTEN   0   100   0.0.0.0:25   0.0.0.0:*   users:(("master",pid=...))

Postfix слушает порт 25.

Установка Dovecot
#

Ставим пакеты
#

sudo apt install -y \
  dovecot-core \
  dovecot-imapd \
  dovecot-lmtpd

Что установили:

  • dovecot-core - ядро
  • dovecot-imapd - IMAP сервер
  • dovecot-lmtpd - LMTP для приема почты от Postfix

Основной конфиг Dovecot
#

Открой:

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

Настройка аутентификации
#

Открой:

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)
  • Включили аутентификацию через файл паролей

Настройка файла паролей
#

Открой:

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 ([email protected])
  • %d - домен (example.com)
  • %n - локальная часть (user)

Настройка почтовых ящиков
#

Открой:

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
#

Открой:

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 (пока)
#

Открой:

sudo nano /etc/dovecot/conf.d/10-ssl.conf

Измени:

ssl = no

Потом включим с Let’s Encrypt. Пока отключаем.

Создаем файл пользователей
#

sudo nano /etc/dovecot/users

Формат файла:

email:password_hash:5000:5000::

Создадим пользователя [email protected] с паролем SecurePass123:

Генерируем хеш:

sudo doveadm pw -s CRYPT -p SecurePass123

Вернет что-то вроде:

{CRYPT}$6$random_salt$hash_here

Копируй только часть после {CRYPT}, т.е. $6$random_salt$hash_here.

Запиши в /etc/dovecot/users:

[email protected]:$6$random_salt$hash_here:5000:5000::

Создай еще пользователя [email protected] с паролем UserPass456:

sudo doveadm pw -s CRYPT -p UserPass456

Добавь в файл:

[email protected]:$6$hash1:5000:5000::
[email protected]:$6$hash2:5000:5000::

Формат строки:

email:hash:uid:gid:gecos:home:shell

У нас home и shell пустые, т.к. используем static userdb.

Права на файл
#

sudo chmod 640 /etc/dovecot/users
sudo chown root:dovecot /etc/dovecot/users

Запускаем Dovecot
#

sudo systemctl enable dovecot
sudo systemctl start dovecot
sudo systemctl status dovecot

Должен быть active (running).

Проверяем порты
#

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
#

Открой:

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)
#

Открой:

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
#

sudo postfix reload

Проверь статус:

sudo systemctl status postfix

Проверь порты:

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:

telnet localhost 25

Увидишь:

220 mail.example.com ESMTP

Выполни команды:

EHLO test.local
MAIL FROM:<[email protected]>
RCPT TO:<[email protected]>
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:

sudo tail -f /var/log/mail.log

Ищи строки вроде этой:

Mar 16 19:54:34 mail postfix/lmtp[24548]: 634D423BB4: to=<[email protected]>, 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 <[email protected]> mPzKDMo1uGnlXwAAt3BTQQ Saved)

Проверь файловую систему:

sudo ls -la /var/spool/mail/example.com/user/new/

Должен появиться файл письма.

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'

Посмотри содержимое:

cat /var/spool/mail/example.com/user/new/*

Должен быть текст письма. Например:

Return-Path: <[email protected]>
Delivered-To: [email protected]
Received: from mail.example.com
        by mail.example.com with LMTP
        id /8HxEHw2uGl4YAAAt3BTQQ
        (envelope-from <[email protected]>)
        for <[email protected]>; 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 <[email protected]>; Mon, 16 Mar 2026 18:37:51 +0300 (MSK)
Subject: Test mail
Message-Id: <[email protected]>
Date: Mon, 16 Mar 2026 18:37:51 +0300 (MSK)
From: [email protected]

This is a test message.

Тест 3: Проверка IMAP
#

Подключись к Dovecot:

telnet localhost 143

Увидишь:

* OK [CAPABILITY IMAP4rev1 SASL-IR LOGIN-REFERRALS ID ENABLE IDLE LITERAL+ AUTH=PLAIN AUTH=LOGIN] Dovecot ready.

Выполни:

a1 LOGIN [email protected] 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: <[email protected]>
Delivered-To: [email protected]
Received: from mail.example.com
        by mail.example.com with LMTP
        id jdVeOFA1uGkiXgAAt3BTQQ
        (envelope-from <[email protected]>)
        for <[email protected]>; 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 <[email protected]>; Mon, 16 Mar 2026 18:33:46 +0300 (MSK)
Subject: Test mail
Message-Id: <[email protected]>
Date: Mon, 16 Mar 2026 18:33:46 +0300 (MSK)
From: [email protected]

This is a test message.

)

Тест 4: Отправка с авторизацией
#

Для теста SMTP AUTH нужен base64 логина и пароля.

Генерируем:

echo -ne '\[email protected]\000SecurePass123' | base64

Где:

  • \000 - нулевой байт (NULL, символ с кодом 0)
  • username - логин ([email protected])
  • \000 - еще один NULL
  • password - пароль (SecurePass123)

Вернет что-то вроде:

AGFkbWluQGV4YW1wbGUuY29tAFNlY3VyZVBhc3MxMjM=

Подключись к порту 587:

telnet localhost 587

Выполни:

EHLO test.local
AUTH PLAIN AGFkbWluQGV4YW1wbGUuY29tAFNlY3VyZVBhc3MxMjM=
MAIL FROM:<[email protected]>
RCPT TO:<[email protected]>
DATA
Subject: Auth test

Test with auth.
.
QUIT

Если авторизация прошла:

235 2.7.0 Authentication successful

Письмо должно быть доставлено.

Что получилось
#

Сейчас у тебя:

Работает:

  • Прием почты на порт 25
  • Отправка почты через порт 587 с авторизацией
  • Доступ к ящикам через IMAP на порту 143
  • Виртуальные домены и ящики
  • Псевдонимы

Не работает:

  • Шифрование (все по открытому каналу)
  • Проверка на вирусы
  • Проверка на спам
  • Защита от брутфорса
  • Веб-интерфейс
  • DKIM подписи

Это рабочий прототип, но не production-ready решение.

Типичные проблемы
#

Postfix не стартует
#

Проверь логи:

journalctl -u postfix -n 50

Частые причины:

  • Опечатка в main.cf
  • Порт 25 занят другим процессом
  • Нет прав на директории

Проверь конфиг:

postfix check

Dovecot не стартует
#

Проверь логи:

journalctl -u dovecot -n 50

Частые причины:

  • Опечатка в конфигах
  • Неправильные права на /etc/dovecot/users
  • Порт 143 занят

Проверь конфиг:

doveconf -n

Письма не доставляются
#

Проверь очередь Postfix:

postqueue -p

Если письма застряли - смотри причину:

tail -f /var/log/mail.log

Частые причины:

  • Неправильный путь в vmailbox
  • Нет прав на /var/spool/mail
  • LMTP сокет не создан

Проверь сокет:

ls -la /var/spool/postfix/private/dovecot-lmtp

Должен быть.

Письма не доставляются: Permission denied
#

Ошибка в логах:

# Permission denied (euid=5000(vmail) missing +x perm: /var/spool/mail)

Проверь владельца реальной директории

ls -ld /var/spool/mail  # Может быть симлинк
ls -ld /var/mail         # Реальная директория

Исправь права

sudo chown -R vmail:vmail /var/mail
sudo chmod 755 /var/mail

Проверь вложенные директории

ls -la /var/mail/

IMAP не работает
#

Проверь авторизацию вручную:

doveadm auth test [email protected] UserPass456

Должно вернуть:

passdb: [email protected] auth succeeded
userdb: [email protected]

Если не работает:

  • Проверь хеш пароля в /etc/dovecot/users
  • Проверь права на файл
  • Проверь логи Dovecot

SMTP AUTH не работает
#

Проверь сокет:

ls -la /var/spool/postfix/private/auth

Должен быть с правами 666 и владельцем postfix:postfix.

Проверь логи:

grep "sasl" /var/log/mail.log

Следующий шаг
#

В следующей части настроим защиту:

  • Антивирус Amavis + ClamAV
  • Антиспам SpamAssassin
  • GreyListing через Postgrey
  • Fail2ban против брутфорса

После этого сервер станет безопаснее и перестанет пропускать вирусы и спам.

Почтовый сервер на Debian 12 - Эта статья — часть серии.
Часть 2: Ты уже здесь

Статьи по теме