Использование спам ловушек для обучения байесовских фильтров


В продолжение игрушек со спамом захотелось прикрутить автоматическое обучение байесовских фильтров спаму на основе спам ловушек.

У меня используются SpamProbe и Rspamd.

Основной вопрос был, как эти самые ловушки придумать и как туда заставить рассылать спам. Решение придумалось самое простое и, на мой взгляд, логичное.

  1. Анализируем лог почтового сервера на попытку доставить письмо в несуществующий ящик.
  2. Считаем количество попыток для каждого ящика.
  3. Если попыток больше определенного, я решил, что более 30, то заносим в базу спам ловушек. Порог требуется для того, чтобы не попадали адреса, которые люди неправильно набрали при вводе.
  4. Все письма поступающие на эти адреса передаем спам фильтру на обучение.
  5. Смотрим результат и периодически перепроверяем какие еще адреса имеет смысл добавить.

Реализация для EXIM:

Сбор адресов

( bzcat /var/log/exim/rejectlog.* ; cat /var/log/exim/rejectlog ) | grep -E 'Unrouteable|not found' | grep -v -E 'root|abuse|postmaster' | sed 's/.*rejected RCPT//;s/.*<//;s/>.*//' | sort | uniq -c | awk '$1 > 30 {print $2}' | sort > /usr/local/etc/exim/spam_trap.txt

Правило для EXIM

ACL

accept domains       = +local_domains
        condition = ${lookup{$local_part@$domain}lsearch{/usr/local/etc/exim/spam_trap.txt} {yes}{no}}

Перенаправление в наш ящик через роутер

learn_spam:
  driver = redirect
  domains = +local_domains
  condition = ${lookup{$local_part@$domain}lsearch{/usr/local/etc/exim/spam_trap.txt} {yes}{no}}
  data = spamtraps@domain.ru

Обучение спам фильтров

#!/bin/sh
spam_cmd="/usr/local/bin/spamprobe -d /var/db/spamprobe"
rspamd_cmd=" /usr/local/bin/rspamc "
path4train="tmp/spamspool/"
date=` date  "+%Y-%m-%d %H:%M"`
/usr/local/bin/fdupes -q -d -N ${path4train}/new/ | grep '[+]' | cat -b
for file in ${path4train}/new/[0-9]*
do
        if [ ! -e "$file" ]       # Проверка наличия файла.
        then
          continue                # Переход к следующей итерации.
        fi
 echo ${date} `ls -l "$file"`
 ${spam_cmd} spam "$file" > /dev/null
 ${rspamd_cmd} learn_spam "$file" > /dev/null
 mv "$file" ${path4train}/cur/ > /dev/null
done

find ${path4train}/cur/ -type f -ctime +7d -delete
 

Соответственно, этот скрипт запускаем по крону с необходимой частотой.

P.S. Вообще, пишут, что желательно байесовским фильтрам отдавать на обучение почту в соотношении 50/50 спам/не спам, но:

  1. Не понятно, как обеспечить такое соотношение и при этом поддерживать свежей базу спама.
  2. Вроде и так работает
  3. По идее, можно прикрутить обучение на основе исходящих писем или анализирую inbox своих ящиков.