Pull to refresh

Разбор спам-полётов ваших аккаунтов в Exim

Reading time3 min
Views4.6K
Так уж исторически сложилось у нас, что больше внимания мы уделяем фильтрации спама во входящей почте, практически напрочь забывая о почте исходящей.
Начав анализировать эту ситуацию мы столкнулись с тем, не можем толком сказать кто «гадить» в наш почтовый трафик, ибо адреса даются динамически. spamassassin тоже не очень помогает (пока) так как исходящий спам имеет практически в 2 раза меньшую оценку чем входящий спам.
И для начала было решено провести небольшое исследование которое и изложено под катом.

Исходные данные


В качестве исходных данных у нас будет:
  • билинговая система. В нашем случае: Abills. Но этот пример можно адаптировать под любой билинг
  • Exim настроенный по практически любому из найденных в интернете конфигов с использованием mysql
  • Собственно СУБД MySQL. в нашем случае это были 2 отдельных сервера. Один для билинга 2-й для сервера статистики которую мы будем собирать

Что мы хотим


Главная задача естественно — выяснить какой пользователь «спамит» через нас. Для этого
  1. Выясняем IP-адрес который отправляет почту
  2. По IP-адресу находим пользователя который в данный момент пользуется этим адресом
  3. Записываем необходимую для последующего анализа информацию в таблицу (login, ip, email_from, email_to, email_time, spam_score)

Итак по пунктам:
  1. IP-адрес выяняем через переменную exim-а — $sender_host_address
  2. Так как в abills-е таблица dv_calls содержит текущие онлайн сессии то пользователя занявшего данный адрес мы находим по запросу:
    SELECT concat("login=",user_name) FROM dv_calls WHERE INET_NTOA(framed_ip_address)='${quote_mysql:$sender_host_address}';
    

    Обратите внимание на возвращаемый результат в виде пары параметр=значение
    . В конфиге exim-а это выглядит следующим образом:
    GET_LOGIN = SELECT concat("login=",user_name) FROM dv_calls WHERE INET_NTOA(framed_ip_address)='${quote_mysql:$sender_host_address}';

    — это макрос который мы будем запускать во время проверки письма антиспамом.
  3. ну и собственно вставка данных через insert будет производится также во время проверки антиспамом
    ADD_STATISTICS = INSERT INTO statistics VALUES ('$acl_m1','${quote_mysql:$sender_host_address}',\
    '${quote_mysql:$sender_address}','${quote_mysql:$acl_m4}',NOW(),$spam_score_int);


Exim


Пробежимся коротко по конфигу exim-а:
  1. Определение 2-х макросов:
    ADD_STATISTICS = INSERT INTO statistics VALUES ('$acl_m1','${quote_mysql:$sender_host_address}',\
    '${quote_mysql:$sender_address}','${quote_mysql:$acl_m4}',NOW(),$spam_score_int);

    GET_LOGIN = SELECT concat("login=",user_name) FROM dv_calls WHERE INET_NTOA(framed_ip_address)='${quote_mysql:$sender_host_address}';

  2. В acl_smtp_rcpt добавляем самым первым пунктом:
    warn
    hosts = LOCAL_NETS
    set acl_m4 = $local_part@$domain

    — это некоторый хак, потому как мы будем в таблицу записывать как адрес отправителя так и адрес получателя. Но в том месте где мы будем это делать переменные $local_part и $domain уже будут неопределены (незнаю это у меня так или вообще в exim-е поэтому жду Ваших комментариев по этому поводу).
  3. В acl_smtp_data в самом начале добавляем следующее:
    warn
    hosts = LOCAL_NETS
    set acl_m0 = ${lookup mysql{GET_LOGIN}{$value}{login=unknown}}
    set acl_m1 = ${extract{login}{$acl_m0}{$value}{unknown}}

    warn
    hosts = LOCAL_NETS
    spam = nobody:true
    set acl_m2 = ${lookup mysql{servers=localhost; ADD_STATISTICS}{$value}{0}}

    здесь в 1-й половине кода — определяем логин по адресу отправителя и записыванием его в переменную acl_m1. Причем, если нам не удается однозначно определить логин клиента то пишем unknown (в нашем случае это будут служебные сообщения серверов и мониторинга).
    Во 2-й половине мы проверяем почту антиспамом для всех НАШИХ клиентов. Причем обратите внимание на запись servers=localhost; ADD_STATISTICS здесь мы явно указываем что надо выполнить запрос на локальном сервере а не на сервере билинга, такия запись exim-а позволяет использовать произвольное число разных подключений к СУБД.

Перезапускаем exim и имеем результат.

Предварительные выводы


За сутки работы этого алгоритма мы нашли 2-х пользователей-рассадников спама. Которые разослали 181 письмо с поддельных адресов со средним коэффициентом спамовости 24 (по шкале нашего антиспама). А так как наш антиспам был настроен на совсем другой порядок оценок (50 — предупреждение) (70 — отсекание) то он естественно пропустил их.
В итоге. Оргвыводы сделаны, список виновников был подан соответствующим органам для подальшего выяснения (штрафования, блокирования, мордобоя и т.д. и т.п.)

P.S.
Практически всю информацию черпаем из спецификации
Натолкнула на мысль по работе с СУБД эта заметка — правда она о грейлистинге который мы планируем внедрить позже
Tags:
Hubs:
Total votes 8: ↑6 and ↓2+4
Comments0

Articles