summaryrefslogtreecommitdiffstats
path: root/doc/rspamd.lyx
diff options
context:
space:
mode:
authorVsevolod Stakhov <vsevolod@rambler-co.ru>2009-09-25 19:50:30 +0400
committerVsevolod Stakhov <vsevolod@rambler-co.ru>2009-09-25 19:50:30 +0400
commit7584957defe9b63084c1fb6b939ae88718752a91 (patch)
tree48944bf382e6a140a9c3b95cb5a4df546bbdad26 /doc/rspamd.lyx
parenta9ab6be27de01f12ce6f201a4efa3eda8be0e36b (diff)
downloadrspamd-7584957defe9b63084c1fb6b939ae88718752a91.tar.gz
rspamd-7584957defe9b63084c1fb6b939ae88718752a91.zip
* Add documentation
Diffstat (limited to 'doc/rspamd.lyx')
-rw-r--r--doc/rspamd.lyx2898
1 files changed, 2898 insertions, 0 deletions
diff --git a/doc/rspamd.lyx b/doc/rspamd.lyx
new file mode 100644
index 000000000..ca2fc3f8e
--- /dev/null
+++ b/doc/rspamd.lyx
@@ -0,0 +1,2898 @@
+#LyX 1.6.2 created this file. For more info see http://www.lyx.org/
+\lyxformat 345
+\begin_document
+\begin_header
+\textclass book
+\begin_preamble
+\usepackage{indentfirst}
+\frenchspacing
+\end_preamble
+\use_default_options false
+\language russian
+\inputencoding utf8
+\font_roman cmr
+\font_sans cmss
+\font_typewriter cmtt
+\font_default_family sfdefault
+\font_sc false
+\font_osf false
+\font_sf_scale 100
+\font_tt_scale 100
+
+\graphics default
+\paperfontsize default
+\spacing single
+\use_hyperref true
+\pdf_title "Rspamd"
+\pdf_author "Vsevolod Stakhov"
+\pdf_bookmarks true
+\pdf_bookmarksnumbered true
+\pdf_bookmarksopen false
+\pdf_bookmarksopenlevel 1
+\pdf_breaklinks false
+\pdf_pdfborder true
+\pdf_colorlinks true
+\pdf_backref false
+\pdf_pdfusetitle true
+\papersize a4paper
+\use_geometry false
+\use_amsmath 0
+\use_esint 0
+\cite_engine basic
+\use_bibtopic false
+\paperorientation portrait
+\secnumdepth 3
+\tocdepth 3
+\paragraph_separation indent
+\defskip medskip
+\quotes_language french
+\papercolumns 1
+\papersides 1
+\paperpagestyle fancy
+\tracking_changes false
+\output_changes false
+\author ""
+\author ""
+\end_header
+
+\begin_body
+
+\begin_layout Title
+Руководство по системе фильтрации спама rspamd.
+\end_layout
+
+\begin_layout Date
+25.09.2009
+\end_layout
+
+\begin_layout Author
+Стахов Всеволод.
+\end_layout
+
+\begin_layout Standard
+\begin_inset CommandInset toc
+LatexCommand tableofcontents
+
+\end_inset
+
+
+\end_layout
+
+\begin_layout Standard
+
+\end_layout
+
+\begin_layout Chapter
+Общая информация и возможности rspamd
+\end_layout
+
+\begin_layout Standard
+Rspamd - это система, предназначенная для фильтрации спама.
+ Изначально rspamd разрабатывался как фильтр для электронной почты, но он
+ может применяться и для другого типа сообщений (например, для jabber или
+ icq сообщений).
+ В основе rspamd лежит концепция асинхронной обработки входящих сообщений.
+ Для этого применяется библиотека libevent.
+ Это накладывает определенные ограничения на возможности rspamd, так как
+ для любой блокирующей операции (например, чтение из сетевого сокета) необходимо
+ регистрировать отдельное событие и его обработчика, но дает преимущества
+ в скорости работы системы и уменьшает различные служебные затраты (например,
+ на создание процессов или потоков).
+ Rspamd поддерживает встроенные фильтры на языке lua, что позволяет писать
+ собственные фильтры без необходимости пересборки системы.
+ Rspamd настраивается путем редактирования конфигурационного файла.
+ Также имеется управляющий интерфейс, посредством которого можно различным
+ образом управлять работой системы и получать ее текущее состояние.
+ Rspamd поддерживает различные типы фильтров: фильтры на основе регулярных
+ выражений, фильтры на основе DNS запросов, фильтры на основе статистики,
+ фильтры по различным спискам и другие типы фильтров (например, фильтры,
+ написанные на языке lua и выполняющие различные действия по анализу сообщений).
+ Rspamd имеет протокол, совместимый с системой spamassassin (в дальнейшем
+ протокол spamc), а также его расширение - rspamc, позволяющее передавать
+ больше информации фильтру, что ускоряет обработку сообщений.
+ Система rspamd состоит из двух основных частей: монитор процессов и процессы,
+ осуществляющие обработку (workers).
+ Монитор процессов отвечает за старт системы, открытие/закрытие журналов
+ работы, а также обеспечивает непрерывную работу рабочих процессов и их
+ перезапуск при необходимости.
+\end_layout
+
+\begin_layout Chapter
+Установка rspamd
+\end_layout
+
+\begin_layout Section
+Требования
+\end_layout
+
+\begin_layout Itemize
+GNU C компилятор (работоспособность проверялась на gcc 4.2.1)
+\end_layout
+
+\begin_layout Itemize
+cmake -
+\begin_inset CommandInset href
+LatexCommand href
+name "http://cmake.org/"
+target "http://cmake.org/"
+
+\end_inset
+
+ используется для конфигурации сборки и генерации Makefile.
+ Необходимая версия - не менее 2.6.
+\end_layout
+
+\begin_layout Itemize
+glib -
+\begin_inset CommandInset href
+LatexCommand href
+name "http://ftp.gnome.org/"
+target "http://ftp.gnome.org/pub/GNOME/sources/glib/2.20/"
+
+\end_inset
+
+ используется для различного рода утилит и структур хранения данных (хеши,
+ деревья, списки).
+ Необходимая версия - не менее 2.16.
+\end_layout
+
+\begin_layout Itemize
+gmime -
+\begin_inset CommandInset href
+LatexCommand href
+name "http://ftp.acc.umu.se"
+target "http://ftp.acc.umu.se/pub/GNOME/sources/gmime/2.2/"
+
+\end_inset
+
+ используется для разбора mime структуры сообщений.
+ Необходимая версия 2.2.
+ Работа с gmime 2.4 и старше не проверялась.
+\end_layout
+
+\begin_layout Itemize
+lua -
+\begin_inset CommandInset href
+LatexCommand href
+name "http://www.lua.org/"
+target "http://www.lua.org/download.html"
+
+\end_inset
+
+ используется для работы lua плагинов (без liblua работа rspamd возможна,
+ но без поддержки lua плагинов).
+ Версия необходима не меньше, чем 5.1.
+\end_layout
+
+\begin_layout Itemize
+libevent -
+\begin_inset CommandInset href
+LatexCommand href
+name "http://www.monkey.org/~provos/libevent/"
+target "http://www.monkey.org/~provos/libevent/"
+
+\end_inset
+
+ используется для кросс-платформенной обработки асинхронных событий, а также
+ для определения DNS имен (также асинхронного).
+\end_layout
+
+\begin_layout Section
+Установка
+\end_layout
+
+\begin_layout Standard
+Для сборки rspamd необходимо скачать архив (самая свежая версия может быть
+ найдена на
+\begin_inset CommandInset href
+LatexCommand href
+name "http://cebka.pp.ru/distfiles/"
+target "http://cebka.pp.ru/distfiles/"
+
+\end_inset
+
+).
+ После этого необходимо распаковать архив и скомпилировать код:
+\end_layout
+
+\begin_layout LyX-Code
+$ tar xzf rspamd-x.x.x.tar.gz
+\end_layout
+
+\begin_layout LyX-Code
+$ cd rspamd-x.x.x
+\end_layout
+
+\begin_layout LyX-Code
+$ cmake .
+\end_layout
+
+\begin_layout LyX-Code
+$ make
+\end_layout
+
+\begin_layout Standard
+Установка осуществляется стандартным
+\end_layout
+
+\begin_layout LyX-Code
+# make install
+\end_layout
+
+\begin_layout Standard
+В процессе установки копируются исполняемые файлы rspamd: bin/rspamd и bin/rspam
+c, а также примеры конфигурации и плагины, устанавливающиеся в каталог etc/rspam
+d/.
+ Также для ОС FreeBSD устанавливается стартовый скрипт rspamd.sh в каталог
+ etc/rc.d.
+
+\end_layout
+
+\begin_layout Section
+Запуск
+\end_layout
+
+\begin_layout Standard
+Rspamd запускается либо из стартового скрипта, либо непосредственно вызовом
+ rspamd.
+ Доступные опции командной строки:
+\end_layout
+
+\begin_layout Code
+-h: Показать справочную информацию и выйти
+\end_layout
+
+\begin_layout Code
+-t: Проверить конфигурационный файл и выйти
+\end_layout
+
+\begin_layout Code
+-C: Показать содержимое кеша символов и выйти
+\end_layout
+
+\begin_layout Code
+-V Показать все переменные rspamd и выйти
+\end_layout
+
+\begin_layout Code
+-f: Не выполнять демонизацию
+\end_layout
+
+\begin_layout Code
+-c: Указать путь до конфигурационного файла (по умолчанию используется
+ /usr/local/etc/rspamd.conf)
+\end_layout
+
+\begin_layout Code
+-u: Пользователь, под которым осуществлять работу rspamd
+\end_layout
+
+\begin_layout Code
+-g: Группа, под которой осуществять работу rspamd
+\end_layout
+
+\begin_layout Standard
+Если rspamd запускается от суперпользователя, то после создания лог-файла,
+ PID-файла, а также сокетов, принимающих соединения, осуществляется сброс
+ привиллегий до пользователя и группы, указанных в опциях командной строки
+ (таким образом, все рабочие процессы работают от указанного пользователя
+ и группы).
+\end_layout
+
+\begin_layout Chapter
+Общие принципы работы
+\end_layout
+
+\begin_layout Standard
+Прежде чем приступать к настройке rspamd необходимо понять основные принципы
+ функционирования системы.
+\end_layout
+
+\begin_layout Section
+Планирование и запуск рабочих процессов
+\end_layout
+
+\begin_layout Standard
+При запуске rspamd происходят следующие действия:
+\end_layout
+
+\begin_layout Enumerate
+Запускается главный процесс (rspamd main)
+\end_layout
+
+\begin_layout Enumerate
+Инициализируются конфигурационные параметры по умолчанию
+\end_layout
+
+\begin_layout Enumerate
+Читаются параметры командной строки
+\end_layout
+
+\begin_layout Enumerate
+Настраивается журналирование ошибок в терминал
+\end_layout
+
+\begin_layout Enumerate
+Читается и парсится конфигурационный файл
+\end_layout
+
+\begin_layout Enumerate
+Инициализируются модули
+\end_layout
+
+\begin_layout Enumerate
+Модули читают свои конфигурационные параметры
+\end_layout
+
+\begin_layout Enumerate
+Устанавливаются лимиты
+\end_layout
+
+\begin_layout Enumerate
+Настраивается журналирование, указанное в конфигурационном файле
+\end_layout
+
+\begin_layout Enumerate
+Происходит демонизация (если не указан флаг -f)
+\end_layout
+
+\begin_layout Enumerate
+Настраивается обработка сигналов головным процессом
+\end_layout
+
+\begin_layout Enumerate
+Записывается PID-файл
+\end_layout
+
+\begin_layout Enumerate
+Инициализируются lua плагины
+\end_layout
+
+\begin_layout Enumerate
+Инициализируется подсистема событий и mime парсер
+\end_layout
+
+\begin_layout Enumerate
+Загружается кеш символов
+\end_layout
+
+\begin_layout Enumerate
+Порождаются рабочие процессы (сброс привиллегий осуществляется сразу же
+ после вызова fork)
+\end_layout
+
+\begin_layout Enumerate
+Начинается цикл обработки сигналов
+\end_layout
+
+\begin_layout Standard
+Головной процесс rspamd реагирует на следующие сигналы:
+\end_layout
+
+\begin_layout Itemize
+SIGTERM - послать всем рабочим процессам SIGTERM, дождаться их завершения
+ и выйти
+\end_layout
+
+\begin_layout Itemize
+SIGINT - то же, что и SIGTERM
+\end_layout
+
+\begin_layout Itemize
+SIGHUP - переинициализировать журналирование и породить новые рабочие процессы,
+ завершив старые (при этом, существующие рабочие процессы завершают работу,
+ обработав уже полученные соединения)
+\end_layout
+
+\begin_layout Itemize
+SIGCHLD - головной процесс получает этот сигнал при завершении работы рабочего
+ процесса.
+ Если рабочий процесс завершился некорректно, то планируется его перезапуск
+ через 2 секунды.
+\end_layout
+
+\begin_layout Itemize
+SIGUSR2 - приходит от рабочего процесса, когда тот успешно инициализируется
+\end_layout
+
+\begin_layout Itemize
+SIGALARM - сигнализирует о необходимости запуска рабочего процесса, который
+ был запланирован после получения SIGCHLD
+\end_layout
+
+\begin_layout Standard
+Таким образом, головной процесс отвечает за инициализацию, конфигурацию,
+ работу с PID-файлом, работу с журналированием, а также за порождение рабочих
+ процессов.
+ В ходе работы головной процесс постоянно следит за работой рабочих процессов
+ и обеспечивает перезапуск некорректно завершившихся рабочих процессов.
+ Для ротации файлов журналирования рабочему процессу необходимо послать
+ сигнал SIGHUP.
+\end_layout
+
+\begin_layout Section
+Логика обработки сообщений
+\end_layout
+
+\begin_layout Standard
+Инициализация рабочего процесса предельно проста: происходит переинициализация
+ libevent, а также инициализация DNS resolver'а.
+ После этого рабочий процесс устанавливает обработчик готовности к чтению
+ слушающего сокета (этот сокет создается в головном процессе и передается
+ рабочему процессу как параметр).
+ При готовности к чтению на слущающем сокете рабочий процесс создает новый
+ объект типа worker_task и делается accept на слушающем сокете.
+ После этого rspamd обрабатывает протокол rspamc (или же spamc) и читает
+ сообщение.
+ После окончания получения сообщения rspamd декодирует его содержимое и
+ начинает обработку.
+ Для более простого изложения принципов работы rspamd необходимо описать
+ некоторые понятия:
+\end_layout
+
+\begin_layout Itemize
+Символ - это правило фильтрации rspamd, например, некоторое регулярное выражение
+ или же запрос к DNS или же любое другое действие.
+ Символ имеет собственный вес и имя.
+ Таким образом, символ можно считать результатом работы одного правила фильтраци
+и.
+ Если это правило сработало, то оно добавляет символ с определенным весом
+ и атрибутами, если нет, то символ не добавляется.
+\end_layout
+
+\begin_layout Itemize
+Метрика - это набор логически связанных правил и связанных с ними символов.
+ Такая группа имеет свой предел очков, после набора которых сообщение считается
+ по этой метрике спамом.
+ Очки формируются после подсчета весов символов, добавленных в метрику (при
+ этом, разумеется, несработавшие правила символов не добавляют и их вес
+ равен нулю) и обработки этих весов функцией консолидации.
+ По умолчанию такой функцией является функция-факторизатор, которая просто
+ считает вес каждого символа равным константе, заданной в конфигурационном
+ файле для этого символа, например, следующие параметры в конфигурационном
+ файле задают вес символа MIME_HTML_ONLY равный одному, а вес символа FAKE_HTML
+ - восьми:
+\end_layout
+
+\begin_layout LyX-Code
+"MIME_HTML_ONLY" = 1;
+\end_layout
+
+\begin_layout LyX-Code
+"FAKE_HTML" = 8;
+\end_layout
+
+\begin_layout Itemize
+Модуль - это набор правил rspamd, который обеспечивает общие проверки.
+ Например, модуль проверки регулярных выражений или модуль проверки URL'ей
+ по
+\begin_inset Quotes eld
+\end_inset
+
+черным
+\begin_inset Quotes erd
+\end_inset
+
+ спискам.
+ Модули также могут быть написаны на языке LUA.
+ Каждый модуль регистрирует символы, соответствующие сконфигурированным
+ в нем правилам, в таблице символов заданной метрики (или метрики по умолчанию
+
+\begin_inset Quotes eld
+\end_inset
+
+default
+\begin_inset Quotes erd
+\end_inset
+
+).
+\end_layout
+
+\begin_layout Itemize
+Таблица символов метрики - это таблица, хранящая данные о зарегистрированных
+ символах, таблица отсортирована, чтобы обеспечить проверку самых
+\begin_inset Quotes eld
+\end_inset
+
+удобных
+\begin_inset Quotes erd
+\end_inset
+
+ правил в первую очередь.
+ Критерий
+\begin_inset Quotes eld
+\end_inset
+
+удобности
+\begin_inset Quotes erd
+\end_inset
+
+ составляется из трех составляющих: веса правила, частоты его срабатывания
+ и времени его выполнения.
+ Чем больше вес, частота срабатывания и меньше время выполнения, тем раньше
+ будет проверено это правило.
+\end_layout
+
+\begin_layout Itemize
+Классификатор - это алгоритм, обеспечивающий определение принадлежности
+ сообщения к какому-либо классу.
+ Класс определяется символом (например символ SPAM, имеющий вес 5 и символ
+ HAM, имеющий вес -5).
+ Принадлежность к классу обеспечивается либо статистически, путем разбора
+ текста сообщения на токены и сравнения с известными токенами, хранящимися
+ на диске в виде файла токенов (statfile), либо же иным алгоритмом (например,
+ нейросетью).
+ В результате работы классификатора определяется соответствие сообщения
+ какому-либо классу и добавления соответствующего этому классу символа.
+ Классификатор отличается от обычного модуля тем, что он не просто проверяет
+ какие-либо характеристики сообщения, а сравнивает содержание сообщения
+ с известными ему наборами.
+ То есть, классификатор для его работы необходимо обучать на различных наборах.
+ В настоящее время в rspamd реализован алгоритм классификации winnow и разбора
+ на токены OSB.
+ О них будет написано в дальнейшем.
+\end_layout
+
+\begin_layout Standard
+Обработка осуществляется по следующей логике:
+\end_layout
+
+\begin_layout Itemize
+для каждой метрики выбирается таблица символов и выбираются по очереди символы
+ (по степени
+\begin_inset Quotes eld
+\end_inset
+
+удобности
+\begin_inset Quotes erd
+\end_inset
+
+)
+\end_layout
+
+\begin_layout Itemize
+для каждого символа вызывается соответствующее правило
+\end_layout
+
+\begin_layout Itemize
+после вызова очередного правила проверяется, не превысил ли результат метрики
+ порогового результата
+\end_layout
+
+\begin_layout Itemize
+при превышении порога сообщение считается по этой метрике спамом и больше
+ символов из этой метрики не проверяется
+\end_layout
+
+\begin_layout Itemize
+для сообщения проверяется принадлежность к какому-либо классу для корректировки
+ результата
+\end_layout
+
+\begin_layout Itemize
+после определения принадлежности к классу происходит окончательный пересчет
+ очков по метрике и при совпадении критериев автообучения происходит автообучени
+е классификатора
+\end_layout
+
+\begin_layout Standard
+После обработки сообщений для каждой из метрик выводится результат.
+ Если используется протокол spamc, то считается только метрика
+\begin_inset Quotes eld
+\end_inset
+
+default
+\begin_inset Quotes erd
+\end_inset
+
+, а дополнительные метрики добавляются как заголовки вида X-Spam-Status:
+ metric; result.
+ Для протокола rspamc выводятся результаты всех метрик, что позволяет настраиват
+ь различные группы правил и осуществлять фильтрацию сообщений не только
+ как spam/ham, а задавать различные критерии оценки.
+\end_layout
+
+\begin_layout Chapter
+Настройка rspamd
+\end_layout
+
+\begin_layout Section
+Общие правила настройки
+\end_layout
+
+\begin_layout Standard
+Файл конфигурации rspamd имеет следующий синтаксис:
+\end_layout
+
+\begin_layout LyX-Code
+param = value;
+\end_layout
+
+\begin_layout Standard
+Точка с запятой является обязательной в конце каждой директивы.
+ Некоторые директивы являются составными и обрамляются фигурными скобками,
+ например:
+\end_layout
+
+\begin_layout LyX-Code
+section {
+\end_layout
+
+\begin_deeper
+\begin_layout LyX-Code
+param = value;
+\end_layout
+
+\end_deeper
+\begin_layout LyX-Code
+};
+\end_layout
+
+\begin_layout Standard
+Также позволяется включать другие файлы (точка с запятой в конце директивы
+ не нужна):
+\end_layout
+
+\begin_layout LyX-Code
+.include /path/to/file
+\end_layout
+
+\begin_layout Standard
+В конфигурационном файле допускается определять и использовать переменные:
+\end_layout
+
+\begin_layout LyX-Code
+$var = "some text";
+\end_layout
+
+\begin_layout LyX-Code
+param = "${var}";
+\end_layout
+
+\begin_layout Standard
+Приведенный фрагмент определяет переменную $var и присваивает параметру
+
+\begin_inset Quotes eld
+\end_inset
+
+param
+\begin_inset Quotes erd
+\end_inset
+
+ значение
+\begin_inset Quotes eld
+\end_inset
+
+some text
+\begin_inset Quotes erd
+\end_inset
+
+.
+ Переменные имеют глобальную область действия, обрамление переменных фигурными
+ скобками при использовании (вида ${some_variable}) обязательно.
+ Большинство строк конфигурационного файла обрамляется двойными кавычками.
+ Одинарные кавычки применяются только при конфигурации модуля (это поведение
+ подлежит пересмотру в следующих версиях):
+\end_layout
+
+\begin_layout LyX-Code
+.module 'name' {
+\end_layout
+
+\begin_deeper
+\begin_layout LyX-Code
+param = "value";
+\end_layout
+
+\end_deeper
+\begin_layout LyX-Code
+};
+\end_layout
+
+\begin_layout Subsection
+Определения списков
+\end_layout
+
+\begin_layout Standard
+В rspamd многие параметры задаются в виде списков.
+ Списки задаются ссылкой на файл или же http ресурс.
+ Основное отличие таких файлов в том, что rspamd проверяет изменения в таких
+ файлах (примерно раз в минуту, используя случайный разброс) и перегружает
+ списки при их модификации.
+ Таким же образом организована загрузка списков через http, только вместо
+ modification time используется HTTP 1.1 заголовок If-Modified-Since, в ответ
+ на который http сервер может выдать ответ 304: Not modified, в таком случае
+ rspamd не перечитывает список.
+ Списками задаются те параметры, которые могут содержать много значений
+ и которые могут часто меняться.
+ Для того, чтобы не приходилось выполнять перезапуск rspamd списки перечитываютс
+я по мере их обновления.
+ Определения списков выглядят следующим образом:
+\end_layout
+
+\begin_layout Itemize
+http список:
+\end_layout
+
+\begin_layout LyX-Code
+param = "http://test.ru:81/some/path.php";
+\end_layout
+
+\begin_layout LyX-Code
+param = "http://test.ru/some/other.txt";
+\end_layout
+
+\begin_layout Itemize
+file список:
+\end_layout
+
+\begin_layout LyX-Code
+param = "file:///var/run/rspamd/some.file";
+\end_layout
+
+\begin_layout Section
+Общие параметры конфигурации
+\end_layout
+
+\begin_layout Standard
+Общие параметры не принадлежат никакой секции и позволяют задавать общие
+ настройки системы.
+\end_layout
+
+\begin_layout Itemize
+pidfile - путь до PID-файла:
+\end_layout
+
+\begin_layout LyX-Code
+pidfile = "/var/run/rspamd.pid";
+\end_layout
+
+\begin_layout Itemize
+statfile_pool_size - размер пула файлов статистики в памяти.
+ Может быть с суффиксом, определяющим единицы измерение (по умолчанию байты):
+ K - килобайты, M - мегабайты, G - гигабайты.
+\end_layout
+
+\begin_layout LyX-Code
+statfile_pool_size = 40M;
+\end_layout
+
+\begin_layout Itemize
+raw_mode - если этот параметр равен
+\begin_inset Quotes eld
+\end_inset
+
+yes
+\begin_inset Quotes erd
+\end_inset
+
+, то rspamd не осуществляет перекодировку сообщений в utf8, в этом режиме
+ проверка сообщений осуществляется быстрее, но при этом одинаковые сообщения
+ в разных кодировках будут обрабатываться как разные.
+\end_layout
+
+\begin_layout LyX-Code
+raw_mode = yes;
+\end_layout
+
+\begin_layout Itemize
+filters - строка, содержащая список включенных модулей, имена модулей разделяютс
+я запятыми и/или пробелами.
+\end_layout
+
+\begin_layout LyX-Code
+filters = "surbl,regexp,chartable,emails";
+\end_layout
+
+\begin_layout Section
+Настройка процессов
+\end_layout
+
+\begin_layout Standard
+Данные секции служат для определения параметров рабочих процессов.
+ Общие параметры рабочего процесса:
+\end_layout
+
+\begin_layout Itemize
+type - тип рабочего процесса:
+\end_layout
+
+\begin_deeper
+\begin_layout Itemize
+normal - обычный процесс обработки сообщений
+\end_layout
+
+\begin_layout Itemize
+controller - управляющий процесс
+\end_layout
+
+\begin_layout Itemize
+lmtp - процесс обработки сообщений по протоколу lmtp
+\end_layout
+
+\begin_layout Itemize
+fuzzy - хранилище хешей
+\end_layout
+
+\end_deeper
+\begin_layout LyX-Code
+type = "normal";
+\end_layout
+
+\begin_layout Itemize
+bind_socket - параметры слушающего сокета процесса, может определять либо
+ tcp сокет, либо unix сокет:
+\end_layout
+
+\begin_deeper
+\begin_layout Itemize
+host:port - осуществляет bind на указанные host и port
+\end_layout
+
+\begin_layout Itemize
+*:port - осуществляет bind на указанные port на всех локальных адресах
+\end_layout
+
+\begin_layout Itemize
+/path/to/socket - осуществляет bind на указанный unix socket
+\end_layout
+
+\end_deeper
+\begin_layout LyX-Code
+bind_socket = localhost:11334;
+\end_layout
+
+\begin_layout Itemize
+count - количество процессов данного типа.
+ По умолчанию это число равно числу логических процессоров в системе.
+\end_layout
+
+\begin_layout LyX-Code
+count = 1;
+\end_layout
+
+\begin_layout Standard
+Для процессов типа
+\begin_inset Quotes eld
+\end_inset
+
+controller
+\begin_inset Quotes erd
+\end_inset
+
+ можно также указать пароль для привиллегированных команд параметром password,
+ а для процессов типа
+\begin_inset Quotes eld
+\end_inset
+
+fuzzy
+\begin_inset Quotes erd
+\end_inset
+
+ необходимо указать путь к файлу, который будет использован как хранилище
+ хешей параметром hashfile.
+ Пример настройки рабочих процессов:
+\end_layout
+
+\begin_layout LyX-Code
+worker {
+\end_layout
+
+\begin_deeper
+\begin_layout LyX-Code
+ type = "normal";
+\end_layout
+
+\begin_layout LyX-Code
+ count = 1;
+\end_layout
+
+\begin_layout LyX-Code
+ bind_socket = *:11333;
+\end_layout
+
+\end_deeper
+\begin_layout LyX-Code
+};
+\end_layout
+
+\begin_layout LyX-Code
+
+\end_layout
+
+\begin_layout LyX-Code
+worker {
+\end_layout
+
+\begin_deeper
+\begin_layout LyX-Code
+ type = "controller";
+\end_layout
+
+\begin_layout LyX-Code
+ bind_socket = localhost:11334;
+\end_layout
+
+\begin_layout LyX-Code
+ count = 1;
+\end_layout
+
+\begin_layout LyX-Code
+ password = "q1";
+\end_layout
+
+\end_deeper
+\begin_layout LyX-Code
+};
+\end_layout
+
+\begin_layout LyX-Code
+worker {
+\end_layout
+
+\begin_deeper
+\begin_layout LyX-Code
+ type = "fuzzy";
+\end_layout
+
+\begin_layout LyX-Code
+ bind_socket = localhost:11335;
+\end_layout
+
+\begin_layout LyX-Code
+ count = 1;
+\end_layout
+
+\begin_layout LyX-Code
+ hashfile = "/tmp/fuzzy.db";
+\end_layout
+
+\end_deeper
+\begin_layout LyX-Code
+};
+\end_layout
+
+\begin_layout Section
+Настройки журналирования
+\end_layout
+
+\begin_layout Standard
+Данные настройки определяют тип журналирования и его параметры.
+\end_layout
+
+\begin_layout Itemize
+log_type - тип журналирования:
+\end_layout
+
+\begin_deeper
+\begin_layout Itemize
+console - журналирование в stderr
+\end_layout
+
+\begin_layout Itemize
+syslog - журналирование через syslog
+\end_layout
+
+\begin_layout Itemize
+file - журналирование в файл
+\end_layout
+
+\end_deeper
+\begin_layout LyX-Code
+log_type = console;
+\end_layout
+
+\begin_layout Itemize
+log_level - уровень ведения журнала
+\end_layout
+
+\begin_deeper
+\begin_layout Itemize
+DEBUG - журналирование отладочной информации
+\end_layout
+
+\begin_layout Itemize
+INFO - журналирование информационных событий
+\end_layout
+
+\begin_layout Itemize
+WARN - журналирование только предупреждений
+\end_layout
+
+\begin_layout Itemize
+ERROR - журналирование только ошибок
+\end_layout
+
+\end_deeper
+\begin_layout LyX-Code
+log_level = INFO;
+\end_layout
+
+\begin_layout Itemize
+log_facility - используется для журналирования в syslog и определяет назначение
+ сообщений.
+ Более подробно об этом можно узнать из man syslog.
+\end_layout
+
+\begin_layout LyX-Code
+log_facility = "LOG_MAIL";
+\end_layout
+
+\begin_layout Itemize
+log_file - используется для журналирования в файл и путь к файлу журнала.
+\end_layout
+
+\begin_layout LyX-Code
+log_file = "/var/log/rspamd.log";
+\end_layout
+
+\begin_layout Standard
+Пример настройки журналирования:
+\end_layout
+
+\begin_layout LyX-Code
+logging {
+\end_layout
+
+\begin_deeper
+\begin_layout LyX-Code
+ log_type = file;
+\end_layout
+
+\begin_layout LyX-Code
+ log_level = INFO;
+\end_layout
+
+\begin_layout LyX-Code
+ log_file = "/var/log/rspamd.log"
+\end_layout
+
+\end_deeper
+\begin_layout LyX-Code
+};
+\end_layout
+
+\begin_layout Section
+Настройки метрики
+\end_layout
+
+\begin_layout Standard
+Для настроек метрик используются секции
+\begin_inset Quotes eld
+\end_inset
+
+metric
+\begin_inset Quotes erd
+\end_inset
+
+.
+ Основные параметры метрик:
+\end_layout
+
+\begin_layout Itemize
+name - имя метрики.
+\end_layout
+
+\begin_layout LyX-Code
+name = "default";
+\end_layout
+
+\begin_layout Itemize
+required_score - минимальное число очков, необходимое, чтобы сообщение считалось
+ спамом по данной метрике.
+\end_layout
+
+\begin_layout LyX-Code
+required_score = 10;
+\end_layout
+
+\begin_layout Itemize
+cache_file - путь до файла, содержащего кеш символов метрики (используется,
+ чтобы сохранить статистику
+\begin_inset Quotes eld
+\end_inset
+
+удобности
+\begin_inset Quotes erd
+\end_inset
+
+ символов метрики, чтобы при перезапуске rspamd не терять накопленных данных).
+\end_layout
+
+\begin_layout LyX-Code
+cache_file = "/var/run/rspamd/metric.cache";
+\end_layout
+
+\begin_layout Standard
+Пример настройки метрики:
+\end_layout
+
+\begin_layout LyX-Code
+metric {
+\end_layout
+
+\begin_deeper
+\begin_layout LyX-Code
+ name = "default";
+\end_layout
+
+\begin_layout LyX-Code
+ required_score = 10.1;
+\end_layout
+
+\begin_layout LyX-Code
+ cache_file = "/tmp/symbols.cache";
+\end_layout
+
+\end_deeper
+\begin_layout LyX-Code
+};
+\end_layout
+
+\begin_layout Section
+Настройка классификаторов
+\end_layout
+
+\begin_layout Standard
+Для настройки классификаторов используются секции
+\begin_inset Quotes eld
+\end_inset
+
+classifier
+\begin_inset Quotes erd
+\end_inset
+
+.
+ Общие настройки классфикатора:
+\end_layout
+
+\begin_layout Itemize
+type - алгоритм классификатора (в настоящее время определен только
+\begin_inset Quotes eld
+\end_inset
+
+winnow
+\begin_inset Quotes erd
+\end_inset
+
+).
+\end_layout
+
+\begin_layout LyX-Code
+type = "winnow";
+\end_layout
+
+\begin_layout Itemize
+tokenizer - алгоритм разбиения сообщения на токены (в настоящее время определен
+ только
+\begin_inset Quotes eld
+\end_inset
+
+osb-text
+\begin_inset Quotes erd
+\end_inset
+
+).
+\end_layout
+
+\begin_layout LyX-Code
+tokenizer = "osb-text";
+\end_layout
+
+\begin_layout Standard
+Также каждый классификатор может содержать определения классов и соответствующих
+ им файлов токенов.
+ Для этого используется подсекция statfile, содержащая следующие параметры:
+\end_layout
+
+\begin_layout Itemize
+symbol - имя класса и имя символа, используемого для данного класса.
+\end_layout
+
+\begin_layout LyX-Code
+symbol = "WINNOW_SPAM";
+\end_layout
+
+\begin_layout Itemize
+path - путь до файла.
+\end_layout
+
+\begin_layout LyX-Code
+path = "/var/run/rspamd/winnow.spam";
+\end_layout
+
+\begin_layout Itemize
+size - размер данного файла.
+ Также может иметь суффикс размерности.
+\end_layout
+
+\begin_layout LyX-Code
+size = 100M;
+\end_layout
+
+\begin_layout Standard
+Внутри каждого определения класса можно использовать подсекцию autolearn,
+ определяющую условия, при которых происходит автоматическое обучение данного
+ класса.
+ Секция имеет следующие параметры:
+\end_layout
+
+\begin_layout Itemize
+min_mark - минимальное число очков, при котором осуществляется обучение.
+\end_layout
+
+\begin_layout LyX-Code
+min_mark = 10.1;
+\end_layout
+
+\begin_layout Itemize
+max_mark - максимальное число очков, при котором осуществляется обучение.
+\end_layout
+
+\begin_layout LyX-Code
+max_mark = 0.1;
+\end_layout
+
+\begin_layout Standard
+Автообучение происходит, если данное сообщение отвечает данным критериям.
+ То есть, логично обучать класификатор HAM сообщениями, указав максимальное
+ количество очков, близкое к нулю и SPAM сообщениями, указав минимальное
+ число очков, близкое к срабатыванию триггера SPAM для данной метрики.
+ Таким образом, классифицируемые как спам сообщения обучают класс SPAM,
+ а классифицируемые как HAM (то есть, на них не сработали правила метрики)
+ - обучают класс HAM.
+\end_layout
+
+\begin_layout Standard
+Пример определения классификатора:
+\end_layout
+
+\begin_layout LyX-Code
+classifier {
+\end_layout
+
+\begin_deeper
+\begin_layout LyX-Code
+type = "winnow";
+\end_layout
+
+\begin_layout LyX-Code
+tokenizer = "osb-text";
+\end_layout
+
+\end_deeper
+\begin_layout LyX-Code
+
+\end_layout
+
+\begin_deeper
+\begin_layout LyX-Code
+statfile {
+\end_layout
+
+\begin_deeper
+\begin_layout LyX-Code
+symbol = "WINNOW_SPAM";
+\end_layout
+
+\begin_layout LyX-Code
+path = "/tmp/test.spam";
+\end_layout
+
+\begin_layout LyX-Code
+size = 10M;
+\end_layout
+
+\begin_layout LyX-Code
+
+\end_layout
+
+\begin_layout LyX-Code
+autolearn {
+\end_layout
+
+\begin_deeper
+\begin_layout LyX-Code
+min_mark = 10.0;
+\end_layout
+
+\end_deeper
+\begin_layout LyX-Code
+};
+\end_layout
+
+\end_deeper
+\begin_layout LyX-Code
+};
+\end_layout
+
+\begin_layout LyX-Code
+
+\end_layout
+
+\begin_layout LyX-Code
+statfile {
+\end_layout
+
+\begin_deeper
+\begin_layout LyX-Code
+symbol = "WINNOW_HAM";
+\end_layout
+
+\begin_layout LyX-Code
+path = "/tmp/test.ham";
+\end_layout
+
+\begin_layout LyX-Code
+size = 10M;
+\end_layout
+
+\begin_layout LyX-Code
+
+\end_layout
+
+\begin_layout LyX-Code
+autolearn {
+\end_layout
+
+\begin_deeper
+\begin_layout LyX-Code
+max_mark = 0.1;
+\end_layout
+
+\end_deeper
+\begin_layout LyX-Code
+};
+\end_layout
+
+\end_deeper
+\begin_layout LyX-Code
+};
+\end_layout
+
+\end_deeper
+\begin_layout LyX-Code
+};
+\end_layout
+
+\begin_layout Section
+Настройка коэффициентов символов
+\end_layout
+
+\begin_layout Standard
+Для настройки коэффициентов применяется секция
+\begin_inset Quotes eld
+\end_inset
+
+factors
+\begin_inset Quotes erd
+\end_inset
+
+.
+ Данная секция состоит из набора определений вида
+\end_layout
+
+\begin_layout LyX-Code
+"СИМВОЛ" = вес;
+\end_layout
+
+\begin_layout Standard
+например:
+\end_layout
+
+\begin_layout LyX-Code
+"R_UNDISC_RCPT" = 5;
+\end_layout
+
+\begin_layout LyX-Code
+"MISSING_MID" = 3;
+\end_layout
+
+\begin_layout LyX-Code
+"R_RCVD_SPAMBOTS" = 3;
+\end_layout
+
+\begin_layout LyX-Code
+"R_TO_SEEMS_AUTO" = 3;
+\end_layout
+
+\begin_layout LyX-Code
+"R_MISSING_CHARSET" = 5;
+\end_layout
+
+\begin_layout Chapter
+Настройка модулей
+\end_layout
+
+\begin_layout Section
+Настройка модуля surbl
+\end_layout
+
+\begin_layout Standard
+Модуль surbl служит для проверки URL'ей в письме на различных
+\begin_inset Quotes eld
+\end_inset
+
+черных
+\begin_inset Quotes erd
+\end_inset
+
+ списках.
+ Модуль делает следующее: для каждого из url, найденных в сообщении, извлекает
+ доменный компонент (2-го или 3-го уровня), добавляет суффикс имени surbl
+ и делает dns запрос.
+ При успешном определении такого имени добавляется символ.
+ Пример работы:
+\end_layout
+
+\begin_layout LyX-Code
+URL (http://some.test.ru/index.html) -> test.ru + (insecure-bl.rambler.ru) ->
+\end_layout
+
+\begin_layout LyX-Code
+resolve test.ru.insecure-bl.rambler.ru -> 127.0.0.1 -> add symbol
+\end_layout
+
+\begin_layout Standard
+Параметры настройки:
+\end_layout
+
+\begin_layout LyX-Code
+.module 'surbl' {
+\end_layout
+
+\begin_deeper
+\begin_layout LyX-Code
+ # Определение суффикса SURBL
+\end_layout
+
+\begin_layout LyX-Code
+ # Символы '%b' заменяются на значение определенного бита
+\end_layout
+
+\begin_layout LyX-Code
+ suffix_%b_SURBL_MULTI = "multi.surbl.org";
+\end_layout
+
+\begin_layout LyX-Code
+
+\end_layout
+
+\begin_layout LyX-Code
+ # Суффикс для каждого из бит
+\end_layout
+
+\begin_layout LyX-Code
+ bit_2 = "SC"; # sc.surbl.org
+\end_layout
+
+\begin_layout LyX-Code
+ bit_4 = "WS"; # ws.surbl.org
+\end_layout
+
+\begin_layout LyX-Code
+ bit_8 = "PH"; # ph.surbl.org
+\end_layout
+
+\begin_layout LyX-Code
+ bit_16 = "OB"; # ob.surbl.org
+\end_layout
+
+\begin_layout LyX-Code
+ bit_32 = "AB"; # ab.surbl.org
+\end_layout
+
+\begin_layout LyX-Code
+ bit_64 = "JP"; # jp.surbl.org
+\end_layout
+
+\begin_layout LyX-Code
+
+\end_layout
+
+\begin_layout LyX-Code
+ # Имя метрики
+\end_layout
+
+\begin_layout LyX-Code
+ metric = "default";
+\end_layout
+
+\begin_layout LyX-Code
+ # Список доменов, для которых необходимо использовать 3 доменных
+\end_layout
+
+\begin_layout LyX-Code
+ # компонента, вместо двух
+\end_layout
+
+\begin_layout LyX-Code
+ 2tld = "file:///etc/rspamd/2tld.inc";
+\end_layout
+
+\begin_layout LyX-Code
+ # Список URL'ей, которые не будут проверяться этим модулем
+\end_layout
+
+\begin_layout LyX-Code
+ whitelist = "file:///etc/rspamd/surbl-whitelist.inc";
+\end_layout
+
+\end_deeper
+\begin_layout LyX-Code
+};
+\end_layout
+
+\begin_layout Standard
+Некоторые пояснения по данной конфигурации.
+ Модуль SURBL может осуществлять проверку битов в полученном от DNS сервера
+ ответе, и вставлять соответствующий символ.
+ Это используется для проверки сразу нескольких списков одним DNS запросе.
+ Тогда ответ сервера содержит списки, в которых встретился данный URL в
+ виде битов адреса.
+ Более подробно с этим можно ознакомиться тут:
+\begin_inset CommandInset href
+LatexCommand href
+name "http://www.surbl.org/lists.html#multi"
+target "http://www.surbl.org/lists.html#multi"
+
+\end_inset
+
+.
+ Список 2tld используется для задания списка доменов, для которых необходимо
+ проверять не два уровня доменного имени, а три.
+ Например, это актуально для виртуальных хостингов или же специальных зон
+ для доменов третьего уровня, например org.ru или pp.ru.
+\end_layout
+
+\begin_layout Section
+Настройка модуля regexp
+\end_layout
+
+\begin_layout Standard
+Модуль regexp является очень важным в работе rspamd, так как определяет
+ все правила фильтрации сообщений по регулярным выражениям.
+ Модуль работает с логическими выражениями из регулярных выражений, поэтому
+ его настройка выглядит достаточно запутанной.
+ Однако, если пользоваться переменными, то логика работы становится более
+ понятной.
+ При настройке самого модуля используются простые директивы вида:
+\end_layout
+
+\begin_layout Code
+ИМЯ_СИМВОЛА = "логическое выражение"
+\end_layout
+
+\begin_layout Standard
+Само логическое выражение содержит различные регулярные выражения и функции,
+ объединенные символами логики:
+\end_layout
+
+\begin_layout Itemize
+& - логическое
+\begin_inset Quotes eld
+\end_inset
+
+\begin_inset Quotes erd
+\end_inset
+
+
+\end_layout
+
+\begin_layout Itemize
+| - логическое
+\begin_inset Quotes eld
+\end_inset
+
+ИЛИ
+\begin_inset Quotes erd
+\end_inset
+
+
+\end_layout
+
+\begin_layout Itemize
+! - логическое отрицание
+\end_layout
+
+\begin_layout Standard
+Приоритет операций может изменяться скобками, например:
+\end_layout
+
+\begin_layout LyX-Code
+A & B | C - выполняется слева направо A & B затем | C
+\end_layout
+
+\begin_layout LyX-Code
+A & (B | C) - выполняется как (B | C) затем & A
+\end_layout
+
+\begin_layout Standard
+Сами регулярные выражения совместимы с perl regular expressions.
+ Их синтаксис можно изучить в соответствующей литературе:
+\begin_inset CommandInset href
+LatexCommand href
+name "http://perldoc.perl.org/perlre.html"
+target "http://perldoc.perl.org/perlre.html"
+
+\end_inset
+
+.
+ У rspamd есть дополнительные флаги, определяющие, в какой части сообщения
+ искать заданное регулярное выражение:
+\end_layout
+
+\begin_layout Itemize
+r - "сырой" незакодированный в utf8 regexp
+\end_layout
+
+\begin_layout Itemize
+H - ищет по заголовкам сообщения
+\end_layout
+
+\begin_layout Itemize
+M - ищет по всему сообщению (в "сыром" виде, то есть без mime декодинга)
+
+\end_layout
+
+\begin_layout Itemize
+P - ищет по всем текстовым mime частям
+\end_layout
+
+\begin_layout Itemize
+U - ищет по url
+\end_layout
+
+\begin_layout Itemize
+X - ищет по "сырым" хедерам (опять же без декодирования)
+\end_layout
+
+\begin_layout Standard
+Если в регулярном выражении встречаются символы двойной кавычки (
+\begin_inset Quotes eld
+\end_inset
+
+) или же слэша (/), то их необходимо экранировать обратным слэшем (при этом
+ сам обратный слэш экранировать необязательно):
+\end_layout
+
+\begin_layout LyX-Code
+
+\backslash
+"
+\backslash
+/
+\end_layout
+
+\begin_layout Standard
+Для поиска по заголовкам формат регулярного выражения несколько меняется:
+\end_layout
+
+\begin_layout LyX-Code
+Имя_заголовка=/регулярное_выражение/H
+\end_layout
+
+\begin_layout Standard
+При поиске по заголовкам происходит поиск заголовков с таким именем и сравнение
+ их значений с регулярным выражением, пока это выражение не будет найдено,
+ либо пока не будут проверены все заголовки с таким именем.
+ Для multipart сообщений происходит поиск заголовков по всем частям сообщения.
+ Это справедливо для всех функций, работающих с заголовками.
+ Поиск по
+\begin_inset Quotes eld
+\end_inset
+
+сырым
+\begin_inset Quotes erd
+\end_inset
+
+ заголовкам происходит без учета mime частей - только по заголовкам самого
+ сообщения.
+ При этом, хотя и не происходит декодирования заголовков, но происходит
+ их де-фолдинг (фолдинг - перенос заголовков по строчкам).
+ Модуль regexp также может использовать внутри логических выражений встроенные
+ функции rspamd.
+ Встроенные функции всегда возвращат логическое значение (истина или ложь)
+ и могут принимать аргументы (в том числе аргументы, являющиеся логическими
+ выражениями).
+ Список встроенных функций:
+\end_layout
+
+\begin_layout Itemize
+header_exists - принимает в качестве аргумента имя хедера, возвращает true,
+ если такой заголовок существует
+\end_layout
+
+\begin_layout Itemize
+compare_parts_distance - принимает в качестве аргумента число от 0 до 100,
+ которое отражает разницу в процентах между частями письма.
+ Функция работает с сообщениями, содержащими 2 текстовые части (text/plain
+ и text/html) и возвращает true тогда, когда эти части различаются более
+ чем на n процентов.
+ Если аргумент не указан, то по умолчанию ищется различие в 100% (полностью
+ разные части).
+\end_layout
+
+\begin_layout Itemize
+compare_transfer_encoding - сравнивает Content-Transfer-Encoding с заданной
+ строкой
+\end_layout
+
+\begin_layout Itemize
+content_type_compare_param - сравнивает параметр content-type заголовка
+ с регулярным выражением или строкой:
+\end_layout
+
+\begin_layout LyX-Code
+content_type_compare_param(Charset, /windows-
+\backslash
+d+/)
+\end_layout
+
+\begin_layout LyX-Code
+content_type_compare_param(Charset, ascii)
+\end_layout
+
+\begin_layout Itemize
+content_type_has_param - проверяет, есть ли в заголовке content-type определенны
+й параметр
+\end_layout
+
+\begin_layout Itemize
+content_type_is_subtype - сравнивает подтип content-type с регулярным выражением
+ или строкой
+\end_layout
+
+\begin_layout Itemize
+content_type_is_type - сравнивает тип content-type с регулярным выражением
+ или строкой
+\end_layout
+
+\begin_layout LyX-Code
+content_type_is_type(text)
+\end_layout
+
+\begin_layout LyX-Code
+content_type_is_subtype(/?.html/)
+\end_layout
+
+\begin_layout Itemize
+regexp_match_number - принимает в качестве первого параметра число, которое
+ означает порог сработавших регэкспов и список регэкспов или функций, которые
+ должны проверяться.
+ Если число сработавших регэкспов или функций больше порога, функция возвращает
+ TRUE, иначе - FALSE, например:
+\end_layout
+
+\begin_layout LyX-Code
+regexp_match_number(2, ${__RE1}, ${__RE2}, header_exists(Subject))
+\end_layout
+
+\begin_layout Itemize
+has_only_html_part - функция возвращает TRUE, если в сообщении есть только
+ одна HTML часть
+\end_layout
+
+\begin_layout Itemize
+compare_recipients_distance - вычисляет процент схожих получателей письма.
+ Принимает аргумент - порог в процентах похожести.
+
+\end_layout
+
+\begin_layout Itemize
+is_recipients_sorted - возвращает TRUE, если список получателей сортирован
+ (работает только если число получателей >= 5).
+
+\end_layout
+
+\begin_layout Itemize
+is_html_balanced - возвращает TRUE, если теги всех html частей сбалансированы
+
+\end_layout
+
+\begin_layout Itemize
+has_html_tag - возвращает TRUE, если заданный html тег найден
+\end_layout
+
+\begin_layout Standard
+Данные функции были созданы для решения задач, которые сложно или же невозможно
+ решить при помощи обычных регулярных выражений.
+ При конфигурации модуля regexp целесообразно определить все логические
+ выражения в отдельных переменных, подключить их при помощи директивы .include
+ и задавать символы как:
+\end_layout
+
+\begin_layout LyX-Code
+СИМВОЛ="${переменная}";
+\end_layout
+
+\begin_layout Standard
+иначе конфигурация модуля будет практически нечитаемой из-за обилия регулярных
+ выражений.
+\end_layout
+
+\begin_layout Chapter
+Cтатистические алгоритмы
+\end_layout
+
+\begin_layout Section
+Winnow и OSB
+\end_layout
+
+\begin_layout Standard
+В rspamd используется алгоритм ортогональных разреженных биграмм (OSB),
+ который основан на следующем принципе:
+\end_layout
+
+\begin_layout Code
+\begin_inset listings
+inline false
+status open
+
+\begin_layout Quotation
+
+\end_layout
+
+\begin_layout Quotation
+
+\end_layout
+
+\begin_layout Quotation
+
+ н -----------------------------------
+\end_layout
+
+\begin_layout Quotation
+
+ а -----------------------------------
+\end_layout
+
+\begin_layout Quotation
+
+ б -----------------------------------
+\end_layout
+
+\begin_layout Quotation
+
+ о | w1 | w2 | w3 | w4 | w5 |
+\end_layout
+
+\begin_layout Quotation
+
+ р | | | | | | --> выходные токены
+\end_layout
+
+\begin_layout Quotation
+
+ ы -----------------------------------
+\end_layout
+
+\begin_layout Quotation
+
+ / Текущий набор хешей и весов
+\end_layout
+
+\begin_layout Quotation
+
+ /
+\end_layout
+
+\begin_layout Quotation
+
+Входные токены
+\end_layout
+
+\end_inset
+
+
+\end_layout
+
+\begin_layout Standard
+То есть, процесс преобразования можно представить следующим образом: для
+ каждого набора весов (w1..w5) составляется набор хешей.
+ Токены образуются из текста.
+ Например, возьмем некое письмо и наложим на него окно:
+\end_layout
+
+\begin_layout LyX-Code
+"Мама мыла раму."
+\end_layout
+
+\begin_layout LyX-Code
+|________|
+\end_layout
+
+\begin_layout Standard
+В данном окне создаются 2 токена:
+\end_layout
+
+\begin_layout Standard
+h("Мама"), h("мыла"), где h - хеш функция.
+\end_layout
+
+\begin_layout Standard
+Дальше окно двигается вправо на один токен и опять создаются 2 токена: h("мыла")
+, h("раму")
+\end_layout
+
+\begin_layout Standard
+В rspamd используется окно в 5 токенов и используются пары:
+\end_layout
+
+\begin_layout LyX-Code
+1 - 5 -- h1
+\end_layout
+
+\begin_layout LyX-Code
+2 - 5 -- h2
+\end_layout
+
+\begin_layout LyX-Code
+3 - 5 -- h3
+\end_layout
+
+\begin_layout LyX-Code
+4 - 5 -- h4
+\end_layout
+
+\begin_layout Standard
+Каждый такой токен состоит из двух хешей (h1 и h2).
+ То есть каждое слово текста может давать до 5-ти токенов.
+ Это делается для того, чтобы в статистических алгоритмах учитывать не индивидуа
+льные слова, и их сочетания, чтобы уменьшить ошибку.
+\end_layout
+
+\begin_layout Standard
+После этого мы должны вычислить принадлежность потока выходных токенов к
+ некоторому классу.
+ Для этого используется алгоритм Winnow.
+ Идея алгоритма очень проста:
+\end_layout
+
+\begin_layout Enumerate
+Каждый возможный входной токен имеет вес 1.0 (то есть, нас интересуют только
+ те токены, которые не равны 1.0)
+\end_layout
+
+\begin_layout Enumerate
+Для обучения проделываем следующие шаги:
+\end_layout
+
+\begin_deeper
+\begin_layout Enumerate
+генерируем набор токенов путем OSB алгоритма
+\end_layout
+
+\begin_layout Enumerate
+удаляем все дупликаты
+\end_layout
+
+\begin_layout Enumerate
+если данный входной набор принадлежит классу (например, спам или неспам),
+ то умножаем вес каждого встреченного токена на т.н.
+ Promotion Constant, которая равна 1,23
+\end_layout
+
+\begin_layout Enumerate
+если данный входной набор не принадлежит классу, то умножаем каждый найденный
+ токен на Demotion Constant в данном классе, которая равна 0,83
+\end_layout
+
+\begin_layout Enumerate
+абсолютно неважно, сколько раз встречался данный токен во входном потоке,
+ мы его умножаем на promotion или demotion только один раз
+\end_layout
+
+\end_deeper
+\begin_layout Enumerate
+Для классификации потока мы поступаем следующим образом:
+\end_layout
+
+\begin_deeper
+\begin_layout Enumerate
+генерируем набор токенов путем OSB алгоритма
+\end_layout
+
+\begin_layout Enumerate
+удаляем все дупликаты
+\end_layout
+
+\begin_layout Enumerate
+суммируем веса всех токенов, найденных в каждом из файлов данных статистики
+ (при этом те токены, которые мы не нашли, имеют вес 1)
+\end_layout
+
+\begin_layout Enumerate
+затем мы делим полученную сумму на число токенов и смотрим, какой из классов
+ (файлов данных) набрал больше очков и делаем заключение о принадлежности
+ входного текста к классу
+\end_layout
+
+\end_deeper
+\begin_layout Standard
+Файлы данных статистики представляют собой следующие структуры:
+\end_layout
+
+\begin_layout LyX-Code
+{
+\end_layout
+
+\begin_layout LyX-Code
+Header,
+\end_layout
+
+\begin_layout LyX-Code
+{ feature_block1..feature_blockN }
+\end_layout
+
+\begin_layout LyX-Code
+}
+\end_layout
+
+\begin_layout Standard
+Заголовок файла очень прост:
+\end_layout
+
+\begin_layout LyX-Code
+struct {
+\end_layout
+
+\begin_deeper
+\begin_layout LyX-Code
+char magic[3] = { 'r', 's', 'd' };
+\end_layout
+
+\begin_layout LyX-Code
+u_char version[2] = { '1', '0' };
+\end_layout
+
+\begin_layout LyX-Code
+uint64_t create_time;
+\end_layout
+
+\end_deeper
+\begin_layout LyX-Code
+}
+\end_layout
+
+\begin_layout Standard
+Каждый feature_block состоит из 4-х полей:
+\end_layout
+
+\begin_layout LyX-Code
+struct {
+\end_layout
+
+\begin_deeper
+\begin_layout LyX-Code
+uint32_t hash1;
+\end_layout
+
+\begin_layout LyX-Code
+uint32_t hash2;
+\end_layout
+
+\begin_layout LyX-Code
+float value;
+\end_layout
+
+\begin_layout LyX-Code
+uint32_t last_access;
+\end_layout
+
+\end_deeper
+\begin_layout LyX-Code
+}
+\end_layout
+
+\begin_layout Standard
+Итого 16 байт на каждый feature.
+ 0-е значения показывают свободную ячейку.
+ Значение hash1 используется в качестве индекса:
+\end_layout
+
+\begin_layout LyX-Code
+idx = hash1 % filesize;
+\end_layout
+
+\begin_layout Standard
+Где filesize - размер в количестве feature_block'ов.
+ При этом данный токен должен помещаться в заданную ячейку или ячейку за
+ ним.
+ При этом образуется цепочка токенов:
+\end_layout
+
+\begin_layout Standard
+\begin_inset listings
+inline false
+status open
+
+\begin_layout Plain Layout
+
+idx
+\end_layout
+
+\begin_layout Plain Layout
+
+
+\backslash
+
+\end_layout
+
+\begin_layout Plain Layout
+
+| занят | занят | занят | свободен |
+\end_layout
+
+\begin_layout Plain Layout
+
+
+\backslash
+-----^
+\backslash
+-----^
+\backslash
+-----^
+\end_layout
+
+\end_inset
+
+При этом, длина такой цепочки должна быть лимитирована некоторым разумным
+ числом, например 128.
+ Тогда максимальное время доступа будет не более 128-и итераций.
+ Если мы не нашли за 128 итераций свободную ячейку, то мы можем поместить
+ новый токен на место того, который меньше всего использовался (min (last_access
+)).
+ При этом при доступе к ячейке необходимо обновлять last_access:
+\end_layout
+
+\begin_layout Code
+last_access = now - creation_time.
+
+\end_layout
+
+\begin_layout Standard
+Такая организация позволяет замещать только наименее используемые токены.
+\end_layout
+
+\begin_layout Chapter
+Протокол rspamc
+\end_layout
+
+\begin_layout Standard
+Формат ответа:
+\end_layout
+
+\begin_layout LyX-Code
+SPAMD/1.1 0 EX_OK
+\end_layout
+
+\begin_layout LyX-Code
+
+\backslash
+ /
+\backslash
+/
+\end_layout
+
+\begin_layout LyX-Code
+Версия Код ошибки
+\end_layout
+
+\begin_layout LyX-Code
+Spam: False ; 2 / 5
+\end_layout
+
+\begin_layout Standard
+Это формат совместимости с sa-spamd (без метрик).
+ Новый формат ответа:
+\end_layout
+
+\begin_layout LyX-Code
+RSPAMD/1.0 0 EX_OK
+\end_layout
+
+\begin_layout LyX-Code
+Metric: Name; Spam_Result; Spam_Mark / Spam_Mark_Required
+\end_layout
+
+\begin_layout LyX-Code
+Metric: Name2 ; Spam_Result2 ; Spam_Mark2 / Spam_Mark_Required2
+\end_layout
+
+\begin_layout Standard
+Заголовков типа metric может быть несколько.
+ Формат вывода символов:
+\end_layout
+
+\begin_layout LyX-Code
+SYMBOL1, SYMBOL2, SYMBOL3 -- формат совместимости с sa-spamd
+\end_layout
+
+\begin_layout LyX-Code
+Symbol: Name; Param1,Param2,Param3 -- формат rspamd
+\end_layout
+
+\begin_layout Standard
+Формат ответа зависит от формата запроса:
+\end_layout
+
+\begin_layout LyX-Code
+PROCESS SPAMC/1.2
+\end_layout
+
+\begin_layout LyX-Code
+
+\backslash
+ /
+\backslash
+ /
+\end_layout
+
+\begin_layout LyX-Code
+Команда Версия
+\end_layout
+
+\begin_layout Standard
+В любом из режимов работы поддерживаются следующие заголовки:
+\end_layout
+
+\begin_layout Itemize
+Content-Length - длина сообщения
+\end_layout
+
+\begin_layout Itemize
+Helo - HELO, полученный от клиента
+\end_layout
+
+\begin_layout Itemize
+From - MAIL FROM
+\end_layout
+
+\begin_layout Itemize
+IP - IP клиента
+\end_layout
+
+\begin_layout Itemize
+Recipient-Number - число реципиентов
+\end_layout
+
+\begin_layout Itemize
+Rcpt - реципиент
+\end_layout
+
+\begin_layout Itemize
+Queue-ID - идентификатор очереди
+\end_layout
+
+\begin_layout Standard
+Эти значения могут использоваться в фильтрах rspamd.
+\end_layout
+
+\begin_layout Chapter
+Клиент rspamc
+\end_layout
+
+\begin_layout Standard
+Клиент rspamc представляет собой программу, написанную на perl и предназначенную
+ для работы с системой rspamd.
+ Rspamc принимает следующие аргументы:
+\end_layout
+
+\begin_layout Itemize
+-с: определяет путь к конфигурационному файлу rspamd, используется для работы
+ с локальным rspamd
+\end_layout
+
+\begin_layout Itemize
+-h: определяет адрес удаленного rspamd сервера
+\end_layout
+
+\begin_layout Itemize
+-p: определяет порт для удаленного rspamd сервера
+\end_layout
+
+\begin_layout Itemize
+-P: определяет пароль для работы с привиллегированными командами rspamd
+\end_layout
+
+\begin_layout Itemize
+-s: определяет имя символа для обучения классификатора
+\end_layout
+
+\begin_layout Standard
+Последним аргументом rspamc принимает команду.
+ Если команда не задана, то используется команда SYMBOLS.
+ Команды, принимаемые rspamc:
+\end_layout
+
+\begin_layout Itemize
+команды по обработке сообщений:
+\end_layout
+
+\begin_deeper
+\begin_layout Itemize
+symbols - по данной команде проверяется сообщение, переданное через stdin
+ rspamc
+\end_layout
+
+\begin_layout Itemize
+check - по данной команде выводится только результат по метрикам без символов
+\end_layout
+
+\begin_layout Itemize
+process - возвращает не только символы, но и исходное сообщение
+\end_layout
+
+\begin_layout Itemize
+urls - выводит все найденные url'и
+\end_layout
+
+\begin_layout Itemize
+emails - выводит все найденные адреса e-mail в сообщении
+\end_layout
+
+\end_deeper
+\begin_layout Itemize
+команды по работе с управляющим интерфейсом
+\end_layout
+
+\begin_deeper
+\begin_layout Itemize
+stat - выводит статистику работы
+\end_layout
+
+\begin_layout Itemize
+learn - обучает классификатор по определенному классу (указанному опцией
+ -s)
+\end_layout
+
+\begin_layout Itemize
+shutdown - останавливает систему rspamd
+\end_layout
+
+\begin_layout Itemize
+uptime - выводит время работы rspamd
+\end_layout
+
+\begin_layout Itemize
+counters - выводит значения счетчиков символов
+\end_layout
+
+\begin_layout Itemize
+fuzzy_add - добавляет fuzzy hash в хранилище
+\end_layout
+
+\begin_layout Itemize
+fuzzy_del - удаляет fuzzy_hash из хранилища
+\end_layout
+
+\end_deeper
+\begin_layout Chapter
+LUA API плагинов
+\end_layout
+
+\begin_layout Standard
+Rspamd позволяет реализовывать различную логику в виде lua плагинов, для
+ чего используется директива modules.
+ Данная директива позволяет задавать пути к каталогам, содержащим скрипты
+ на lua:
+\end_layout
+
+\begin_layout LyX-Code
+modules {
+\end_layout
+
+\begin_deeper
+\begin_layout LyX-Code
+module_path =
+\begin_inset Quotes fld
+\end_inset
+
+/some/path/
+\begin_inset Quotes frd
+\end_inset
+
+;
+\end_layout
+
+\end_deeper
+\begin_layout LyX-Code
+};
+\end_layout
+
+\begin_layout Standard
+При инициализации rspamd загружает все файлы вида *.lua и выполняет их (при
+ ошибке в коде плагинов rspamd запускаться не будет, выдавая ошибку конфигурации
+, при указанной опции -t будет проверяться не только синтаксис конфигурационного
+ файла, но и синтаксис плагинов).
+ При этом, определяется глобальная переменная rspamd_config, позволяющая
+ извлекать опции конфигурации и регистрировать правила и соответствующие
+ им символы.
+ Таким образом, каждый lua плагин условно можно разделить на две части:
+ исполняемый код, выполняющий настройку опций модуля, регистрирующий функции
+ правил (callbacks), и собственно обработчики правил.
+
+\end_layout
+
+\begin_layout Section
+Настройка lua модуля
+\end_layout
+
+\begin_layout Standard
+Для извлечения параметров конфигурации и регистрации обработчиков правил
+ применяется глобальная переменная rspamd_config, которая обладает рядом
+ полезных методов:
+\end_layout
+
+\begin_layout Itemize
+get_module_opt (module_name, option_name) - возвращает значение опции option_nam
+e для модуля с именем module_name.
+ То есть, если в конфигурационном файле есть следующая запись:
+\end_layout
+
+\begin_layout LyX-Code
+module 'test' {
+\end_layout
+
+\begin_deeper
+\begin_layout LyX-Code
+param =
+\begin_inset Quotes fld
+\end_inset
+
+value
+\begin_inset Quotes frd
+\end_inset
+
+;
+\end_layout
+
+\end_deeper
+\begin_layout LyX-Code
+};
+\end_layout
+
+\begin_deeper
+\begin_layout Standard
+То вызов rspamd_config:get_module_opt('test', 'param') вернет строку 'value';
+\end_layout
+
+\end_deeper
+\begin_layout Itemize
+get_all_opts (module_name) - возвращает таблицу из всех опций для данного
+ модуля, ключом служит имя опции:
+\end_layout
+
+\begin_layout LyX-Code
+local opts = rspamd_config:get_all_opts('test')
+\end_layout
+
+\begin_layout LyX-Code
+if opts then
+\end_layout
+
+\begin_deeper
+\begin_layout LyX-Code
+var = opts['param']
+\end_layout
+
+\begin_layout LyX-Code
+for k,v in pairs opts do
+\end_layout
+
+\begin_deeper
+\begin_layout LyX-Code
+print (
+\begin_inset Quotes fld
+\end_inset
+
+Param:
+\begin_inset Quotes frd
+\end_inset
+
+ ..
+ k ..
+
+\begin_inset Quotes fld
+\end_inset
+
+ Value:
+\begin_inset Quotes frd
+\end_inset
+
+ ..
+ v)
+\end_layout
+
+\end_deeper
+\begin_layout LyX-Code
+end
+\end_layout
+
+\end_deeper
+\begin_layout LyX-Code
+end
+\end_layout
+
+\begin_layout Itemize
+get_metric (name) - возвращает объект метрики с данным именем
+\end_layout
+
+\begin_layout Standard
+Объект метрики используется для регистрации символов:
+\end_layout
+
+\begin_layout Itemize
+register_symbol (symbol, initial_weight, callback) - symbol определяет имя
+ символа, initial_weight - изначальный вес, callback - строка с именем функции:
+\end_layout
+
+\begin_layout LyX-Code
+local m = rspamd_config:get_metric('default')
+\end_layout
+
+\begin_layout LyX-Code
+if m then
+\end_layout
+
+\begin_deeper
+\begin_layout LyX-Code
+m:register_symbol('TEST', 1.0, 'some_callback')
+\end_layout
+
+\end_deeper
+\begin_layout LyX-Code
+end
+\end_layout
+
+\begin_layout Standard
+После регистрации обработчика символа этот обработчик будет вызываться rspamd
+ обычным образом, используя планировщик символов (это подробно описано в
+ 3.2).
+\end_layout
+
+\begin_layout Section
+Обработчик правила
+\end_layout
+
+\begin_layout Standard
+Обработчик правила - это функция, реализующая логику правила.
+ В качестве параметра она принимает объект task, из которого можно извлечь
+ различную информацию о сообщении.
+ После выполнения логики работы обработчик может вставить символ, используя
+ тот же объект task.
+ Таким образом типичная функция-обработчик выглядит следующим образом:
+\end_layout
+
+\begin_layout LyX-Code
+function some_callback(task)
+\end_layout
+
+\begin_deeper
+\begin_layout LyX-Code
+if some_condition(task) then
+\end_layout
+
+\begin_deeper
+\begin_layout LyX-Code
+task:insert_result(metric, symbol, 1)
+\end_layout
+
+\end_deeper
+\begin_layout LyX-Code
+end
+\end_layout
+
+\end_deeper
+\begin_layout LyX-Code
+end
+\end_layout
+
+\begin_layout Standard
+Функция insert_result принимает в качестве параметров имя метрики, имя символа,
+ вес и необязательный список строковых параметров, которые будут ассоциированы
+ с этим символом.
+ Объект task предоставляет ряд функций, позволяющих создать логику правила
+ фильтрации:
+\end_layout
+
+\begin_layout Itemize
+get_received_headers() - возвращает массив из обработанных заголовков Received
+ в виде таблицы:
+\end_layout
+
+\begin_deeper
+\begin_layout Itemize
+h['from_hostname'] - hostname, откуда получено сообщение
+\end_layout
+
+\begin_layout Itemize
+h['from_ip'] - ip, откуда получено сообщение
+\end_layout
+
+\begin_layout Itemize
+h['real_hostname'] - hostname, распознанное самим релеем
+\end_layout
+
+\begin_layout Itemize
+h['real_ip'] - ip, который соответствует real_hostname
+\end_layout
+
+\begin_layout Itemize
+h['by_hostname'] - hostname самого релея
+\end_layout
+
+\begin_layout Standard
+received заголовки в массиве идут в обратном порядке, то есть, первые релеи
+ письма будут первыми элементами массива
+\end_layout
+
+\end_deeper
+\begin_layout Itemize
+get_raw_headers() - возвращает строку, содержащую все заголовки сообщения
+ в неразобранном виде
+\end_layout
+
+\begin_layout Itemize
+get_text_parts() - возвращает массив объектов типа text_part
+\end_layout
+
+\begin_layout Itemize
+get_urls() - возвращает массив строк, содержащих извлеченные из сообщения
+ URL'и
+\end_layout
+
+\begin_layout Itemize
+get_message() - возвращает объект типа сообщение
+\end_layout
+
+\begin_layout Standard
+Объект
+\begin_inset Quotes fld
+\end_inset
+
+message
+\begin_inset Quotes frd
+\end_inset
+
+ применяется для манипуляций с заголовками:
+\end_layout
+
+\begin_layout Itemize
+get_header(headername) - возвращает массив всех значений заголовков с таким
+ именем (может быть массив из одного элемента, если такой заголовок в сообщении
+ представлен единожды)
+\end_layout
+
+\begin_layout Itemize
+set_header(headername, headervalue) - устанавливает заданный заголовок
+\end_layout
+
+\begin_layout Standard
+Объект text_part предназначен для манипуляций с текстовым содержимым сообщения:
+\end_layout
+
+\begin_layout Itemize
+get_content() - возвращает текстовое содержимое части
+\end_layout
+
+\begin_layout Itemize
+is_html() - возвращает true, если данная часть представляет собой HTML
+\end_layout
+
+\begin_layout Itemize
+is_empty() - возвращает true, если данная часть не содержит текста
+\end_layout
+
+\begin_layout Itemize
+get_fuzzy() - возвращает строку с нечетким хешем для данного сообщения
+\end_layout
+
+\begin_layout Standard
+Пример функции-обработчика:
+\end_layout
+
+\begin_layout LyX-Code
+function received_cb (task)
+\end_layout
+
+\begin_deeper
+\begin_layout LyX-Code
+local recvh = task:get_received_headers()
+\end_layout
+
+\begin_layout LyX-Code
+for _,rh in ipairs(recvh) do
+\end_layout
+
+\begin_deeper
+\begin_layout LyX-Code
+if rh['real_ip'] then
+\end_layout
+
+\begin_deeper
+\begin_layout LyX-Code
+local parts = task:get_text_parts()
+\end_layout
+
+\begin_layout LyX-Code
+for _,part in ipairs(parts) do
+\end_layout
+
+\begin_deeper
+\begin_layout LyX-Code
+if not part:is_empty() then
+\end_layout
+
+\begin_deeper
+\begin_layout LyX-Code
+local text = part:get_content()
+\end_layout
+
+\begin_layout LyX-Code
+if some_filter(text) then
+\end_layout
+
+\begin_layout LyX-Code
+task:insert_result(metric, symbol, 1)
+\end_layout
+
+\begin_layout LyX-Code
+end
+\end_layout
+
+\end_deeper
+\begin_layout LyX-Code
+end
+\end_layout
+
+\end_deeper
+\begin_layout LyX-Code
+end
+\end_layout
+
+\end_deeper
+\begin_layout LyX-Code
+end
+\end_layout
+
+\end_deeper
+\begin_layout LyX-Code
+end
+\end_layout
+
+\end_deeper
+\begin_layout LyX-Code
+end
+\end_layout
+
+\begin_layout Section
+Использование DNS
+\end_layout
+
+\begin_layout Standard
+Для многих задач фильтрации сообщений используются различные DNS запросы,
+ поэтому lua интерфейс предоставляет возможность планирования DNS запросов,
+ используя объект task:
+\end_layout
+
+\begin_layout Itemize
+resolve_dns_a(host, callback) - выполняет прямое преобразование имени host,
+ после чего вызывает обработчик callback
+\end_layout
+
+\begin_layout Itemize
+resolve_dns_ptr(ip, callback) - то же, что и предыдущее, но выполняет обратное
+ преобразование ip
+\end_layout
+
+\begin_layout Standard
+Так как DNS преобразования осуществляются асинхронно, то необходимо задавать
+ обработчик, который будет вызываться по завершению DNS запроса.
+ Обработчик имеет следующий вид:
+\end_layout
+
+\begin_layout LyX-Code
+function dns_cb(task, to_resolve, results, err)
+\end_layout
+
+\begin_layout Itemize
+task - объект task
+\end_layout
+
+\begin_layout Itemize
+to_resolve - строка, содержащая имя хоста или ip, для которого выполнялось
+ преобразование
+\end_layout
+
+\begin_layout Itemize
+results - массив, содержащий ip адреса (для прямого преобразования) или
+ же имя хоста (для обратного).
+ В случае ошибки этот параметр имеет значение nil
+\end_layout
+
+\begin_layout Itemize
+err - строка, описывающая ошибку (или nil, если преобразование успешно завершило
+сь)
+\end_layout
+
+\begin_layout Standard
+Пример функции-обработчика результатов DNS запроса:
+\end_layout
+
+\begin_layout LyX-Code
+function dns_cb(task, to_resolve, results, err)
+\end_layout
+
+\begin_deeper
+\begin_layout LyX-Code
+if results then
+\end_layout
+
+\begin_deeper
+\begin_layout LyX-Code
+local _,_,rbl = string.find(to_resolve, '%d+
+\backslash
+.%d+
+\backslash
+.%d+
+\backslash
+.%d+
+\backslash
+.(.+)')
+\end_layout
+
+\begin_layout LyX-Code
+task:insert_result(metric, symbol, 1, rbl)
+\end_layout
+
+\end_deeper
+\begin_layout LyX-Code
+end
+\end_layout
+
+\end_deeper
+\begin_layout LyX-Code
+end
+\end_layout
+
+\begin_layout Chapter
+Использование HTTP Redirector
+\end_layout
+
+\begin_layout Standard
+TODO
+\end_layout
+
+\begin_layout Chapter
+Хранилище нечетких хешей
+\end_layout
+
+\begin_layout Standard
+TODO
+\end_layout
+
+\end_body
+\end_document