réplica de
https://github.com/rspamd/rspamd.git
synced 2024-07-31 08:18:22 +02:00
4300 líneas
127 KiB
Plaintext
4300 líneas
127 KiB
Plaintext
#LyX 1.6.4 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
|
||
22.03.2010
|
||
\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 Subsection
|
||
Настройка синхронизации статистики
|
||
\end_layout
|
||
|
||
\begin_layout Standard
|
||
Статистические данные можно синхронизировать между несколькими rspamd.
|
||
Для этого используется master/slave синхронизация и бинарный лог изменений
|
||
в статистическом файле.
|
||
Для настройки синхронизации используются следующие параметры при определении
|
||
статистического файла:
|
||
\end_layout
|
||
|
||
\begin_layout LyX-Code
|
||
statfile {
|
||
\end_layout
|
||
|
||
\begin_deeper
|
||
\begin_layout LyX-Code
|
||
...
|
||
\end_layout
|
||
|
||
\begin_layout LyX-Code
|
||
binlog = "slave";
|
||
\end_layout
|
||
|
||
\begin_layout LyX-Code
|
||
binlog_master = "somehost:11334";
|
||
\end_layout
|
||
|
||
\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
|
||
...
|
||
\end_layout
|
||
|
||
\begin_layout LyX-Code
|
||
binlog = "master";
|
||
\end_layout
|
||
|
||
\begin_layout LyX-Code
|
||
...
|
||
\end_layout
|
||
|
||
\end_deeper
|
||
\begin_layout LyX-Code
|
||
};
|
||
\end_layout
|
||
|
||
\begin_layout Standard
|
||
При настройке slave для синхронизации указывается адрес master для данного
|
||
файла.
|
||
Этот адрес фактически является адресом контроллера, который сконфигурирован
|
||
работать с данным файлом как master.
|
||
Если rspamd настроен работать с данным файлом статистики как master, то
|
||
создается специальный файл с таким же именем, как файл статистики, но имеющим
|
||
суффикс .binlog.
|
||
В данный файл записываются ревизии и изменения, внесенные в файл статистики.
|
||
Данный файл хранит фиксированное число изменений и ротируется при переполнении.
|
||
Синхронизация производится всеми slave хостами с промежутком от 1-й до
|
||
2-х минут.
|
||
При этом, нет разницы, в каком состоянии был файл статистики на slave хосте
|
||
- после синхронизации файл статистики на slave будет в точности совпадать
|
||
с файлом статистики на master'е.
|
||
Обновления файлов статистики являются инкрементальными, то есть передаются
|
||
только изменения, а не файлы целиком.
|
||
Синхронизация файлов статистики позволяет легко построить кластер rspamd,
|
||
которые работают и обучаются идентично (хотя обучение должно производиться
|
||
через контроллер мастера).
|
||
\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 Standard
|
||
В секции
|
||
\begin_inset Quotes fld
|
||
\end_inset
|
||
|
||
factors
|
||
\begin_inset Quotes frd
|
||
\end_inset
|
||
|
||
также можно задать параметр grow_factor, который задает коэффициент приращения
|
||
при добавлении символов в метрику.
|
||
Работает это так: допустим, добавляется первый символ - его реальный вес
|
||
будет равен 1 * factor (то есть, если factor равен 1, то и реальный вес
|
||
будет равен 1), после чего следующий символ будет иметь реальный вес grow_facto
|
||
r * factor (например, если grow_factor = 1.1, то реальный вес будет 1.1 *
|
||
factor), далее следующий будет иметь вес (1 + ((grow_factor) - 1)*2)*factor
|
||
(то есть, при предыдущем grow_factor, реальный вес будет 1.2 * factor, следующий
|
||
символ 1.3, затем 1.4 и.т.д.).
|
||
Данная возможность позволяет увеличивать вес письмам, проходящим по нескольким
|
||
правилам.
|
||
Правила с отрицательным весом не увеличивают grow_factor и не модифицируются
|
||
им (то есть, реальный вес таких правил равен 1 * factor).
|
||
Пример задания параметра grow_factor:
|
||
\end_layout
|
||
|
||
\begin_layout LyX-Code
|
||
grow_factor = 1.1;
|
||
\end_layout
|
||
|
||
\begin_layout Standard
|
||
Также существует возможность создавать
|
||
\begin_inset Quotes fld
|
||
\end_inset
|
||
|
||
составные
|
||
\begin_inset Quotes frd
|
||
\end_inset
|
||
|
||
символы - символы, которые являются комбинацией других символов.
|
||
Это нужно для возможности указывать, что комбинация определенных символов
|
||
имеет больший (или, наоборот, меньший) вес, чем сумма весов нескольких
|
||
символов.
|
||
Составные символы представляют собой логические выражения из других символов,
|
||
например:
|
||
\end_layout
|
||
|
||
\begin_layout LyX-Code
|
||
composites {
|
||
\end_layout
|
||
|
||
\begin_deeper
|
||
\begin_layout LyX-Code
|
||
COMPOSITE_SYMBOL1 =
|
||
\begin_inset Quotes fld
|
||
\end_inset
|
||
|
||
SYMBOL1 & (SYMBOL2 | SYMBOL3)
|
||
\begin_inset Quotes frd
|
||
\end_inset
|
||
|
||
;
|
||
\end_layout
|
||
|
||
\begin_layout LyX-Code
|
||
COMPOSITE_SYMBOL2 =
|
||
\begin_inset Quotes fld
|
||
\end_inset
|
||
|
||
SYMBOL3 & !SYMBOL4
|
||
\begin_inset Quotes frd
|
||
\end_inset
|
||
|
||
;
|
||
\end_layout
|
||
|
||
\end_deeper
|
||
\begin_layout LyX-Code
|
||
};
|
||
\end_layout
|
||
|
||
\begin_layout Standard
|
||
При добавлении составного символа все символы, входящие в него, удаляются
|
||
из результата.
|
||
То есть, при срабатывании COMPOSITE_SYMBOL1 из предыдущего примера символы
|
||
SYMBOL1, SYMBOL2 и SYMBOL3 в ответе не появятся.
|
||
\end_layout
|
||
|
||
\begin_layout Section
|
||
Представления и настройки
|
||
\end_layout
|
||
|
||
\begin_layout Subsection
|
||
Представления
|
||
\end_layout
|
||
|
||
\begin_layout Standard
|
||
В rspamd существует возможность настройки правил, которые будут проверяться,
|
||
исходя из определенных критериев.
|
||
Представления настраиваются в конфигурационном файле rspamd и позволяют
|
||
разделить правила, исходя из входящих данных, например, заголовок From
|
||
письма или же по ip, откуда нам пришло данное письмо.
|
||
Представления проверяются при проверке любого правила и при совпадении
|
||
данных письма проверяются не все символы, а те, которые заданы данным представл
|
||
ением.
|
||
При настройки представлений задаются входные данные письма (from и ip)
|
||
и символы, которые должны проверяться.
|
||
Входные данные могут дублироваться, то есть, можно задать несколько from
|
||
и несколько ip, задаются эти параметры либо в виде регулярных выражений:
|
||
\end_layout
|
||
|
||
\begin_layout LyX-Code
|
||
from =
|
||
\begin_inset Quotes fld
|
||
\end_inset
|
||
|
||
/^.*@somedomain.com$
|
||
\begin_inset Quotes frd
|
||
\end_inset
|
||
|
||
;
|
||
\end_layout
|
||
|
||
\begin_layout LyX-Code
|
||
from =
|
||
\begin_inset Quotes fld
|
||
\end_inset
|
||
|
||
/^.*@otherdoma[a-z]+.com$
|
||
\begin_inset Quotes frd
|
||
\end_inset
|
||
|
||
;
|
||
\end_layout
|
||
|
||
\begin_layout Standard
|
||
либо в виде map:
|
||
\end_layout
|
||
|
||
\begin_layout LyX-Code
|
||
from =
|
||
\begin_inset Quotes fld
|
||
\end_inset
|
||
|
||
file:///usr/local/etc/rspamd/from.map
|
||
\begin_inset Quotes frd
|
||
\end_inset
|
||
|
||
;
|
||
\end_layout
|
||
|
||
\begin_layout LyX-Code
|
||
ip =
|
||
\begin_inset Quotes fld
|
||
\end_inset
|
||
|
||
http://somehost:81/ip.map
|
||
\begin_inset Quotes frd
|
||
\end_inset
|
||
|
||
;
|
||
\end_layout
|
||
|
||
\begin_layout Standard
|
||
Символы также могут быть заданы несколькими директивами symbols (которые
|
||
будут объединены в список):
|
||
\end_layout
|
||
|
||
\begin_layout LyX-Code
|
||
symbols =
|
||
\begin_inset Quotes fld
|
||
\end_inset
|
||
|
||
/^.*URIBL.*$/
|
||
\begin_inset Quotes frd
|
||
\end_inset
|
||
|
||
;
|
||
\end_layout
|
||
|
||
\begin_layout Standard
|
||
Пример задания представления в конфигурационном файле:
|
||
\end_layout
|
||
|
||
\begin_layout LyX-Code
|
||
view {
|
||
\end_layout
|
||
|
||
\begin_deeper
|
||
\begin_layout LyX-Code
|
||
ip = "file:///usr/local/etc/rspamd/ip_internal.inc";
|
||
\end_layout
|
||
|
||
\begin_layout LyX-Code
|
||
skip_check = yes;
|
||
\end_layout
|
||
|
||
\begin_layout LyX-Code
|
||
from = "file:///usr/local/etc/rspamd/from_internal.inc";
|
||
\end_layout
|
||
|
||
\begin_layout LyX-Code
|
||
symbols = "/^.*URIBL.*$/";
|
||
\end_layout
|
||
|
||
\end_deeper
|
||
\begin_layout LyX-Code
|
||
};
|
||
\end_layout
|
||
|
||
\begin_layout Standard
|
||
Директива
|
||
\begin_inset Quotes fld
|
||
\end_inset
|
||
|
||
skip_check
|
||
\begin_inset Quotes frd
|
||
\end_inset
|
||
|
||
используется для пропуска всех проверок rspamd для данного представлений.
|
||
В результате при использовании протокола rspamc 1.1 вместо маркера спама
|
||
(True или False) будет маркер пропуска (Skip).
|
||
При использовании spamc или же rspamc 1.0 будет стандартный маркер False
|
||
(так как реально у письма будет 0 баллов).
|
||
\end_layout
|
||
|
||
\begin_layout Subsection
|
||
Пользовательские настройки
|
||
\end_layout
|
||
|
||
\begin_layout Standard
|
||
Пользовательские настройки, в отличие от представлений, дают возможность
|
||
выбора правил, а также настройки граничных значений баллов письма, исходя
|
||
из получателя письма.
|
||
При этом, настройки можно задавать индивидуально пользователю или же всему
|
||
домену пользователя.
|
||
Индивидуальные настройки пользователя перекрывают настройки домена.
|
||
При выборе настроек используются следующие данные (учитывая последовательность)
|
||
:
|
||
\end_layout
|
||
|
||
\begin_layout Enumerate
|
||
проверяется заголовок Deliver-To, передаваемый при использовании протокола
|
||
rspamc;
|
||
\end_layout
|
||
|
||
\begin_layout Enumerate
|
||
проверяется заголовок User, передаваемый MTA exim при использовании любого
|
||
протокола;
|
||
\end_layout
|
||
|
||
\begin_layout Enumerate
|
||
проверяется первый получатель письма из заголовка rspamc Rcpt;
|
||
\end_layout
|
||
|
||
\begin_layout Enumerate
|
||
проверяется первый получатель письма из заголовка mime To.
|
||
\end_layout
|
||
|
||
\begin_layout Standard
|
||
Необходимо обратить внимание , что при наличии нескольких получателей, будет
|
||
проверяться только первый из них, чтобы избегать двусмысленного поведения.
|
||
Сами настройки задаются в json файлах, так как данные файлы могут содержать
|
||
очень много информации о пользователях, и хранить это все в конфигурационном
|
||
файле нецелесообразно.
|
||
Для задания пользовательских настроек используется секция
|
||
\begin_inset Quotes fld
|
||
\end_inset
|
||
|
||
settings
|
||
\begin_inset Quotes frd
|
||
\end_inset
|
||
|
||
, которая содержит всего два параметра: user_settings и domain_settings.
|
||
Например:
|
||
\end_layout
|
||
|
||
\begin_layout LyX-Code
|
||
settings {
|
||
\end_layout
|
||
|
||
\begin_deeper
|
||
\begin_layout LyX-Code
|
||
user_settings = "http://somehost/users.php";
|
||
\end_layout
|
||
|
||
\begin_layout LyX-Code
|
||
domain_settings = "http://somehost/domains.php";
|
||
\end_layout
|
||
|
||
\end_deeper
|
||
\begin_layout LyX-Code
|
||
};
|
||
\end_layout
|
||
|
||
\begin_layout Standard
|
||
Формат соответствующих json файлов достаточно прост - это массив объектов,
|
||
задающих настройки.
|
||
Объект настройки содержит следующие параметры:
|
||
\end_layout
|
||
|
||
\begin_layout Itemize
|
||
name - имя пользователя или домена;
|
||
\end_layout
|
||
|
||
\begin_layout Itemize
|
||
metrics - объект, задающий предельные очки по метрикам, вида
|
||
\begin_inset Quotes fld
|
||
\end_inset
|
||
|
||
metric_name
|
||
\begin_inset Quotes frd
|
||
\end_inset
|
||
|
||
-> score;
|
||
\end_layout
|
||
|
||
\begin_layout Itemize
|
||
factors - объект, задающий индивидуальные настройки множителей вида
|
||
\begin_inset Quotes fld
|
||
\end_inset
|
||
|
||
symbol
|
||
\begin_inset Quotes frd
|
||
\end_inset
|
||
|
||
-> score;
|
||
\end_layout
|
||
|
||
\begin_layout Itemize
|
||
want_spam - булево значение, при задании его как true, rspamd отключает
|
||
проверки для данного пользователя.
|
||
\end_layout
|
||
|
||
\begin_layout Standard
|
||
Пример json настроек:
|
||
\end_layout
|
||
|
||
\begin_layout LyX-Code
|
||
[
|
||
\end_layout
|
||
|
||
\begin_deeper
|
||
\begin_layout LyX-Code
|
||
{
|
||
\end_layout
|
||
|
||
\begin_deeper
|
||
\begin_layout LyX-Code
|
||
"name":"somedomain.ru",
|
||
\end_layout
|
||
|
||
\begin_layout LyX-Code
|
||
"metrics":{"default":11},
|
||
\end_layout
|
||
|
||
\begin_layout LyX-Code
|
||
"factors":{"R_FUZZY":10.1},
|
||
\end_layout
|
||
|
||
\begin_layout LyX-Code
|
||
"want_spam":false
|
||
\end_layout
|
||
|
||
\end_deeper
|
||
\begin_layout LyX-Code
|
||
},
|
||
\end_layout
|
||
|
||
\begin_layout LyX-Code
|
||
{
|
||
\end_layout
|
||
|
||
\begin_deeper
|
||
\begin_layout LyX-Code
|
||
"name":"some.other.domain.com",
|
||
\end_layout
|
||
|
||
\begin_layout LyX-Code
|
||
"metrics":{"default":5.5},
|
||
\end_layout
|
||
|
||
\begin_layout LyX-Code
|
||
"factors":{"URIBL":20.3},
|
||
\end_layout
|
||
|
||
\begin_layout LyX-Code
|
||
"want_spam":false
|
||
\end_layout
|
||
|
||
\end_deeper
|
||
\begin_layout LyX-Code
|
||
}
|
||
\end_layout
|
||
|
||
\end_deeper
|
||
\begin_layout LyX-Code
|
||
]
|
||
\end_layout
|
||
|
||
\begin_layout Standard
|
||
Файлы настроек перезагружаются по мере обновления, как и любые другие файлы
|
||
списков.
|
||
\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 Section
|
||
Настройка модуля spf
|
||
\end_layout
|
||
|
||
\begin_layout Standard
|
||
Модуль spf предназначен для проверки spf записей для отправителя письма.
|
||
Технология SPF позволяет определить в DNS TXT запись для данного домена
|
||
с определениями, с каких ip адресов или сетей допустима отправка почты
|
||
для данного домена.
|
||
Также spf позволяет создавать
|
||
\begin_inset Quotes fld
|
||
\end_inset
|
||
|
||
черные списки
|
||
\begin_inset Quotes frd
|
||
\end_inset
|
||
|
||
для данного домена - адреса, с которых запрещена отправка почты для домена.
|
||
Rspamd может получать spf записи, и проверять, возможна ли отправка почты
|
||
данного домена с данного ip.
|
||
При этом возможно добавление 3-х символов:
|
||
\end_layout
|
||
|
||
\begin_layout Itemize
|
||
FAIL - отправка запрещена
|
||
\end_layout
|
||
|
||
\begin_layout Itemize
|
||
SOFTFAIL - отправка явно не разрешена, но и явно не запрещена
|
||
\end_layout
|
||
|
||
\begin_layout Itemize
|
||
ALLOW - отправка явно разрешена
|
||
\end_layout
|
||
|
||
\begin_layout Standard
|
||
Для задания этих символов можно использовать настройки модуля spf:
|
||
\end_layout
|
||
|
||
\begin_layout LyX-Code
|
||
.module 'spf' {
|
||
\end_layout
|
||
|
||
\begin_deeper
|
||
\begin_layout LyX-Code
|
||
symbol_fail = "SPF_FAIL";
|
||
\end_layout
|
||
|
||
\begin_layout LyX-Code
|
||
symbol_softfail = "SPF_SOFTFAIL";
|
||
\end_layout
|
||
|
||
\begin_layout LyX-Code
|
||
symbol_allow = "SPF_ALLOW";
|
||
\end_layout
|
||
|
||
\end_deeper
|
||
\begin_layout LyX-Code
|
||
};
|
||
\end_layout
|
||
|
||
\begin_layout Standard
|
||
Коэффициенты для данных символов лучше определить следующим образом: высокий
|
||
вес для символа FAIL, достаточно низкий вес для символа SOFTFAIL и отрицательны
|
||
й вес для символа ALLOW.
|
||
\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_deeper
|
||
\begin_layout LyX-Code
|
||
Header,
|
||
\end_layout
|
||
|
||
\begin_layout LyX-Code
|
||
{ feature_block1..feature_blockN }
|
||
\end_layout
|
||
|
||
\end_deeper
|
||
\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
|
||
double 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
|
||
Формат запроса схож с http:
|
||
\end_layout
|
||
|
||
\begin_layout LyX-Code
|
||
COMMAND RSPAMC/1.0
|
||
\end_layout
|
||
|
||
\begin_layout Standard
|
||
При этом допустимы следующие команды:
|
||
\end_layout
|
||
|
||
\begin_layout Itemize
|
||
CHECK - проверить сообщение и выдать результат по каждой из метрик (не выводя
|
||
символов)
|
||
\end_layout
|
||
|
||
\begin_layout Itemize
|
||
SYMBOLS - проверить сообщение, выдать результат по каждой из метрик и символы
|
||
по каждой из метрик
|
||
\end_layout
|
||
|
||
\begin_layout Itemize
|
||
PROCESS - проверить сообщение, выдать результат по каждой из метрик, а затем
|
||
вывести исходное сообщение
|
||
\end_layout
|
||
|
||
\begin_layout Itemize
|
||
PING - не принимая сообщение выдать готовность к работе
|
||
\end_layout
|
||
|
||
\begin_layout Standard
|
||
Также в зависимости от подключенных плагинов могут быть доступны другие
|
||
команды протокола, например URLS (вывести все найденные в сообщении url'и)
|
||
или EMAILS.
|
||
\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 Itemize
|
||
register_function(name, callback) - регистрирует функцию lua для использования
|
||
в логических выражениях rspamd, callback в данном случае - строка с именем
|
||
функции, пример применения:
|
||
\end_layout
|
||
|
||
\begin_layout LyX-Code
|
||
function some_func(task, arg1, arg2)
|
||
\end_layout
|
||
|
||
\begin_deeper
|
||
\begin_layout LyX-Code
|
||
return false
|
||
\end_layout
|
||
|
||
\end_deeper
|
||
\begin_layout LyX-Code
|
||
end
|
||
\end_layout
|
||
|
||
\begin_layout LyX-Code
|
||
rspamd_config:register_function('lua_func', 'some_func')
|
||
\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 Itemize
|
||
get_recipients() - возвращает массив получателей письма, переданных в ходе
|
||
smtp диалога (командами RCPT TO:)
|
||
\end_layout
|
||
|
||
\begin_layout Itemize
|
||
get_from() - возвращает адрес отправителя письма, переданных в ходе smtp
|
||
диалога (команда MAIL FROM:)
|
||
\end_layout
|
||
|
||
\begin_layout Itemize
|
||
get_helo() - возвращает значение HELO
|
||
\end_layout
|
||
|
||
\begin_layout Itemize
|
||
get_from_ip() - возвращает ip адрес, откуда нам пришло данное письмо
|
||
\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 Section
|
||
Использование файлов-списков
|
||
\end_layout
|
||
|
||
\begin_layout Standard
|
||
В lua плагинах можно задавать и использовать файлы списков, как это описано
|
||
в п.
|
||
4.1.
|
||
Это полезно, когда в lua необходимо использовать некоторые данные, которые
|
||
бы асинхронно обновлялись в процессе работы rspamd.
|
||
API по работе со списками сожержит следующие функции:
|
||
\end_layout
|
||
|
||
\begin_layout Itemize
|
||
rspamd_config:add_radix_map (string) - добавляет определение списка, содержащего
|
||
ip адреса и сети.
|
||
При удачном добавлении возвращается объект типа rspamd_radix, который может
|
||
использоваться в обработчиках символов для определения наличия в каком-либо
|
||
списке заданного ip;
|
||
\end_layout
|
||
|
||
\begin_layout Itemize
|
||
rspamd_config:add_hash_map (string) - добавляет определение списка строк
|
||
(доменов), при успешном добавлении возвращает объект типа rspamd_hash.
|
||
\end_layout
|
||
|
||
\begin_layout Standard
|
||
Использовать списки целесообразно в функциях-обработчкиках, так как сразу
|
||
же после добавления эти списки могут оказаться пустыми.
|
||
Объекты, возвращаемые функциями, регистрирующими файлы списков, имеют метод
|
||
get_key, позволяющий определить наличие какого-либо элемента в списке.
|
||
Для списков ip адресов этот объект принимает целое число, для списка строк
|
||
- строку.
|
||
Простой пример использования списков.
|
||
\end_layout
|
||
|
||
\begin_layout Standard
|
||
Регистрация:
|
||
\end_layout
|
||
|
||
\begin_layout LyX-Code
|
||
local radix_list = nil
|
||
\end_layout
|
||
|
||
\begin_layout LyX-Code
|
||
local host_list = nil
|
||
\end_layout
|
||
|
||
\begin_layout LyX-Code
|
||
radix_list = rspamd_config:add_radix_map ('http://somehost/ip.list')
|
||
\end_layout
|
||
|
||
\begin_layout LyX-Code
|
||
host_list = rspamd_config:add_hash_map ('http://otherhost/host.list')
|
||
\end_layout
|
||
|
||
\begin_layout Standard
|
||
Использование в обработчике символа:
|
||
\end_layout
|
||
|
||
\begin_layout LyX-Code
|
||
function check_whitelist (task)
|
||
\end_layout
|
||
|
||
\begin_deeper
|
||
\begin_layout LyX-Code
|
||
-- check client's ip
|
||
\end_layout
|
||
|
||
\begin_layout LyX-Code
|
||
local ipn = task:get_from_ip_num()
|
||
\end_layout
|
||
|
||
\begin_layout LyX-Code
|
||
if ipn and radix_list then
|
||
\end_layout
|
||
|
||
\begin_deeper
|
||
\begin_layout LyX-Code
|
||
local key = radix_list:get_key(ipn)
|
||
\end_layout
|
||
|
||
\begin_layout LyX-Code
|
||
if key then
|
||
\end_layout
|
||
|
||
\begin_deeper
|
||
\begin_layout LyX-Code
|
||
task:insert_result(metric, symbol_ip, 1)
|
||
\end_layout
|
||
|
||
\end_deeper
|
||
\begin_layout LyX-Code
|
||
end
|
||
\end_layout
|
||
|
||
\end_deeper
|
||
\begin_layout LyX-Code
|
||
end
|
||
\end_layout
|
||
|
||
\begin_layout LyX-Code
|
||
|
||
\end_layout
|
||
|
||
\begin_layout LyX-Code
|
||
-- check client's from domain
|
||
\end_layout
|
||
|
||
\begin_layout LyX-Code
|
||
local from = task:get_from()
|
||
\end_layout
|
||
|
||
\begin_layout LyX-Code
|
||
if from and host_list then
|
||
\end_layout
|
||
|
||
\begin_deeper
|
||
\begin_layout LyX-Code
|
||
-- extract domain part
|
||
\end_layout
|
||
|
||
\begin_layout LyX-Code
|
||
local _,_,domain = string.find(from, '@(.+)>?$')
|
||
\end_layout
|
||
|
||
\begin_layout LyX-Code
|
||
local key = host_list:get_key(domain)
|
||
\end_layout
|
||
|
||
\begin_layout LyX-Code
|
||
if key then
|
||
\end_layout
|
||
|
||
\begin_deeper
|
||
\begin_layout LyX-Code
|
||
task:insert_result(metric, symbol_from, 1)
|
||
\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 Chapter
|
||
Perl API rspamd
|
||
\end_layout
|
||
|
||
\begin_layout Standard
|
||
Для обработки сообщений системой rspamd было создано простое perl api для
|
||
проверки сообщений системой rspamd и обучения системы rspamd.
|
||
Данное API содержится в модуле Mail::Rspamd::Client.
|
||
Использование API достаточно тривиально:
|
||
\end_layout
|
||
|
||
\begin_layout LyX-Code
|
||
#!/usr/bin/perl -w
|
||
\end_layout
|
||
|
||
\begin_layout LyX-Code
|
||
|
||
\end_layout
|
||
|
||
\begin_layout LyX-Code
|
||
use Mail::Rspamd::Client;
|
||
\end_layout
|
||
|
||
\begin_layout LyX-Code
|
||
|
||
\end_layout
|
||
|
||
\begin_layout LyX-Code
|
||
my $testmsg;
|
||
\end_layout
|
||
|
||
\begin_layout LyX-Code
|
||
while (<>) {
|
||
\end_layout
|
||
|
||
\begin_deeper
|
||
\begin_layout LyX-Code
|
||
$testmsg .= $_;
|
||
\end_layout
|
||
|
||
\end_deeper
|
||
\begin_layout LyX-Code
|
||
}
|
||
\end_layout
|
||
|
||
\begin_layout LyX-Code
|
||
my $client = new Mail::Rspamd::Client(
|
||
\end_layout
|
||
|
||
\begin_deeper
|
||
\begin_layout LyX-Code
|
||
{
|
||
\end_layout
|
||
|
||
\begin_deeper
|
||
\begin_layout LyX-Code
|
||
port => 11333,
|
||
\end_layout
|
||
|
||
\begin_layout LyX-Code
|
||
hosts => ['localhost:11333',],
|
||
\end_layout
|
||
|
||
\begin_layout LyX-Code
|
||
ip => '127.0.0.1'
|
||
\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
|
||
if ($client->ping()) {
|
||
\end_layout
|
||
|
||
\begin_deeper
|
||
\begin_layout LyX-Code
|
||
print "Ping is ok
|
||
\backslash
|
||
n";
|
||
\end_layout
|
||
|
||
\end_deeper
|
||
\begin_layout LyX-Code
|
||
}
|
||
\end_layout
|
||
|
||
\begin_layout LyX-Code
|
||
my $result = $client->check($testmsg);
|
||
\end_layout
|
||
|
||
\begin_layout LyX-Code
|
||
|
||
\end_layout
|
||
|
||
\begin_layout LyX-Code
|
||
if ($result && $result->{'default'}->{'isspam'} eq 'True') {
|
||
\end_layout
|
||
|
||
\begin_deeper
|
||
\begin_layout LyX-Code
|
||
print "spam
|
||
\backslash
|
||
n";
|
||
\end_layout
|
||
|
||
\end_deeper
|
||
\begin_layout LyX-Code
|
||
} else {
|
||
\end_layout
|
||
|
||
\begin_deeper
|
||
\begin_layout LyX-Code
|
||
print "ham
|
||
\backslash
|
||
n";
|
||
\end_layout
|
||
|
||
\end_deeper
|
||
\begin_layout LyX-Code
|
||
}
|
||
\end_layout
|
||
|
||
\begin_layout Standard
|
||
Результаты обработки сообщения возвращаются в виде ссылки на хеш, который
|
||
индексирован по метрикам.
|
||
Каждая из метрик, в свою очередь, также является ссылкой на хеш, содержащий
|
||
поля:
|
||
\end_layout
|
||
|
||
\begin_layout Itemize
|
||
isspam - строка 'True' или 'False'
|
||
\end_layout
|
||
|
||
\begin_layout Itemize
|
||
score - вес сообщения
|
||
\end_layout
|
||
|
||
\begin_layout Itemize
|
||
threshold - предельный вес данной метрики
|
||
\end_layout
|
||
|
||
\begin_layout Itemize
|
||
symbols - массив символов для данного сообщения
|
||
\end_layout
|
||
|
||
\begin_layout Standard
|
||
Модуль имеет внутреннюю логику работы с несколькими серверами rspamd, выбирая
|
||
каждый раз случайный сервер, а также помечая долго не работающие сервера,
|
||
исключая их из списка активных на некоторое время.
|
||
При создании Mail::Rspamd::Client также можно указать параметр from (значение
|
||
SMTP команды mail from), параметр rcpt (массив SMTP команд rcpt to) и user
|
||
(авторизированный пользователь SMTP).
|
||
Полный список параметров:
|
||
\end_layout
|
||
|
||
\begin_layout Itemize
|
||
username - имя пользователя (строка)
|
||
\end_layout
|
||
|
||
\begin_layout Itemize
|
||
ip - ip адрес, с которого пришло сообщение (строка)
|
||
\end_layout
|
||
|
||
\begin_layout Itemize
|
||
subject - тема письма (для не mime сообщений)
|
||
\end_layout
|
||
|
||
\begin_layout Itemize
|
||
timeout - время ожидания в секундах (число)
|
||
\end_layout
|
||
|
||
\begin_layout Itemize
|
||
password - пароль для команд котроллера (строка)
|
||
\end_layout
|
||
|
||
\begin_layout Itemize
|
||
statfile - имя символа файла статистики для обучения (строка)
|
||
\end_layout
|
||
|
||
\begin_layout Itemize
|
||
weight - вес сообщения для команд fuzzy_add и learn (число)
|
||
\end_layout
|
||
|
||
\begin_layout Itemize
|
||
imap_search - строка поиска по IMAP (строка)
|
||
\end_layout
|
||
|
||
\begin_layout Standard
|
||
Для выполнения команды на всех серверах используется команда do_all_cmd,
|
||
возвращающая хеш вида host => %results.
|
||
|
||
\end_layout
|
||
|
||
\begin_layout Chapter
|
||
Использование HTTP Redirector
|
||
\end_layout
|
||
|
||
\begin_layout Standard
|
||
HTTP редиректор представляет собой утилиту, которая умеет проверять различные
|
||
способы HTTP редиректов и выдавать реальный URL для любого заданного.
|
||
Данная утилита предназначена для проверки URL'ей вида tinyurl.com, youfrog.com
|
||
и прочих сервисов
|
||
\begin_inset Quotes fld
|
||
\end_inset
|
||
|
||
коротких
|
||
\begin_inset Quotes frd
|
||
\end_inset
|
||
|
||
URL'ей.
|
||
HTTP редиректор работает как обычный HTTP сервер и принимает стандартные
|
||
запросы вида:
|
||
\end_layout
|
||
|
||
\begin_layout LyX-Code
|
||
GET /url_to_resolve HTTP/1.0
|
||
\end_layout
|
||
|
||
\begin_layout LyX-Code
|
||
|
||
\end_layout
|
||
|
||
\begin_layout Standard
|
||
Для работы URL редиректор требует ряд perl модулей:
|
||
\end_layout
|
||
|
||
\begin_layout Itemize
|
||
HTTP::Request - обработка HTTP запросов;
|
||
\end_layout
|
||
|
||
\begin_layout Itemize
|
||
POE (Component::Server::TCP Filter::HTTPD Component::Client::HTTP) - для
|
||
асинхронной обработки соединений;
|
||
\end_layout
|
||
|
||
\begin_layout Itemize
|
||
HTML::HeadParser - для парсинга HTTP заголовков;
|
||
\end_layout
|
||
|
||
\begin_layout Itemize
|
||
SWF::Element - для обработки SWF (adobe flash) редиректов;
|
||
\end_layout
|
||
|
||
\begin_layout Itemize
|
||
Cache::Memcached::Fast - для хранения кеша URL'ей;
|
||
\end_layout
|
||
|
||
\begin_layout Itemize
|
||
Digest::SHA256 - для индексации хеша;
|
||
\end_layout
|
||
|
||
\begin_layout Itemize
|
||
Proc::Daemon, Proc::PidUtil - для демонизации и управления процессом;
|
||
\end_layout
|
||
|
||
\begin_layout Itemize
|
||
URI::Escape - для нормализации URL'ей.
|
||
\end_layout
|
||
|
||
\begin_layout Standard
|
||
Настройка утилиты осуществляется правкой скрипта rspamd-redirector, конфигурацио
|
||
нные параметры находятся в хеше %cfg:
|
||
\end_layout
|
||
|
||
\begin_layout LyX-Code
|
||
our %cfg = (
|
||
\end_layout
|
||
|
||
\begin_deeper
|
||
\begin_layout LyX-Code
|
||
port => 8080, # Порт для приема соединений
|
||
\end_layout
|
||
|
||
\begin_layout LyX-Code
|
||
max_size => 102400, # Максимальный размер принимаемых
|
||
данных
|
||
\end_layout
|
||
|
||
\begin_layout LyX-Code
|
||
http_timeout => 5, # Таймаут соединений (секунды)
|
||
\end_layout
|
||
|
||
\begin_layout LyX-Code
|
||
max_rec => 5, # Максимум подзапросов
|
||
\end_layout
|
||
|
||
\begin_layout LyX-Code
|
||
pidfile => '/var/run/rspamd/redirector.pid',# Путь до файла pid'а
|
||
\end_layout
|
||
|
||
\begin_layout LyX-Code
|
||
logfile => '/var/log/rspamd-redirector.log',# Путь до log файла
|
||
\end_layout
|
||
|
||
\begin_layout LyX-Code
|
||
do_log => 0, # Включить логирование запросов
|
||
\end_layout
|
||
|
||
\begin_layout LyX-Code
|
||
debug => 0, # Включить отладочную информацию
|
||
\end_layout
|
||
|
||
\begin_layout LyX-Code
|
||
memcached_servers => # Сервера кеша URL'ей
|
||
\end_layout
|
||
|
||
\begin_deeper
|
||
\begin_layout LyX-Code
|
||
[
|
||
\end_layout
|
||
|
||
\begin_deeper
|
||
\begin_layout LyX-Code
|
||
{ address => 'localhost:11211', weight => 2.5 },
|
||
\end_layout
|
||
|
||
\end_deeper
|
||
\begin_layout LyX-Code
|
||
],
|
||
\end_layout
|
||
|
||
\end_deeper
|
||
\begin_layout LyX-Code
|
||
digest_bits => 256, # Число бит в ключе кеша
|
||
\end_layout
|
||
|
||
\begin_layout LyX-Code
|
||
cache_expire => 3600, # Время в секундах хранения
|
||
записи кеша
|
||
\end_layout
|
||
|
||
\begin_layout LyX-Code
|
||
user => '@RSPAMD_USER@', # Пользователь
|
||
\end_layout
|
||
|
||
\begin_layout LyX-Code
|
||
group => '@RSPAMD_GROUP@', # Группа
|
||
\end_layout
|
||
|
||
\end_deeper
|
||
\begin_layout LyX-Code
|
||
);
|
||
\end_layout
|
||
|
||
\begin_layout Standard
|
||
Для работы с redirector'ом необходимо учитывать следующее: при определенни
|
||
редиректа rspamd-redirector делает полноценный http запрос, то есть, если
|
||
мы будем пытаться разрешить запросы с различными GET параметрами в URL
|
||
(например http://some_evil_host/unsubscribe?email=good@email.com), то тем
|
||
самым можем занести
|
||
\begin_inset Quotes fld
|
||
\end_inset
|
||
|
||
хорошие
|
||
\begin_inset Quotes frd
|
||
\end_inset
|
||
|
||
адреса в списки спамеров.
|
||
Кроме этого, появляется возможность организовать атаку на некоторый http
|
||
сервер, послав много писем, содержащих его адрес.
|
||
Поэтому проверять редиректы можно только у проверенных доменов.
|
||
Для этого используются настройки модуля surbl в самом rspamd (так как именно
|
||
модуль surbl отвечает за работу с редиректором):
|
||
\end_layout
|
||
|
||
\begin_layout LyX-Code
|
||
.module 'surbl' {
|
||
\end_layout
|
||
|
||
\begin_deeper
|
||
\begin_layout LyX-Code
|
||
...
|
||
\end_layout
|
||
|
||
\begin_layout LyX-Code
|
||
redirector = "localhost:8080";
|
||
\end_layout
|
||
|
||
\begin_layout LyX-Code
|
||
# Connect timeout for redirector
|
||
\end_layout
|
||
|
||
\begin_layout LyX-Code
|
||
redirector_connect_timeout = "1s";
|
||
\end_layout
|
||
|
||
\begin_layout LyX-Code
|
||
# IO timeout for redirector
|
||
\end_layout
|
||
|
||
\begin_layout LyX-Code
|
||
redirector_read_timeout = "10s";
|
||
\end_layout
|
||
|
||
\begin_layout LyX-Code
|
||
# Maps for hosts that should be checked with redirector
|
||
\end_layout
|
||
|
||
\begin_layout LyX-Code
|
||
redirector_hosts_map = "http://some_host/redirector.hosts";
|
||
\end_layout
|
||
|
||
\begin_layout LyX-Code
|
||
...
|
||
\end_layout
|
||
|
||
\end_deeper
|
||
\begin_layout LyX-Code
|
||
};
|
||
\end_layout
|
||
|
||
\begin_layout Standard
|
||
При этом список redirector_hosts_map содержит домены, которые будут перед
|
||
проверкой по surbl листам проверяться на наличие редиректов (то есть, именно
|
||
в том виде, что будет при surbl запросе - 2 или 3 компонента имени хоста).
|
||
Кеш URL'ей обязателен для работы редиректора, так как в противном случае
|
||
массовая рассылка с одинаковым URL'ем приведет к большому числу http запросов.
|
||
Кроме этого, кеш URL'ей существенно ускоряет работу редиректора.
|
||
Лог файл редиректора позволяет увидеть, какие редиректы были распознаны
|
||
и их тип: HTTP редирект, HTML редирект (тег meta refresh), JavaScript редирект
|
||
(location = ...), SWF редирект или же кешированный редирект (найденный в memcached
|
||
).
|
||
Взаимодействие с редиректором возможно не только из rspamd, но и из любого
|
||
другого приложения, работающего по HTTP протоколу.
|
||
\end_layout
|
||
|
||
\begin_layout Chapter
|
||
Хранилище нечетких хешей
|
||
\end_layout
|
||
|
||
\begin_layout Standard
|
||
Нечеткий хеш (fuzzy hash) отличается от обычного тем, что при небольшом
|
||
изменении в исходном тексте, он также меняется незначительно.
|
||
Традиционный (криптографический) хеш в таком случае меняется сильно.
|
||
Эта особенность позволяет использовать нечеткие хеши для определения степени
|
||
похожести текстов (у похожих текстов будут похожие нечеткие хеши).
|
||
Эта операция является более быстрой, чем сравнение текстов, кроме этого,
|
||
нечеткие хеши можно хранить, сравнивая с ними впоследствие полученные сообщения.
|
||
В rspamd есть возможность использования хранилища нечетких хешей для проверки
|
||
сообщений.
|
||
При этом считаются хеши всех текстовых частей сообщения, а затем эти хеши
|
||
проверяются на наличие в хранилище (с определенным процентом ошибки).
|
||
Для хранилища хешей создается специальный процесс fuzzy, который работает
|
||
с рабочим процессом rspamd по UDP протоколу.
|
||
Несколько хранилищ создают общее хранилище хешей, каждый из элементов которого
|
||
содержит часть хешей.
|
||
При добавлении или удалении нового хранилища в общее хранилище, все данные
|
||
хешей теряются (возможно, это будет устранено в будущем).
|
||
При проверке хеша выбирается одно из хранилищ (соответственно хешу) и на
|
||
него шлется запрос.
|
||
При записи хеша выбирается то же самое хранилище, что и при проверке.
|
||
Запись и удаление хеша из общего хранилища обеспечивается командами fuzzy_add
|
||
и fuzzy_del на любом из контроллеров, использующих данное хранилище.
|
||
Это можно делать, например, используя клиент rspamc:
|
||
\end_layout
|
||
|
||
\begin_layout LyX-Code
|
||
rspamc fuzzy_add < message_to_add.eml
|
||
\end_layout
|
||
|
||
\begin_layout LyX-Code
|
||
rspamd fuzzy_del < message_to_del.eml
|
||
\end_layout
|
||
|
||
\begin_layout Standard
|
||
Настройка хранилища обеспечивается созданием записи для процесса fuzzy storage:
|
||
\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 for fuzzy interface
|
||
\end_layout
|
||
|
||
\begin_layout LyX-Code
|
||
bind_socket = *:11335;
|
||
\end_layout
|
||
|
||
\begin_layout LyX-Code
|
||
count = 1;
|
||
\end_layout
|
||
|
||
\begin_layout LyX-Code
|
||
# Path to filesystem storage
|
||
\end_layout
|
||
|
||
\begin_layout LyX-Code
|
||
hashfile = "/tmp/fuzzy.db";
|
||
\end_layout
|
||
|
||
\begin_layout LyX-Code
|
||
# Expire time for hashes in storage (h - for hours, d - for days)
|
||
\end_layout
|
||
|
||
\begin_layout LyX-Code
|
||
expire = "10d";
|
||
\end_layout
|
||
|
||
\end_deeper
|
||
\begin_layout LyX-Code
|
||
};
|
||
\end_layout
|
||
|
||
\begin_layout Standard
|
||
Для увеличения производительности хранилища можно заменить нечеткий поиск
|
||
на поиск точного соответствия, а также установкой libJudy (
|
||
\begin_inset CommandInset href
|
||
LatexCommand href
|
||
name "judy arrays"
|
||
target "http://judy.sourceforge.net"
|
||
|
||
\end_inset
|
||
|
||
).
|
||
После этого необходимо пересобрать rspamd (libJudy обнаруживается автоматически
|
||
) и указать в настройках fuzzy worker'а параметр:
|
||
\end_layout
|
||
|
||
\begin_layout LyX-Code
|
||
use_judy = "yes";
|
||
\end_layout
|
||
|
||
\begin_layout Standard
|
||
Настройка hashfile используется для указания файла, в который периодически
|
||
будут записываться полученные в хранилище хеши (частота синхронизации с
|
||
файлом зависит от интенсивности модификаций в хранилище, также синхронизация
|
||
происходит при завершении процесса fuzzy storage).
|
||
Для настройки клиентской части хранилища используется модуль fuzzy_check:
|
||
\end_layout
|
||
|
||
\begin_layout LyX-Code
|
||
.module 'fuzzy_check' {
|
||
\end_layout
|
||
|
||
\begin_deeper
|
||
\begin_layout LyX-Code
|
||
metric = "default";
|
||
\end_layout
|
||
|
||
\begin_layout LyX-Code
|
||
symbol = "R_FUZZY";
|
||
\end_layout
|
||
|
||
\begin_layout LyX-Code
|
||
# List of fuzzy storage servers, separated by ',' or ';' or simple by spaces
|
||
|
||
\end_layout
|
||
|
||
\begin_layout LyX-Code
|
||
servers = "localhost:11335;some_host:11335";
|
||
\end_layout
|
||
|
||
\end_deeper
|
||
\begin_layout LyX-Code
|
||
};
|
||
\end_layout
|
||
|
||
\begin_layout Standard
|
||
После настройки клиентской части с указанными серверами начинает работать
|
||
как рабочий процесс (для проверки сообщений), так и контроллер (для записи/удал
|
||
ения хешей из хранилища).
|
||
|
||
\end_layout
|
||
|
||
\begin_layout Chapter
|
||
CGI интерфейс rspamd
|
||
\end_layout
|
||
|
||
\begin_layout Standard
|
||
Rspamd имеет простой интерфейс для управления кластером серверов при помощи
|
||
веб браузера.
|
||
Интерфейс позволяет выполнять основные команды (проверка сообщений, обучение
|
||
rspamd, операции с fuzzy хешами, статистика) на выбранных серверах.
|
||
Для передачи сообщения rspamd используется либо поле текстового ввода,
|
||
либо непосредственная загрузка файла.
|
||
Если используется поле текстового ввода и сообщение вводится в него без
|
||
mime заголовков (например, для обучения), то интерфейс автоматически вставляет
|
||
заголовки по умолчанию и передает составленное таким образом сообщение
|
||
для обработки rspamd.
|
||
Запуск CGI интерфейса возможен двумя способами: как standalone сервера
|
||
и как cgi скрипта.
|
||
Первый способ подходит для тестовой работы или же для использования в один
|
||
поток.
|
||
Второй способ лишен этиго недостатка, но требует наличия настроенного веб
|
||
сервера.
|
||
Для работы с rspamd используется модуль Mail::Rspamd::Client, описанный
|
||
ранее.
|
||
Аргументы запуска CGI интерфейса:
|
||
\end_layout
|
||
|
||
\begin_layout Itemize
|
||
-standalone - запуск в виде standalone http сервера
|
||
\end_layout
|
||
|
||
\begin_layout Itemize
|
||
-port - порт для запуска
|
||
\end_layout
|
||
|
||
\begin_layout Itemize
|
||
-host - имя хоста для запуска standalone сервера
|
||
\end_layout
|
||
|
||
\begin_layout Itemize
|
||
-cfg - имя файла, содержащего список серверов, с которыми будет работать
|
||
CGI интерфейс
|
||
\end_layout
|
||
|
||
\end_body
|
||
\end_document
|