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% (полностью разные части). * 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).