DPI для linux в виде расширения iptables

За основу взят проект ntop.org nDPI

Оно доступно на github.com/vel21ripn/nDPI ветка netfilter-2.6
(git clone -b netfilter-2.6 https://github.com/vel21ripn/nDPI.git)

Ветка по умолчанию: netfilter-2.2, но в ближайшее время будет переход на ветку flow_info

Ветка netfilter больше не будет развиваться.

Ветка netfilter-2.2 больше не будет развиваться.

Ветка netfilter-2.6 больше не будет развиваться.

Ветка netfilter проверялась на ядрах 3.14.x - 3.18.x,4.1,4.4,4.8,4.9,4.14

Ветки netfilter-2.2,netfilter-2.6,flow_info проверялись только на ядрах 4.4 и выше

Тестируемые архитектуры: x86 и x86_64.

Для работы используется iptables-1.4.21 или iptables-1.6.*

Есть подробная инструкци для ubuntu и CentOS составленная as_lan

Спасибо TTPartizan за сбор трафика CSGO,dota2,WoT

Образцы трафика для тестирования nDPI. Откуда они были взяты - не могу найти.


Другие поделки

Мои улучшения IMQ теперь будут здесь

Поиск множества строк (аналог -m string) NEW! Вариант ipset с типом "string"


Последние изменения


2019-03-25

Новая ветка flow_info на базе 2.6-stable

В новой ветке существенно уменьшена разница между вариантом с патчем ядра и без него

Возможно, через некоторое время, вариант без патча ядра станет основным.

При загрузке модуля с параметром "ndpi_enable_flow=1" появляется файл /proc/net/xt_ndpi/flows который можно использовать вместо ipt_NETFLOW для получения счетчиков трафика с доп. информацией в виде названия протокола nDPI и имен хостов для некоторых протоколов.

Информация собирается только о том трафике, который был отмечен через -j NDPI --flow-info

Минимальная настройка для сбора информации о трафике через интерфейс eth1

modprobe xt_ndpi ndpi_enable_flow=1

echo "timeout=330" >/proc/net/xt_ndpi/flows
echo "limit=500000" >/proc/net/xt_ndpi/flows

iptables -t mangle -A PREROUTING -m ndpi --all
iptables -t mangle -A OUTPUT -m ndpi --all
iptables -t mangle -A PREROUTING -i eth1 -m ndpi ! --error -j NDPI --flow-info
iptables -t mangle -A POSTROUTING -o eth1 -m ndpi ! --error -j NDPI --flow-info
while true; do
 sleep 300
 cat /proc/net/xt_ndpi/flows >/tmp/traf_`date +%Y-%m-%d-%H-%M`
done

Команда

cat /proc/net/xt_ndpi/flows

Выводит примерно следующее:

TIME 1553364302
1553364302 1553364302 4 6 xxx.xxx.xxx.3 59440 74.125.205.155 443 64 0 1 0 I=20,20 P=Google.SSL
1553364302 1553364302 4 6 xxx.xxx.xxx.4 62327 95.106.141.165 40186 52 0 1 0 I=20,20 P=BitTorrent
1553364302 1553364302 4 6 xxx.xxx.xxx.4 52418 185.60.115.21 80 52 0 1 0 I=20,20 P=Starcraft.HTTP
1553364301 1553364301 4 6 217.66.156.233 62198 xxx.xxx.xxx.153 443 64 60 1 1 I=20,20 P=SSL
1553364301 1553364301 4 17 xxx.xxx.xxx.4 49164 173.194.222.157 443 1378 2756 1 2 I=20,20 P=Google.QUIC H=www.googleadservices.com
1553364301 1553364301 4 17 xxx.xxx.xxx.49 44919 69.171.255.11 53 100 227 1 1 I=20,20 P=Facebook.DNS H=instagram.fhel3-1.fna.fbcdn.net
1553364301 1553364301 4 6 xxx.xxx.xxx.3 59438 64.233.161.104 443 447 2762 4 3 I=20,20 P=Google.SSL C=www.google.com

Описание полей в файле FLOW_INFO.txt

Расходы памяти на хранение данных 176-432 байта на одно соединение.

Лимит не жесткий! Проверка порисходит 2 раза в секунду.

Если CPS 2000, то лимит легко может быть превышен на 1000 записей. Если лимит превышен, то будут удалены данные о самых старых соединениях


2019-01-29

Обновление до 2.6-stable (ветка netfilter-2.6)


2018-10-01

Обновление до 2.4-stable


2018-06-21

Сделан механизм для создания пользовательских протоколов. Протокол будет определяться либо на базе ip или ip/port, либо на основании имени хоста (имя хоста есть в 3-х протоколах: http,https,dns). Для https используется имя из серверного сертификата.

Добавляются протоколы достаточно просто:

echo "add_custom XXXXX" >/proc/net/xt_ndpi/proto

Для протоколов на основании ip/port данные пишутся в /proc/net/xt_ndpi/ip_proto

Для протоколов на основании имени хоста данные пишутся в /proc/net/xt_ndpi/host_proto

Соответственно в них можно посмотреть текущие настройки.

Изменение host_proto является тяжелой операцией!

Не рекомендуется добавлять туда много данных по одной строке.
Наименее затратный вариант это когда все записывается за 1 раз.

То, что пишется в файл host_proto добавляется к текущей конфигурации
(полностью совпадающие описания игнорируются).

Удалить данные из host_proto можно только целиком ( echo reset >/proc/net/xt_ndpi/host_proto ) !


2018-04-03

Успешно прошло недельное тестирование ndpi-netfilter на базе ndpi-2.3-dev (ветка netfilter-2.2)

Добавлен патч для ядер 4.15

Ветка netfilter2 удалена как бесперспективная

Внесены изменения в процесс сборки ndpi-netfilter (Compile and install)


2017-08-31

Начато тестирование ndpi-netfilter на базе ndpi-2.0-stable

Пока слишком большой процент неизвестного трафика.

2016-12-10

версия на гитхабе 1.7.0-netfilter-222-edf7a3b

Более аккуратно детектится BT. Проблема в том, что в BT/utp/udp есть пакеты начинающиеся с байтов 0x01,0x00 и других критериев нет, а в других протоколах оно так же встречается. Так в BT частенько попадал трафик CSGO, dota2, WoT.

Добавлен протокол для CSGO/DOTA2. Как из различить - пока не знаю. Возможно по адресам серверров.

Трафик WoT пока считается неизвестным. Можно попробовать детектить его через /proc/net/xt_ndpi/ip_port


2016-04-27

версия на гитхабе 1.7.0-netfilter-212-56eacee

Восстановлена работа без патча. Проверено только на ядрах 4.4.

Решена проблема в случае использования хостом туннеля типа ipip


2016-04-18

версия на гитхабе 1.7.0-netfilter-209-7fc13cd

backport https://github.com/ntop/nDPI/pull/173
        
    Fixed buffer overflows with safe str search
    Fixed more buffer overflows with small packets
    Fixed oscar buffer overflow

2016-01-09

версия на гитхабе 1.7.0-netfilter-191-2c1da32

Исправлена ошибка в "-j NDPI --ndpi-id" (маску забыл инвертировать).

Сделана проверка соосветствия версии модуля ядра и расширения iptables.

Добавлены опции для работы с базовым (мастер) протоколом. Если по http передается mpeg-файл, то протокол будет mpeg, а мастер-протокол будет http. Теперь можно проверить наличие мастрер-протокола ( опция --have-master ), можно отдельно проверять протокол ( --match-proto ) или только мастрер-протокол ( --match-master ).

Хелп выводит список протоколов в 4 столбца, в алфавитном порядке. Отдельно указан список отключенных протоколов. Аналогично добавлены уточняющие ключи в NDPI-target

--ndpi-id-p - установка метки/класса только по протоколу

--ndpi-id-m - установка метки/класса только по мастер-протоколу.

2015-12-17

Исправлена логика -j NDPI --ndpi-id. Теперь метка и маска применяется всегда и для обоих протоколов.

Сначала применяется для основного протокола, потом для подпротокола.

Чтобы неизвестный трафик не менял метку можно пользоваться конструкцией

iptables ... -m ndpi ! --unknown -j NDPI --ndpi-id --set-mark

2015-12-09

Исправлено обнаружение подпротоколов. После первого обнаружения протокола процесс обработки останавливался. Архив не выкладываю - берите на гитхабе (commit 645348d266c56ceb84c083abc3e5705dfff0689d)

Есть ошибки в детектировании BT :( Как только будет время - займусь.

nDPI-1.7.20151023.tar.gz nDPI основанный на 1.7-stable GIT commit ff04ff42fea866adfb55852d537c471a0ad496a6 diff

Теперь оно доступно на github.com/vel21ripn/nDPI ветка netfilter

nDPI-1.5.1.20150513.tar.gz nDPI основанный на GIT commit d3c979aa57466ed5aada2b2369ccedda2c05a372 diff

Сборка

  1. Берем архив nDPI основанный на GIT commit a3d66b07778981d5abbf2d2525f83eb349e3a4f3
    md5: 663ee4018f5fa5b199f0798917f6d3a7 и распаковываем

  2. cd nDPI-1.7.20151023

    ./autogen.sh

    cd ndpi-netfilter

  3. Если версия ядра меньше 3.10 и ядро еще не пропатчено, то патчим, включаем NF_CONNTRACK_CUSTOM=2, пересобираем ядро и перегружаемся.

    ( W=`pwd` ; cd /usr/src/linux; patch -p1 <$W/kernel-patch/XXXX.diff ; make menuconfig ; make ; ... )
    

    Патч v3.4.97 подходит для ядер >=3.4.92

    Патч v3.10.20 подходит для ядер 3.10/3.11(?)

    Патч v3.12.7 подходит для ядер 3.12.

    Патч v3.14.2 подходит для ядер 3.14.1-3.14.4

    Патч v3.14.5 подходит для ядер >3.14.5 и 3.18.10

    Патч v4.0.3 подходит для ядер >=4.0.3

  4. Далее, строим iptables-extension и ядерный модуль (находясь в ndpi-netfilter)

    make
    make install
    make modules_install
    

PS Чтоб выгрузить модуль не забываем "conntrack -F && rmmod xt_ndpi"

Изменения

2015.10.23

Добавлена опция "-B X" для ndpiReader включающая хеш BT + мелкие правки.

2015.10.22

Исправлена ошибка компиляции без IPv6, немного переделана обработка ошибок, изменены счетчики ошибок (для отладки).

2015.10.20

исправлена ошибка приводившая к тому, что BT протокол считался unknown

2015.09.29

nDPI-1.7.20151010.tar.gz nDPI-1.7 основанный на GIT commit ff04ff42fea866adfb55852d537c471a0ad496a6 diff

Исправлена ошибка со счетчиком использования модуля (моя) проявляющаяся при работе с контейнерами и исправлена ошибка в протоколе dns.

13.05.2015

nDPI-1.5.1.20150513.tar.gz nDPI-1.5 основанный на GIT commit d3c979aa57466ed5aada2b2369ccedda2c05a372 md5: 2db6fbe13bbd6b239c9900802546f479

Внимание! Перед сборкой ndpi-netfilter нужно запустить autogen.sh

24.04.2015

nDPI-1.5.1.r9249.tar.gz md5: e964e3bb42f9ed35ad7be20fcd44abec

Обновление до SVN r9249. Особо в изменения не вникал, но заметил правильные тенденции на счет протоколов которые тупо детектятся по портам.

21.03.2015

nDPI-1.5.1.r8994_v1.tar.gz md5: b1fe951c1998dd14cf34d015de43d7cc

Добавил xt_ndpi/proto

Формат для изменения данных

id|all|any mark[/mask]

id,mark и mask - hex! Разница между all и any: all включает unknown, а any - нет.

Если первый символ # - то строка игнорируется. Можно делать
cat /proc/net/xt_ndpi/proto >ndpi_proto_mark.txt и
cat ndpi_proto_mark.txt >/proc/net/xt_ndpi/proto

Теперь "-j NDPI --ndpi-id" делает с указанным полем (mark или prio) & ~mask | mark. Т.е. теперь каждому протоколу можно задать свою марку!

06.03.2015

Обновление до SNV r8994 nDPI-1.5.1.r8994.tar.gz md5: 1cc27cd991a2b9f74b907f116f65b8a1

30.01.2015

Исправление ошибки в Bittorrent. Спасибо stasn77

Обновленная версия nDPI-1.5.1.r8636_v3e.tar.gz md5: 9cc6cf55907b2fe428766006229db9de

29.01.2015

Исправление ошибки для x86_64 без IPv6 nDPI-1.5.1.r8636_v3d.tar.gz md5: 12ecfb2f202f10018b945f0a3c7949b2

27.01.2015

Кто успел забрать nDPI-1.5.1.r8636_v3b.tar.gz - удалите его!

Правильный архив nDPI-1.5.1.r8636_v3c.tar.gz! md5: eb12cc1052f42bb0d2709677b2212406

Исправлены 2 ошибки:
- Пакеты TCP/UDP идентифицировались как ICMP
- В "-j NDPI" убрана опция "--ret"
архив nDPI основанный на ревизии r8636

21.01.2015

Тем кому нужен connlabel вместе с ndpi берем архив nDPI основанный на ревизии r8636 и обязательно патчим ядро.

9.01.2015

Серьезно уменьшен объем памяти. Размер структуры flow теперь примерно 788/840 байт и ее размер не сильно зависит от разрядности процессора.

Для ядер 3.10 и выше не требуется патчить ядро! Для ядер ниже 3.10 нужно патчить ядро.

Внимание! Без патча ядра ndpi несовместим с xt_connlabel. Kernel oops и panic гарантированы!

Теоретически оно должно работать с патчем и на ядрах 3.2, но это не проверялось. Если у кого заработает, то напишите.

Есть подвижки с ntop.org. Часть изменений удалось внести в официальное дерево. Работа над этим будет продолжаться. Цель - сделать ndpi-netfilter частью проекта nDPI

5.12.2014

Переход на nDPI-1.5.1+ svn rev.r8636, проверена сборка и работоспособность на x86_64

Изменения!

Добавлена поддержка IPv6. По-умолчанию собирается с IPv6, модуль при загрузке пишет об этом.

Для отключения IPv6 нужно в файле nDPI/src/include/ndpi_protocol_ids.h закомментарить строку 33

#define NDPI_DETECTION_SUPPORT_IPV6

Появилась возможность смотреть какие торренты аннонсируются в трафике (/proc/net/xt_ndpi/announce). Потребляет 64кБ.

Пока отключается только при компиляции комментированием в файле nDPI/ndpi-netfilter/src/main.c строки 45

#define BT_ANNOUNCE


Для отлова ошибок в ядерной части проще всего добавить поддержку в ядро ramoops.

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

CONFIG_PSTORE_CONSOLE=y
CONFIG_PSTORE_RAM=m|y

Для совсем новых ядер нужен распаковщик сообщения deflate-ramoops . Он написан на перле и хочет Compress::Zlib

1.12.2014

Найден баг

баг очень неприятный! Почему он не обнаружился ранее - непонятно :( . патч для исправления

25.11.2014

Пожелание:

Где-то перед тем как отправить tcp-пакет в ndpi настоятельно рекомедуется прохождение через 2 правила

iptables -A FORWARD -m conntrack --ctstate INVALID,UNTRACKED -j DROP
iptables -A FORWARD -m state --state NEW -p tcp ! --syn -j DROP

В первую очередь это касается анализа отмирроренного трафика.

24.11.2014

Переход на nDPI-1.5.1+ svn rev.8568

Большие изменения в BT: добавлен парсер сообщений (dht) и хеш для хранения ip:port получаемых парсером

По-умолчанию хеш отключен! Чтобы его включить нужно указать его размер 1-32 (параметр bt_hash_size). Число элементо хеша будет равно N*1024.

Кроме это можно указать время хранения данных в хеше 900-3600 секунд (параметр bt_hash_timeout)

По моим наблюдениям, большая часть повторных обращений происходит в пределах 30 минут

Число хранимых элементов в хеше и другую информацию о хеше можно посмотреть в /proc/net/xt_ndpi/info

Чем больше хранящихся элементов, тем длинее цепочка, тем дольше поиск

При тестировании на одном сервере в хеше было ~11000 элементов

При тестировании на сети /24 с 300Мбитным трафиком число элементов было 0.8-1.2 миллиона элементов!

Каждый элемент - 24 байта!

файл /proc/net/xt_ndpi/info сделан для отладки и сбора статистики.
В дальнейшем он скорее всего будет убран.

Формат /proc/net/xt_ndpi/info

Первая строка

hash_size 8192 hash timeout 2100s count 622642 min 0 max 117 gc 248549

hash_size 8192 - размер хеш-наблицы

hash timeout 2100s - время хранения

count 622642 - общее число элементов в хеше

min 0 - минимальная длина цепочки в хеш-таблице

max 117 - максимальная длина цепочки в хеш-таблице

gc 248549 - счетчик удалений из хеша

Дальше идут длины цепочек для каждой цепочки хеш-таблицы

Если в файл /proc/net/xt_ndpi/info записать число от 0 до hash_size-2, то в этом файле будет показано содержимое цепочки

Чтобы посмотреть общую информацию о хеше в файл нужно записать "-1"

16.11.2014

Переход на ядра 3.17 - используем патчи от 3.14

03.10.2014

Переход на nDPI-1.5.1+ svn rev.8369. улучшено распознание udp трафика bittorent (dht и uTP)

11.07.2014

Добавлена поддержка ядер 3.4 на уровне сборки. Если у кого соберется и заработает, то напишите на ЛОР

Немного дополнено определение bittorrent.
Торренты дают большой процент неопределенного трафика из-за неудачных попыток установления соединения и шифрования :(

Добавлен target NDPI. Он умеет ставить метки и менять приоритет (дубль MARK & CLASSIFY), метка может включать в себя ID протокола, возможно добавление поведения -j RETURN и -j ACCEPT
ID протокола можно посмотреть командой "iptables -m ndpi --help".

iptables -A INPUT -j NDPI --help
NDPI target options:
  --value value/mask                  Set value = (value & ~mask) | value
  --ndpi-id                           Set value = (value & ~0xff) | proto
  --set-mark                          Set nfmark = value
  --set-clsf                          Set priority = value
  --accept                            -j ACCEPT

Примеры

iptables -A FORWARD -m ndpi --proto sip,skype,msn -j NDPI --value 0x30010 --set-clsf --accept

эквивалентно

iptables -A FORWARD -m ndpi --proto sip,skype,msn -j CLASSIFY --set-class 3:10
iptables -A FORWARD -m ndpi --proto sip,skype,msn -j ACCEPT

9.07.2014

Cтабильно работающая версия