summaryrefslogtreecommitdiffstats
path: root/README.utf8.txt
blob: b27e2876f1ba63f3c80ffdaed1320fac7cce6999 (plain)
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
API Rspamd.
===========

API rspamd описано подробно в Doxygen документации.

Логика работы фильтров rspamd.
==============================

1) Все фильтры регистрируются в конфиг файле в описании цепочек фильтров:
header_filters=regexp,my_func
где имя фильтра - это либо название c модуля, либо название перл функции
Типы фильтров:
* header_filters - фильтр заголовков
* mime_filters - фильтр для каждой mime части
* message_filters - фильтр всего сообщения целиком
* url_filters - фильтры URL ссылок
Свои результаты фильтры регистрируют при помощи добавления результата в метрику.

2) Метрика - это символьное значение, в котором регистрируют свои результаты фильтры
Существует метрика по умолчанию - "default", в которой регистрируют результаты фильтры,
для которых явно не определена метрика
Для каждой метрики существует специальная функция консолидации, которая рассчитывает коэффициенты
результатов согласно внутренней логике соответствия символов и коэффициентов. По умолчанию такой
функцией является простая сумма, которая настраивается особым образом в конфигурационном файле:

# Блок factors
factors {
	# Например, "SURBL_DNS"=5.0
	"SYMBOL_NAME" = coefficient;
};
Также для метрики можно зарегистрировать особую функцию, прописав в описании метрики
metric {
	name = "test_metric";
	function = "some_function";
	required_score = 20.0;
};
Пока поддерживаются только перловые функции.

3) Результат - это пара значений: SYMBOL:FLAG, при этом, SYMBOL - это
строчка, характеризующая результат, а FLAG - сработал данный фильтр или нет 
(1 или 0). Результат добавляется в метрику, после чего передается функции консолидации.

4) Итог - на выходе мы имеем обработанное сообщение, список метрик и их символов и результаты
проверки.

Протокол.
=========

Формат ответа:
SPAMD/1.1 0 EX_OK 
\       / \/
 Версия   Код
         ошибки
Spam: False ; 2 / 5
Это формат совместимости с sa-spamd (без метрик)

Новый формат ответа:
RSPAMD/1.0 0 EX_OK
Metric: Name; Spam_Result; Spam_Mark / Spam_Mark_Required
Metric: Name2 ; Spam_Result2 ; Spam_Mark2 / Spam_Mark_Required2

Заголовков типа metric может быть несколько.
Формат вывода символов:
SYMBOL1, SYMBOL2, SYMBOL3 -- формат совместимости с sa-spamd
Symbol: Name; Param1,Param2,Param3 -- формат rspamd

Формат ответа зависит от формата запроса:
PROCESS SPAMC/1.2
\     / \       /
Команда  Версия

SPAMC - протокол совместимости с sa-spamd
RSPAMC - новый протокол rspamd
В любом из режимов работы поддерживаются следующие заголовки:
Content-Length - длина сообщения
Helo - HELO, полученный от клиента
From - MAIL FROM
IP - IP клиента
Recipient-Number - число реципиентов
Rcpt - реципиент
Queue-ID - идентификатор очереди

Эти значения могут использоваться в фильтрах rspamd.

Регулярные выражения
====================

Регулярные выражения разбираются модулем regexp, поэтому их настройка выглядит следующим образом
.module 'regexp' {
	SYMBOL = "regexp_expression";
};
header_filters = "regexp";

Обратите внимание, что модуль regexp надо регистрировать как header filter, так как иначе он не будет работать.
Эту проблему надо исправлять, но это не первоочередная задача.

Формат регэкспов такой:
/pattern/flags
При этом может быть такой формат:
headername=/pattern/flags
если регэксп ищет соответствие хедера и выражения
Флаги регэскпов:
i, m, s, x, u, o - такие же, как у perl/pcre
r - "сырой" незакодированный в utf8 regexp
H - ищет по заголовкам
M - ищет по всему сообщению (в "сыром" виде)
P - ищет по всем mime частям
U - ищет по url
X - ищет по "сырым" хедерам (тут нужно учитывать фолдинг и ставить, где надо, /m для multiline матчинга)

Выражение регэкспов может содержать сложные выражения из нескольких регэкспов, операторов логики и скобок:
SOME_SYMBOL = "To=/blah@blah/H & !(From=/blah@blah/H | Subject=/blah/H)"

Также можно использовать переменные:
$to_blah = "To=/blah@blah/H";
$from_blah = "From=/blah@blah/H";
$subject_blah = "Subject=/blah/H";

тогда предыдущее выражение будет таким

SOME_SYMBOL = "${to_blah} & !(${from_blah} | ${subject_blah})"

Логические выражения rspamd
===========================

Условия, содержащие регулярные выражения, функции, логические операции, скобки, могут использоваться
для задания правил фильтрации. Общие правила работы:
- логическими операциями могут быть логическое "И": '&', логическое "ИЛИ": '|' и логическое отрицание:
'!'.
- приоритет логических операций такой: & и | -> !, для изменения приоритета можно пользоваться скобками:
 (A&!B) | !(C|D)
- пробелы в выражениях игнорируются
- операнд, содержащий /re/args или же string=/re/args считается регулярным выражением, внутри регулярного
выражения все символы '/' и '"' должны экранироваться символом '\'. Сам '\' при этом экранировать не нужно.
- операнд, который принимает аргументы, считается функцией, аргументом функции может являться другая функция,
при этом порядок вызова функций-аргументов - справа налево (как это сделано в gcc)
- в rspamd встроен ряд функций:
  * header_exists - принимает в качестве аргумента имя хедера, возвращает true, если такой заголовок существует
  * compare_parts_distance - принимает в качестве аргумента число от 0 до 100, которое отражает разницу в процентах
    между частями письма. Функция работает с сообщениями, содержащими 2 текстовые части (text/plain и text/html) и
	возвращает true тогда, когда эти части различаются более чем на n процентов. Если аргумент не указан, то
	по умолчанию ищется различие в 100% (полностью разные части).
  * compare_transfer_encoding - сравнивает Content-Transfer-Encoding с заданной строкой
  * content_type_compare_param - сравнивает параметр content-type заголовка с регулярным выражением или строкой:
     content_type_compare_param(Charset, /windows-\d+/)
	 content_type_compare_param(Charset, ascii)
  * content_type_has_param - проверяет, есть ли в заголовке content-type определенный параметр
  * content_type_is_subtype - сравнивает подтип content-type с регулярным выражением или строкой
  * content_type_is_type - сравнивает тип content-type с регулярным выражением или строкой
     content_type_is_type(text)
     content_type_is_subtype(/?.html/)
  * regexp_match_number - принимает в качестве первого параметра число, которое означает порог сработавших регэкспов и 
    список регэкспов или функций, которые должны проверяться. Если число сработавших регэкспов или функций больше порога,
	функция возвращает TRUE, иначе - FALSE, например:
	regexp_match_number(2, ${__RE1}, ${__RE2}, header_exists(Subject))
  * has_only_html_part - функция возвращает TRUE, если в сообщении есть только одна HTML часть
  * compare_recipients_distance - вычисляет процент схожих получателей письма. Принимает аргумент - порог в процентах похожести.
  * is_recipients_sorted - возвращает TRUE, если список получателей сортирован (работает только если число получателей >= 5).
  * is_html_balanced - возвращает TRUE, если теги всех html частей сбалансированы
  * has_html_tag - возвращает TRUE, если заданный html тег найден

Модуль chartable.
================

Модуль предназначен для поиска слов со смешанными символами, например:
kашa - часть в латинице, а часть в кириллице.
Параметры модуля:

.module 'chartable' {
	metric = "default";
	symbold = "R_MIXED_CHARSET";
	threshold = "0.1";
};

threshold - это отношение переходов между кодировками к общему числу символов в словах, например, имеем слово
"kаша" (первая буква латинская), тогда общее число переходов - 3, а число переходов между кодировками - 1, тогда 
отношение - 1/3.

Для включения модуля его необходимо добавить в список mime_filters:
mime_filters = "chartable";