Выберите продукт

Серверные фильтры Sieve: авторазбор почты в Dovecot без лишних нагрузок

Серверные фильтры на Sieve разбирают почту при доставке: сортируют по папкам, ставят флаги, пересылают копии и включают автоответ без участия клиента. В гайде — настройка Dovecot с LMTP/LDA, ManageSieve, безопасные лимиты, логирование и отладка.
Серверные фильтры Sieve: авторазбор почты в Dovecot без лишних нагрузок

Если вы администрируете свой почтовый сервер на 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.

Сравнение путей доставки: LMTP против LDA в 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 — гибкие ресурсы, простая масштабируемость, изоляция нагрузки.

FastFox VDS
Облачный VDS-сервер в России
Аренда виртуальных серверов с моментальным развертыванием инфраструктуры от 195₽ / мес

Базовый пользовательский скрипт 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, и пользовательское правило не выполнится.

Отладка Sieve: примеры логов и разбор правил

Рецепты правил: практические примеры

Сортировка рассылок по 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), определить безопасные лимиты и обеспечить логирование. А дальше — дело техники: добавляйте точные правила, раскатывайте глобальные политики и спите спокойно, зная, что почтовый ящик пользователей остаётся чистым и структурированным.

Поделиться статьей

Вам будет интересно

ACME renewal monitoring: systemd timer, healthcheck и правильный fullchain.pem OpenAI Статья написана AI (GPT 5)

ACME renewal monitoring: systemd timer, healthcheck и правильный fullchain.pem

Разберём практичную схему мониторинга продления ACME/Let’s Encrypt: почему systemd timer удобнее cron, как правильно использовать ...
EPP-статусы домена: ok, clientHold и serverHold — что означают и как снять блокировку OpenAI Статья написана AI (GPT 5)

EPP-статусы домена: ok, clientHold и serverHold — что означают и как снять блокировку

Если домен зарегистрирован и NS прописаны, но сайт и почта не работают, часто виноваты EPP-статусы в WHOIS/RDAP. Разберём ok, clie ...
Kubernetes NodeLocal DNSCache: как победить DNS latency и NXDOMAIN storm в CoreDNS OpenAI Статья написана AI (GPT 5)

Kubernetes NodeLocal DNSCache: как победить DNS latency и NXDOMAIN storm в CoreDNS

DNS в Kubernetes часто становится скрытым узким местом: растёт latency, CoreDNS уходит в CPU, на нодах раздувается conntrack и всп ...