Postfix + SpamAssassin + ClamAV: нормальный антиспам-шлюз вместо самописных списков
Перешли с самописного набора RBL-листов на зрелый стек с обучаемым фильтром. Неделя обучения на реальной почте - и спам срезался резко. Как не потерять живые письма и что делать с ложными срабатываниями.
Postfix + SpamAssassin + ClamAV складывается в рабочий стандарт антиспам-шлюза
К концу прошлого года спам окончательно перестал быть досадой и превратился в рабочую проблему. Почтовые ящики у нескольких клиентов начали получать по сотне мусорных писем в день, и то, что мы держали в качестве фильтрации - набор RBL-листов, пару самописных скриптов и ручные правила на ключевые слова - уже не справлялось. Пятьдесят процентов спама проходило мимо. Ключевые слова надо обновлять руками, а рассыльщики мусора менять подачу быстрее, чем мы успеваем реагировать.
Решение складывалось постепенно, но к этому январю мы его собрали и обкатали: Postfix в роли почтового сервера, SpamAssassin как обучаемый фильтр, ClamAV для вирусов. Всё это работает как шлюз - принимает почту снаружи, режет мусор и вирусы, отдаёт чистое дальше на Exchange или куда клиент скажет.
Почему самописное перестало тянуть
Логика самописного фильтра линейная: список плохих IP, список подозрительных слов в теме, список доменов-помоек. Пишешь правило - ловишь один паттерн. Рассыльщики меняют IP - правило протухает. Добавляешь новый IP - они уже ушли на следующий. Это игра, в которой проигрываешь по определению, потому что реагируешь, а не предсказываешь.
SpamAssassin устроен иначе. Он не ищет одно конкретное слово или адрес - он накапливает очки по десяткам признаков: заголовки, репутация отправителя, структура письма, соотношение текста и ссылок, результаты по нескольким RBL сразу. Ни один признак сам по себе не решает, но их сумма даёт оценку. Если набралось выше порога - спам. И главное: фильтр можно обучать на реальной почте конкретного клиента через механизм bayesian - он смотрит, что пользователи помечают как мусор, и подстраивает веса.
Как собирали шлюз
Схема простая: Postfix принимает письмо, отдаёт его через amavisd-new, который вызывает ClamAV и SpamAssassin последовательно. Если антивирус нашёл вредонос - письмо уходит в карантин, не к получателю. Если SpamAssassin набил очки выше порога - письмо помечается заголовком X-Spam-Status: Yes и Score в теме. Дальше уже Exchange или почтовый клиент сортирует помеченное в папку «Спам».
Принципиальный момент, который мы зафиксировали сразу: не удалять, а помечать. Удалять спам автоматически на шлюзе - значит рано или поздно потерять живое письмо. Ложные срабатывания будут, это надо принять как данность. Вопрос не «будут ли», а «как быстро найти».
Именно поэтому всё, что набрало выше порога, уходит в папку пользователя, а не в никуда. Раз в день пользователь туда заглядывает - это полминуты - и если что-то живое попало не туда, нажимает «Не спам». SpamAssassin учится.
Неделя обучения
Первые три дня после запуска шлюза мы не трогали никаких настроек. Просто включили обучение: всё, что приходит и помечается получателями как спам через кнопку в Outlook, уходит на sa-learn --spam. Что не помечается как спам - уходит в sa-learn --ham. База признаков росла.
К середине первой недели разница стала видна. Байесовский фильтр начал угадывать письма, которые не попадали ни под один RBL и не содержали явного мусорного заголовка, - просто потому что видел похожую структуру в уже размеченных письмах. Статистика, не магия, но работает убедительно.
Результат: спама в «Входящих» стало несопоставимо меньше - не ноль, но разница видна. Ложных срабатываний за первые две недели оказалось штук пять на несколько сотен пользователей. Мы ввели правило: если кто-то не получил ожидаемое письмо - первым делом смотрим папку со спамом.
Что делать с ложными срабатываниями
Ложное срабатывание - не трагедия, если про него знают. Трагедия - когда клиент неделю ждёт коммерческое предложение, а оно лежало в спаме и он туда не смотрел.
Несколько вещей, которые помогают держать это под контролем:
- Whitelist по отправителю. Контрагенты, с которыми переписка идёт регулярно, заносятся в белый список. SpamAssassin просто добавляет им очков в плюс, и даже если письмо выглядит подозрительно, совокупный балл не дотянет до порога.
- Порог выше среднего. Дефолтный порог в SpamAssassin - 5 баллов. Мы в первых установках держим 6-7, чтобы не рубить на краях. Потом, когда байесовская база наполнится, можно чуть опустить.
- Регулярный взгляд в карантин. Не пользователем, а нами раз в неделю при сопровождении. Если там оседает что-то явно живое - значит, правило или RBL слишком агрессивные, надо разбираться.
ClamAV в этой схеме вопросов не поднимает: он либо нашёл известный вредонос, либо нет. Ложных срабатываний по вирусам у нас пока не было, а пару зараженных вложений он поймал уже в первые дни - одно из них было именно той породы, что лезет в сеть сама, и хорошо, что до пользователя не добралось.
Что получилось
Шлюз сейчас стоит у трёх клиентов. У всех троих почта шла напрямую на Exchange или Sendmail, и везде проблема спама была хронической. После перехода на шлюз ни один не попросил вернуть обратно.
Трудозатраты на поддержку упали: больше не надо руками добавлять IP в ручные списки и следить за тем, не протухли ли правила. SpamAssassin обновляет свои правила сам, ClamAV - базы вирусов через freshclam. Основная ручная работа - разбирать редкие жалобы на ложные срабатывания и периодически смотреть в карантин.
Аппаратных требований у шлюза немного: виртуалка с парой гигабайт памяти справляется с потоком почты среднего офиса без заметной нагрузки. Часть таких шлюзов живёт на сопровождаемой инфраструктуре рядом с другими сервисами клиента.
Что схема не решает: спам от людей, которых клиент знает лично и которые пишут с личного ящика. Там фильтр не поможет - это не технический вопрос. Но основной поток мусора, который раньше шёл не переставая, шлюз режет без особых усилий.
- SLA-договор на сопровождение: как мы его написали · 14 декабря 2004
- Червь Blaster и патчи, которые ставили «когда-нибудь» · 18 августа 2003