Машинне навчання замість DPI. Будуємо класифікатор трафіку

image

Навряд чи можна уявити світ сучасних мережевих технологій без DPI (deep packet inspection – глибокий аналіз пакетів). На ньому тримаються системи виявлення мережевих атак, левова частка політик безпеки корпоративних мереж, шейпінг і блокування користувача трафіку оператором зв'язку – так-так, щоб виконувати вимоги Роскомнадзора, кошти DPI зобов'язаний мати кожен провайдер.

І все-таки, при всій своїй затребуваності, DPI – витратний звір. На магістральних лініях зв'язку вартість апаратного рішення (про софт тут мова йти не може) обчислюється мільйонами зелених американських чоловічків. А програмні рішення на кшталт OpenDPI підходять тільки для невеликих корпоративних і кампусних мереж. Справа все в тому, що швидко визначити протокол прикладного рівня за шаблоном, яких можуть бути тисячі — завдання дуже дешева.

У даній статті я хочу запропонувати спосіб ефективного вирішення одного з головних завдань DPI – визначення протоколу прикладного рівня – при цьому не звіряючись зі списком широко відомих портів (well-known ports) і не дивлячись на корисну навантаження пакетів. Взагалі.

Підхід до вирішення
По-перше, визначимося з об'єктом класифікації — для якоїсь сутності ми будемо визначати протокол прикладного рівня?

У засобах DPI, як правило, об'єктом класифікації виступає потік трафіку транспортного рівня – це сукупність IP-пакетів, у яких збігається протокол транспортного рівня, а також невпорядкована пара endpoint-ів: <(ip джерела, порт джерела), (ip призначення, порт призначення)>. Ми теж будемо працювати саме з такими потоками.

Ідея, яка лежить в основі запропонованого методу, полягає в тому, що різні програми, що користуються різними протоколами, також генерують потоки транспортного рівня з різними статистичними характеристиками. Якщо акуратно і чітко визначити набір статистичних показників потоку, то за значеннями цих показників можна буде з високою точністю передбачати, яке додаток згенерувало цей потік, і, відповідно, який протокол прикладного рівня цим потоком переноситься.

Перш ніж визначати ці метрики, введемо кілька визначень:
  • Клієнт – ініціатор TCP-з'єднання або відправник першої UDP-дейтаграми потоку, залежно від протоколу транспортного рівня;
  • Сервер – приймаюча сторона TCP-з'єднання або адресат першої UDP-дейтаграми потоку, залежно від протоколу транспортного рівня.
  • Порція даних – сукупність корисного навантаження прикладного рівня, яка передавалася від однієї сторони іншій (від клієнта до сервера або навпаки), і при цьому не переривалася корисним навантаженням з іншого боку.
Останнє визначення вимагає деякого пояснення, так що мій внутрішній Мікеланджело поспішає на допомогу:

image
В даному прикладі після TCP-рукостискання клієнт починає передавати корисну навантаження – отже, починається порція даних з боку клієнта. Поки сервер не посилає ніякої корисної навантаження у відповідь, а всього лише шле ACK, порція даних з боку клієнта триває. Коли сервер відчуває необхідність передати якусь навантаження прикладного рівня, порція даних клієнта закінчується, і починається порція даних сервера. Як нескладно зрозуміти, вся передача корисного навантаження являє собою чергування порцій даних то з одного, то з іншого боку. При дуже інтенсивному обміні даних з обох сторін порції даних можуть вироджуватися в окремі пакети IP.

Статистичні метрики потоку
Всі наші статистичні характеристики потоку будуть танцювати навколо чотирьох рядів чисел:
  • Послідовність розмірів сегментів транспортного рівня (TCP або UDP), відправлених з боку клієнта;
  • Послідовність розмірів сегментів транспортного рівня, відправлених з боку сервера;
  • Послідовність розмірів порцій даних, відправлених з боку клієнта;
  • Послідовність розмірів порцій даних, відправлених з боку сервера;
Для представленого на малюнку вище короткого прикладу це ряди будуть мати наступні значення:
  • Розміри сегментів з боку клієнта: [220, 520]
  • Розміри сегментів з боку сервера: [720, 420]
  • Розміри порцій даних з боку клієнта: [700]
  • Розміри порцій даних зі сторони сервера: [1100]
Ці 4 ряди чисел (як ми побачимо згодом) дуже добре характеризують потік даних, і на їх основі можна досить точно вгадати протокол прикладного рівня.

Включивши фантазію, сформулюємо статистичні характеристики потоку даних, відштовхуючись від цих 4 рядів чисел:
  1. Середній розмір пакета з боку клієнта
  2. Стандартне відхилення розміру пакета з боку клієнта
  3. Середній розмір пакета з боку сервера
  4. Стандартне відхилення розміру пакета з боку сервера
  5. Середній розмір порції даних з боку клієнта
  6. Стандартне відхилення розміру порції даних з боку клієнта
  7. Середній розмір порції даних зі сторони сервера
  8. Стандартне відхилення розміру порції даних зі сторони сервера
  9. Середнє число пакетів на порцію даних з боку клієнта
  10. Середнє число пакетів на порцію даних зі сторони сервера
  11. ККД клієнта – кількість переданої навантаження прикладного рівня, поділена на загальну кількість переданої навантаження прикладного та транспортного рівня
  12. ККД сервера
  13. Співвідношення байт – у скільки разів клієнт передав більше даних, ніж сервер
  14. Співвідношення корисного навантаження – у скільки разів клієнт передав більше даних, ніж сервер
  15. Співвідношення пакетів – у скільки разів клієнт передав більше пакетів, ніж сервер
  16. Загальна кількість переданих байт з боку клієнта
  17. Загальна кількість переданої навантаження прикладного рівня з боку клієнта
  18. Загальна кількість переданих сегментів транспортного рівня з боку клієнта
  19. Загальна кількість переданих порцій даних з боку клієнта
  20. Загальна кількість переданих байт з боку сервера
  21. Загальна кількість переданої навантаження прикладного рівня з боку сервера
  22. Загальна кількість переданих сегментів транспортного рівня з боку сервера
  23. Загальна кількість переданих порцій даних зі сторони сервера
  24. Розмір першого сегменту транспортного рівня з боку клієнта
  25. Розмір другого сегменту транспортного рівня з боку клієнта
  26. Розмір першого сегменту транспортного рівня з боку сервера
  27. Розмір другого сегменту транспортного рівня з боку сервера
  28. Розмір першої порції даних з боку клієнта
  29. Розмір другої порції даних з боку клієнта
  30. Розмір першої порції даних зі сторони сервера
  31. Розмір другої порції даних зі сторони сервера
  32. Тип протоколу транспортного рівня (0 — UDP, 1 — TCP)
Тепер треба пояснити декілька моментів.

По-перше, ознаки виду «загальна кількість Х» самі по собі нестабільні, тому що їх значення залежить від того, як довго ми спостерігаємо за потоком. Чим більше спостерігаємо, тим, природно, більше буде передано і байт і прикладної навантаження, і сегментів, і порцій даних. Щоб додати визначеності ці показники, ми в майбутньому будемо розглядати не весь потік цілком від початку спостереження до кінця, а деякий зріз кожного потоку за першим N сегментах транспортного рівня. При обрахунку всіх перерахованих метрик будемо використовувати тільки перші N сегментів.

По-друге, може бути незрозуміло, навіщо нам у показниках розмір першого і другого сегмента і порції даних з кожної сторони. Як показано в одній з наукових робіт на цю тему[1] (посилання на джерела), розміри перших декількох IP-пакетів можуть нести багато інформації про використовуваному протоколі. Так що зайвими ці показники не будуть.

Тепер визначимося, як ми будемо намагатися вгадати протокол прикладного рівня конкретного потоку, маючи на руках розраховані статистичні метрики. Тут нам допоможе машинне навчання. Розглянута задача – це в своїй класичній формулюванні завдання класифікації об'єктів на кілька класів.

У кожного об'єкта цілих 32 характеристики, причому релевантність кожної з них наявної в об'єкта мітці класу на даному етапі дослідження залишається під питанням. Тому розумно буде вибрати популярний алгоритм машинного навчання «Випадковий Ліс» («Random Forest»), оскільки він слабо чутливий до шумів і кореляції ознак (а деякі наші статистичні показники, швидше за все, сильно корелюють між собою).

Даний алгоритм працює за принципом «навчання з учителем». Це означає, що нам потрібна деяка вибірка об'єктів, для якої вже відомі мітки класів. Цю вибірку ми розділимо в пропорції 1 до 2 на навчальну і перевірочну. На навчальній вибірці ми проведемо навчання моделі (в нашому випадку навчання полягає в побудові набору вирішальних дерев), а на перевірочної будемо оцінювати, наскільки добре модель справляється з поставленим завданням.

Час жнив
З методологією проведення експерименту тепер все зрозуміло, залишилося знайти сам трафік, характеристики якого будемо розраховувати.

Ніякої провайдер, звичайно, не пустить нас у свою мережу збирати трафік – хто там знає, які дані ми будемо збирати? Обійдемося кустарними умовами. Протягом кількох днів я проводив захоплення трафіку свого власного комп'ютера, попутно роблячи звичайні справи – сидів у ВК, дивився відео на Youtube, зробив кілька дзвінків в Скайпі, скачав парочку торрентів. В результаті вийшло більше 3 Гб захопленого трафіку.

Тепер згадаємо, що крім самого трафіку нам також потрібно для кожного захопленого потоку достовірно визначити переносимий їм протокол прикладного рівня. І ось тут нам допоможуть засоби DPI, конкретно – бібліотека nDPI. У комплекті з цією бібліотекою поставляється приклад аналізатора трафіку під назвою ndpiReader – він нам і стане в нагоді. Приємний бонус полягає в тому, що це додаток саме за нас розділить всі наші сирі дампи трафіку на потоки транспортного рівня, так що нам цим навіть не доведеться займатися.

Але все-таки покопатися в надрах pcap-файлів буде потрібно. Для цього використовуємо бібліотеку dpkt. На превеликий жаль, її не портували на третю версію Python, так що скрипт обробки pcap-файлів напишемо на другій версії мови.

Збираючи всі вище викладені воєдино, напишемо скрипт, який перетворює PCAP-файли в таблицю ознак і експортує її в формат CSV. Посилання на репозиторій з цим скриптом в кінці статті.

What time is it? Classification time!
Так-так, нарешті ми дісталися до того, заради чого все затівалося!

Але перед тим, як з корабля на бал запихати всю таблицю ознак в перший-ліпший Random Forest, розглянемо дані трохи уважніше. Ось список прикладних протоколів та кількість потоків кожного протоколу, що є в нашій вибірці:

image

Перше, що хочеться зробити – злити весь трафік SSL_No_Cert у SSL, тому що це по суті одне і те ж.

Друге – викинути трафік Apple, NTP, Unencrypted_Jabber і Unknown. У перших трьох протоколів занадто мало потоків, щоб проводити класифікацію, а під Unknown може ховатися все, що завгодно.

Тепер розділимо наші дані на навчальну і перевірочну вибірки. Отримаємо такий розклад:

image

В якості параметрів алгоритму Random Forest після декількох експериментів були обрані наступні значення:
  • Кількість дерев: 27
  • Критерій: ентропія
  • Максимальна глибина дерева: 9
Згадаймо, що деякі наші статистичні характеристики зобов'язують нас фіксувати обсяг розглянутого трафіку для кожного потоку. Для початку візьмемо зріз трафіку побільше – 1000 перших сегментів у кожному потоці. Перевіримо, чи можна взагалі передбачити за нашими статистичними метрик протокол прикладного рівня. Барабанний дріб!

image

Вище представлена таблиця точності і повноти прогнозів по кожному класу. Точність для класу K – це частка пророкувань виду «об'єкт X належить до класу K», які виявилися вірними. Повнота для класу K – кількість об'єктів X, які розпізнані класифікатором як належні класу K, поділена на загальну кількість належать класу K об'єктів. Ф-міра – середнє гармонічне повноти і точності.

Ну і трохи більш проста таблиця:

image

Тут в кожній комірці вказано число, яке означає кількість випадків, коли потік трафіку, що належить зазначеним у заголовку рядка класу, був класифікований як належить зазначеним у заголовку стовпця класу. Тобто, числа на головній діагоналі – правильні класифікації, числа за її межами – різного роду помилки.

В цілому, здається, що класифікатор справляється зі своєю роботою непогано. За винятком рідкісних помилок, все передбачення виявляються вірними.

Алгоритм машинного навчання «Випадковий Ліс» хороший ще й тим, що він може дати нам інформацію про те, які ознаки виявилися більш корисними, ніж інші. З цікавості поглянемо на найважливіші ознаки:

image

Топ стабільно займають ознаки, зав'язані на статистичні характеристики клієнтської сторони. Звідси можна зробити висновок, що саме клієнти різних додатків відрізняються між собою найбільше, а сервери – менше.

Від сервера затесався тільки розмір другого пакету. Це легко пояснюється тим, що за розміром другого пакету можна дуже просто виділити SSL з решти трафіку, адже в другому пакеті сервера передається сертифікат.

Приємно дивує те, що тип протоколу транспортного рівня входить лише в ТОП-10 найбільш важливих ознак – хоча, здавалося б, дуже багато інформації в цій ознаці міститься! А значить, у наших статистичних метриках інформації набагато більше.

Ще хочеться відзначити, що при зміні насіння генератора псевдовипадкових чисел топ найважливіших ознак дещо змінюється. Загальним залишається, що зав'язані на клієнта метрики стабільно вгорі, але їх порядок змінюється. А протокол транспортного рівня стрибає між першим і десятим місцем.

Тепер найцікавіше. До цього ми брали зріз за першим 1000 сегментами кожного потоку, і на основі цього зрізу розраховували статистичні метрики. Виникає закономірне питання: а наскільки можна зменшити цей зріз і все одно отримувати хороші показники класифікації?

Відповідь бентежить. Можна опускати кількість сегментів в кожному потоці до… трьох. Не включаючи TCP handshake, зрозуміло, адже він ніякої інформації не несе.

Нижче представлені значення повноти і точності для кожного класу, таблиця реальних і прогнозованих класів і топ характеристик при побудові і перевірці моделі всього лише на перших трьох сегментах транспортного рівня (TCP це насправді 6 сегментів, три перші відкидаються).

image

image

image

Уважний читач може помітити, що сумарна кількість записів у вибірці стало менше порівняно з минулим випадком. Справа в тому, що для розрахунку більшості характеристик потрібно, щоб була хоча б одна порція даних з боку клієнта і хоча б одна зі сторони сервера. Якщо з'ясовується, що у перших 3 сегментах передавав тільки клієнт або сервер, такий потік відкидається ще на етапі складання таблиці ознак.

Результат вийшов несподіваний тим, що з різким зменшенням кількості сегментів у кожному потоці якість класифікації не погіршився, а навіть дещо покращилося. Зв'язати це можна тим, що саме перші передані сегменти несуть найбільшу інформацію про тип програми. Тому при зменшенні кількості сегментів наші статистичні метрики починають нести інформацію тільки про перших сегментах, а не про всіх, і якість класифікації кілька збільшується.

Висновок
У даній статті я наочно продемонстрував, як можна виробляти достатньо якісний аналіз трафіку з метою визначення протоколу прикладного рівня без засобів DPI. Що характерно, можна досить точно визначити прикладний протокол вже за першим кільком переданим сегментах транспортного рівня.

Весь розроблений код викладений в репозиторії на github. В readme репозиторію дана інструкція, як ви можете повторити отримані в статті результати. У папці csv знаходяться таблиці ознак, отримані після обробки зібраних PCAP-файлів. А ось самі файли PCAP ви там не знайдете – прошу вибачення, але конфіденційність моїх даних насамперед.

В якості наочної ілюстрації роботи класифікатора в реальному часі я розробив нескладне додаток на PyQt4. І навіть записав відео з демонстрацією його роботи.

Для чого можна застосовувати викладений підхід? В перспективі для вирішення вузькоспеціалізованих завдань можна уникнути установки повноцінного DPI, а замість цього обійтися таким ось класифікатора і парсером конкретного прикладного протоколу. Наприклад, якщо нам цікавий тільки трафік HTTP – можна здійснювати попередню класифікацію трафіку засобами машинного навчання, і те, що було розпізнано як HTTP, передавати вже конкретному парсеру HTTP.

Крім того, у параноїків з'явився новий привід для занепокоєння – адже навіть під трьома шарами шифрування теоретично все одно можна сказати, чи говорить клієнт по скайпу, серфить Інтернет або дивиться відео на Youtubе.

Подяки
Хочу подякувати Данила Прохорова і Надію Трофлянину, з якими ми займалися розробкою цієї ідеї, збирали трафік і потім виступали на VII Молодіжному Науковому Форумі МТУЗІ.

Джерела
Неправильно було б не вказати наукові роботи, з яких ми почерпнули натхнення і кілька хороших ідей:
  1. Internet Traffic Classification Demystified: On the Sources of the Discriminative Power
  2. SVM Based Network Traffic Classification Using Correlation Information
  3. Internet Traffic Classification Using Bayesian Analysis Techniques
Джерело: Хабрахабр

0 коментарів

Тільки зареєстровані та авторизовані користувачі можуть залишати коментарі.