1 Сентябрь 2016

Подсистема оценки репутации антиспам пакета Spamassassin

Spamassassin's anit-spam software reputation scoring subsystem

Антиспам система Spamasassin давно приобрела широкую популярность как один из наиболее мощных, комплексных и гибких способов борьбы с несанкционированной рассылкой электронной почты.

Имея в своём составе множество модулей, которые оценивают входящие сообщения множеством различных способов, среди которых имеется и подсистема оценки репутации отправителя на основании исторических данных, которые он получил в ходе предыдущих проверок Spamassassin. Это позволяет более точно ранжировать корреспонденцию по критериям отнесения к спам / не спам сглаживая влияние случайных факторов на общую оценку.

Spamassassin включает в себя два модуля для оценки репутации - старый используемый по умолчанию в стандартной конфигурации AWL и новый TxRep.

1. Модуль AWL

Аббревиатура AWL расшифровывается как Auto White list - автоматический белый лист, что может привести к превратному понимаю сути и механизмов его работы. На самом деле, модуль AWL сглаживает текущую оценку входящего сообщения на основании предыдущих оценок исходящей корреспонденции из подсети (используется маска /16, т.е. учитываются два первых байта в IPv4 адресе, и маска /48 в адресе IPv6) отправителя. Алгоритм его, вкратце, таков:

  1. Расчитывается текущая общая оценка сообщения на основании остальных действующих проверок и правил Spamassassin.
  2. Рассчитывается разница между средней исторической оценкой и текущим значением скорректированным на коэффициент влияния auto_whitelist_factor (значение по умолчанию 0.5).
  3. Историческая оценка корректируется на текущую оценку без учёта полученной разницы.
  4. И, наконец, выдаётся финальная оценка представляющая из себя сумму текущей оценки (п.1) и полученной разницы (п.2).

Пример. Из данной подсети ранее было получено одно сообщение, оцененное в 10 баллов. Новое сообщение получило оценку в 4 балла. Тогда финальная начисленная оценка с учётом фактора AWL составит 2 + (10 / 1 сообщение - 4) * 0.5 = 5. При этом историческая оценка при следующем образении будет скорректирована и составит уже (10 + 2) / 2 сообщения = 6.

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

Рассмотрим подключение модуля AWL к текущей конфигурации Spamassassin.

root@beta:~ # spamassassin --version
SpamAssassin version 3.4.1
  running on Perl version 5.24.1

Начиная с версии 3.3 модуль AWL автоматически включён в конфигурацию по умолчанию. В противном случае всегда это можно сделать путём добавления его загрузки в файл инициализации системы v310.pre.

root@beta:~ # cat /usr/local/etc/mail/spamassassin/v310.pre | grep AWL
# AWL - do auto-whitelist checks
loadplugin Mail::SpamAssassin::Plugin::AWL

Ввиду того, что в данной системе Spamassassin использует хранилище данных на базе MySQL сервера, добавим в базу данных таблицу для хранения исторической информации для работы AWL.

root@beta:~ # mysql --version
mysql  Ver 14.14 Distrib 5.6.32, for FreeBSD11.0 (amd64) using  EditLine wrapper

SQL команда для её создания имеется в составе документации из дистрибутива Spamassassin.

root@beta:~ # cd /usr/local/share/doc/spamassassin/sql/
root@beta:/usr/local/share/doc/spamassassin/sql # root@beta:/usr/local/share/doc/spamassassin/sql # ls awl*
awl_mysql.sql   awl_pg.sql
root@beta:/usr/local/share/doc/spamassassin/sql # cat awl_mysql.sql
CREATE TABLE awl (
  username varchar(100) NOT NULL default '',
  email varbinary(255) NOT NULL default '',
  ip varchar(40) NOT NULL default '',
  count int(11) NOT NULL default '0',
  totscore float NOT NULL default '0',
  signedby varchar(255) NOT NULL default '',
  PRIMARY KEY (username,email,signedby,ip)
) ENGINE=InnoDB;
root@beta:/usr/local/share/doc/spamassassin/sql # mysql -u admin -p <databasename> < awl_mysql.sql
 Enter password: adminpassword

Теперь включим модуль AWL в работу через стандартный конфигурационный файл local.cf.

root@beta:~ # cat cat /usr/local/etc/mail/spamassassin/local.cf
# --- by xM 2013..2016 v.20160829
...
# enabling auto white list
user_awl_dsn                    DBI:mysql:spamassassin:localhost
user_awl_sql_username           spamassassin
user_awl_sql_password           spamassassin
use_auto_whitelist             1
auto_whitelist_factory         Mail::SpamAssassin::SQLBasedAddrList
...

Здесь мы включаем использование хранилища SQL для модуля AWL (user_awl_dsn), задаём имя и пароль для доступа к нему (user_awl_sql_username и user_awl_sql_password), а также указываем имя таблицы для хранения данных (user_awl_sql_table).

Если вы используете компиляцию правил Spamassassin, а я рекомендую её использовать для ускорения работы системы, то также следует не забыть их перекомпилировать стандартной командой sa-compile и перезапустить сервис.

root@beta:~ # sa-compile && service sa-spamd restart
сент.  1 14:25:15.083 [83994] info: generic: base extraction starting. this can take a while...
сент.  1 14:25:15.084 [83994] info: generic: extracting from rules of type body_0
...
Stopping spamd.
Waiting for PIDS: 75070.
Starting spamd.

Увидеть влияние работы модуля AWL можно по отчёту о начислении баллов Spamassassin из загловка письма X-Spam-Report: если, конечно, вы включили его добавление в принимаемое сообщение. Например:

root@beta:~ # cat /path/to/email.eml
...
X-Spam-Report: 
    * -0.0 RCVD_IN_DNSWL_NONE RBL: Sender listed at http://www.dnswl.org/, no
    * trust
    * [162.222.243.86 listed in list.dnswl.org]
    * -0.0 SPF_PASS SPF: sender matches SPF record
    * -1.9 BAYES_00 BODY: Bayes spam probability is 0 to 1%
    * [score: 0.0000]
    * 0.0 HTML_MESSAGE BODY: HTML included in message
    * -0.1 DKIM_VALID_AU Message has a valid DKIM or DK signature from author's
    * domain
    * -0.1 DKIM_VALID Message has at least one valid DKIM or DK signature
    * 0.1 DKIM_SIGNED Message has a DKIM or DK signature, not necessarily
    * valid
    * 1.1 DCC_CHECK Detected as bulk mail by DCC (dcc-servers.net)
    * -0.5 AWL AWL: Adjusted score from AWL reputation of From: address
...

Также для понимания сути работы модуля AWL полезно будет взглянуть на то, как наполняется данными созданная SQL-таблица.

root@beta:~ # mysql -p spamassassin
Enter password:
...
mysql> SELECT * FROM `awl` ORDER BY `time` LIMIT 5;
+----------------+------------------------+--------+-------+----------+----------+---------------------+
| username       | email                  | ip     | count | totscore | signedby | time                |
+----------------+------------------------+--------+-------+----------+----------+---------------------+
| user@domain    | unquhmx@bizneroa.co.ua | 95.46  |     1 |    12.89 |          | 2016-09-01 00:03:56 |
| user@domain    | oqmaxml@gomelins.co.ua | 91.107 |     1 |   12.341 |          | 2016-09-01 00:05:29 |
| user@domain    | upveywp@kolinges.eu    | 95.215 |     1 |   13.106 |          | 2016-09-01 00:06:21 |
| user@domain    | acsihkj@holihik.co.ua  | 95.46  |     1 |   12.524 |          | 2016-09-01 00:09:21 |
| user@domain    | admuqnf@geremans.co.ua | 91.107 |     1 |   12.791 |          | 2016-09-01 00:11:04 |
+----------------+------------------------+--------+-------+----------+----------+---------------------+
5 rows in set (0,02 sec)
mysql> QUIT
Bye

Обратите внимание, что username заполняется именно теми данными, от имени кого вызывается проверка Spamassassin (см. ключ -u сетевого клиента spamc). Поле email заполняется данными из заголовка From: входящего письма.

Ввиду того, что сам модуль AWL не имеет механизма ограничений размеров таблицы хранимой информации, то в целях оптимизации разумно будет поддерживать его размер в пределах актуального интервала времени - в моём случае это 90 дней.

Регулярную очистку неактуальных данных наиболее эффективно можно реализовать через события (EVENT) MySQL.

...
mysql> CREATE EVENT `awl_cleanup` ON SCHEDULE EVERY 1 DAY STARTS '2016-09-01 23:55:00' ON COMPLETION NOT PRESERVE ENABLE DO DELETE FROM `awl` WHERE `time` < NOW() - INTERVAL 90 DAY;
Query OK, 0 rows affected (0,01 sec)
mysql> SHOW EVENTS;
+--------------+-------------+----------------+-----------+-----------+------------+----------------+----------------+---------------------+------+---------+------------+----------------------+----------------------+--------------------+
| Db           | Name        | Definer        | Time zone | Type      | Execute at | Interval value | Interval field | Starts              | Ends | Status  | Originator | character_set_client | collation_connection | Database Collation |
+--------------+-------------+----------------+-----------+-----------+------------+----------------+----------------+---------------------+------+---------+------------+----------------------+----------------------+--------------------+
| spamassassin | awl_cleanup | root@localhost | SYSTEM    | RECURRING | NULL       | 1              | DAY            | 2016-09-01 23:55:00 | NULL | ENABLED |          1 | utf8                 | utf8_general_ci      | utf8_unicode_ci    |
+--------------+-------------+----------------+-----------+-----------+------------+----------------+----------------+---------------------+------+---------+------------+----------------------+----------------------+--------------------+
1 row in set (0,16 sec)

mysql> QUIT
Bye

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

2. Модуль TxRep

Способом, призванным избавиться от недостатков AWL стало появление около двух лет назад в составе пакета Spamassassin его альтернативы - модуля TxRep.

Новый алгоритм лишён недостатков предшественника за счёт использования более широкого набора данных и комплексного подхода используемых для оценки истории оправителя критериев. Кроме того, теперь имеется возможность учёта влияния на историю процесса ручного обучения фильтров Spamassassin через команду sa-learn (и сетевой клиент spamc), а также имеющегося механизма самообучения autolearn. Ранее, напомню, обучение влияло лишь на Bayes-фильтры.

Подробнее об отличиях и возможностях модуля TxRep можно прочитать в документации.

Благодаря тому, что новый модуль оценки репутации отправителя писался с оглядкой на предшествующий AWL, он имеет возможность использовать накопленные в результате его работы данные.

Для перехода на новый алгоритм оценки следует загрузить модуль TxRep отключив одновременно AWL, поскольку их совместное использование невозможно.

root@beta:~ # cat /usr/local/etc/mail/spamassassin/v310.pre | egrep '(AWL|TxRep)'
# AWL - do auto-whitelist checks
#loadplugin Mail::SpamAssassin::Plugin::AWL
# TxRep - normalize scores with sender reputation records
loadplugin Mail::SpamAssassin::Plugin::TxRep

Затем надо проделать аналогичные действия, включив TxRep в работу с базой данных на SQL-сервере.

root@beta:~ # cat cat /usr/local/etc/mail/spamassassin/local.cf
# --- by xM 2013..2016 v.20160829
...
# enabling auto white list
user_awl_dsn                    DBI:mysql:spamassassin:localhost
user_awl_sql_username           spamassassin
user_awl_sql_password           spamassassin
#use_auto_whitelist             1
#auto_whitelist_factory         Mail::SpamAssassin::SQLBasedAddrList
use_txrep                       1
txrep_factory                   Mail::SpamAssassin::SQLBasedAddrList
user_awl_sql_table              awl
...

Обратите внимание, что тут опцией user_awl_sql_table разрешается использование уже созданной ранее таблицы awl с данными модуля-предшественника.

Далее перекомпилируем правила и перезапустим демон Spamassassin.

root@beta:~ # sa-compile && service sa-spamd restart
сент.  1 16:26:55.712 [85268] info: generic: base extraction starting. this can take a while...
сент.  1 16:26:55.712 [85268] info: generic: extracting from rules of type body_0
...
Stopping spamd.
Waiting for PIDS: 84139.
Starting spamd.

Через некоторое время можно пронаблюдать результаты сбора данных в ходе работы модуля TxRep.

root@beta:~ # mysql -p spamassassin
Enter password:
...
mysql> SELECT * FROM `awl` ORDER BY `time` DESC LIMIT 9;
+-----------------+-------------------------------------------------------+------+-------+----------+--------------------+---------------------+
| username        | email                                                 | ip   | count | totscore | signedby           | time                |
+-----------------+-------------------------------------------------------+------+-------+----------+--------------------+---------------------+
| user@domain     | vegas-slot@jackpot-a-happy.us                         | none |     1 |   16.146 | jackpot-a-happy.us | 2016-09-01 16:30:37 |
| user@domain     | 5f757e90997b0ffc593769a796c1c01a9c55a968@sa_generated | none |     1 |   16.146 | 1472740234         | 2016-09-01 16:30:37 |
| user@domain     | 173.232.3.29                                          | none |     1 |   16.146 |                    | 2016-09-01 16:30:37 |
| user@domain     | mta8.nedproductions.biz                               | none |     1 |   16.146 | helo               | 2016-09-01 16:30:37 |
| user@domain     | jackpot-a-happy.us                                    | none |     1 |   16.146 | jackpot-a-happy.us | 2016-09-01 16:30:37 |
| user@domain     | doteka.ru                                             | none |     2 |     8.46 | spf                | 2016-09-01 16:30:02 |
| user@domain     | 188.138.88.74                                         | none |     2 |     8.46 |                    | 2016-09-01 16:30:02 |
| user@domain     | ujhefch@doteka.ru                                     | none |     1 |    3.236 | spf                | 2016-09-01 16:30:02 |
| user@domain     | e22b84b18a3045197fb9cbf65fcbb225136ab0d5@sa_generated | none |     1 |  3.42237 | 1472740195         | 2016-09-01 16:30:02 |
+-----------------+-------------------------------------------------------+------+-------+----------+--------------------+---------------------+
9 rows in set (0,02 sec)

Здесь приведены записи для двух последних входящих писем, которые смогли добраться до Spamassassin. Как видно, более совершенный механизм оценки репутации отправителя требует хранения существенно большего объёма информации. Он превосходит потребный для работы AWL объём не менее чем в 5 раз, а на практике со временем и на порядок больше записей для той же входящей нагрузки.

Поле email теперь используется не только для хранения адреса отправителя, но и для имён и IP адресов хостов, а также индивидуальных сигнатур письма, которые используются для нужд обучения, а поле ip теперь заполняется данными от IP адресе подсети только в случае отсутствия у письма записи SPF или подписи DKIM. Также достойна внимания строка с содержимым helo поля signedby - это HELO/EHLO из самого старого по времени заголовка Recieved: входящего письма.

По мере работы нового модуля в составе системы борьбы со спамом Spamassassin его результаты и их влияние на общую оценку письма можно посмотреть в уже упоминавшемся выше заголовке X-Spam-Report:.

root@beta:~ # cat /path/to/email.eml
...
X-Spam-Report: 
    * -0.0 RCVD_IN_DNSWL_NONE RBL: Sender listed at http://www.dnswl.org/, no
    * trust
    * [95.211.146.161 listed in list.dnswl.org]
    * -0.0 SPF_PASS SPF: sender matches SPF record
    * -1.9 BAYES_00 BODY: Bayes spam probability is 0 to 1%
    * [score: 0.0000]
    * 0.0 HTML_MESSAGE BODY: HTML included in message
    * 0.1 DKIM_SIGNED Message has a DKIM or DK signature, not necessarily
    * valid
    * -0.1 DKIM_VALID_AU Message has a valid DKIM or DK signature from author's
    * domain
    * -0.1 DKIM_VALID Message has at least one valid DKIM or DK signature
    * 0.2 TXREP TXREP: Score normalizing based on sender's reputation
...

В заключение, хотелось бы сказать, что модуль TxRep является относительно новым и код его не до конца отлажен. В этой связи скачайте свежую версию с последними исправлениями из SVN-репозитория проекта перед компиляцией.

root@beta:~ # locate TxRep.pm
/usr/local/lib/perl5/site_perl/Mail/SpamAssassin/Plugin/TxRep.pm
root@beta:~ # cd /usr/local/lib/perl5/site_perl/Mail/SpamAssassin/Plugin
root@beta:/usr/local/lib/perl5/site_perl/Mail/SpamAssassin/Plugin # fetch http://svn.apache.org/repos/asf/spamassassin/trunk/lib/Mail/SpamAssassin/Plugin/TxRep.pm
TxRep.pm                                      100% of   81 kB  193 kBps 00m00s

Текущая версия волне работоспособна и я рекомендую её к использованию в реальной практике.

3. PROFIT!

Статья была полезной? Тогда прошу не стесняться и поддерживать деньгами через PayPal или Яндекс.Деньги.