nuclight: (Default)
Со времени событий вокруг uTP прошло более 4 месяцев, разработчики uTorrent на месте не стояли, в теме на nag.ru тоже накатали уже более сорока страниц. Придумал и я принципиально новый способ ловить соединения торрентов, но обо всём по порядку.Рабочий скрипт с демонстрацией концепта прилагается )
nuclight: (Default)
Краткое содержание: как отфильтровать uTP на FreeBSD в теме на Наге уже сказали, однако для случая пакетов внутри туннеля PPTP GRE решения не было, о чем здесь и будет рассказано, но сначала - предыстория.

У вас вдруг стал хуже работать Интернет?..


В конце 2008 года разработчики uTorrent собрались заменить транспортный протокол с TCP на UDP, реализовав поверх него свою прослойку под названием чTP - дескать, так будет эффективнее. Тогда же исследователь по имени Ричард Беннет заявил, что это будет полная жопа для всего Интернета - UDP менее 2% во всём трафике, он используется для приложений реального времени (игры, телефония) и для критически важного DNS, в общем, пострадают все, из-за отсутствия в нём нормального congestion control (обработки перегрузок сети). Разработчики на это ответили, что они сделают congestion control еще лучше, чем в TCP, и торрент станет даже меньше забивать каналы и мешать другим, чем сейчас. И включили по умолчанию новый протокол uTP в бета-версиях uTorrent 1.8 (правда, сначала только на прием). Время шло, обещанной жопы всея Интернета не было...
До этого февраля. Буквально в понедельник админы бывшего СССР начали спрашивать друг друга, у всех ли отмечено сильное возрастание нагрузки за последние дни. Таки да, оказалось у многих. Выяснилось, что месяц назад вышел uTorrent 2.0, у кучи народа вылезло окошко с предложением обновиться, и с начала февраля пошел рост PPS (нагрузки по пакетам в секунду), причем обратите внимание, не трафика. Много где оборудование к такому неожиданному повороту сюжета было не готово, и проблемы работы Интернета ощутили на себе все, не только "качки". Более того, не только оборудование провайдеров - у многих стали гнать домашние роутеры и ADSL-модемы (вот пост на Хабре на тему), хотя опять же человек может не связать обновление у себя uTorrent и начать обвинять провайдера.
Read more... )
nuclight: (Default)
Этот пост пригодится вам не только на FreeBSD, но и на Linux и любой другой системе с BPF (для Windows есть вот такое) в случае, когда вы хотите написать приложение, отбирающее напрямую с линии пакеты по некоторому критерию, как tcpdump (ну скажем, хотите проконтролировать ARP в вашей сети по типу приложения ipguard, или еще что). Здесь идет более подробная версия куска моей презентации на RootConf 2009 (по ссылке доступны слайды и видео), где также рассматривался и упоминаемый далее Netgraph.Read more... )
nuclight: (Default)
Тут коллега Citrin ([livejournal.com profile] ospf_ripe) поделился опытом о программировании netgraph-ноды ng_bpf(4). Этот узел использует BPF (Berkeley Packet Filter) и позволяет ловить пакеты по определенным критериям, то есть может все то же самое, что и всем хорошо известный tcpdump. То есть, если ipfw(8) у нас умеет фильтровать только по заголовку пакета, то с помощью этой ноды можем фильтровать пакеты прямо в ядре как хотим, по содержимому, благо netgraph легко стыкуется с ipfw при помощи ng_ipfw(4). Citrin'у это понадобилось для фильтрации спамерских DNS-запросов на MX-записи (DoS'ящих DNS-сервер), что требует не такого уж и тривиального анализа пакета - нужно смотреть на байты, которые лежат по смещениям, вычисляемым по другим байтам в пакете. И возможности BPF эту задачу решить позволяют.
Да вот незадача - язык bpf(4) представляет собой специфический ассемблер виртуальной BPF-машины. И если tcpdump предоставляет удобный язык, самостоятельно компилируя заданное выражение в опкоды BPF (между прочим, в libpcap встроен неплохой компилятор, даже с оптимизатором), то ng_bpf требует программирования прямо в этих самых опкодах, которые надо откуда-то сначала получить. Конечно, можно изучить этот ассемблер и написать нужную программу на нем, он не очень сложен - но понятно, что это неудобно. Man-страница ng_bpf(4) предлагает способ использования для этой цели отладочного вывода компилятора libpcap, используемого в tcpdump, с помощью вспомогательного awk-скрипта. Здесь, однако, возникает проблема с отсылкой пакетов в netgraph из ipfw - они туда приходят без Ethernet-заголовка, занимающего 14 байт. А tcpdump генерирует программу с его проверкой. Есть, конечно, вариант подключения ng_bpf к ng_ether(4), напрямую, без файрвола, тогда выражение будет соответствовать. Однако это означает, что необходимо будет самостоятельно здесь же в программе проверять адреса назначения и тому подобное, что удобнее делать в файрволе, отправляя лишь нужные пакеты, кроме того, поскольку проверяться будет каждый пакет, возрастет нагрузка (ng_bpf может быть довольно прожорлив). Citrin решил это написанием небольшой программки на Си, которая компилирует выражение с типом DLT_RAW - каковые пакеты и ходят через ng_ipfw, что описал в подробностях на http://citrin.ru/freebsd:ng_ipfw_ng_bpf вместе с остальными подробностями по фильтрации MX-запросов (живой пример всегда интересен).
Здесь надо заметить, что по ссылке описан случай, когда пакеты, удовлетворяющие условию, просто отбрасываются - часто же нужно что-то сделать с ними дальше в файрволе другое, после проверки по содержимому как части правил файрвола, так сказать. Это можно сделать спомощью появившихся во FreeBSD 6.2-RELEASE тегов ipfw (ipfw tags) - в нетграф на пакет навешивается тег, потом в ipfw он проверяется (возможен и обратный сценарий). Когда я писал для этой цели ng_tag(4) (эта нода тоже вошла в состав 6.2), я столкнулся с той же проблемой - мне надо было фильтровать p2p-пакеты, что делалось в ng_bpf(4). И я, и Citrin попробовали опцию tcpdump -y raw, но tcpdump проверяет допустимый DLT для интерфейса, и не дает указать DLT_RAW. В результате в примере в man ng_tag даются выражения tcpdump в "сырых" смещениях от начала пакета, вычисленных вручную по их формату (это все же проще, чем писать на ассемблере BPF, да); то же сделано и в проскакивавших в mail-листах FreeBSD подробных примерах фильтрации ICQ (авторства bird_of_Luck в IRC-сети RusNet) и BitTorrent.
Стоит заметить, что не всякий L7 filtering может быть сделан с помощью ng_bpf - поскольку в этом ассемблере запрещены условные переходы назад и таким образом циклы, нельзя организовать, например, поиск фиксированной подстроки по заранее неизвестному (и никак не вычисляемому из других данных) смещению в пакете (то, что делает iptables -m string) - думается, в будущем будет написан netgraph-узел, который займется именно этим :)
...Ну а что касается любителей хитрых трюков, то способ использования tcpdump в привычном виде без всяких программок все же был найден :) Для этого необходим файл, записанный ранее с помощью tcpdump -w с data link type DLT_RAW. Содержимое неважно - ведь используется отладочный вывод. То есть, необходимо дать команду вида tcpdump -ddd -r file.raw expression (заменить в скриптах по вкусу).
Получить такой файл можно, например, с помощью утилиты ipfwpcap(8). Это, кстати, довольно полезная вещь сама по себе - вешается на divert-сокет и записывает в файл, который потом можно прочитать с помощью tcpdump -r, пришедшие в него пакеты. Она включена в состав 7-CURRENT, правда, я бы порекомендовал взять версию с http://antigreen.org/vadim/freebsd/ipfwpcap/ - там добавлено несколько полезных фич вроде переоткрытия логов по SIGHUP и т.п. приближений по функционалу к pflogd(8).

UPD: Более подробно тема программирования BPF раскрыта здесь: http://nuclight.livejournal.com/124989.html

February 2017

S M T W T F S
   1 234
567891011
12131415161718
19202122232425
262728    

Syndicate

RSS Atom

Style Credit

Expand Cut Tags

No cut tags
Page generated Jul. 11th, 2025 07:28 pm
Powered by Dreamwidth Studios