LINUX.ORG.RU
ФорумAdmin

Как DPI распознают HTTP

 , , ,


1

3

Итак, я делаю DPI на базе Suricata для блокировки запрещённых сайтов из реестра РФ и не только. Как я понял, DPI реагирует на запросы GET и Host: в пакете. Также DPI может реагировать на начальные хедеры http пакета. Вот пример запроса:

GET /
Host: kasparov.ru
DPI начинает работать, когда эти два совпадения встретятся в пакете.
Также интересно узнать, как через iptables можно послать HTTP 302 Redirect.

Остальные сигнатуры в DPI используются для того, чтобы избежать блокировки в других протоколах кроме http

★★★★★

Последнее исправление: ne-vlezay (всего исправлений: 2)

Итак, я делаю DPI на базе Suricata для блокировки запрещённых сайтов из реестра РФ и не только.

ОМГ. Тендер выиграл? :)

blind_oracle ★★★★★
()

В чём вопрос-то? DPI это Deep Packet Inspection. Нужно распознавать TCP-пакеты, относящиеся к HTTP, распознавать их содержимое, отлавливать начала запросов, вытаскивать хост и адрес и отсылать поддельный ответ при детектировании.

Legioner ★★★★★
()
Ответ на: комментарий от Legioner

Suricata например может расставлять метки на обнаруженные данные.
Далее -m connmark и с этим потоком можно уже поступать по своему.
Грубо говоря, в iptables/ip6tables реализован простенький DPI по средствам модуля string. Если надо заблочить url через iptables, делаем как-то так:

iptables -t mangle -A PREROUTING -m string --string "GET /" --algo bm -m string --string "Host: kasparov.ru" --algo bm -j CONNMARK --set-mark 0x2/0xfe 
iptables -t mangle -A FORWARD -m connmark 0x2/0xfe -p tcp -j REJERCT --reject-with tcp-rst

Правда NAT/DNAT работать не будет потому, что connmark срабатывает не с самого начала, а с того момента, когда был проматчен пакет.
Не знаю, почему об этом так мало документации. Все почему то предпочитают использовать коммерческие продукты.

Кстати, у меня весь прокси заблочен так:

iptables -t mangle -A PREROUTING -m string --string "GET http://" --algo bm  -j CONNMARK --set-mark 0x2/0xfe
iptables -t mangle -A PREROUTING -m string --string "CONNECT " --algo bm -m string --string "HTTP" --algo bm -j CONNMARK --set-mark 0x2/0xfe
iptables -t mangle -A FORWARD -m connmark 0x2/0xfe -p tcp -j REJERCT --reject-with tcp-rst

Если нужно сделать шейпинг или исключение, то:
iptables -t mangle -A PREROUTING -m string --string "PASV" --algo bm  -j CONNMARK --set-mark 0x4/0xfe
iptables -t mangle -A FORWARD -m connmark 0x4/0xfe -p tcp -j ACCEPT

С реестром немного сложнее, но при желании записи из реестра можно раскидать по отдельным таблицам.

Почему я выбрал Suricata? Да потому что в ней нету ограничения на количество правил. Также там можно модифицировать пакеты прямо на лету.

Кстати, список пралил ipt для Suricata выгледит так:
iptables -t mangle -N NFQ_RDR
iptables -t mangle -A NFQ_RDR -m connbytes --connbytes 1000000 --connbytes-dir both --connbytes-mode bytes -j RETURN
iptables -t mangle -A NFQ_RDR -m mark ! --mark 0x1/0x1 -j NFQUEUE --queue-num 0 --queue-bypass

iptables -t mangle -N CONNMARK_DPI
iptables -t mangle -A CONNMARK_DPI -m mark --mark 0x2/oxfe -j CONNMARK --save-mark
iptables -t mangle -A CONNMARK_DPI -m mark --mark 0x4/oxfe -j CONNMARK --save-mark
iptables -t mangle -A CONNMARK_DPI -m mark --mark 0x6/oxfe -j CONNMARK --save-mark
iptables -t mangle -A CONNMARK_DPI -m mark --mark 0x8/oxfe -j CONNMARK --save-mark
iptables -t mangle -A CONNMARK_DPI -m connmark --mark 0x2/oxfe -j CONNMARK --restore-mark
iptables -t mangle -A CONNMARK_DPI -m connmark --mark 0x4/oxfe -j CONNMARK --restore-mark
iptables -t mangle -A CONNMARK_DPI -m connmark --mark 0x6/oxfe -j CONNMARK --restore-mark
iptables -t mangle -A CONNMARK_DPI -m connmark --mark 0x8/oxfe -j CONNMARK --restore-mark

iptables -t mangle -A PREROUTING -j NFQ_RDR
iptables -t mangle -A PREROUTING -j CONNMARK_DPI

А дальше через connmark поступаем с трафиком на своё усмотрение.

ne-vlezay ★★★★★
() автор топика
Ответ на: комментарий от ne-vlezay

Твои фильтры корректно распознают такую простую схему:

1 пакет GE

2 пакет T /something HTTP/1.1\n\rH

3 пакет ost: bla.com

?

А также не распознают ли HTTP-пакет в тексте внутри сайта (например в форумном посте)?

Legioner ★★★★★
()
Последнее исправление: Legioner (всего исправлений: 1)
Ответ на: комментарий от Legioner

Твои фильтры корректно распознают такую простую схему:

Нет, но при желании подкрутить можно. Правда, в suricata есть движок который собирает пакеты. Про iptables - это обычный payload dpi.

Кстати, проверил через nc, сервер такое тоже не распознаёт. Вот результат:

system@ne-vlezay80:~$ nc ya.ru 80
GE
T
/ HTTP/1.1
H
ost: ya.ru

HTTP/1.1 400 Bad Request
Server: nginx
Date: Mon, 05 Oct 2015 14:30:13 GMT
Content-Type: text/html; charset=utf-8
Content-Length: 166
Connection: close

<html>
<head><title>400 Bad Request</title></head>
<body bgcolor="white">
<center><h1>400 Bad Request</h1></center>
<hr><center>nginx</center>
</body>
</html>

А также не распознают ли HTTP-пакет в тексте внутри сайта (например в форумном посте)?

При желании - да. Но это лучше делать через suricata

ne-vlezay ★★★★★
() автор топика
Ответ на: комментарий от ne-vlezay

Хотя, зачем так уродовать текст http. Все ровно не сработает.

ne-vlezay ★★★★★
() автор топика
Ответ на: комментарий от ne-vlezay

Кстати, проверил через nc, сервер такое тоже не распознаёт. Вот результат:

Ну так ты переводов строки лишних навставлял.

Deleted
()
Ответ на: комментарий от ne-vlezay

А пакет, в который запрос влез целиком, увидел? Это тебе был пример того, как можно (корректно) пофрагментировать запрос.

Вставлять переводы строки в HTTP в произвольных местах нельзя.

i-rinat ★★★★★
()
Ответ на: комментарий от ne-vlezay

Кстати проверил, -m string на это не реагирует. Интересно, сработает ли suricata

ne-vlezay ★★★★★
() автор топика
Ответ на: комментарий от i-rinat

-m string реализует pload dpi. Suricata реализует full dpi. Вот кстати результат теста suricata:

torrent@debian:~$ echo -en "GET http://ya.ru/ HTTP/1.0\r\n\r\n" | pv -L 10 | nc -q -1 ya.ru 80
  11 B 0:00:01 [9,29 B/s] [ <=>                                                ]
torrent@debian:~$ echo -en "GET http://ya.ru/ HTTP/1.0\r\n\r\n" | pv -L 10 | nc -q -1 ya.ru 80
  11 B 0:00:01 [9,28 B/s] [ <=>                                                ]
torrent@debian:~$

ne-vlezay ★★★★★
() автор топика
Ответ на: комментарий от ne-vlezay

Какой вообще смысл надеяться на сравнение в пакетном фильтре? HTTP это протокол прикладного уровня. Попытки анализа его на третьем-четвёртом просто не имеют смысла. И, как уже раньше здесь писали, есть неслабый шанс ложных срабатываний.

i-rinat ★★★★★
()
Ответ на: комментарий от i-rinat

А какие есть решения с открытым исходным кодам для анализа на прикладном уровне

ne-vlezay ★★★★★
() автор топика
Ответ на: комментарий от i-rinat

Кстати, о ложных срабатываниях. Чтобы небыло ложных срабатываний, необнодимо прописать исключения для других протоколов. Наприпер, Если мы хотим сделать исключение для ftp, то мы должны его матчить по ключевым словам.
Дело в том, что если анализировать портоколы на прикладном уровне, то анализ в этом случае идёт как обычный текст. По этому в систему анализа пакетов нужно добавлять исключения. Для того чтобы пометить все пакеты начиная с определённого места, нужно использовать модуль -m connbytes и для назначения марки -j CONNMARK.

Ещё можно на всякий пожарный нейтрализовать метку при обнаружении определённых протоколов.

ne-vlezay ★★★★★
() автор топика
Последнее исправление: ne-vlezay (всего исправлений: 1)
Ответ на: комментарий от ne-vlezay

А как на счёт suricata. Мне как известно, что suricata работает на прекладном

http://suricata-ids.org/features/all-features/

Написано же: «App layer decoding of: HTTP, SSL, TLS, SMB, SMB2, DCERPC, SMTP, FTP, SSH, DNS»

А какие есть решения с открытым исходным кодам для анализа на прикладном уровне

Я не занимался этим никогда, без понятия.

i-rinat ★★★★★
()
Ответ на: комментарий от i-rinat

Ещё там есть опция luajit. Вот через lua какраз можно сделать dpi

ne-vlezay ★★★★★
() автор топика

Кстати, в Suricata есть очень интересная опция pcre. Я исследовал DPI своего провайдера, и выяснил, что он блокирует так:
1. Матчит GET и Host
2. Когда сервер пытается ответить, от отсылает серверу RST - и клиенту RST.


Это реализуется:
1. В suricata создаём два правила и первому вешаем set_nfq_mark: 0x2/0xffffffff; второму вешаем set_nfq_mark: 0x4/0xffffffff;.
2. В iptables добавляем:

iptables -t mangle -N PROXY_BL
iptables -t mangle -A PROXY_BL -m mark --mark 0x2/0xfe -j CONNMARK --save-mark
iptables -t mangle -A PROXY_BL -m mark --mark 0x4/0xfe -m connmark --mark 0x2/0xfe -j CONNMARK --set-mark 0x48/0xfe
iptables -t mangle -A PROXY_BL -m mark --mark 0x2/0xfe -j CONNMARK --restore-mark

iptables -A FORWARD -m connmark --mark 0x48/0xfe -p tcp -j REJECT --reject-with tcp-rst

Единственный минус: клиенту не всегда приходит TCP RST и по этой причине соединение виснит.

ne-vlezay ★★★★★
() автор топика
Ответ на: комментарий от i-rinat

Вопрос: как клиенту отправить хотябы RST

ne-vlezay ★★★★★
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.