Как задать обязательный Sieve-фильтр всему домену Zimbra и отдельное правило одному ящику
Пользовательские фильтры в Zimbra каждый настраивает сам — и это ровно то, что не годится, когда нужно правило, действующее на весь домен: например, автоматически помечать письма от определённого адреса или раскладывать входящие по папкам ещё до того, как их увидит человек. У Zimbra есть отдельный механизм для этого — административный Sieve-скрипт, zimbraAdminSieveScriptBefore, — и он умеет работать одновременно на уровне домена и на уровне одного ящика, с понятным приоритетом между ними.
Чем административный Sieve отличается от обычных пользовательских фильтров
Обычные фильтры Zimbra пользователь создаёт и меняет сам через Настройки → Фильтры. Административный сценарий — это другой механизм: атрибут zimbraAdminSieveScriptBefore хранит Sieve-скрипт, который выполняется до пользовательских правил и от пользователя не зависит — он не появляется в его интерфейсе фильтров и не может быть случайно отключён кликом. Атрибут появился в ZCS 8.7.8, и у него есть парный zimbraAdminSieveScriptAfter — сценарий, который выполняется уже после пользовательских правил. Before нужен, когда правило должно сработать гарантированно и раньше всего остального, After — когда вы хотите дать пользователю первым разложить почту по-своему, а «подобрать хвосты» уже административно. Именно поэтому Before — правильный инструмент для правил уровня компании, а не пользовательские фильтры, которые сотрудник в теории может выключить или переписать.
По справочнику атрибутов Zimbra 10 он задаётся на аккаунте, CoS и домене (статья Tech Center упоминает ещё и сервер, но в описании атрибута этого уровня нет, и я на него не полагаюсь) — то есть одно и то же административное правило можно применить сразу ко всем нынешним и будущим ящикам домена, не заходя в настройки каждого по отдельности. Это особенно ценно при найме: новый сотрудник получает обязательное правило автоматически с момента создания ящика, без отдельного шага настройки. Если у компании уже настроена корпоративная почта с централизованным администрированием, административный Sieve — естественное продолжение той же логики: минимум ручных действий на каждого нового человека.
Как задать сценарий: команда zmprov и синтаксис Sieve
Официальный пример загрузки сценария из файла выглядит так:
cat /tmp/myfilters | xargs -0 zmprov ma info@example.com zimbraAdminSieveScriptBeforeЗдесь ma — сокращение modifyAccount, и команда применяет сценарий к одному конкретному ящику info@example.com. Использование xargs -0 — не случайность: сценарий Sieve может содержать переносы строк и специальные символы, которые обычная подстановка аргументов командной строки могла бы разбить на части, а xargs -0 передаёт содержимое файла как единый аргумент.
Сам файл /tmp/myfilters содержит обычный Sieve-скрипт. Два базовых действия, которые нужны в большинстве обязательных правил: fileinto — переместить письмо в конкретную папку, и stop — прекратить дальнейшую обработку сценария после совпадения условия. Простейший пример правила «письма от определённого отправителя — сразу в папку Уведомления»:
require ["fileinto"];
if address :is "from" "noreply@example.com" {
fileinto "Уведомления";
stop;
}Строка require обязательна: без объявления расширения fileinto сценарий не пройдёт проверку синтаксиса. В официальном примере Tech Center в require перечислены сразу fileinto, reject, tag, flag и editheader — объявляйте только то, чем реально пользуетесь.
Чтобы убрать административный сценарий с ящика, значение атрибута задаётся пустой строкой — так делает и Tech Center:
zmprov ma info@example.com zimbraAdminSieveScriptBefore ""Только учтите: пустое значение означает не «у ящика нет правил», а «у ящика нет своего значения». После этого аккаунт снова наследует сценарий из CoS или домена. По той же идее я писал про серверную фильтрацию Dovecot Sieve в офисе — там язык фильтров тот же Sieve, но применяется он уже не в Zimbra, а на голом Dovecot, и часть логики административных сценариев переносится почти без изменений.
Уровень домена вместо уровня ящика
Чтобы правило подхватили сразу все ящики домена — существующие и будущие, — тот же атрибут задаётся не на аккаунте, а на домене. Команда для домена использует modifyDomain вместо modifyAccount: cat /tmp/myfilters | xargs -0 zmprov md example.com zimbraAdminSieveScriptBefore. Разница только в объекте, к которому применяется атрибут (account или domain) — синтаксис самого Sieve-скрипта не меняется.
В обсуждении на форуме Zimbra по этой теме подтверждено, что доменный сценарий действительно применяется как к уже существующим пользователям домена, так и к тем, кто будет создан позже, а не только к снапшоту ящиков на момент настройки. Это важно для компаний, где сотрудники регулярно приходят и уходят: обязательное правило не нужно переустанавливать вручную на каждого нового человека — оно наследуется автоматически на уровне домена. Но есть нюанс наследования, который легко упустить: атрибут наследуется по цепочке аккаунт → CoS → домен. Если кто-то когда-то задал сценарий в консоли на CoS (CoS → Advanced → Sieve), то для всех ящиков этого класса обслуживания сработает он, а не доменный. Прежде чем удивляться, почему доменное правило «не работает» у половины сотрудников, я проверяю zmprov gc default zimbraAdminSieveScriptBefore для каждого используемого CoS.
Что произойдёт, если правило задано и на домене, и на аккаунте
Реальный сценарий: на весь домен настроено общее правило, но для одного конкретного ящика — например, руководителя — нужно другое поведение или вообще отсутствие общего правила. Здесь важно понимать приоритет: если zimbraAdminSieveScriptBefore задан одновременно на домене и на аккаунте, используется сценарий аккаунта — он не суммируется со сценарием домена и не выполняется вслед за ним. Это прямо написано в статье Tech Center о Sieve и в официальном блоге Zimbra: при конфликте между доменным и аккаунтным сценарием побеждает аккаунтный, целиком заменяя доменный для этого конкретного ящика.
Практический вывод: если вы хотите, чтобы VIP-ящик получал доменное правило плюс своё дополнительное условие, простого добавления сценария на аккаунт недостаточно — в файл для конкретного ящика нужно продублировать логику доменного сценария и добавить к ней собственные условия, потому что доменный сценарий для этого ящика перестанет применяться вовсе. То же самое подтверждается в обсуждении «Zimbra Filter rules?» на форуме: там администратор успешно совместил общий сценарий для домена и отдельный, полностью самостоятельный сценарий для VIP-аккаунта — именно как два независимых сценария, а не как надстройку одного над другим.
Отсюда и мой порядок внедрения. Доменный сценарий никогда не пишется сразу на домен: сначала я вешаю его на тестовый ящик через zmprov ma, отправляю туда несколько писем, которые должны и не должны попасть под правило, и только потом переношу тот же файл на домен через zmprov md. Ошибка в общем сценарии бьёт по всем сотрудникам сразу — например, лишний stop или неудачное условие на From может увести в папку половину рабочей почты, и заметят это не сразу, а когда кто-то не получит важное письмо. После переноса тестовый ящик очищаю пустым значением, чтобы он вернулся к доменному сценарию и дальше служил контрольной точкой: если у него почта раскладывается правильно, значит, доменное правило действует.
Кейс: домен и исключение для одного ящика в художественной школе
У условного клиента — художественной школы «АртШкола Радуга», 12 рабочих мест — администратор хотел, чтобы уведомления от системы онлайн-записи на занятия автоматически уходили в отдельную папку у всех преподавателей, но директор школы настоял, чтобы у него эти письма оставались во «Входящих» — он лично отслеживал записи и не хотел лишнего клика в отдельную папку.
Решение выстроили в два шага. Сначала на домен наложили общий сценарий:
cat /tmp/notify-filter.sieve | xargs -0 zmprov md artshkola-raduga.example zimbraAdminSieveScriptBeforeсо скриптом, перекладывающим письма от адреса системы записи в папку «Запись на занятия» с последующим stop. Все преподаватели получили это правило автоматически, без индивидуальной настройки каждого ящика.
Затем для ящика директора применили отдельный, независимый сценарий, который сознательно оставляет такие письма во «Входящих»:
cat /tmp/director-keep.sieve | xargs -0 zmprov ma director@artshkola-raduga.example zimbraAdminSieveScriptBeforeФайл director-keep.sieve не содержал условия про систему записи — только комментарий с назначением и одну команду keep;. Пустым его оставлять нельзя: пустое значение атрибута на аккаунте означает «своего сценария нет», и ящик директора снова унаследовал бы доменное правило. А непустой сценарий аккаунта полностью замещает доменный, поэтому письма падали во «Входящие», как и требовалось. Проверили результат тестовыми письмами от адреса системы записи на три ящика: у преподавателей уведомления уходили в отдельную папку, у директора оставались на виду. Вся работа заняла около часа вместе с тестами, а сами файлы сценариев мы положили в репозиторий конфигурации школы с пометкой, какой ящик на каком сценарии.
Где ещё это настраивается и что можно сломать
В консоли администратора те же атрибуты доступны без прямого zmprov: раздел CoS → Advanced → Sieve содержит настройки административного сценария на уровне класса обслуживания, а Domains → Advanced → Sieve — на уровне домена. Для разовой точечной настройки консоль удобнее, а для версионируемых сценариев с историей изменений я предпочитаю держать сами файлы .sieve в системе контроля версий и применять их через zmprov — так проще откатить правило, если оно случайно перекрыло почту не тому ящику.
Отдельная тонкость — атрибут zimbraSieveEditHeaderEnabled (с ZCS 8.8.4, задаётся на аккаунте, CoS или домене, по умолчанию FALSE). Он разрешает в административных сценариях команды изменения заголовков — addheader, deleteheader и replaceheader; Tech Center в своём примере включает его первым шагом: zmprov mc default zimbraSieveEditHeaderEnabled TRUE. Если атрибут выключен, эти команды при выполнении административного сценария просто не исполняются, а fileinto, stop и остальные действия работают как обычно — выключение не отключает фильтры целиком. Не забудьте и "editheader" в строке require. И ещё одно ограничение: заголовки из zimbraSieveImmutableHeaders (Received, DKIM-Signature, Authentication-Results, Message-ID и другие) менять нельзя даже при включённом атрибуте.
Административные сценарии стоит держать в документации отдельным пунктом ещё и потому, что они легко забываются при смене платформы. Когда я веду миграцию с Zimbra на Carbonio CE, обязательные Sieve-скрипты домена и отдельных аккаунтов — из тех вещей, которые не переносятся автоматически вместе с почтой и требуют отдельной сверки после переезда.
- zmprov ma <account> zimbraAdminSieveScriptBefore — обязательный сценарий для одного ящика
- zmprov md <domain> zimbraAdminSieveScriptBefore — обязательный сценарий для всего домена
- При конфликте побеждает сценарий аккаунта — сценарий домена для этого ящика не выполняется вовсе
- zmprov mc <CoS> zimbraSieveEditHeaderEnabled TRUE — разрешает addheader/deleteheader/replaceheader
- zmprov gc <CoS> zimbraAdminSieveScriptBefore — сценарий на CoS перекрывает доменный
- CoS → Advanced → Sieve и Domains → Advanced → Sieve — те же настройки в консоли администратора
Частые вопросы
Чем административный Sieve-фильтр отличается от обычного пользовательского?
Административный сценарий задаётся атрибутом zimbraAdminSieveScriptBefore на уровне аккаунта, CoS или домена и выполняется до пользовательских фильтров. Пользователь не видит и не может отключить его через свой интерфейс настроек.
Как применить обязательное правило сразу ко всем ящикам домена?
Задайте zimbraAdminSieveScriptBefore командой modifyDomain: cat /tmp/myfilters | xargs -0 zmprov md example.com zimbraAdminSieveScriptBefore. Правило подхватят и существующие, и будущие ящики домена.
Что произойдёт, если сценарий задан и на домене, и на конкретном аккаунте?
Сработает только сценарий аккаунта — он полностью заменяет доменный для этого ящика, а не дополняет его. Если нужна логика домена плюс своё условие, придётся продублировать доменный сценарий в файле для аккаунта.
Как убрать обязательный сценарий с ящика или домена?
Задайте атрибуту пустое значение: zmprov ma info@example.com zimbraAdminSieveScriptBefore "" (для домена — zmprov md). Учтите: у аккаунта после этого снова начнёт действовать сценарий CoS или домена.
Почему действие addheader в административном сценарии не срабатывает?
Проверьте атрибут zimbraSieveEditHeaderEnabled (аккаунт, CoS или домен, по умолчанию FALSE) и наличие editheader в require. Без TRUE команды addheader, deleteheader и replaceheader в административном сценарии не выполняются.
Можно ли настроить обязательный сценарий через консоль администратора без zmprov?
Да, те же атрибуты доступны в разделах CoS → Advanced → Sieve и Domains → Advanced → Sieve. Для версионируемых сложных сценариев удобнее держать файлы .sieve отдельно и применять их через zmprov.
Источники
- Zimbra Tech Center: Sieve — Административный сценарий zimbraAdminSieveScriptBefore/After, пример загрузки через xargs -0 zmprov ma, require, fileinto/stop, приоритет аккаунта над доменом, сброс пустым значением, zimbraSieveEditHeaderEnabled TRUE. https://wiki.zimbra.com/wiki/Sieve
- Zimbra Forums: Zimbra Filter rules? (solved) — Подтверждён рабочий сценарий: обязательное правило на домен для всех текущих и будущих пользователей плюс отдельный независимый сценарий для VIP-аккаунта. https://forums.zimbra.org/viewtopic.php?t=69709
- Zimbra Blog: Zimbra SkillZ — Using Sieve Filters on Zimbra — Приоритет сценария аккаунта над доменным при одновременной настройке, синтаксис zmprov ma/md zimbraAdminSieveScriptBefore, назначение zimbraSieveEditHeaderEnabled. https://blog.zimbra.com/2021/07/zimbra-skillz-using-sieve-filters-on-zimbra/
- Zimbra 10 Config Guide — атрибуты Sieve — zimbraAdminSieveScriptBefore/After: account,cos,domain, accountCosDomainInherited, с 8.7.8; zimbraSieveEditHeaderEnabled: account,cos,domain, с 8.8.4, FALSE, addheader/deleteheader/replaceheader; zimbraSieveImmutableHeaders. https://zimbra.github.io/documentation/zimbra-10/config-guide.html



