Основные компоненты сервера

В этом разделе описаны основные компоненты сервера, их функционирование, настройка, взаимосвязи.

Домен

Домен - это контекст выполнения любого запроса в рамках СпамоБорца. Домен представляет собой просто набор пар вида: имя свойства, значение свойства. Свойствами домена могут быть простые значения: числа, строки и т.п., так и более сложные элементы, являющиеся компонентами СпамоБорца: лог сообщений, firewall.

У домена может быть предок (тоже являющийся доменом). Тогда операция получения свойства домена при отсутствии свойства у данного домена будет обращаться с запросом к предку, так можно организовать наследование доменов: домен-предок содержит свойства “по умолчанию”, а домены-наследники (его дети) переопределяют необходимые свойства, уточняя поведение сервера для различных ситуаций. Например, базовый домен определяет свойства анализа сообщений для всего сайта, а поддомены-наследники конкретизируют эти свойства для различных видов общения (чат, личные сообщения и т.п.)

../_images/domains-png.png

Домен может иметь имя, тогда он становится адресуемым относительно своего предка (аналогично адресуемости каталогов в файловой системе). Относительного одного домена адрес другого может выглядеть так: a/b, тогда относительно текущего корневого домена мы должны взять потомка с именем a, а у него потомка с именем b.

Примеры

Пример дерева доменов:

../_images/domains.png

В этом примере в корневому домену прикреплено три дочерних поддомена, каждый из которых отвечает за фильтрацию спама в трех различных разделах сайта:

  • pm - личные сообщения;
  • chat - чат;
  • comments - пользовательские комментарии.

Пример содержимого домена:

../_images/rootdomain.png

В данном домене находится:

Домен по умолчанию

В системе существует домен по умолчанию, который является предком всех корневых доменов партнеров. Домен по умолчанию может определять свойства, которые будут служить значениями по умолчанию для всех поддоменов. Сам по себе домен по умолчанию недоступен для изменения, он не может быть адресован через API СпамоБорца.

Партнер

Партнер - единица авторизации относительно сервера. Практически все запросы API СпамоБорца требуют авторизации, т.е. указания партнера, от имени которого выполняется запрос. Партнер может обладать функциональностью биллинга/аккаунтинга (т.е. вести учет количества запросов к серверу и т.п.). Партнеры изолированы друг от друга, авторизовавшись под одним партнером нет возможности повлиять на данные другого партнера.

Самое главное свойство партнера - его корневой домен, который определяет корень возможных контекстов исполнения запросов. Любой запрос, выполненный от имени партнера, будет исполняться в его корневом домене или в доменах, являющихся потомками корневого домена.

Механизм авторизации партнеров

Механизм авторизации партнеров определяет способ, которым по информации, переданной в API СпамоБорца, определяется текущий партнер для выполнения запроса.

Доверительный механизм авторизации

Доверительный механизм применяется для инсталляций, обслуживающих один проект, когда нет необходимости каким-то образом авторизовать входящие запросы. В данной ситуации сервер СпамоБорец защищен от посторонних запросов либо сетевым firewall, либо дополнительным HTTP-proxy с возможностью блокировки по IP-адресу или HTTP-авторизацией.

В случае доверительного механизма авторизации существует всего один партнер, который определяет свой единственный корневой домен.

Сообщение

Сообщение - единица передачи информации в СпамоБорец. Сообщение состоит из атрибутов, набор которых, типы и т.п., полностью настраиваются в рамках домена. Типичные атрибуты сообщения:

  • текст сообщения: чаще всего подвергается анализу различными методами;
  • ID пользователя, отправившего сообщение: может использовать при анализе на частоту отправки сообщений, для выявления и блокировки спамеров и т.п.;
  • другие атрибуты: e-mail отправителя, ник, логин, IP-адрес, данные об адресате сообщения, любая другая информация, которая может быть полезна для анализа сообщения.

Сообщение при передаче через API СпамоБорца проходит через механизм сериализации, который, используя данные о типах атрибутов, осуществляет корректное сохранение и восстановление сообщения.

Пример сообщения
Атрибут Домен атрибута Значение атрибута
text Текстовый домен “Ты не хочешь пойти сегодня погулять? Часиков в восемь?”
fromID Уник. целоцисленный домен 38
fromIP IP-адрес 127.0.0.1
fromEmail E-mail bob@example.com

Атрибут сообщения

Атрибут сообщения - составная часть сообщения. Атрибут хранит свое значение, а также свой тип - домен атрибута. Тип значения определяется доменом: для текстового домена это будет строка, а для целочисленного, например, - число.

Домен атрибута сообщений

Домен атрибута определяет тип атрибута сообщения. Разнообразие доменов атрибутов определяет возможные типы данных и смысл атрибутов сообщений. Домен может определять не только тип значения, но и дополнительные логические характеристики (например, уникальность значения).

Текстовый домен

Текстовый домен используется обычно для передачи текста сообщения. Внутренняя кодировка хранения - Unicode, т.е. СпамоБорец готов к обработке данных на любых языках. При передаче данных через API СпамоБорца значение такого атрибута обычно кодируется в кодировке UTF-8.

При десериализации атрибута текстового домена убираются пробельные символы в начале и в конце строки.

TextAttributeDomain(name)
Parameters:
  • name – имя атрибута

Целочисленный домен

Целочисленный домен может использоваться для передачи различных чисел, связанных с сообщением или его адресатами и адресантами.

При передаче в API СпамоБорца используется тип данных “число”.

IntAttributeDomain(name)
Parameters:
  • name – имя атрибута

Уникальный целочисленный домен

Уникальный целочисленный домен отличается от целочисленного только логической привязкой “уникальный”, которая определяет смысл атрибута. Данный домен может использоваться, например, для передачи ID пользователя - отправителя сообщения.

UniqueIntAttributeDomain(name)
Parameters:
  • name – имя атрибута

Домен сообщения

Домен сообщения - это набор доменов атрибутов сообщения. Домен определяет формат сообщений. Домен определяет возможный набор атрибутов сообщения, каждое сообщение может содержать лишь часть перечисленных атрибутов (например, если данных недостаточно).

Домен сообщения хранится в домене в свойстве с именем messageDomain. Наличие домена сообщения является обязательным.

MessageDomain(attributeDomain1[, ...])
В качестве параметров конструктора домен сообщения принимает список доменов атрибутов.

Пример:

MessageDomain(TextAttributeDomain("text"), UniqueIntAttributeDomain("fromID))

Модель анализа сообщений

Модель анализа сообщений осуществляет классификацию сообщений, выделяя в потоке сообщений, например, спам, флуд, оскорбления, предложения интимного характера и т.п. классы. Работа модели основана на процессе обучения. В режиме обучения модель получает образец исходных данных с необходимой пометкой - к какому классу относится тот или иной элемент. После обучения модель готова на новых данных готова классифицировать поступающие на вход данные.

Модель анализа сообщений поддерживает два условных класса: “хороший” (good) и “плохой” (bad). Интерпретация классов зависит от задачи: одна модель может отвечать за классификацию “спам” - не-“спам”, другая: “мат” - не “мат”. Модель стремится минимизировать ошибки классификации, связанные с классификацией “хорошего” сообщения как “плохого”. Модель в качестве исходных данных на вход принимает текст сообщения.

Модель анализа сообщений хранится в домене в свойствах с произвольным именем.

Простая Байесовская модель (BayesModel)

Простая Байесовская модель основана на теореме Байеса [1]. Данная модель не имеет практической ценности, т.к. состояние модели (обучения) не сохраняется, а находится лишь в оперативной памяти и при перезапуске сервера пропадает.

BayesModel()

DataMining-модель (DataMiningModel)

Данная модель построена на принципах интеллектуального анализа данных [2]. Она обладает хорошей возможностью к обучению, высокой эффективностью и точностью классификации.

Note

Данная модель доступна только в Pro-варианте СпамоБорца.

DataMiningModel()

Хранилище данных

Хранилище данных используется для хранения данных в рамках домена. Хранилище предоставляет абстракцию коллекции пар (ключ, значение), при этом каждый ключ может иметь срок годности (предельное время хранения). Хранилище может обладать разными характеристиками по скорости доступа, отношения к перезапуску (надежность), а также к распределенному использованию.

Хранилище в памяти (DomainMemoryStorage)

Данные такого хранилища хранятся в оперативной памяти сервера, теряются при перезапуске сервера. Может использоваться для хранения ключей с малым временем жизни, использующихся, например, при анализе частоты отправки сообщений за небольшой промежуток времени (полчаса и меньше).

DomainMemoryStorage()

Хранилище на диске (DomainedDBMStorage)

Хранилище на диске обеспечивает постоянное, надежное хранение информации на локальном диске сервера, на котором работает СпамоБорец. Содержимое хранилища не теряется при перезапуске сервера. Скорость доступа ниже, чем у хранилища в памяти.

DomainedDBMStorage()

Правила

Правила анализа сообщений выполняют основную работу по анализу сообщений, они применяются в рамках работы firewall к сообщениями относительно текущего домена. Вызов правила синтаксически совпадает с вызовом правила: у правила есть имя, а также набор именованных параметров.

Таким образом, каждое правило в качестве неявного параметра получает сообщение и домен, относительно которого происходит анализ данного сообщения. Домен используется правилами для получения дополнительных параметров настройки, дополнительных компонентов, например, хранилищ данных.

Правила, связанные с моделью анализа сообщений

Все правила этого раздела принимают в качестве параметра имя модели анализа сообщения, сама модель должна быть доступна через текущий домен.

modelClassify(model="model", attribute="text')

Классифицировать сообщение с помощью модели анализа сообщения.

Правило через домен обращается к модели с указанными именем, из сообщения берет значение текстового атрибута (текст сообщения), после чего текст сообщения передается модели на классификацию. Если модель классифицирует данное сообщение как “хорошее”, правило возвращает истину, иначе - ложь.

Parameters:
  • model – имя модели анализа сообщений в текущем домене
  • attribute – имя атрибута сообщения, содержащего текст сообщения, который и будет передан модели
Returns:

истина, если модель классифицирует текст сообщения как “хороший”, и ложь, если наоборот

modelTrain(model="model", attribute="text", marker="good")

Обучить модель анализа сообщений на тексте сообщения, указав категорию сообщения: “плохое” или “хорошее”.

Правило через домен обращается к модели с указанным именем, из сообщения берет значение текстового атрибута (текст сообщения), который передается в модель анализа сообщений на обучение, модель обучается на указанном тексте в соответствие со значением маркера: хорошее это сообщение или плохое.

Правило всегда истинно.

Parameters:
  • model – имя модели анализа сообщений в текущем домене
  • attribute – имя атрибута сообщения, содержащего текст сообщения, который и будет передан модели
  • marker – классификация сообщения для модели: “good” - хорошее или “bad” - плохое
Returns:

истина

Правила, связанные с логом сообщений

messageLogPut(log="messageLog", tag=None)

Положить сообщение с текущим набором тегов в лог.

Правило находит в домене лог сообщений с указанным именем и помещает в него сообщение. Вместе с сообщением в лог записываются тэги, которые были присвоены сообщению предыдущими действиями firewall. С помощью параметра tag можно добавить к записи в логе (не с самому сообщению) дополнительный тэг.

Правило всегда истинно.

Parameters:
  • log – имя лога сообщений в текущем домене
  • tag – имя тэга, дополнительно дописываемого к записи в логе
Returns:

истина

Правила валидации

Правила данного раздела осуществляют проверки сообщения на валидность (длину, регулярное выражение и т.п.)

regexpCheck(regexp, attribute="text")

Правило применяет к значению текстового атрибута сообщения указанное регулярное выражение, результатом правила является успешность применения выражения.

Parameters:
  • regexp – регулярное выражение, синтаксис Python, например: .*lala{2,3}(|bcd)
  • attribute – имя атрибута сообщения, содержащего текст сообщения
Returns:

результат применения регулярного выражения: соответствует текст ему или нет

lengthCheck(minLength=None, maxLength=None, attribute="text")

Правило проверяет длину текстового атрибута сообщения.

Правило берет из сообщения текстовый атрибут с указанным именем и сравнивает его длину с указанными пределами (minLength и maxLength). Если параметр minLength задан и длина текстового атрибута меньше minLength, правило вернет “ложь”. Аналгично, если задан maxLength и длина значения атрибута больше maxLength, правило вернет “ложь”. Во всех остальных случаях результатом вычисления будет “истина”.

Parameters:
  • minLength – минимальная длина значения атрибута или None, если не надо осуществлять проверку на минимальную длину
  • maxLength – максимальная длина значения атрибута или None, если не надо осуществлять проверку на максимальную длину
  • attribute – имя атрибута сообщения, содержащего текст сообщения
attributeCheck(attribute, value)

Правило проверяет соответствие значения атрибута сообщения указанному значению.

Т.е. правило выполняет проверку вида: message.attribute == value ?

Parameters:
  • attribute – имя атрибута сообщения
  • value – проверяемое значение атрибута
Returns:

истина, если значение атрибута совпадает с указанным значением

hasAttribute(attribute)

Правило проверяет наличие указанного атрибута у сообщения

Parameters:
  • attribute – имя атрибута сообщения
Returns:

истина, если у сообщения имеется указанный атрибут

Правила анализа текста сообщений

Данная группа осуществляет проверку текста сообщений.

messageFloodCheck(attribute='text', minLength=16, minMean=1.5, maxVariance=2.0)

Правило анализирует значение текстового атрибута сообщение на флуд. Под флудом понимается отправка большого количества похожих фраз в тексте сообщения.

Алгоритм работы: Текст сообщения разбивается на триграммы (например для фразы “привет андрей!” будут составлены следующие триграммы: “при”, “рив”, “иве”, “вет”, “ета”, “тан”, “анд”, “ндр”, “дре”, “рей”, “ей!”), и подсчитывается количество вхождений каждой триграммы. В результате получается последовательность чисел, для которой рассчитывается значение математического ожидания и дисперсии. Сообщение будет считаться флудом (возвращаемое значение “ложь”), если значение математического ожидания меньше minMean, а значение дисперсии больше maxVariance.

Если длина сообщения меньше minLength, правило вернет “истину” (анализ коротких сообщений может дать большую погрешность при рассчете математического ожидания и дисперсии).

При запуске на тестовой базе, содержащей нормальные сообщения, из 16674 сообщений правило не заблокировала ни одного сообщения. При запуске на тестовой базе, содержащей флуд, из 1477 было обнаружено 956 сообщений, содержащих флуд, что составляет 65% от общего числа сообщений.

Parameters:
  • attribute – имя атрибута сообщения, содержащего текст сообщения
  • minLength – минимальная длина значения атрибута
  • minMean – минимальное значение математического ожидания появления триграмма
  • maxVariance – максимальное значение дисперсии

Правила проверки на частоту

Данная группа осуществляет проверку на частоту (скорость) тех или иных событий, ограничивая, например, число сообщений в секунду.

messageFrequencyCheck(attribute="text", storage="storage", timeout=300, count=3, minLength=10)

Проверка на частоту отправки сообщений с одним и тем же (или похожим) текстом.

Правило берет значение текстового атрибута сообщения. Проверка выполняется, если его длина больше minLength символов. Далее текст сообщения нормализуется (убираются пробельные символы, символы переводятся в нижний регистр). От полученной строки вычисляется md5-хэш. Полученный хэш используется для сравнения сообщений, если хэши равны, то считается, что и сообщения равны.

Правило проверяет, что в течение timeout секунд не было отправлено более count сообщений с одним и тем же хэшом. Если количество отправленных сообщений превышает count, правило возвращает “ложь”, иначе “истину”.

Parameters:
  • attribute – имя атрибута сообщения, содержащего текст сообщения
  • storage – имя свойства домена, содержащего хранилище, которое используется правилом для хранения информации
  • timeout – анализируемый на частоту отправки период времени, секунды
  • count – максимальное число отправляемых в течение timeout секунд сообщений с одинаковым хэшом
  • minLength – минимальная длина сообщения, при достижении которого правило начинает работать
userFrequencyCheck(attribute="from", storage="storage", timeout=300, count=3)

Проверка на частоту отправки сообщений одним пользователем (или группой пользователей).

Группа или пользователь определяются атрибутом сообщения с именем from. Значением этого атрибута, может быть, например, ID пользователя, отправившего сообщение. Правило проверяет, что в течение timeout секунд не было отправлено более count сообщений с одним и тем же значением атрибута from.

Parameters:
  • attribute – имя атрибута сообщения, которое определяет отправителя сообщения
  • storage – имя свойства домена, содержащего хранилище, которое используется правилом для хранения информации
  • timeout – анализируемый на частоту отправки период времени, секунды
  • count – максимальное число отправляемых в течение timeout секунд сообщений с одинаковым from

Правила, используемые для тестирования

Правила этой группы могут использоваться для целей отладки, тестирования сервиса.

ruleTrue()
Returns:истина
ruleFlase()
Returns:ложь

Firewall

Firewall определяет цепочку действий, которые выполняются над входящим сообщением. Результат выполнения действий firewall - результат анализа, строка, которая классифицирует сообщение (спам, флуд и т.п.) Сообщение с дополнительными метками (тэгами) проходит через цепочку действий firewall, при этом к сообщению добавляются новые метки (тэги), а на выходе из firewall формируется окончательное решение - результат анализа.

Синтаксис действий firewall

firewall         ::=  rule+
rule             ::=  [label ":"] [if_condition] statement
label            ::=  "0-9"+
if_condition     ::=  "if" ["not"] tags_list
statement        ::=  do_statement | skip_statement | stop_statement
do_statement     ::=  "do" rule_call ["mark" tags_list]
skip_statement   ::=  "skip" "to" label
stop_statement   ::=  "stop" "as" decision
tags_list        ::=  tag (, tag)*
rule_call        ::=  rule_name "(" rule_param (, rule_param)*  ")"
rule_param       ::=  rule_param_name "=" rule_param_value
tag              ::=  "A-z0-9"+
decision         ::=  "A-z0-9"+
rule_name        ::=  "A-z0-9"+
rule_param_name  ::=  "A-z0-9"+
rule_param_value ::=  """ "string" """ | "0-9"+

Набор действий firewall состоит из отдельных действий, каждое из которых располагается на новой строке. К каждому действию слева может быть добавлена числовая метка label. Действие может начинаться с условия if, тогда в зависимости от тэгов сообщения, действие может быть выполнено или пропущено.

Существует три вида действий:

  • действие do осуществляет применение правила к сообщению, и, в зависимости от результатов выполнения правила, привязывает к сообщению дополнительные метки;
  • действие skip осуществляет переход вниз по цепочке действий к действию с указанной меткой, пропуская часть действий;
  • действие stop останавливает работу firewall, указывая сформировавшийся результат анализа - решение, принятое firewall.

Действие do

do_statement ::=  "do" rule_name "(" rule_param (, rule_param)*  ")" ["mark" tags_list]

Действие do выполняет правило и, в зависимости от результата выполнения правила, дописывает к сообщению указанные тэги. Выполнение правила также может иметь побочный эффект (например, запись сообщения в лог сообщений).

Вызов правила синтаксически похож на вызов функции с набором именованных параметров. В соответствие с набором документированных параметров правила, в действии do можно указать аргументы правила с их значениями или оставить им значения по умолчанию, например:

lengthCheck(minLength=3)

Такое обращение приведет к вызову правилу lengthCheck с параметрами (неуказанные явно параметры приняли значения по умолчанию):

minLength=3, maxLength=None, attribute="text"

Если результатом вычисления правила будет ложь и в правиле присутствует mark-часть, то теги из списка tags_list будут присоединены к текущему списку тэгов сообщения.

Рассмотрим пример. На входе в firewall у сообщения пустой набор тэгов - []. После выполнения правила:

do ruleFalse() mark a, b

У сообщения набор тэгов станет таким: [a, b].

После выполнения правила:

do lengthCheck(minLength=3) mark tooshort

Если длина текста сообщения меньше 3 символов к сообщению добавится тэг tooshort: [a, b, tooshort], а если длина текста больше либо равна 3 символам, набор тэгов не изменится.

Действие stop

stop_statement ::=  "stop" "as" decision

Действие stop останавливает выполнение набора действий firewall, возвращая decision в качестве результата выполнения firewall.

Например:

stop as OK

Остановить выполнение firewall, вернуть "OK" в качестве результата выполнения.

Условие if

Условие if может быть присоединено слева к любому из вышеописанных действий.

if_condition ::=  "if" ["not"] tags_list

Условие позволяет выключить выполнения действий для определенной комбинации тэгов проходящего через действие сообщения. Условие if позволить выполнить действие, если у сообщения есть все тэги из списка tags_list, а условие if not позволит выполнить действие, если у сообщения нет ни одного тэга из списка tags_list.

Например:

do lengthCheck(minLength=3) mark tooshort
if not tooshort do messageLogPut()

В лог сообщений не попадут слишком короткие сообщения.

Примеры наборов действий

Пустой набор действий не считается валидным для firewall, при его обработке будет получен результат UNKNOWN. Если все действия firewall выполнены, и не встретилось по пути ни одного действия stop, результатом выполнения будет также UNKNOWN.

Если выполнения какого либо правила привело к ошибке или при выполнении действия skip не было найдено действие с соответствующей меткой, выполнение firewall считается ошибочным и клиенту возвращается ошибка.

Пример:

do lengthCheck(minLength=1, maxLength=1000) mark invalid
if invalid skip to 1000
do messageFrequencyCheck() mark messagefrequent, frequent
do userFrequencyCheck() mark userfrequent, frequent
if frequent skip to 1000
do modelClassify() mark spam
1000: do messageLogPut()
if invalid stop as INVALID
if frequent stop as FREQUENT
if spam stop as SPAM
stop as OK

Содержимое домена для выполнения такого набора правил:

  • storage: DomainMemoryStorage
  • messageDomain : MessageDomain(TextAttributeDomain("text"), UniqueIntAttributeDomain("from"))
  • messageAnalyzer : firewall с приведенными выше правилами
  • messageLog : MessageLog()
  • model : BayesModel()

Лог сообщений

Лог сообщений позволяет сохранить на какое-то время сообщения, прошедшие через firewall вместе с тэгами, которые были им присвоены. Сам лог сообщений хранится в домене, являясь его свойством.

MessageLog(storage="storage", timeChunk=10, numChunks=100)
Parameters:
  • storage – имя свойства домена, в котором находится хранилище
  • timeChunk – емкость одного ключа хранилища в секундах
  • numChunks – количество выделяемых в хранилище ключей

Лог сообщений является кольцевым логом, который хранит сообщения за последние timeChunk*(numChunks-1) секунд в указанном хранилище. По запросу клиента лог может вернуть произвольное подмножество сохраненных записей.

При записи в лог каждое сообщение получает ID, который увеличивается с каждым новом сообщением, и является уникальным в пределах данного лога сообщений.

[1]http://ru.wikipedia.org/wiki/Теорема_Байеса
[2]http://ru.wikipedia.org/wiki/Data_mining

Table Of Contents

Previous topic

Запуск сервера

Next topic

Настройка сервера

Quick search