Нейронная сеть против DDoS'а

    Предисловие


    Некоторые из вас наверняка недавно проходили Stanford'ские курсы, в частности ai-class и ml-class. Однако, одно дело просмотреть несколько видео-лекций, поотвечать на вопросики quiz'ов и написать десяток программ в Matlab/Octave, другое дело начать применять полученные знания на практике. Дабы знания полученые от Andrew Ng не угодили в тот же тёмный угол моего мозга, где заблудились dft, Специальная теория относительности и Уравнение Эйлера Лагранжа, я решил не повторять институтских ошибок и, пока знания ещё свежи в памяти, практиковаться как можно больше.

    И тут как раз на наш сайтик приехал DDoS. Отбиваться от которого можно было админско-программерскими (grep / awk / etc) способами или же прибегнуть к использованию технологий машинного обучения.

    Далее пойдёт рассказ о создании нейронной сети на Python 2.7 / PyBrain и её применении для защиты от DDoS'а.


    Введение


    Что мы имеем: сервер под DDoS'ом средненьким ботнетом (20,000-50,000) и access.log'и с него. Иметь access.log до начала DDoS'а весьма полезно, т.к. он описывает практически 100% легитимных клиентов, а следовательно, отличный dataset для тренировки нейронной сети.

    Что мы хотим получить: классификатор, который по записи в access.log'е говорил бы нам с некоторой долей вероятности от кого пришел запрос: от бота или от человека. Благодаря такому классификатору мы сможем сформировать вектор атаки (набор подсетей) и отправить их в firewall / хостеру.

    Подготовка


    Для тренировки классификатора нам понадобятся два набора данных: для "плохих" и "хороших" запросов. Да, довольно забавно, что для того, чтобы найти ботов, нужно сначала найти ботов. Тут нам как раз и понадобятся grep, например, для того, чтобы вытащить из лога все запросы с IP'шников с большим кол-вом 503'их ошибок (rate limiting nginx'а).

    В итоге у нас должны получиться 3 access.log'а:
    • Dataset с "хорошими" запросами из access.log'а до начала DDoS'а
    • Dataset с "плохими" запросами, нагрепанными на предыдущем этапе.
    • Dataset, который нам необходимо классифицировать, разделив запросы на плохие и хорошие. Обычно это tail -f access.log'а с сервра под DDoS'ом

    Далее необходимо научиться парсить т.н. combined лог nginx'а. Наверняка уже где-то в интернетах есть готовая регулярка, но я изобрёл свой велосипед:
    (?P<ip>[0-9.:a-f]+) [^ ]+ [^ ]+ \[.*\] "(?P<url>.*)" (?P<code>[0-9]+) (?P<size>[0-9]+) "(?P<refer>.*)" "(?P<useragent>.*)"$


    /* В связи с тем, что я написал yet another log parser, в очередной раз вспомнилась идея о изначальной сериализации лога в json, ибо логи на продакшне в большинстве своём не для людей, а для программ. */

    После того как мы научились парсить лог, необходимо выделить features (особенности/маркеры/признаки), составить их словарь и по нему в дальнейшем составлять feature-vector для каждой записи dataset'ов. Об этом дальше.

    Машинное обучение в общем


    Мы остановились на выделении features из логов, для этого берём "хороший" и "плохой" логи и пытаемся найти в них всевозможные features aka признаки. В combined логе их не так уж и много, я взял следующие:

    • Сам запрос, попарсенный на тип запроса(HEAD/GET/POST/etc), url и http_version. Url парсится на протокол, имя хоста, путь и все ключи от query_string
    • Referer, попарсенный аналогично url в запросе.
    • User-Agent, попарсенный волшебной уличной магией, ибо его формат довольно сильно варьируется от браузера к браузеру. В RFC2616 про него сказано совсем немного. Наверняка можно много лучше.
    • status, только в случае кодов 503/404/403. Вообще, во время DDoS'а сервер любит отвечать 500/502, поэтому учитывать будем только вышеописанные коды.

    /* Кстати, первая версия скрипта, которую я использовал для защиты от DDoS'а, содержала злостный баг, благодаря которому не учитывалась примерно половина признаков. Однако, даже в таком состоянии код умудрялся вполне сносно работать, благодаря чему собственно баг долгое время и скрывался. В этом плане очень прав оказался Andrew, говоря, что побеждает не самый умный алгоритм, а тот, которому скормят больше данных. */

    Итак, мы подошли к моменту, когда имеем на руках огромный список всевозможных features, которые могут присутствовать в запросе. Это и есть наш словарь. Словарь нужен для того, чтобы из любого возможного запроса создать feature-vector. Бинарный (состоящий из нулей и единиц) M-мерный вектор (где M — длина словаря), который отражает присутствие каждого признака из словаря в запросе.
    Очень хорошо, если словарь с точки зрения струкруры данных будет hash-таблицей, ибо к нему будет множество обращений типа if word in dictionary.
    Подробнее об этом можно почитать в Lecture Notes 11: Machine Learning System Design

    Пример построения словаря и feature-vector'а


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

    Запись из "плохого" лога:
    0.0.0.0 - - [20/Dec/2011:20:00:08 +0400] "POST /forum/index.php HTTP/1.1" 503 107 "http://www.mozilla-europe.org/" "-"


    Запись из "хорошего" лога:
    0.0.0.0 - - [20/Dec/2011:15:00:03 +0400] "GET /forum/rss.php?topic=347425 HTTP/1.0" 200 1685 "-" "Mozilla/5.0 (Windows; U; Windows NT 5.1; pl; rv:1.9) Gecko/2008052906 Firefox/3.0"


    Получившийся словарь:
    ['__UA___OS_U', '__UA_EMPTY', '__REQ___METHOD_POST', '__REQ___HTTP_VER_HTTP/1.0', '__REQ___URL___NETLOC_', '__REQ___URL___PATH_/forum/rss.php', '__REQ___URL___PATH_/forum/index.php', '__REQ___URL___SCHEME_', '__REQ___HTTP_VER_HTTP/1.1', '__UA___VER_Firefox/3.0', '__REFER___NETLOC_www.mozilla-europe.org', '__UA___OS_Windows', '__UA___BASE_Mozilla/5.0', '__CODE_503', '__UA___OS_pl', '__REFER___PATH_/', '__REFER___SCHEME_http', '__NO_REFER__', '__REQ___METHOD_GET', '__UA___OS_Windows NT 5.1', '__UA___OS_rv:1.9', '__REQ___URL___QS_topic', '__UA___VER_Gecko/2008052906']


    Тестовая запись:
    0.0.0.0 - - [20/Dec/2011:20:00:01 +0400] "GET /forum/viewtopic.php?t=425550 HTTP/1.1" 502 107 "-" "BTWebClient/3000(25824)"


    Её feature-vector:
    [False, False, False, False, True, False, False, True, True, False, False, False, False, False, False, False, False, True, True, False, False, False, False]


    Заметьте, насколько "разрежен" (sparse) feature-vector — такое поведение будет наблюдаться для всех запросов.

    Разделение Dataset'а


    Хорошей практикой является разделение dataset'а на несколько частей. Я бил на две части в пропорции 70/30:

    • Training set. На нём мы обучаем нашу нейронную сеть.
    • Test set. Им мы проверяем, насколько хорошо обучена наша нейронная сеть.

    Такое разбиение обусловлено тем фактом, что нейронная сеть с наименьшим training error (ошибкой на training set) будет выдавать большую ошибку на новых данных, ибо мы «переобучили» сеть, заточив её под training set.
    В дальнейшем, если придётся озадачиться выбором оптимальных констант, dataset надо будет разбить на 3 части в соотношении 60/20/20: Training set, Test set и Cross validation. Последний как раз и будет служить для выбора оптимальных параметров нейронной сети (например weightdecay).

    Нейронная сеть в частности


    Теперь, когда у нас на руках больше нет никаких текстовых логов, а есть только матрицы из feature-vector'ов, можно приступать к построению самой нейронной сети.

    Начнём с выбора структуры. Я выбрал сеть из одного скрытого слоя размером с удвоенный входной слой. Почему? Всё просто: так завещал Andrew Ng в случае, если не знаете с чего начать. Думаю, в дальнейшем с этим можно поиграться, порисовав графики обучения.
    Функцией активации для скрытого слоя выбрана многострадальная сигмойда, а для выходного слоя — Softmax. Последний выбран на случай, если придётся делать
    многоклассовую класиффикацию c mutually exclusive классами. Например, "хорошие" запросы отправлять на бэкенд, "плохие" — в бан на фаерволе, а "серые" — разгадывать капчу.

    Нейронная сеть склонна к уходу в локальный минимум, поэтому у себя в коде я строю несколько сетей и выбираю ту, у которой наименьший Test error (Заметьте, именно ошибка на test set, а не trainig set).

    Disclaimer


    Я не настоящий сварщик. О Machine Learning я знаю только то, что подчерпнул из ml-class и ai-class. На питоне программировать начал относительно недавно, а код ниже был написан минут за 30 (время, как вы понимаете, поджимало) и в дальнейшем был лишь слегка подпилен напильником.

    Код


    Сам скрипт небольшой — 2-3 страницы A4 в зависимости от шрифта. С ним можно ознакомиться тут: github.com/SaveTheRbtz/junk/tree/master/neural_networks_vs_ddos

    Также этот код не самодостаточен. Ему всё равно нужна скриптовая обвязка. Например, если IP сделал N плохих запросов в течение X минут, то банить его на firewall'е.

    Производительность


    • lfu_cache. Портировал с ActiveState, дабы сильно ускорить обработку запросов-"высокочастотников". Down-side — повышенное потребление памяти.
    • PyBrain, внезапно, написан на python и поэтому не очень быстр, однако, он может использовать ATLAS-based-модуль arac, если при создании сети указать Fast=True. Подробнее про это можно почитать в документации к PyBrain.
    • Распараллеливание. Свою нейронную сеть я обучил на довольно "толстом" серверном Nehalem'е, однако, даже там чувствовалась ущербность однопоточного обучения. Можно поразмыслить на тему распараллеливания обучения нейронной сети. Простое решение — тренировать сразу несколько нейронных сетей параллельно и из них выбирать лучшую, но это создаст дополнительную нагрузку на память, что тоже не очень хорошо. Хотелось бы более универсальное решение. Возможно имеет смысл просто переписать всё на C, благо вся теоретическая база в ml-class'е была расжевана.
    • Потребление памяти и кол-во features. Хорошей оптимизацией по памяти являлся переход со стндартных питоновских массивов на numpy'ные. Так же уменьшение размера dictionary и/или использование PCA может очень хорошо помочь, об этом чуть ниже.

    На будущее


    • Дополнительные поля в лог. В combined лог можно добавить ещё много всего, стоит подумать на тему, какие поля помогут в идентификации ботов. Возможно, имеет смысл учитывать первый октет IP адреса, ибо в не интернациональном web-проекте китайские пользователи вероятнее всего боты.
    • Principal Component Analysis. Позволит сильно сократить размерность feature-vector'ов, тем самым уменьшив время тренировки нейронной сети.
    • Preprocessing/Normalizing для features. Например, всё, что попадает под regexp [a-fA-F0-9]{32}, можно заменять словом __MD5__, всё, что похоже на дату — словом __DATE__ и т.д., тем самым уменьшить кол-во малочастотных features и соответственно размер словаря.
    • Тюнинг констант и струкруры нейронной сети. Текущие были взяты с потолка, а именно из мануала по созданию классификатора на базе PyBrain (да-да, помните, я писал, что код был написан ну оооочень быстро). Имело бы смысл порисовать графики обучения нейронной сети при разных значениях параметров, благо matplotlib под рукой.
    • Online обучение. Стратегия умных атакующих часто меняется. Хорошо бы было придумать способы для до-/переобучения нейронной сети "на ходу". Впрочем, это легче сказать, чем сделать.

    Ещё почитать


    Machine Learning Lecture Notes — Записи по курсу ml-class.
    UFLDL — Unsupervised Feature Learning and Deep Learning. Так же от профессора Andrew Ng.

    Вместо заключения


    Весьма интересно, как к решению проблемы классификации подходят сварщики настоящие, например highloadlab. Однако, что-то мне подсказывает, что их алгоритмы — это тайна из серии формулы ранжирования Яндекса.
    Share post

    Comments 46

      +9
      Зашел в профиль плюсануть, а там уже.
      Хороший топик, читал с интересом.
        +2
        Идея хорошая, но написать такое когда УЖЕ идет ддос атака практически нереально ( сроки маленькие + стресс ). Раскопаю ка я свой диплом… нейросеть на питоне для управления металлургическим печами )))
          0
          Если давление во времмя DDoS'а мешает программировать, то конечно нужно блокировать старыми добрыми методами, однако потом ничто не мешает собрать логи и уже в спокойной обстановке попробовать написать что-нибудь интересное.
            0
            А можно подробнее про Ваш диплом? Что делали, для чего нейронную сеть использовали, получилось ли что-то живое в итоге, или все только на бумаге?
            +16
            Не учитывается самое важное — поведение бота. То есть анализировать надо не одну строчку, а последовательность строк с одного IP…
              +6
              Мне кажется, поведение клиента — это вообще единственный критерий, где нейронная сеть могла бы пригодиться. Для простого отсева клиентов по их IP сеть практически бесполезна.
                0
                Да, я по началу тоже думал принимать решения базируясь не на конкретном запросе, а на блоках, сгруппированных по IP или лучше session_id. Но потом пришла ещё пара мыслей:
                1) Строить некий call-graph для каждой сессии и анализировать его.
                2) Использовать js для записи и анализировать поведение пользователей.

                Но это уже тема для отдельного поста или даже полноценного ПО.
                  0
                  Да, вот цитата из статьи: «Также этот код не самодостаточен. Ему всё равно нужна скриптовая обвязка. Например, если IP сделал N плохих запросов в течение X минут, то банить его на firewall'е.»

                  Нужно найти способ алгоритмизировать анализ поведения во времени, тогда будет интеллектуальная система! Хотя, для отсева IP-адресов явных ботов, предложенная методика отлично подойдет.
                  +3
                  Можно заранее обучить сеть определять хороших посетителей (то есть тех, кто уже посещал сайт). Пока дела идут хорошо, мы ее не используем, но при этом постоянно переучиваем. При начале DDoS'а мы ее задействуем. Очевидно, что она не избавит от всех атакующих, но может серьезно урезать их число.
                    +1
                    Такая идея определенно защитит, но не пропустит новых пользователей. Мне кажется такой принцип является наиболее дешевым и простым.
                      +1
                      К сожалению такая нейронная сеть скорее всего сойдётся на том, что будет любой запрос классифицировать как хороший, поэтому такой метод недееспособен.
                        0
                        Если не писать в белый список данные во время атаки, то все будет нормально.
                          0
                          Наверное, вы имели ввиду обратное, что любой запрос, кроме тех, что у нее были в обучающем множестве, сеть будет определять как плохой. Но ведь для того и существует тестирующее множество, чтобы сеть не переобучилась.
                            0
                            Нет, я имел в виду именно то, что написал.

                            Давайте поясню:
                            Давайте отбросим всю математику за процессом обучения и представим нейронную сеть как чёрный ящик. Вы в него кидаете данные, а он выдаёт класс этих данных. При обучении только «хорошими» запросами вы научите нейронную сеть говорить, что запрос хороший, на ЛЮБЫЕ входные данные, ведь именно такое поведение будет выдавать наименьшие ошибки на training и test set'ах.
                              0
                              По поводу «наименьших ошибок на training и test set'ах». Вы совершенно правы, что на обучающем множестве с каждым пробегом ошибка будет падать. Но на тестовом множестве с определенного момента она начнет расти. В этот момент сеть обучилась, и обучение необходимо остановить, поскольку дальше пойдет переобучение.
                              Давайте для примера упростим задачу. Будем считать, что у нас есть только данные GeoIP (широта и долгота). Аудитория нашего сайта — территория России. После обучения на «хороших» запросах наша сеть с определенной погрешностью определяет запросы с территории России. Начинается DDoS. Большинство запросов с территории России сеть пропускает, а все остальные запросы — блокирует.
                              При таком обучении тоже идет классификация, но неявная. «Хорошие» запросы противопоставляются «всем остальным возможным».
                                0
                                «Но на тестовом множестве с определенного момента она(ошибка) начнет расти.»

                                Моё утверждение было таково: Нейронная сеть обученая только хорошими запросами сойдётся к тому, что будет выдавать «хорошо» на любой ввод. Теперь вопрос: как сеть которая выдаёт на любые входные данные «хорошо» может хоть раз ошибится на тестовом множестве?

                                ПС. Ещё вопрос: а вы пробовали сами проделать вышеописаный вами эксперимент? Можно и без эксперимента, просто расписав формулы на листочке.
                                  0
                                  Просто чтобы Вы не считали меня «человеком с улицы» скажу, что в 2001 году я защитил магистерскую диссертацию в ГУ-ВШЭ по теме «Нейросетевые технологии в финансовом анализе».

                                  Мои утверждения:
                                  1) Нейронная сеть, обученная на «хороших» запросах без тестирующего множества («переученная»), будет на любой запрос (кроме тех, что ей были представлены на обучение) отвечать, что он «плохой». Все потому, что она «запомнила» исходные данные.
                                  2) Нейронная сеть, обученная на «хороших» запросах с тестирующим множеством, будет на «хороший» запрос отвечать, что он «хороший», а на «все остальные», что они «не хорошие». При этом если «плохой» запрос неотличим от «хорошего», то сеть его также будет считать «хорошим». В примере, приведенном выше, если «плохой» запрос будет идти из России, а не из Китая, то сеть его пропустит.

                                  Непонимание возникло потому, что Вы фокусируетесь на «плохих» запросах. А я говорю о «хороших». Есть аналогия из мира электронной почты и борьбы со спамом — «черный» и «белый» списки. Приведенный Вами метод аналогичен «черному», упомянутый мною — «белому».
                                    0
                                    Хммм, всё равно не могу понять: как без «плохих» примеров, даже при наличии test set'а, запрретить сети отвечать на всё запросы «хороший». Ведь именно такой подход обеспечит ей 0% ошибок на Training set и Test set.

                                    Все потому, что она «запомнила» исходные данные.

                                    Ммм… Для того чтобы она действительно смогла «запомнить» все feature vector'а нужно очень большое количество нейронов (= кол-во features * кол-во запросов). Так же скорее всего придётся вводить какие-то ограничения на количество одновременно активных нейронов (sparsity), иначе сеть опять сойдётся на «всё хорошо». Ещё к этому нужно добавить, что я не очень хорошо понимаю как поощрять сеть за удачные «запоминания» и наказывать за неудавшиеся. Хотя, логично предположить, что обучить нейронную сеть запоминать возможно — яркий тому пример наш мозг.

                                    ПС. Так же я не понял разницу между вашими 1) и 2).
                                      0
                                      Во-первых, по поводу «0% ошибок на Training set и Test set». По ссылкам вы найдете два графика — в теории и на практике (ссылка на статью). На графиках видно, что ошибка на тестовом множестве с определенного момента начинает расти.

                                      Во-вторых, не имея «плохих» примеров, их можно сконструировать из «хороших», инвертируя булевы значения и интервалы. Очевидно, что это будут не «плохие» значения в вашем понимании, а просто «все остальные возможные».

                                      В-третьих, «запомнить» для нейронной сети, если это само не является целью, — это самое плохое, что с ней может случиться. Ее цель — «обобщать».

                                      P.S. Позвольте проиллюстрировать разницу на этом графике (ссылка на статью). Когда сеть не переучена (нижний рисунок), новое наблюдение классифицируется как принадлежащее «зеленой области». Когда сеть переучена (верхний правый рисунок), новое наблюдение не попадает в зеленую область. Тестовое множество помогает нам эмулировать поступление новых данных и не давать сети переучиваться.
                                        0
                                        1) Она может начать расти только если в тестовом наборе есть «плохие» примеры, иначе ошибка будет 0% и там и там.
                                        2) Вот это уже интересно. То есть «плохие» примеры всё же есть, но они генерируются из «хороших». Правда похоже это возможно делать только имея на руках единовременно все «хорошие», иначе сложно ответить на вопрос: не встречался/встретится ли только что сгенерированный «плохой» пример в «хорошем» наборе. Также, пока не очень понимаю как генерировать словарь для создания feature vector'ов и рассчитывать размер input layer без наличия на руках всех запросов единовременно. Впрочем, некоторыи идеи на этот счёт есть.
                                        3) С этим согласен.
                                          0
                                          Нейросетевые технологии могут быть применены не только к задаче классификации (то, что вы описали в обсуждаемой статье), но и к задаче кластеризации (то, о чем я безуспешно пытаюсь вам сказать). Для решения первой нам нужно не менее двух классов, для решения последней — просто набор данных.

                                          Давайте вернемся к вышеупомянутому примеру, где все «хорошие» запросы шли с территории России, а про «плохие» мы и слыхом не слыхивали.
                                          Сеть будем обучать только на «хороших» запросах. На вход будем подавать вектор [lat, lng]. На выходе будем получать значения из интервала (0, 1). Ошибкой для нас будет разность между единицей и фактическим выходом из сети (не стандартное отклонение — для наглядности). Разделим все наши «запросы» на два множества — обучающее и тестовое. Начнем обучение сети.
                                          Средняя ошибка на первом прогоне будет в районе 0.5 — для обоих множеств. С каждым прогоном эти ошибки будут падать, так как мы заставляем сеть выдавать результат все более близкий к единице. Но на определенном этапе ошибка обучающего множества упадет, а ошибка тестового множества — вырастет. Почему?
                                          К примеру, потому, что в обучающем множестве не было ни одного запроса из Надыма, а в тестовом множестве он был.
                                          Обучение только на «хороших» данных — это нетипичное решение типичной задачи кластеризации.
                                            0
                                            Я в вашем примере не могу понять одну вещь: откуда в тестовой выборке появится Надым, ведь он не «хороший»?
                                              0
                                              К примеру, всего «хороших» запросов у нас было 100 (в том числе Надым). Четверь из них (25 запросов, в том числе Надым) мы отобрали случайным образом и сформировали из них тестовое множество. Оставшиеся три четверти (75 запросов) — это наше обучающее множество.
                                              В данной постановке задачи у нас вообще нет понятия «плохие» запросы. Когда начинается DDoS, мы блокируем все, что не узнается.
                                        0
                                        /* На случай, если кто-то, всё же, до сюда дочитал */


                                        avrelian Натолкнул меня на интересную мысль: Как можно использовать Нейронную Сеть для кластеризации данных?

                                        После прочтения нескольких десятков pdf'ок по Clusterization using Neural Networks стали выделятся некоторые алгоритмы для unsupervised обучения нейронных сетей. Особо можно выделить SOTA (Self Organising Tree Algorithm — Развитие идеи SOM — Self-Organized Maps) и семейство алгоритмов ART*. Остановлюсь подробнее на последних, ибо они более напоминают устройство нашего мозга: алгоритм устроен на сравнении ожиданий с данными от сенсоров. Если посмотреть на матчасть, то видно, как алгоритм умудряется балансировать между обучением и запоминанием. Так же, довольно интересной для новичков в ML будет являться структура нейронной сети используемой в ART*/SOTA алгоритмах.

                                        В общем будет с чем поиграться на досуге.
                          +1
                          «Можно поразмыслить на тему распараллеливания обучения нейронной сети. Простое решение — тренировать сразу несколько нейронных сетей параллельно и из них выбирать лучшую, но это создаст дополнительную нагрузку на память, что тоже не очень хорошо.»

                          Совсем не хорошо, по сути, будут растрачиваться ресурсы на обучение 2 разных сетей, вместо одной.
                          Оптимальным вариантом считается параллельное вычисление изменения весовых коэффициентов, к примеру, такой модификации легко подвергаются алгоритмы обучения QuickProp и PRProp, где при вычислении весовых коэффициентов используются:
                          • — их значения на предыдущей итерации
                          • — прошлое изменение коэффициента
                          • — значение градиента на текущей и предыдущей итерации

                          Следовательно, вычисление каждого коэффициента можно распараллелить.
                            0
                            Эта моя фраза говорила примерно о следующем: запускать параллельно несколько однопоточных обучений или последовательно запускать многопоточные обучения — это почти одно и тоже. А нам похоже всё равно придётся несколько сетей тренировать, ибо никто не гарантирует, что мы при обучении не упрёмся в локальный минимум. Так же дополнительные нейронные сети нужны для выбора констант — weightdecay и momentum. Но это конечно если я правильно понял теорию.

                            ПС. А так да, подход с многопоточным обучением одной нейронной сети более масштабируем, чем несколько паралельных однопоточных обучений.
                            ППС. ИМХО, первым кандидатом на распараллеливание является этап перемножения матриц.
                            ПППС. За QuickProp и PRProp отдельное спасибо, пойду про них почитаю…
                            +11
                            Решение жизнеспособное, как функция обнаружения критериев, но практически ненужная.
                            Отфильтровывать бота по единичным запросам гораздо проще обычным grep по известным критериям, их немного. Строить для этого НС нецелесообразно. У НС есть еще один минус, боты могут получить команду на изменение типа атаки. Поправить скрипты фильтрации просто, переобучить НС в общем случае сложно (дорого по времени и вычислительным ресурсам).

                            НС имела бы смысл, если бы вы реализовали обнаружение бота по истории его запросов, т.е. поведенческий анализ, но это уже значительно сложнее и MLP тут не выручит.

                            Резюмируя, подход рабочий, необычный, но практически невостребованый. Данную задачу при конкретных указанных условиях grep выполняет быстрее, проще и гибче.
                              +4
                              Ну как вам сказать… Переписание скриптов с grep'ами — это тоже обучение нейронной сети, которую мы привыкли называть мозгом. Оно, кстати, тоже занимает некоторое время.
                              0
                              Вы не поверите, как вы вовремя. Я через неделю защищаю диплом именно по этой теме.

                              По образованию я — специалист по информационной безопасности.
                                +5
                                Отличная статья. И как раз для Хабра.
                                Для улучшения результатов разрешите посоветовать небольшие усовершенствования:

                                1) После первого MPL легко определить значимость входов (меняем один вход в возможном диапазоне, смотрим как меняется выход). Незначимые входы — зло.
                                2) На отобранных значимых входах учим новую сеть — она будет меньше и точнее (т.к. убили часть шума)
                                3) Пр обучении второго MPL лучше использовать функционал Тихонова — интеллект сети (умение обобщать) будет выше.

                                А вообще для данной задачи дерево решений наверное было бы лучше — быстрее и возможно точнее. имхо.
                                  0
                                  Если я правильно понял — с пунктами 1) и 2) должен справиться PCA.
                                  А вот про третий пункт (и дерево решений, кстати) нужно будет поискать в интернетах, спасибо!
                                • UFO just landed and posted this here
                                    –1
                                    Проблема нейронки — переучивание — долгий процесс.
                                    Не проще ли байзанов фильтр имплементировать? Он быстрее будет в плане переучивания.
                                    И да, обязательно нужен интерфейс.
                                      0
                                      Насчёт байесовского фильтра — интересная идея на подумать, спасибо.
                                        0
                                        Байесовский вряд ли подойдет вам, он не способен к обобщению. То есть он входные фичи отдельно классифицирует и возвращает умноженные коэффициенты вероятностей для каждой из них отдельно.

                                        Я использую SVM для классификации, чего и вам желаю)
                                      –1
                                      Какой-то уж через-чур простой и прямолинейный ботнет вам попался.

                                      А что бы вы делали, если ботнет был заточен под ваш сайт и был обучен
                                      1) на поведении реальных юзеров и посылал «хорошие» заголовки
                                      2) на структуре вашего сайта
                                      ?
                                      0
                                      Не поверите, но нейронную сеть начал писать только после того как не смог сходу «нагрепать» запросы от ботов, вот, например, угадайте какой из запросов тут от бота:
                                      0.0.0.0 - - [20/Dec/2011:18:13:08 +0400] "GET /forum/index.php HTTP/1.1" 200 25364 "-" "Opera/9.80 (Windows NT 5.1; U; ru) Presto/2.9.168 Version/11.52"

                                      0.0.0.0 - - [20/Dec/2011:15:56:40 +0400] "GET /forum/index.php HTTP/1.1" 200 25364 "-" "Opera/9.80 (Windows NT 6.1; U; ru) Presto/2.10.229 Version/11.60"

                                      Так что с заголовками было всё ок.

                                      Как я понимаю, нейронная сеть мне хорошо помогла «поймать» продвинутый, но всё же ограниченный генератор User-agent'ов аттакующего.
                                        0
                                        Вопрос по производительности.

                                        Ясно, что есть проблемы, но не указан их порядок.

                                        Т.е. хочется узнать
                                        1. размер тренировочного массива данных (приблизительное количество записей в логах)
                                        2. сколько времени заняла тренировка сети.
                                          0
                                          Производительность очень сильно зависит от реализации. Цифры я не озвучивал специально, ибо это всего лишь набросок, темболее на питоне. Любые числа названные мной будут на порядки отличаться от продакш системы.
                                            0
                                            Тем не менее интересен сам порядок цифр. Я до этого не сталкивался с практическим machine learning. Есть только базовые теоретические знания и желание перейти к практике (есть ряд подходящих задач). Всюду говорят, что обучение может занять значительное время, но непонятно: значительное — это сколько?
                                            20 секунд для массива из миллиона элементов и 100 features — это нормально, много, мало? Или при использовании неоптимизированнных однопотоковых алгоритмов для подобных массивов следует ожидать часов и дней на тренировку сети?

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

                                            P.S. Кстати, сколько всего признаков получилось?
                                              +1
                                              У меня обучение занимало от секунд (1000 экземпляров, ~300 признаков) до дней (1,000,000 экземпляров, ~10000 признаков). Но, ещё раз замечу, что это ни о чём не говорит — всё слишком сильно зависит от алгоритма.
                                          0
                                          Было интересно, спасибо. Я тоже, когда проходил обучение, задавался вопросом на тему фильтрации ботов при ддос атаках и рассматривал в том числе и нейросеть. Помнится тогда мне показалось, что anomaly detection более органично подошло бы под эту задачу — много положительных примеров и заранее не известны отрицательные.
                                            0
                                            Я тоже думал по началу это сделать на определении аномалий, но там есть нюанс: нужно вводить дополнительные features являющиеся комбинацией существующих, чтобы ловить запросы с OS Windows ME и referer'ом fc-zenit.ru, а это очень сильно увеличивает их кол-во. Например, из 100 признаков мы получим 5050, если захотим ловить по комбинации двух признаков, а если по трём, то все 171700.
                                              0
                                              Можно попробовать зайти с другой стороны. Например в качестве features брать количество заголовков у запроса, количество разных агентов (useragent) для одного ip за определенный период времени (за час, например), высчитывать общую частоту запросов для разных агентов (вдруг появится слишком частый или наоборот — много уникальных), тоже самое с запрашиваемыми страницами (url), наличием или отсутствием кук, рефереров (и их частота появления) и т.д. По идее наберется разумное количество features.
                                            0
                                            Плюсанул бы карму, да у самого не хватает по новым правилам. Хороший топик, спасибо. У самого диплом по нейронным сетям)

                                            Only users with full accounts can post comments. Log in, please.