Антиспам Zimbra: порог 6.31, zmtrainsa и мёртвые обновления

У клиента-производства в Хамовниках антиспам был включён, а спама приходило по сорок писем в день на человека. Я потратил вечер на версию про раскрученные пороги и ошибся. Правила фильтра не обновлялись с момента установки, а байесовский фильтр не видел ни одного обучающего письма за четыре года. Разбираю цепочку от Postfix до вердикта.

«Антиспам у нас включён» — и сорок писем мусора в день

Фраза, которую я слышу чаще любой другой на почтовых серверах: антиспам включён, галочка стоит, что вы ещё от нас хотите. Галочка действительно стоит. Фильтр действительно работает. Просто он работает по правилам, которые не менялись с того дня, как сервер поставили.

Спам живёт короткими волнами и переписывается быстрее, чем любой другой класс почты. Набор признаков, актуальный в 2019 году, к 2021-му ловит хорошо если половину. Ваш фильтр при этом не сломан и не выключен: он честно считает баллы, честно сравнивает с порогом, честно пропускает то, что по его устаревшим меркам выглядит письмом от живого человека.

Проверить это можно за минуту, и почти на каждом унаследованном сервере результат один и тот же. Три ключа, отвечающих за обновление правил, стоят в положении «выключено». Не потому, что кто-то их выключил, — потому что они такими поставляются.

Второй слой той же истории — обучаемая часть фильтра. Она есть у всех, включена у всех и у большинства не обучена вообще.

Хамовники, сентябрь 2021: с чем я пришёл

Производственная компания, 39 рабочих мест, офис и небольшой цех в Хамовниках. Zimbra Open Source, поставлена в мае 2017-го — тогда это была ещё ветка 8.7. В 2019-м один из приходящих админов докатил её до 8.8.15, и это единственное, что он за свой год сделал: ключи локальной конфигурации апгрейд не пересчитывает, они переезжают в новую версию как лежали. За четыре года у них сменилось двое таких админов. Меня позвали после эпизода, который их напугал сильнее ежедневного мусора: в бухгалтерию пришёл счёт от имени поставщика, реквизиты в нём были чужие, и оплату остановили на этапе сверки. Сумма — 343 000 рублей. Повезло.

Замерил поток за неделю, прежде чем что-то трогать. Считаю это обязательным шагом: без цифры «до» вы потом не докажете ни себе, ни клиенту, что стало лучше.

$ zmprov gqu $(zmhostname) | wc -l
39

$ grep -c "Passed SPAM" /opt/zimbra/log/amavis.log
0
$ grep -c "Passed CLEAN" /opt/zimbra/log/amavis.log
11842

Ноль писем, помеченных спамом, за сутки. При этом в ящиках спам был — я открыл почту директора и насчитал в папке «Входящие» 37 таких писем за один день. То есть фильтр не отбрасывал спам не потому, что не находил его, а потому, что не набирал по нему баллов.

Что происходит с письмом на самом деле

Путь входящего письма в Zimbra короче, чем кажется, но проходит через несколько рук.

  • Письмо приходит на Postfix, порт 25 или 587.
  • Postfix отдаёт его в amavis — внутренний порт 10024.
  • amavis параллельно зовёт SpamAssassin (считает баллы) и ClamAV (ищет вредонос).
  • amavis принимает решение: пропустить, пометить, отправить в карантин или отбить.
  • Письмо возвращается в Postfix на порт 10025 и уходит в ящик по LMTP на 7025.

Балльная система здесь ключевая. SpamAssassin не отвечает «спам или не спам» — он складывает веса сработавших правил и выдаёт число. Дальше это число сравнивается с порогом, который в Zimbra по умолчанию равен 6.31. Выше — письмо считается спамом.

Каждое правило — это признак: подозрительный заголовок, характерная структура ссылок, домен из списка, несоответствие обратного адреса. Именно набор этих правил и обновляется — или не обновляется. Когда правил мало и они старые, современная рассылка спокойно набирает 2,4 балла при пороге 6,31 и уезжает во «Входящие» без единой пометки.

Вторая половина оценки — байесовская. Это статистика по словам и сочетаниям, которую фильтр строит на ваших собственных письмах. Она подтягивает балл вверх или вниз в зависимости от того, на что похоже конкретное письмо. Пока обучающей выборки нет, эта половина молчит.

Ложная версия: «предыдущий админ раскрутил пороги»

Версия была логичная. Классический сценарий: кто-то пожаловался, что важное письмо ушло в спам, админ поднял порог до пятнадцати, все успокоились, а через полгода в почте помойка. Я видел такое трижды и был почти уверен, что вижу в четвёртый.

Полез смотреть. Порог оказался дефолтным — 6.31, никто его не трогал. Проценты в консоли администрирования, отвечающие за пометку и за удаление, тоже стояли в исходных значениях: 33 и 75. Белый список amavis содержал три адреса, все три — реальные контрагенты, ничего похожего на маску целого домена.

Вторая моя версия: подвисли сигнатуры антивируса, файрвол режет обновления, и amavis из-за таймаутов пропускает почту без проверки. Проверил и это:

$ tail -3 /opt/zimbra/log/freshclam.log
Thu Sep 16 14:02:11 2021 -> daily.cvd updated (version: 26296, sigs: 1980483)
Thu Sep 16 16:02:09 2021 -> daily.cvd is up to date
Thu Sep 16 18:02:12 2021 -> daily.cvd is up to date

Сигнатуры обновлялись каждые два часа, как и положено. Антивирусная часть была в идеальном состоянии — и она же оказалась подсказкой. Обновления вируснóй базы работали ровно потому, что они включены по умолчанию. У антиспамной части умолчания другие.

Настоящая причина: три ключа и пустая обучающая выборка

Строка, ради которой стоило приезжать:

$ zmlocalconfig -s | grep antispam_enable
antispam_enable_restarts = false
antispam_enable_rule_compilation = false
antispam_enable_rule_updates = false

Три ключа. Первый разрешает службе перезапускаться после обновления правил, второй — компилировать правила, что заметно ускоряет проверку, третий — собственно скачивать обновления. Все три по умолчанию выключены, и на этом сервере они пролежали выключенными четыре года и четыре месяца.

Дальше вторая половина. У Zimbra есть штатный механизм обучения: когда пользователь в веб-клиенте нажимает кнопку «Спам», копия письма улетает в служебный ящик, а ночная задача скармливает накопленное фильтру через zmtrainsa. Симметрично работает кнопка «Не спам». Механизм отличный, но у него есть условие: люди должны нажимать кнопки.

В этой компании их не нажимал никто. Спам просто удаляли, как удаляют бумажную рекламу из почтового ящика. Служебные ящики за четыре года остались пустыми, и обучаемая часть фильтра не получила ни одного примера. Ни спама, ни нормальной почты.

Чтобы байес начал приносить пользу, ему нужно порядка 200 примеров спама и 200 примеров нормальной почты. Меньше — он будет ошибаться в обе стороны, что хуже, чем не работать вовсе.

Проверьте у себя за две минуты

Первая команда — про обновление правил. Вторая — про то, находит ли фильтр вообще хоть что-нибудь.

su - zimbra
zmlocalconfig -s | grep antispam_enable
grep -c "Passed SPAM" /opt/zimbra/log/amavis.log
grep -c "Passed CLEAN" /opt/zimbra/log/amavis.log
ls -l /opt/zimbra/data/spamassassin/localrules/

Трактовка:

Что увиделиЧто это значитКогда действовать
Все три ключа true, доля SPAM в логе 10–35%Фильтр в рабочем состоянииНичего не трогать
Все три ключа falseПравила не обновлялись с даты установки сервераНа этой неделе
Ключи true, но SPAM в логе нольОбновления включены, а служба после них не перезапускаласьНа этой неделе
Доля SPAM выше 60%Порог занижен или чужой список подмешался — ищите ложные срабатыванияВ ближайшее окно
Каталог localrules пуст и датирован днём установкиСобственных правил нет, всё работает на дистрибутивном набореИнформативно

И отдельный вопрос, который я задаю на каждом объекте: кто-нибудь у вас пользуется кнопкой «Спам» в веб-почте? Если ответ «а зачем» — обучаемая часть фильтра у вас выключена фактически, независимо от настроек.

Что мы сделали и на чём я обжёгся

Порядок работ был такой.

zmlocalconfig -e antispam_enable_rule_updates=true
zmlocalconfig -e antispam_enable_restarts=true
zmlocalconfig -e antispam_enable_rule_compilation=true
zmamavisdctl restart
zmmtactl restart

Первое обновление правил приехало через сорок минут. Уже на следующий день доля помеченного спама поднялась с нуля до 14% потока — только за счёт свежих правил, без всякого обучения.

Дальше я взялся за обучение и наступил на грабли, о которых теперь предупреждаю всех. Мне нужны были 200 примеров спама, и я нашёл их быстрым способом: выгрузил папку «Удалённые» у трёх сотрудников — почти девятьсот писем — и скормил их фильтру как спам.

zmtrainsa spam@example.ru spam
zmtrainsa ham@example.ru ham

В «Удалённых» лежал не только спам. Там лежали 60 нормальных писем от поставщика металла, которые человек прочитал и удалил. Фильтр добросовестно выучил, что письма с этого домена — мусор, и четыре дня подряд отправлял их в спам. По календарю разбирались мы с этим дольше, чем настраивали всё остальное — четыре дня против одного вечера: пришлось переобучать обратной выборкой и ждать, пока статистика перевесит.

Правильный путь скучнее и надёжнее. Выборку для спама берут из папки «Спам», а не из «Удалённых». Выборку для нормальной почты — из «Входящих» тех людей, кто вообще не пользуется рассылками. И перед первым обучением её просматривают глазами, хотя бы по темам. Двести писем — это двадцать минут чтения. Мои сэкономленные двадцать минут стоили клиенту четырёх дней странной почты.

Отдельно мы объяснили людям про кнопку. Не рассылкой, а на пятиминутке: показали, куда нажимать, и сказали, что от этого почта станет чище лично у них. Через месяц служебный ящик собирал по 120–160 писем в неделю, и обучение пошло само.

Какие ручки лучше не крутить

Соблазн подкрутить порог возникает у всех, и почти всегда это ошибка.

  • Порог 6.31. Опускать его вниз — прямой путь к потере рабочей почты. Каждая десятая доля балла в этой зоне стоит вам писем от реальных контрагентов, а ловит она в основном то, что и так поймается свежими правилами. Я трогаю порог только там, где уже включены обновления и обучен байес, и никогда не сдвигаю больше чем на полбалла за раз.
  • Проценты пометки и удаления в консоли. Значения 33 и 75 — рабочие. Меняя их вслепую, вы получаете либо тихое удаление нормальных писем без следа, либо пометки на всём подряд.
  • Веса отдельных правил. Для них есть отдельный файл — ~/data/spamassassin/localrules/zzsauser.cf. Правки живут там и переживают обновления; править дистрибутивные файлы бесполезно, их перезапишут.
# /opt/zimbra/data/spamassassin/localrules/zzsauser.cf
score RCVD_IN_UCEPROTECT   0.5
whitelist_from  *@postavshik-metall.ru

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

Результат в цифрах и сколько стоило молчание

Замеры до и через два месяца после, тот же поток, те же люди.

ПоказательСентябрь 2021Ноябрь 2021
Писем, помеченных спамом0 в сутки1870 в сутки
Спама во «Входящих» у директора37 писем в день2–4 письма в день
Ложных срабатываний6 писем за месяц, все возвращены
Обучающая выборка0 / 0около 340 спама, 260 нормальных
Работ с моей стороны6 часов, из них 2 на разбор моей же ошибки с выборкой

Цена бездействия считается грубо, но считается. Тридцать девять человек, каждый тратил на разбор мусора 5–7 минут в день. Это примерно 4 часа рабочего времени компании ежедневно, около 80 часов в месяц. По их же внутренней ставке — порядка 55 тысяч рублей в месяц, которые уходили в никуда четыре года подряд. И отдельной строкой — счёт на 343 000 рублей от поддельного поставщика, который остановили вручную и случайно.

Работа заняла шесть часов. Из них три ключа переключаются за минуту.

Если хотите понять, где вы: выполните команду про три ключа и посчитайте строки в журнале amavis за сутки. Пришлите мне эти четыре строки вывода — отвечу, обновляются ли у вас правила, обучен ли фильтр и стоит ли вообще что-то трогать. Часто ответ — «включите три ключа и подождите неделю», и этого достаточно.

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

Почему обновления правил выключены по умолчанию, если они так важны?

Историческая осторожность: обновление правил меняет поведение фильтра без вашего участия, и в теории может привести к тому, что нормальная почта начнёт набирать баллы. На практике за годы работы я видел ровно один случай, когда свежее правило дало массовое ложное срабатывание, и он лечился одной строкой в пользовательском файле весов. А вот серверов, где эти ключи выключены годами, я видел десятки — по моим наблюдениям, это самая распространённая находка на унаследованной Zimbra после устаревшего патч-уровня.

Сколько писем нужно фильтру, чтобы начать работать?

Ориентир — около двухсот примеров спама и около двухсот примеров нормальной почты. Причём вторая половина важнее первой: без неё фильтр знает, как выглядит мусор, но не знает, как выглядит ваша обычная переписка, и начинает промахиваться по своим же. Меньше двухсот — эффект будет непредсказуемым в обе стороны. Больше — лучше, но отдача растёт медленно, и гораздо ценнее не объём выборки, а её чистота: одно неверно размеченное письмо от постоянного контрагента отравляет статистику надолго.

Пользователи нажимают «Спам», а ничего не меняется. Почему?

Скорее всего, копии писем накапливаются в служебном ящике, но ночная задача обучения до них не доходит — либо обучение не запускается, либо служба после него не перезапускается. Проверьте, растёт ли служебный ящик и падает ли он обратно к нулю после ночи. Если растёт и не падает — механизм собран наполовину. Если не растёт вовсе, значит копии туда не уходят, и надо смотреть настройки на уровне сервера, а не ругать пользователей.

Можно ли просто поставить внешний фильтр перед Zimbra и не мучиться?

Можно, и для компании от полусотни человек это часто разумно: внешний шлюз снимает с вашего сервера и спам, и часть нагрузки. Но у решения есть цена — абонентская плата, зависимость от внешней площадки и вопрос, где физически обрабатывается ваша переписка. Для тридцати девяти рабочих мест в Хамовниках это было дороже, чем шесть часов настройки того, что уже куплено и стоит. Мой порядок такой: сначала привести в порядок штатный фильтр, померить результат, и только потом решать, нужен ли внешний.

Стоит ли отправлять спам в карантин вместо папки пользователя?

Мне карантин не нравится в малых компаниях. Он создаёт третье место, куда надо ходить, и о нём забывают ровно до того дня, когда там окажется важное письмо. Папка «Спам» в почтовом ящике лучше: она у человека перед глазами, он туда заглядывает раз в пару дней, и та же самая кнопка позволяет вернуть письмо и заодно обучить фильтр. Карантин имеет смысл, когда нужен централизованный разбор — например, при жёстких требованиях к контролю входящей почты.

Нужна помощь с проектом?

Специалисты АйТи Фреш помогут с архитектурой, DevOps, безопасностью и разработкой — 15+ лет опыта

📞 Связаться с нами
#Zimbra#антиспам#SpamAssassin#amavis#почта
Комментарии 0

Оставить комментарий

загрузка...

Подпишитесь на рассылку ITfresh

Раз в неделю — практические гайды для руководителя IT и сисадмина: безопасность, 1С, миграции, резервные копии, лайфхаки из реальных проектов.

Реквизиты оператора персональных данных

ООО «АЙТИ-ФРЕШ», ИНН 7719418495, КПП 771901001. Юридический адрес: 105523, г. Москва, Щёлковское шоссе, д. 92, корп. 7. Контакт: info@itfresh.ru, +7 903 729-62-41. Оператор обрабатывает e-mail подписчика в целях рассылки информационных и рекламных материалов до момента отзыва согласия.