В этом разделе описаны основные компоненты сервера, их функционирование, настройка, взаимосвязи.
Домен - это контекст выполнения любого запроса в рамках СпамоБорца. Домен представляет собой просто набор пар вида: имя свойства, значение свойства. Свойствами домена могут быть простые значения: числа, строки и т.п., так и более сложные элементы, являющиеся компонентами СпамоБорца: лог сообщений, firewall.
У домена может быть предок (тоже являющийся доменом). Тогда операция получения свойства домена при отсутствии свойства у данного домена будет обращаться с запросом к предку, так можно организовать наследование доменов: домен-предок содержит свойства “по умолчанию”, а домены-наследники (его дети) переопределяют необходимые свойства, уточняя поведение сервера для различных ситуаций. Например, базовый домен определяет свойства анализа сообщений для всего сайта, а поддомены-наследники конкретизируют эти свойства для различных видов общения (чат, личные сообщения и т.п.)
Домен может иметь имя, тогда он становится адресуемым относительно своего предка (аналогично адресуемости каталогов в файловой системе). Относительного одного домена адрес другого может выглядеть так: a/b, тогда относительно текущего корневого домена мы должны взять потомка с именем a, а у него потомка с именем b.
Пример дерева доменов:
В этом примере в корневому домену прикреплено три дочерних поддомена, каждый из которых отвечает за фильтрацию спама в трех различных разделах сайта:
Пример содержимого домена:
В данном домене находится:
В системе существует домен по умолчанию, который является предком всех корневых доменов партнеров. Домен по умолчанию может определять свойства, которые будут служить значениями по умолчанию для всех поддоменов. Сам по себе домен по умолчанию недоступен для изменения, он не может быть адресован через API СпамоБорца.
Партнер - единица авторизации относительно сервера. Практически все запросы API СпамоБорца требуют авторизации, т.е. указания партнера, от имени которого выполняется запрос. Партнер может обладать функциональностью биллинга/аккаунтинга (т.е. вести учет количества запросов к серверу и т.п.). Партнеры изолированы друг от друга, авторизовавшись под одним партнером нет возможности повлиять на данные другого партнера.
Самое главное свойство партнера - его корневой домен, который определяет корень возможных контекстов исполнения запросов. Любой запрос, выполненный от имени партнера, будет исполняться в его корневом домене или в доменах, являющихся потомками корневого домена.
Механизм авторизации партнеров определяет способ, которым по информации, переданной в API СпамоБорца, определяется текущий партнер для выполнения запроса.
Доверительный механизм применяется для инсталляций, обслуживающих один проект, когда нет необходимости каким-то образом авторизовать входящие запросы. В данной ситуации сервер СпамоБорец защищен от посторонних запросов либо сетевым firewall, либо дополнительным HTTP-proxy с возможностью блокировки по IP-адресу или HTTP-авторизацией.
В случае доверительного механизма авторизации существует всего один партнер, который определяет свой единственный корневой домен.
Сообщение - единица передачи информации в СпамоБорец. Сообщение состоит из атрибутов, набор которых, типы и т.п., полностью настраиваются в рамках домена. Типичные атрибуты сообщения:
- текст сообщения: чаще всего подвергается анализу различными методами;
- ID пользователя, отправившего сообщение: может использовать при анализе на частоту отправки сообщений, для выявления и блокировки спамеров и т.п.;
- другие атрибуты: e-mail отправителя, ник, логин, IP-адрес, данные об адресате сообщения, любая другая информация, которая может быть полезна для анализа сообщения.
Сообщение при передаче через API СпамоБорца проходит через механизм сериализации, который, используя данные о типах атрибутов, осуществляет корректное сохранение и восстановление сообщения.
Атрибут | Домен атрибута | Значение атрибута |
---|---|---|
text | Текстовый домен | “Ты не хочешь пойти сегодня погулять? Часиков в восемь?” |
fromID | Уник. целоцисленный домен | 38 |
fromIP | IP-адрес | 127.0.0.1 |
fromEmail | bob@example.com |
Атрибут сообщения - составная часть сообщения. Атрибут хранит свое значение, а также свой тип - домен атрибута. Тип значения определяется доменом: для текстового домена это будет строка, а для целочисленного, например, - число.
Домен атрибута определяет тип атрибута сообщения. Разнообразие доменов атрибутов определяет возможные типы данных и смысл атрибутов сообщений. Домен может определять не только тип значения, но и дополнительные логические характеристики (например, уникальность значения).
Текстовый домен используется обычно для передачи текста сообщения. Внутренняя кодировка хранения - Unicode, т.е. СпамоБорец готов к обработке данных на любых языках. При передаче данных через API СпамоБорца значение такого атрибута обычно кодируется в кодировке UTF-8.
При десериализации атрибута текстового домена убираются пробельные символы в начале и в конце строки.
Parameters: |
|
---|
Целочисленный домен может использоваться для передачи различных чисел, связанных с сообщением или его адресатами и адресантами.
При передаче в API СпамоБорца используется тип данных “число”.
Parameters: |
|
---|
Уникальный целочисленный домен отличается от целочисленного только логической привязкой “уникальный”, которая определяет смысл атрибута. Данный домен может использоваться, например, для передачи ID пользователя - отправителя сообщения.
Parameters: |
|
---|
Домен сообщения - это набор доменов атрибутов сообщения. Домен определяет формат сообщений. Домен определяет возможный набор атрибутов сообщения, каждое сообщение может содержать лишь часть перечисленных атрибутов (например, если данных недостаточно).
Домен сообщения хранится в домене в свойстве с именем messageDomain. Наличие домена сообщения является обязательным.
Пример:
MessageDomain(TextAttributeDomain("text"), UniqueIntAttributeDomain("fromID))
Модель анализа сообщений осуществляет классификацию сообщений, выделяя в потоке сообщений, например, спам, флуд, оскорбления, предложения интимного характера и т.п. классы. Работа модели основана на процессе обучения. В режиме обучения модель получает образец исходных данных с необходимой пометкой - к какому классу относится тот или иной элемент. После обучения модель готова на новых данных готова классифицировать поступающие на вход данные.
Модель анализа сообщений поддерживает два условных класса: “хороший” (good) и “плохой” (bad). Интерпретация классов зависит от задачи: одна модель может отвечать за классификацию “спам” - не-“спам”, другая: “мат” - не “мат”. Модель стремится минимизировать ошибки классификации, связанные с классификацией “хорошего” сообщения как “плохого”. Модель в качестве исходных данных на вход принимает текст сообщения.
Модель анализа сообщений хранится в домене в свойствах с произвольным именем.
Хранилище данных используется для хранения данных в рамках домена. Хранилище предоставляет абстракцию коллекции пар (ключ, значение), при этом каждый ключ может иметь срок годности (предельное время хранения). Хранилище может обладать разными характеристиками по скорости доступа, отношения к перезапуску (надежность), а также к распределенному использованию.
Данные такого хранилища хранятся в оперативной памяти сервера, теряются при перезапуске сервера. Может использоваться для хранения ключей с малым временем жизни, использующихся, например, при анализе частоты отправки сообщений за небольшой промежуток времени (полчаса и меньше).
Хранилище на диске обеспечивает постоянное, надежное хранение информации на локальном диске сервера, на котором работает СпамоБорец. Содержимое хранилища не теряется при перезапуске сервера. Скорость доступа ниже, чем у хранилища в памяти.
Правила анализа сообщений выполняют основную работу по анализу сообщений, они применяются в рамках работы firewall к сообщениями относительно текущего домена. Вызов правила синтаксически совпадает с вызовом правила: у правила есть имя, а также набор именованных параметров.
Таким образом, каждое правило в качестве неявного параметра получает сообщение и домен, относительно которого происходит анализ данного сообщения. Домен используется правилами для получения дополнительных параметров настройки, дополнительных компонентов, например, хранилищ данных.
Все правила этого раздела принимают в качестве параметра имя модели анализа сообщения, сама модель должна быть доступна через текущий домен.
Классифицировать сообщение с помощью модели анализа сообщения.
Правило через домен обращается к модели с указанными именем, из сообщения берет значение текстового атрибута (текст сообщения), после чего текст сообщения передается модели на классификацию. Если модель классифицирует данное сообщение как “хорошее”, правило возвращает истину, иначе - ложь.
Parameters: |
|
---|---|
Returns: | истина, если модель классифицирует текст сообщения как “хороший”, и ложь, если наоборот |
Обучить модель анализа сообщений на тексте сообщения, указав категорию сообщения: “плохое” или “хорошее”.
Правило через домен обращается к модели с указанным именем, из сообщения берет значение текстового атрибута (текст сообщения), который передается в модель анализа сообщений на обучение, модель обучается на указанном тексте в соответствие со значением маркера: хорошее это сообщение или плохое.
Правило всегда истинно.
Parameters: |
|
---|---|
Returns: | истина |
Положить сообщение с текущим набором тегов в лог.
Правило находит в домене лог сообщений с указанным именем и помещает в него сообщение. Вместе с сообщением в лог записываются тэги, которые были присвоены сообщению предыдущими действиями firewall. С помощью параметра tag можно добавить к записи в логе (не с самому сообщению) дополнительный тэг.
Правило всегда истинно.
Parameters: |
|
---|---|
Returns: | истина |
Правила данного раздела осуществляют проверки сообщения на валидность (длину, регулярное выражение и т.п.)
Правило применяет к значению текстового атрибута сообщения указанное регулярное выражение, результатом правила является успешность применения выражения.
Parameters: |
|
---|---|
Returns: | результат применения регулярного выражения: соответствует текст ему или нет |
Правило проверяет длину текстового атрибута сообщения.
Правило берет из сообщения текстовый атрибут с указанным именем и сравнивает его длину с указанными пределами (minLength и maxLength). Если параметр minLength задан и длина текстового атрибута меньше minLength, правило вернет “ложь”. Аналгично, если задан maxLength и длина значения атрибута больше maxLength, правило вернет “ложь”. Во всех остальных случаях результатом вычисления будет “истина”.
Parameters: |
|
---|
Правило проверяет соответствие значения атрибута сообщения указанному значению.
Т.е. правило выполняет проверку вида: message.attribute == value ?
Parameters: |
|
---|---|
Returns: | истина, если значение атрибута совпадает с указанным значением |
Правило проверяет наличие указанного атрибута у сообщения
Parameters: |
|
---|---|
Returns: | истина, если у сообщения имеется указанный атрибут |
Данная группа осуществляет проверку текста сообщений.
Правило анализирует значение текстового атрибута сообщение на флуд. Под флудом понимается отправка большого количества похожих фраз в тексте сообщения.
Алгоритм работы: Текст сообщения разбивается на триграммы (например для фразы “привет андрей!” будут составлены следующие триграммы: “при”, “рив”, “иве”, “вет”, “ета”, “тан”, “анд”, “ндр”, “дре”, “рей”, “ей!”), и подсчитывается количество вхождений каждой триграммы. В результате получается последовательность чисел, для которой рассчитывается значение математического ожидания и дисперсии. Сообщение будет считаться флудом (возвращаемое значение “ложь”), если значение математического ожидания меньше minMean, а значение дисперсии больше maxVariance.
Если длина сообщения меньше minLength, правило вернет “истину” (анализ коротких сообщений может дать большую погрешность при рассчете математического ожидания и дисперсии).
При запуске на тестовой базе, содержащей нормальные сообщения, из 16674 сообщений правило не заблокировала ни одного сообщения. При запуске на тестовой базе, содержащей флуд, из 1477 было обнаружено 956 сообщений, содержащих флуд, что составляет 65% от общего числа сообщений.
Parameters: |
|
---|
Данная группа осуществляет проверку на частоту (скорость) тех или иных событий, ограничивая, например, число сообщений в секунду.
Проверка на частоту отправки сообщений с одним и тем же (или похожим) текстом.
Правило берет значение текстового атрибута сообщения. Проверка выполняется, если его длина больше minLength символов. Далее текст сообщения нормализуется (убираются пробельные символы, символы переводятся в нижний регистр). От полученной строки вычисляется md5-хэш. Полученный хэш используется для сравнения сообщений, если хэши равны, то считается, что и сообщения равны.
Правило проверяет, что в течение timeout секунд не было отправлено более count сообщений с одним и тем же хэшом. Если количество отправленных сообщений превышает count, правило возвращает “ложь”, иначе “истину”.
Parameters: |
|
---|
Проверка на частоту отправки сообщений одним пользователем (или группой пользователей).
Группа или пользователь определяются атрибутом сообщения с именем from. Значением этого атрибута, может быть, например, ID пользователя, отправившего сообщение. Правило проверяет, что в течение timeout секунд не было отправлено более count сообщений с одним и тем же значением атрибута from.
Parameters: |
|
---|
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_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 символам, набор тэгов не изменится.
skip_statement ::= "skip" "to" label
Действие skip пропускает действия firewall до тех пор, пока не найдется действие, метка которого будет равна label. Поиск осуществляется только вниз, то есть возвратов “назад” этим правилом организовать нельзя. В случае, если действия с указанной в правиле skip не найдется, такая ситуация считается ошибочным выполнением firewall.
Например:
skip to 10
do messageLogPut()
10: doLengthCheck(maxLength=1000) mark toolong
При таком наборе действий второе действие (do messageLogPut()) не будет никогда выполняться, т.к. первое действие осуществляет безусловный переход к третьему.
stop_statement ::= "stop" "as" decision
Действие stop останавливает выполнение набора действий firewall, возвращая decision в качестве результата выполнения firewall.
Например:
stop as OK
Остановить выполнение firewall, вернуть "OK" в качестве результата выполнения.
Условие 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 вместе с тэгами, которые были им присвоены. Сам лог сообщений хранится в домене, являясь его свойством.
Parameters: |
|
---|
Лог сообщений является кольцевым логом, который хранит сообщения за последние timeChunk*(numChunks-1) секунд в указанном хранилище. По запросу клиента лог может вернуть произвольное подмножество сохраненных записей.
При записи в лог каждое сообщение получает ID, который увеличивается с каждым новом сообщением, и является уникальным в пределах данного лога сообщений.
[1] | http://ru.wikipedia.org/wiki/Теорема_Байеса |
[2] | http://ru.wikipedia.org/wiki/Data_mining |