Если вы администрируете свой почтовый сервер на Dovecot, рано или поздно встанет вопрос: как навести порядок в потоке писем без того, чтобы заставлять пользователей держать открытым почтовый клиент? Ответ — серверные фильтры Sieve. Они исполняются на этапе доставки, не грузят IMAP-сессию, прозрачно работают для всех клиентов и позволяют централизованно внедрять корпоративные правила. В этой статье разберёмся, как включить Sieve (Pigeonhole) в Dovecot, связать с Postfix через LDA/LMTP, безопасно описать rules для сортировки и не наломать дров с нагрузкой и доставляемостью.
Зачем серверные фильтры Sieve
Клиентские правила в почтовых приложениях работают только когда клиент запущен и синхронизирован. Серверные правила Sieve выполняются при доставке каждой входящей копии письма: сортируют по папкам, ставят флаги, перенаправляют копию, включают отпускной автоответ. Они не требуют активности пользователя и уменьшают трафик IMAP, потому что письма сразу оказываются в целевой папке, без лишних перемещений по IDLE.
Технически Sieve в Dovecot реализован в компоненте Pigeonhole. Скрипты компилируются в байткод, что минимизирует CPU и системные вызовы. Это позволяет держать сотни и тысячи «серверных правил» на одном экземпляре без ощутимого влияния на задержки доставки — особенно если использовать LMTP.
Архитектура: Dovecot + Pigeonhole + LDA/LMTP
Фильтры Sieve работают в процессе доставки. В Dovecot есть два пути доставки: LDA (локальный доставщик, утилита dovecot-lda) и LMTP (служба lmtp, работает как локальный сокет или TCP). Оба пути поддерживают Sieve-плагины. В связке с Postfix обычно выбирают LMTP: это избавляет Postfix от форкинга внешнего процесса для каждого письма, а Dovecot сам эффективно распределяет доставку по воркерам. LDA уместен там, где LMTP по каким-то причинам недоступен.
Коротко: LMTP — рекомендованный способ. Он масштабируется лучше и формально «ближе» к SMTP, сохраняя конвейер доставки внутри Dovecot.

Установка и пакеты
Ниже — ориентировочные команды для популярных систем. Названия пакетов могут различаться в зависимости от репозиториев и версии ОС.
# Debian/Ubuntu
apt update
apt install dovecot-imapd dovecot-lmtpd dovecot-sieve dovecot-managesieved
# RHEL/Alma/Rocky (EPEL может потребоваться)
dnf install dovecot dovecot-pigeonhole
Включаем Sieve в Dovecot
Проверьте, что в конфигурации включены нужные протоколы, а плагины Sieve подключены к выбранному методу доставки.
# /etc/dovecot/dovecot.conf
protocols = imap lmtp
Подключите плагин Sieve для LDA и/или LMTP:
# /etc/dovecot/conf.d/15-lda.conf
protocol lda {
mail_plugins = $mail_plugins sieve
}
# /etc/dovecot/conf.d/20-lmtp.conf
protocol lmtp {
mail_plugins = $mail_plugins sieve
}
Базовая конфигурация плагина Sieve (пути можно менять под свою структуру каталогов):
# /etc/dovecot/conf.d/90-sieve.conf
plugin {
sieve = file:~/.dovecot.sieve
sieve_dir = ~/sieve
# Глобальные сценарии до и после пользовательских
sieve_before = /etc/dovecot/sieve.d/before
sieve_after = /etc/dovecot/sieve.d/after
# Ограничения безопасности и защиты от петель
sieve_max_script_size = 1M
sieve_max_actions = 32
sieve_max_redirects = 4
# Локальный лог Sieve на пользователя
sieve_user_log = ~/sieve/sieve.log
}
ManageSieve (порт 4190): редактирование правил из клиентов
Чтобы пользователи и админы могли редактировать правила прямо из почтовых клиентов/веб-почты, включите ManageSieve.
# /etc/dovecot/conf.d/20-managesieve.conf
service managesieve-login {
inet_listener sieve {
port = 4190
}
}
service managesieve {}
Обязательно ограничьте доступ к порту 4190 на уровне файрвола и включите шифрование. ManageSieve использует ту же подсистему TLS, что и IMAP/POP3.
Интеграция с Postfix: LMTP или LDA
Вариант 1: LMTP (рекомендуется)
Настройте Postfix на доставку через сокет LMTP Dovecot. В Postfix:
# /etc/postfix/main.cf
virtual_transport = lmtp:unix:private/dovecot-lmtp
# /etc/postfix/master.cf
# Dovecot поднимает lmtp-сервис сам; отдельный блок часто не требуется
В Dovecot LMTP-сервис обычно уже описан в 20-lmtp.conf и слушает unix-сокет private/dovecot-lmtp.
Вариант 2: LDA (dovecot-lda)
Для LDA Postfix вызывает внешний бинарник на каждую доставку. Это проще, но менее эффективно под нагрузкой.
# /etc/postfix/main.cf
mailbox_command = /usr/lib/dovecot/dovecot-lda -f "$SENDER" -a "$RECIPIENT"
Для корректной работы условий по конверту (envelope) и автоответов обязательно передавайте отправителя (-f) и адрес получателя (-a) в LDA.
Если строите весь почтовый стек с нуля, посмотрите материал про связку Postfix+Dovecot+Rspamd на VDS: Почтовый стек Postfix+Dovecot+Rspamd на VDS.
Нужна площадка под прод? Поднимайте почтовый стек на управляемом VDS — гибкие ресурсы, простая масштабируемость, изоляция нагрузки.
Базовый пользовательский скрипт Sieve
Создадим директорию для скриптов и простой сценарий для сортировки. Dovecot при первом запуске скомпилирует .sieve в .svbin автоматически.
# от имени пользователя почты или с нужными правами
mkdir -p ~/sieve
# ~/sieve/default.sieve
require ["fileinto", "imap4flags", "mailbox", "copy", "vacation", "regex", "relational", "comparator-i;ascii-numeric", "include"];
# 1) Спам в Junk по метке антиспама
if anyof (
header :contains "X-Spam-Flag" "YES",
header :value "ge" :comparator "i;ascii-numeric" "X-Spam-Score" "5"
) {
fileinto :create "Junk";
stop;
}
# 2) Письма с листов на свои папки (по List-Id)
if header :contains "List-Id" "nginx.org" {
fileinto :create "INBOX/Lists/nginx";
stop;
}
# 3) Алерты мониторинга в отдельную папку и пометить как прочитанные
if header :matches "Subject" "*[Monitoring]*" {
addflag "\\Seen";
fileinto :create "INBOX/Alerts";
stop;
}
# 4) Уведомления CI
if address :domain "From" "ci.example.com" {
fileinto :create "INBOX/CI";
stop;
}
# 5) Отпуск (включать только при необходимости)
# vacation :days 3 :addresses ["user@example.com"] "Я в отпуске, отвечу позже.";
# По умолчанию оставляем в INBOX
keep;
Если в конфиге задано sieve = file:~/.dovecot.sieve, создайте символическую ссылку на активный сценарий:
ln -s ~/sieve/default.sieve ~/.dovecot.sieve
Расширение
:createв командеfileintoтребует поддержки расширенияmailbox(мы включили его вrequire). Оно автоматически создаст папку при первой сортировке.
Глобальные правила: sieve_before и sieve_after
Иногда нужно задать обязательные серверные правила для всех ящиков: например, первичная фильтрация спама или карантин вирусов. Используйте директории sieve_before и sieve_after. Скрипты из sieve_before выполняются до пользовательских, из sieve_after — после.
# /etc/dovecot/sieve.d/before/10-global-spam.sieve
require ["fileinto"];
if header :contains "X-Virus-Status" "Infected" {
fileinto :create "Quarantine";
stop;
}
После добавления или изменения файлов Dovecot сам перекомпилирует их при первом использовании. Если сомневаетесь — удалите старый .svbin, он будет пересобран автоматически.
Производительность и защита от петель
Почему Sieve «дешёвый» по нагрузке:
- Скрипты компилируются в байткод и кэшируются.
- Когда доставка идёт через LMTP, Dovecot может эффективно распараллеливать воркеры и держать соединение с Postfix локальным.
- Правила исполняются один раз — при доставке, а не при каждом IMAP-доступе к INBOX.
Тем не менее, предусмотрите лимиты:
sieve_max_actions— ограничит общее число действий на сообщение.sieve_max_redirects— защитит от петель пересылки.sieve_max_script_size— не даст разрастись сценариям.
Помните: «петли» часто возникают из двух автоответчиков или бесконечных пересылок между доменами. Лимит редиректов и грамотные условия — обязательны.
Логирование и отладка
Включите лог Sieve на уровне пользователя и общий debug для почты. Это поможет понять, какое именно правило сработало.
# /etc/dovecot/conf.d/10-logging.conf
mail_debug = yes
log_timestamp = "%Y-%m-%d %H:%M:%S %z"
Локальный лог на пользователя задаётся опцией sieve_user_log — он пишется в домашний каталог пользователя. Для быстрой проверки доставки без участия Postfix удобно использовать LDA вручную:
# Тестовая доставка письма из stdin через LDA
cat test.eml | dovecot-lda -d user@example.com -f sender@example.com
Если письмо улетело не туда, проверьте порядок срабатывания: скрипты из sieve_before могут уже сделать stop, и пользовательское правило не выполнится.

Рецепты правил: практические примеры
Сортировка рассылок по List-Id
Практически все рассылки добавляют заголовок List-Id. Это надёжнее, чем Subject с изменчивыми префиксами.
require ["fileinto"];
if header :contains "List-Id" "kubernetes.io" {
fileinto :create "INBOX/Lists/k8s";
stop;
}
Разгрузка INBOX от уведомлений
Ставим флаг прочитанности, чтобы не шуметь уведомлениями, и отправляем в целевую папку.
require ["fileinto", "imap4flags"];
if header :matches "Subject" "*[Jira]*" {
addflag "\\Seen";
fileinto :create "INBOX/PM/Jira";
stop;
}
Автоответ «Отпуск» правильно
Автоответы лучше ограничивать по времени и адресам, чтобы не отвечать на рассылки и технические письма.
require ["vacation", "regex"];
if allof (
not header :matches "List-Id" "*",
not header :matches "Precedence" "bulk|list",
header :matches "To" "*user@example.com*"
) {
vacation :days 5 :subject "В отпуске" :addresses ["user@example.com"]
"Сейчас меня нет на месте. Отвечу, как вернусь.";
}
Безопасная пересылка копии
Если политика позволяет, можно отправить копию на внешний адрес, оставив письмо на сервере.
require ["copy"];
if header :contains "Subject" "Daily Report" {
redirect :copy "team-lead@example.net";
keep;
}
Для устойчивой доставляемости пересылаемых писем используйте SRS для сохранения SPF при форвардинге: SRS для пересылки и SPF.
Управление и редактирование правил
Есть три подхода:
- Пользовательские скрипты в
~/sieveи активный~/.dovecot.sieve(или свой путь в опцииsieve). - ManageSieve на порту 4190 — удобен для пользователей, поддерживается многими почтовыми клиентами и веб-почтой.
- Глобальные правила в
/etc/dovecot/sieve.d/beforeи/etc/dovecot/sieve.d/afterдля политики на уровне домена/организации.
Для сложных сценариев разбивайте логику на части и подключайте через расширение include — так проще поддерживать и тестировать:
# ~/sieve/default.sieve
require ["include", "fileinto"];
include :personal "lists";
include :personal "alerts";
keep;
# ~/sieve/lists.sieve
require ["fileinto"];
if header :contains "List-Id" "devops.example" {
fileinto :create "INBOX/Lists/devops";
stop;
}
Частые ошибки и как их диагностировать
- Скрипт не применяется. Проверьте, что плагин
sieveподключён вprotocol lmtpилиprotocol lda, и что путьsieveуказывает на реальный файл/ссылку. - Нет прав на каталог
~/sieve. Убедитесь, что владелец и права позволяют Dovecot читать и писать лог/байткод. - Папка не создаётся. Добавьте расширение
mailboxи используйтеfileinto :create. Либо создайте папку заранее через IMAP. - Правило «не срабатывает». Смотрите
sieve_user_log, включитеmail_debug, временно уберитеstopиз верхних глобальных правил, чтобы проверить порядок. - Петли пересылки. Ограничьте
sieve_max_redirects, избегайте безусловныхredirectв обе стороны, добавляйте условия. - Условия по конверту не работают. Запускайте Sieve на этапе доставки (LMTP/LDA), а не в контексте IMAP, и передавайте корректно отправителя/получателя.
Итоги
Sieve в Dovecot — это надёжный и лёгкий способ привести поток сообщений в порядок ещё до того, как пользователь откроет почтовый клиент. Вы получаете централизованные серверные правила, предсказуемую сортировку и меньше нагрузки на IMAP. Достаточно настроить связку LMTP или LDA, включить плагин Sieve (Pigeonhole), определить безопасные лимиты и обеспечить логирование. А дальше — дело техники: добавляйте точные правила, раскатывайте глобальные политики и спите спокойно, зная, что почтовый ящик пользователей остаётся чистым и структурированным.


