1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
|
=encoding utf8
=head1 Фильтрация спама при помощи системы rspamd.
=head2 1. История и предпосылки создания.
Мы долгое время использовали для фильтрации спама spamassassin, однако, при
наших объемах почтового трафика (9-10 миллионов писем в сутки) spamassassin
не обеспечивал достаточной производительности. После анализа исходного кода и
принципов работы было выявлены следующие "врожденные" проблемы SA:
=over
=item *
обработка письма осуществляется набором регулярных выражений, однако,
количество этих выражений слишком велико и является ключевым моментом
задумчивости SA (например, для извлечения received заголовков письма, SA
проверяет оные на соответствие всем ему известным MTA, очевидно, что такое
действие не является оптимальным);
=item *
нет возможности явно получить ip адрес, с которого нам отправили письмо (в SA
это делается парсом received заголовков, что я лично не считаю правильным, а тем
более оптимальным способом, так как MTA всегда знает, откуда ему пришло данное
письмо)
=item *
нет возможности передачи спам фильтру данных SMTP диалога
=item *
MIME парсинг писем очень медленный, так как опять же сделан на базе регулярных
выражений
=back
В итоге можно сказать, что основная проблема SA - это излишняя увлеченность
авторов регулярными выражениями и отсутствие оптимизации. В итоге, в качестве
базовых принципов создания rspamd были принципы оптимизации времени обработки
писем, в числе которых:
=over
=item *
полностью асинхронная работа с сетью (на базе libevent), в том числе DNS запросы
и работа с http
=item *
быстрые механизмы выделения памяти
=item *
компиляция всех регулярных выражений и вызов только тех из них, которые наиболее
возможны (то есть, имеется механизм ведения статистики срабатывания различных
правил, и при обработке следующего письма учитывается обработка предыдущих, что
позволяет максимально быстро провести основные тесты)
=item *
расширяемая архитектура: возможность написания плагинов на си, lua, возможность
добавления новых типов фильтров, расширений протокола rspamc, возможность
добавления новых типов статистических алгоритмов, алгоритмов нормализации и
парсинга текстов
=item *
возможность динамической загрузки различных настроек, списков ip адресов и
прочей информации через HTTP протокол с поддержкой даты модификации таких
списков
=item *
использование везде, где возможно, специализированных конечных автоматов для
разбора и анализа текстов
=item *
использование быстрого mime парсера gmime
=back
В результате перехода с SA на rspamd последний показал в среднем в 10 раз более
быструю обработку сообщений. В данный момент rspamd имеет статус бета версии, но
вполне пригоден для работы.
=head2 2. Установка и настройка rspamd
Для сборки rspamd вам потребуются:
=over
=item * libevent
L<http://www.monkey.org/~provos/libevent/> - библиотека для асинхронной
обработки событий
=item * glib
L<http://library.gnome.org/devel/glib/> - библиотека общего назначения,
содержащая многие вещи, о которых разработчики libc, увы, забыли (glib не
является графической библиотекой, хотя и используется, например, gtk)
=item * gmime
L<http://spruce.sourceforge.net/gmime/> - MIME парсер на базе библиотеки glib
=item * lua
L<http://www.lua.org/> - встраиваемый скриптовый язык (в принципе, наличие lua
необязательно, но без lua многий функционал rspamd останется нереализованным)
=item * perl
L<http://www.perl.org/> - на перле написан, например, консольный клиент rspamc,
распознаватель редиректов в URL'ях, поэтому наличие перла в системе крайне
желательно
=item * cmake
L<http://www.cmake.org/> - система сборки, которая позволяет rspamd собираться
(по крайней мере, в теории) на всех Posix совместимых системах. Использовать
стандартные в данной ситуации autotools я не стал, так как считаю их самой
неудобной в использовании системой сборки исходников, которую можно только
придумать.
=item * mercurial
L<http://mercurial.selenic.com/> - система управления версиями (SCM),
используемая для разработки rspamd. Так как в настоящее время rspamd находится в
состоянии бета-версии, то релизы выходят нечасто и зачастую являются менее
стабильными, чем текущая версия в репозитории, поэтому для установки rspamd
лучше использовать версию непосредственно из репозитория.
=back
После установки всех требуемых программ и библиотек можно приступить
непосредственно к установке rspamd.
=over
=item 1
скачиваем текущее состояние репозитория: $ hg clone http://rspamd.hg.sourceforge.net:8000/hgroot/rspamd/rspamd
=item 2
конфигурируем rspamd: $ cd rspamd && cmake .
(при необходимости изменить параметры можно вначале воспользоваться командой
ccmake .)
=item 3
собираем: $ make
=item 4
устанавливаем: # make install
=back
=head3 Конфигурирование
В процессе установки ставятся конфигурационные файлы по умолчанию в каталог
{PREFIX}/etc. При этом, в каталог etc/rspamd устанавливаются правила по
умолчанию (headers, html, drugs, loto и.т.п.), а в каталог
etc/rspamd.conf.sample устанавливается конфигурационный файл по умолчанию. Его
можно скопировать в файл etc/rspamd.conf и отредактировать в соответствии с
собственными предпочтениями. Конфигурационный файл по умолчанию снабжен
комментариями к каждой директиве, а также подробно описан в документации к
rspamd, находящейся в каталоге исходников doc/rspamd.pdf. В данном же
руководстве подробно изложен принцип работы rspamd и настройки всех модулей
системы. Для базовой работы достаточно исправить пути к файлам логов, пидфайлу,
а также обратить внимание на разделы factors и classifiers. Остановлюсь на этом
несколько подробнее.
Все директивы rspamd имеют формат param = value; где символ ';' является
признаком окончания директивы. Также файл разбит на секции, каждая секция имеет
имя (например worker {}) и внутренние директвы внутри фигурных скобок. После
каждой секции также обязателен символ ';'. Также каждый модуль имеет особый
формат секции:
=begin html
<pre>
.module 'name' {
param = value;
};
</pre>
=end html
Все это может показаться сложным на первый взгляд, но это позволяет лучше
структурировать файл и облегчает расширяемость rspamd. Для первоначальной
настройки достаточно обратить внимание на раздел factors, который описывает веса
различных правил, раздел metric, который описывает максимальный вес, чтобы
письмо считалось спамом, а также на раздел classifiers. Раздел classifiers
обеспечивает работу статистических алгоритмов. В rspamd в настоящее время
реализован алгоритм winnow, который работает следующим образом:
=over
=item 1
текст разбивается на слова, также выделяется окно в пять слов
=item 2
окно перемещается по словам, при этом выделяются словосочетания по определенному
алгоритму и вычисляется их хеш
=item 3
каждый полученный таким образом хеш проверяется в файле статистики, в котором
хранятся хеши и их веса, если хеш найден, то его вес добавляется к суммарному
весу данного файла
=item 4
файл, набравший в сумме больше веса считается классом письма
=back
Основная идея такого подхода в определении по словосочетаниям, к какому классу
принадлежит данное письмо. В SA для этой цели используется вероятностный
алгоритм bayes, который достаточно похож на вышеописанный, но считает не веса, а
вероятности. Эффективность каждого из алгоритмов примерно одинакова и зависит в
основном от эффективности обучения. Однако, в отличие от SA, rspamd использует
не отдельные слова, а словосочетания, что повышает его эффективность. В секции
classifiers можно установить различные классы писем, а далее в секции factors
указать их вес (задав, например, для заведомо безвредных писем - ham -
отрицательный вес). Размер файлов статистики должен быть разумно большим для
хранения как можно большего числа хешей. Однако, необходимо учитывать, что эти
файлы целиком загружаются в память (хотя, реализация отображения файла в памяти
в различных ОС допускает загрузку и выгрузку страниц этого файла в своп системы,
но эффективность этого довольно низка), поэтому необходимо соизмерять размер
оперативной памяти и файлов статистики.
=head2 4. Подключение и проверка работоспособности rspamd
Для проверки работы системы rspamd проще всего воспользоваться командой rspamc:
=begin html
<pre>
hostname:~> rspamc stat
Do rspamc command stat
Messages scanned: 1234040
Messages learned: 59151
Connections count: 1176623
Control connections count: 59152
Pools allocated: 2530714
Pools freed: 2530699
Bytes allocated: 66991793394
Memory chunks allocated: 6453232
Shared chunks allocated: 3
Chunks freed: 6453090
Oversized chunks: 468849
Statfile: WINNOW_HAM (version 69); length: 100.0 MB; free blocks: 4563488; total blocks: 6553581; free: 69.63%
Statfile: WINNOW_SPAM (version 36383); length: 100.0 MB; free blocks: 760504; total blocks: 6553581; free: 11.60%
</pre>
=end html
В данном случае выводится общая статистика. Такого же эффекта можно достигнуть
командой telnet на порт процесса controller (он описан в конфигурационном файле
в секции worker, type у которого controller). По умолчанию это порт 11334 на
адресе 127.0.0.1. Работу правил и статистики можно также проверить по команде
rspamc:
=begin html
<pre>
~> rspamc symbols /tmp/mailman.eml
Processing /tmp/mailman.eml
Process file: /tmp/mailman.eml
Sending 4950 bytes...
RSPAMD/1.1 0 OK
Metric: default; False; -3.35 / 10.00 / 0.00
Symbol: WINNOW_HAM; 5.00
Symbol: RECEIVED_RBL; pbl.spamhaus.org,insecure-bl.rambler.ru
Urls:
</pre>
=end html
В данном случае показываются баллы, набранные письмом, а также дополнительная
информация. Подробнее о протоколе rspamc в документации (doc/rspamd.pdf). Для
подключения rspamd к MTA лучше всего использовать milter, если ваш MTA postfix
или sendmail. В качестве milter'а можно использовать, например, rmilter:
L<https://www.milter.org/milter/71/>. О настройке postfix + rmilter мной была
написана следующая заметка: L<http://cebka.pp.ru/blog/2009/02/-nginxpostfixrmilter.html>
Для MTA exim можно воспользоваться файлом local_scan.c в каталоге contrib/exim.
Инструкции по его установке описаны в самом файле, однако, это требует
пересборки MTA. Также rspamd "понимает" протокол SA, поэтому для подключения
rspamd можно использовать те же средства, что и для подключения к MTA SA.
Подробнее о командах rspamc и протоколе rspamc написано опять же в документации.
=head2 5. Обучение rspamd
Процесс обучения важен для корректной работы статистики. Для обучения
используется команда rspamc learn. Для указания файла (класса) письма
используется ключ -s. Пример использования:
=begin html
<pre>
~> rspamc -s WINNOW_HAM learn /tmp/mailman.eml
Processing /tmp/mailman.eml
Process file: /tmp/mailman.eml
Do rspamc command learn
Sending 4950 bytes...
Learn succeed. Sum weight: 128.48
</pre>
=end html
В качестве параметров можно указывать несколько файлов, целые каталоги, а также
imap папки:
=begin html
<pre>
~> rspamc -s WINNOW_SPAM learn imaps:user:cebka:password::host:somehost.rambler.ru:mbox:abuse.spam
Processing imaps:user:cebka:password::host:mailsupport.rambler.ru:mbox:abuse.spam
Enter IMAP password:
Process imap: host: somehost.rambler.ru, mbox: abuse.spam
Do rspamc command learn
Sending 382650 bytes...
Learn succeed. Sum weight: 1850.24
<skipped>
</pre>
=end html
При обучении необходимо учитывать, чтобы количество spam и ham писем было
примерно равным. Вес показывает суммарный вес словосочетаний текста, который был
до обучения данным письмом (то есть, то, насколько велика вероятность
принадлежности данного письма к этому классу). При обнаружении неверных
срабатываний статистики можно несколько раз применить learn к заданному письму,
проверяя его суммарный вес.
=head2 6. Поддержка и дальнейшие действия
Если вы решили использовать rspamd для обработки вашей почты, то лучшим
источником информации будет являться документация к rspamd, а также примеры lua
плагинов: etc/plugins/lua. Целью же данной статьи является ознакомление с
основными приемами по установке, конфигурированию и обучению rspamd, а также
описание преимуществ rspamd по сравнению с SA. Если на любом этапе работы с
rspamd у вас возникает проблема, то можно о ней сообщить мне:
B<vsevolod@highsecure.ru> или же в список рассылки rspamd на sourceforge
(англоговорящий): B<rspamd-devel@lists.sourceforge.net>. Сама система
rspamd находится в состоянии бета-версии, поэтому ваша помощь в тестировании и
запросы функциональности будут неоценимы в развитии rspamd.
|