MAATRIX / Блог / Dovecot с нуля: IMAP-сервер, который работает

Dovecot с нуля: IMAP-сервер, который работает

MAATRIX

Postfix настроен, письма приходят, mail.log чист от ошибок — а почтовый клиент всё равно не может «открыть почту». Это типичная путаница: Postfix принял письмо и положил его на диск, но за то, чтобы пользователь мог зайти в клиент и увидеть это письмо, отвечает совсем другой сервис. Разберём, что такое Dovecot, чем он отличается от Postfix, и как поставить его так, чтобы он не просто «запустился», а реально пускал пользователей в их почту — безопасно и по шифрованному каналу.

MTA и IMAP-сервер — две разные роли, не путайте их

Почтовая инфраструктура на сервере — это не один сервис, а связка минимум из двух ролей.

MTA (Mail Transfer Agent) — Postfix или Exim — отвечает за приём и пересылку почты между серверами: принимает письмо по SMTP от отправителя, проверяет, что домен получателя действительно ваш, и кладёт письмо в почтовый ящик на диске. На исходящем направлении MTA делает обратное — отправляет письмо на SMTP-сервер получателя. Postfix не умеет отдавать письма почтовому клиенту вроде Thunderbird или приложению на телефоне — это не его задача.

IMAP/POP3-сервер — Dovecot или Courier — отвечает за ДОСТУП к уже полученной почте. Именно к нему подключается почтовый клиент, чтобы прочитать письма, разложенные Postfix по папкам, пометить их прочитанными, переместить в архив или удалить. Dovecot ничего не принимает из внешнего мира по SMTP и ничего никуда не пересылает — он только читает и пишет в локальное хранилище писем и отдаёт их по протоколам IMAP или POP3.

Если провести аналогию: Postfix — это почтальон, который раскладывает письма по ячейкам в подъезде. Dovecot — это ключ и дверца, через которую вы эти письма достаёте. Без Postfix почта не будет доходить. Без Dovecot она будет копиться на диске, но вы не сможете открыть её в клиенте — разве что зайдёте на сервер по SSH и почитаете файлы руками.

Есть готовые связки вроде iRedMail или Mailcow, которые разворачивают Postfix, Dovecot, антиспам и веб-интерфейс одним комплектом — если вам нужна вся инфраструктура сразу, разумнее посмотреть в их сторону (сравнение с Postfix отдельно есть в статье про выбор между Postfix и Mailcow). Эта статья — про ситуацию, когда Postfix у вас уже настроен (например, по инструкции по установке Postfix) и нужно добавить именно доступ по IMAP.

Установка Dovecot на Ubuntu

Все команды ниже — для Ubuntu 24.04, но пакеты называются так же и в Debian.

Обновите список пакетов и поставьте ядро Dovecot вместе с IMAP-модулем:

sudo apt update
sudo apt install dovecot-core dovecot-imapd -y

Если планируете отдавать почту ещё и по POP3 (многие клиенты его больше не используют, но кто-то до сих пор просит):

sudo apt install dovecot-pop3d -y

После установки сервис уже запущен с конфигурацией по умолчанию:

sudo systemctl status dovecot
sudo systemctl enable dovecot

Основной конфиг лежит в /etc/dovecot/dovecot.conf, но по факту он состоит из набора инклюдов в /etc/dovecot/conf.d/*.conf — именно эти файлы вы и будете редактировать. Полезная команда для проверки синтаксиса перед перезапуском:

sudo dovecot -n

Она выводит эффективную конфигурацию (не значения по умолчанию, а то, что реально переопределено) и падает с понятной ошибкой, если где-то опечатка — гораздо удобнее, чем ловить сбой при перезапуске сервиса.

Нужен сервер под эту задачу?

Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.

Арендовать VPS

Хранение почты: Maildir, а не mbox

Первое решение, которое нужно принять — в каком формате Dovecot будет читать и писать письма на диске. Есть два классических формата.

mbox — один большой файл на весь ящик, все письма подряд. Формат старый, поддерживается почти везде, но плохо переживает параллельный доступ: если два процесса одновременно пишут в один файл (например, Postfix дописывает новое письмо, пока Dovecot читает или удаляет старое), нужна файловая блокировка на весь файл — и на большом ящике это узкое место. Любая частичная операция (пометить одно письмо прочитанным, удалить одно письмо) требует перезаписи всего файла целиком.

Maildir — каждое письмо хранится отдельным файлом в директории (new/, cur/, tmp/). Пометить письмо прочитанным — значит переименовать файл (в имя добавляется флаг), а не переписать мегабайты данных. Параллельный доступ безопаснее — нет блокировок на уровне всего ящика, потому что разные процессы работают с разными файлами. Для современного сервера, где почта может проверяться сразу с телефона и десктопа, а IMAP-idle держит соединение открытым постоянно, это ощутимая разница в надёжности.

Практически на любом новом сервере есть смысл сразу настраивать Maildir, если только у вас нет legacy-причины держать mbox (например, старый скрипт, который парсит один файл ящика).

Откройте /etc/dovecot/conf.d/10-mail.conf и задайте:

mail_location = maildir:~/Maildir

Это означает, что почта каждого пользователя будет лежать в ~/Maildir — то есть в домашней директории системного пользователя. Если почтовые ящики физически хранятся не в домашних папках, а в отдельном месте (частый случай — /var/mail/vhosts/), путь задаётся явно:

mail_location = maildir:/var/mail/vhosts/%d/%n

где %d — домен, %n — имя пользователя. Важно, чтобы Postfix при доставке письма (через local delivery agent, обычно dovecot lda или lmtp) использовал ровно тот же путь и формат — иначе Postfix положит письмо в mbox, а Dovecot будет искать его в Maildir, и пользователь решит, что почта пропадает.

Аутентификация: с чего начать и когда усложнять

Базовый и самый простой вариант — аутентификация через системных пользователей Linux. Каждый почтовый ящик соответствует реальному пользователю ОС (useradd), пароль проверяется через PAM — тот же механизм, что при SSH-логине. Это то, что работает «из коробки» после установки пакета dovecot-core.

Проверьте, что в /etc/dovecot/conf.d/10-auth.conf подключён нужный механизм:

!include auth-system.conf.ext

Эта строка обычно уже раскомментирована по умолчанию. Она включает файл auth-system.conf.ext, где настроена связка passdb/userdb через PAM — то есть каждый существующий в системе пользователь автоматически может логиниться в Dovecot своим системным паролем.

Плюс подхода — ничего дополнительно настраивать не нужно, ящик появляется сразу при создании пользователя (sudo useradd -m ivan). Минус — на 5-10 ящиков это удобно, но не масштабируется: создавать системного пользователя Linux под каждый почтовый адрес неудобно, системные пользователи путаются с обслуживающими учётками сервера, а сменить пароль без доступа к серверу пользователь не может.

Если ящиков становится много (виртуальный хостинг на несколько доменов, десятки адресов), стандартная практика — увести аутентификацию из системных пользователей в отдельную базу данных (обычно MySQL/PostgreSQL или SQLite), где хранятся виртуальные пользователи, домены и хэши паролей — независимо от системных аккаунтов ОС. В 10-auth.conf для этого подключают auth-sql.conf.ext вместо auth-system.conf.ext и прописывают SQL-запросы поиска пользователя в отдельном dovecot-sql.conf.ext. Это отдельная тема (обычно она идёт в связке с виртуальными доменами в Postfix), но важно понимать: для старта на несколько ящиков системных пользователей вполне достаточно, переусложнять с первого дня не нужно.

TLS обязателен — никакого IMAP в открытом виде

Вот здесь нельзя экономить на настройке. IMAP по умолчанию передаёт логин и пароль в конце процедуры аутентификации почти открытым текстом (base64 — это кодирование, а не шифрование). Без TLS любой, кто видит трафик между клиентом и сервером — от соседа по Wi-Fi до промежуточного узла провайдера, — может достать пароль пользователя простым перехватом пакетов. Современные почтовые клиенты (Thunderbird, Outlook, почтовые приложения на iOS и Android) по умолчанию требуют зашифрованное соединение и в лучшем случае выдадут предупреждение, а часто просто откажутся подключаться к серверу без TLS.

Сертификат для Dovecot берётся оттуда же, откуда и для веб-сервера — Let's Encrypt бесплатно выпускает нужную пару файлов (подробно про сам механизм проверки домена и выпуск — в статье про установку Let's Encrypt). Получив сертификат для домена почты (например, mail.example.com), пропишите пути к нему в /etc/dovecot/conf.d/10-ssl.conf:

ssl = required
ssl_cert = </etc/letsencrypt/live/mail.example.com/fullchain.pem
ssl_key = </etc/letsencrypt/live/mail.example.com/privkey.pem

Обратите внимание на < перед путём — это синтаксис Dovecot, означающий «прочитать содержимое файла», а не просто указать путь строкой. Без угловой скобки конфигурация будет невалидной.

Значение ssl = required запрещает вообще любую аутентификацию без шифрования — даже если клиент попытается подключиться на порт 143 (обычный IMAP) без STARTTLS, сервер откажет в логине. Дополнительно имеет смысл явно запретить передачу пароля в открытую в /etc/dovecot/conf.d/10-auth.conf:

disable_plaintext_auth = yes

Так как сертификаты Let's Encrypt обновляются автоматически раз в 60-90 дней, Dovecot нужно перечитывать их после каждого обновления — иначе он продолжит отдавать старый (просроченный) сертификат до перезапуска. Добавьте хук в certbot:

sudo mkdir -p /etc/letsencrypt/renewal-hooks/deploy
echo '#!/bin/sh
systemctl reload dovecot' | sudo tee /etc/letsencrypt/renewal-hooks/deploy/dovecot.sh
sudo chmod +x /etc/letsencrypt/renewal-hooks/deploy/dovecot.sh

После правок конфигурации перезапустите сервис:

sudo dovecot -n && sudo systemctl restart dovecot

Проверка: сервис реально аутентифицирует, а не просто запущен

systemctl status dovecot со статусом active (running) — это только половина проверки. Она говорит, что процесс не упал, но ничего не говорит о том, действительно ли сервер принимает соединения и корректно логинит пользователей. Проверять нужно с уровня протокола.

Быстрый тест незашифрованного порта (только чтобы убедиться, что порт вообще открыт и Dovecot отвечает баннером — логиниться так не пытайтесь, раз TLS обязателен):

telnet localhost 143

Ожидаемый ответ — приветствие вида * OK [CAPABILITY ...] Dovecot ready. Если соединение сразу рвётся или зависает — проблема на уровне сервиса или firewall, а не аутентификации.

Полноценная проверка TLS-порта (993, IMAPS) через openssl s_client — с -crlf, иначе IMAP-команды не распознаются построчно:

openssl s_client -connect mail.example.com:993 -crlf

После установления соединения и вывода сертификата вы попадаете в интерактивный режим — введите вручную команды протокола IMAP:

a1 LOGIN ivan ваш_пароль
a2 LIST "" "*"
a3 LOGOUT

Если a1 LOGIN вернул a1 OK Logged in, а не a1 NO — сервер реально проверяет пароль, а не просто открывает порт. Команда LIST покажет структуру папок ящика — если она пустая или падает с ошибкой, скорее всего проблема в mail_location из предыдущего раздела.

Ещё один полезный инструмент — встроенная утилита проверки аутентификации без сети вообще, обращается напрямую к passdb:

sudo doveadm auth test ivan

Она спросит пароль в терминале и скажет, прошла ли проверка через настроенный passdb (PAM или SQL) — удобно, когда непонятно, где именно рвётся цепочка: в сети или в самой логике аутентификации.

Финальная и самая честная проверка — подключить реальный почтовый клиент (Thunderbird, K-9 Mail, встроенную почту на телефоне) с настройками IMAP, портом 993, шифрованием SSL/TLS и реальными логином/паролем. Если клиент показал список папок и письма — всё работает целиком, от сети до диска.

Firewall и защита от подбора паролей

Открывать наружу нужно только реально используемые порты. Если вы работаете исключительно через IMAPS с обязательным TLS, порт 143 (обычный IMAP) можно вообще не открывать наружу — оставить только 993:

sudo ufw allow 993/tcp comment 'IMAPS'
sudo ufw deny 143/tcp
sudo ufw status verbose

Если у вас ещё нет базовой настройки firewall на сервере — по шагам это разобрано в статье про установку UFW. Общий принцип один и тот же для любого сервиса: открыт должен быть только порт, который реально нужен извне, всё остальное — закрыто по умолчанию.

Почтовые серверы — одна из самых частых целей автоматизированного перебора паролей: боты сканируют интернет на открытые порты 993/995/143/110 и молотят по ним типовыми парами логин/пароль. Это тот же класс угрозы, что и брутфорс SSH или админки WordPress — общий принцип защиты один: сервис с аутентификацией по паролю должен банить IP после нескольких неудачных попыток, иначе рано или поздно пароль подберут перебором или найдут в чужой утечке.

Для Dovecot стандартный инструмент — fail2ban с готовым фильтром dovecot. Если fail2ban ещё не стоит, установка описана в отдельной статье про fail2ban. Добавьте в /etc/fail2ban/jail.local:

[dovecot]
enabled = true
port = imap,imaps,pop3,pop3s
filter = dovecot
logpath = /var/log/mail.log
maxretry = 5
bantime = 3600
findtime = 600

Проверьте, что Dovecot вообще пишет неудачные попытки логина в лог — по умолчанию должен, но стоит убедиться:

sudo grep "auth failed" /var/log/mail.log

После правки перезапустите fail2ban и проверьте, что джейл активен:

sudo systemctl restart fail2ban
sudo fail2ban-client status dovecot

Пять неудачных попыток за 10 минут — и IP улетает в бан на час. Значения можно ужесточать (например, bantime = 86400 для повторных нарушителей через bantime.increment), но даже базовая настройка закрывает подавляющее большинство автоматических ботов.

Нужен сервер под эту задачу?

Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.

Арендовать VPS

Нужны сами нейросети для контента?

Генерируйте изображения, видео и озвучку нейросетями на falapi.io — десятки моделей в одном окне. Оплата картой РФ и по СБП.

Частые вопросы

Нужен ли Dovecot, если я использую только веб-почту вроде Roundcube?

Да — веб-интерфейс вроде Roundcube сам по себе ничего не хранит, он тоже подключается к серверу по IMAP (обычно на localhost), просто вместо настольного клиента это делает PHP-скрипт. Dovecot всё равно нужен как бэкенд.

Можно ли обойтись без Postfix и держать только Dovecot?

Только если вам не нужно принимать почту извне — например, если письма кладёт локально какой-то другой процесс. В обычном сценарии (свой домен, письма от реальных отправителей) нужен MTA, который их примет и доставит в Maildir.

Что если после смены mail_location старые письма не видны?

Dovecot не переносит письма автоматически при смене формата или пути — их нужно перенести вручную (например, утилитой doveadm import) или скриптом конвертации mbox → Maildir. Просто поменять путь в конфиге недостаточно.

Обязательно ли использовать порт 993, а не STARTTLS на 143?

Оба варианта дают шифрование, если настроены правильно. Явный IMAPS (993, шифрование сразу при подключении) считается чуть надёжнее, потому что не может «откатиться» до открытого соединения на уровне протокола — поэтому его чаще рекомендуют как основной для новых настроек.

Почему клиент показывает ошибку сертификата, хотя Let's Encrypt настроен?

Чаще всего в конфиге Dovecot указан не fullchain.pem (сертификат + промежуточные), а просто cert.pem — тогда клиент не может выстроить цепочку доверия. Проверьте, что в ssl_cert именно fullchain.pem.

Обсудить статью, задать вопрос или начать новую тему

Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.

Перейти в сообщество →