Both sides previous revisionPrevious revisionNext revision | Previous revisionLast revisionBoth sides next revision |
software:article:utp_dpi [2015/05/22 18:07] – [SYN] root | software:article:utp_dpi [2022/02/04 19:48] – ↷ Links adapted because of a move operation root |
---|
====== Torrent/uTP — о протоколе и самодельных DPI ====== | ====== Torrent/uTP — о протоколе и самодельных DPI ====== |
| {{software:article:utorrent_logo.png|}} |
| |
В 2009 году появился [[http://en.wikipedia.org/wiki/Micro_Transport_Protocol|Micro Transport Protocol]], сокращённо - uTP, можно ознакомится [[http://habrahabr.ru/post/68332/|тут]].\\ | В 2009 году появился [[http://en.wikipedia.org/wiki/Micro_Transport_Protocol|Micro Transport Protocol]], сокращённо - uTP, можно ознакомится [[http://habrahabr.ru/post/68332/|тут]].\\ |
Суть задумки в том, чтобы не полагаться на [[http://en.wikipedia.org/wiki/TCP_congestion-avoidance_algorithm|TCP Congestion Control]] [[http://habrahabr.ru/post/168407/|хубр]], которым под windows рулить весьма проблематично, а самим управлять загрузкой канала.\\ | Суть задумки в том, чтобы не полагаться на [[http://en.wikipedia.org/wiki/TCP_congestion-avoidance_algorithm|TCP Congestion Control]], которым под windows управлять весьма проблематично, а самим управлять загрузкой канала.\\ |
Другая причина это возможность приёма входящего соединения через NAT.\\ | Другая причина это возможность приёма входящего соединения через NAT.\\ |
[[http://habrahabr.ru/post/85443/|uTP выявил много узких мест]] как у [[http://forum.nag.ru/forum/index.php?showtopic=55025|провайдеров]] так и у пользователей: ещё вчера прекрасно работающие роутеры превратились в тыкву. А некоторые пользователи обнаружили что торренты качаются на все 100 мегабит, не зависимо от тарифа.\\ | [[http://habrahabr.ru/post/85443/|uTP выявил много узких мест]] как у [[http://forum.nag.ru/forum/index.php?showtopic=55025|провайдеров]] так и у пользователей: ещё вчера прекрасно работавшие роутеры превратились в тыкву.\\ |
{{:ru:software:article:utorrent_logo.png|}} | А некоторые пользователи обнаружили что торренты качаются на все 100 мегабит, не зависимо от тарифа.\\ |
| |
Вот какой бред написан в [[https://ru.wikipedia.org/wiki/ΜTorrent|википедии]]: | |
<code>Также провайдерам намного сложнее блокировать передачу данных через μTP благодаря отсутствию строгих, формализованных отличий UDP пакетов обычного трафика (формируемого, к примеру, сетевыми играми) от трафика, формируемого протоколом μTP, в отличие от TCP пакетов, по содержанию полей которых можно делать вывод об их принадлежности к p2p-трафику.</code> | |
| |
Как не правильно блокировать можно почитать тут: http://geektimes.ru/post/243305/ | Вот какой бред написан в [[https://ru.wikipedia.org/wiki/ΜTorrent|русской википедии]] про uTP:\\ |
и немного ниже :) | "Также провайдерам намного сложнее блокировать передачу данных через μTP благодаря отсутствию строгих, формализованных отличий UDP пакетов обычного трафика (формируемого, к примеру, сетевыми играми) от трафика, формируемого протоколом μTP, в отличие от TCP пакетов, по содержанию полей которых можно делать вывод об их принадлежности к p2p-трафику."\\ |
| [[http://en.wikipedia.org/wiki/Micro_Transport_Protocol|Вики на английском]] более адекватна.\\ |
| |
===== Жизнь с uTP ===== | ===== Жизнь с uTP ===== |
<spoiler title="Слухи, сплетни, домыслы"> | В адрес авторов uTP звучала масса упрёков в изобретении TCP с нуля и хождении по всем граблям, в том что они не взяли уже готовые протоколы, и в том что теперь придётся обновляться и расширятся.\\ |
В адрес авторов uTP звучала масса упрёков в изобретении TCP с нуля и хождении по всем граблям, в том что они не взяли уже готовые протоколы, и в том что теперь придётся обновляться и расширятся. | С точки зрения разработчиков - выбора особо не было: TCP все провайдеры шейпят, для управления всеми аспектами работы tcp протокола в винде нужны права администратора и скорее всего свой драйвер, многие другие протоколы которые ходят поверх IP (tcp/udp/gre/udplite/...) вообще провайдерами фильтруются и в винде их так просто не реализовать.\\ |
С точки зрения разработчиков - выбора особо не было: TCP все провайдеры шейпят и душат, для управления всеми аспектами работы tcp протокола в винде нужны права администратора и скорее всего свой драйвер, многие другие протоколы которые ходят поверх IP (tcp/udp/gre/udplite/...) вообще провайдерами фильтруются и в винде их так просто не реализовать. | Через NAT нормально ходят только TCP и UDP.\\ |
Потому просто взяли и сделали поверх UDP. | Потому просто взяли и сделали поверх UDP.\\ |
| |
Это решение подкосило многие домашние мыльницы и некоторых провайдеров. | Это решение подкосило многие домашние мыльницы и некоторых провайдеров: количество трансляций в NAT роутеров стало очень быстро расти.\\ |
Количество трансляций в NAT роутеров стало очень быстро расти. | Для TCP - NAT знает когда соединение установлено и когда оно завершено, а для UDP понятие соединений отсутствует в принципе, поэтому обычно применяются таймеры для удаления старых сессий.\\ |
Для TCP - NAT знает когда соединение установлено и когда оно завершено, а для UDP понятие соединений отсутствует в принципе, поэтому обычно применяются таймеры для удаления старых сессий. | |
| |
Другим побочным эффектом явилось то, что uTorrent запрашивал больше трафика чем позволял тарифный план провайдера, и от этого страдали даже те провайдеры у которых шейпер был настроен правильно: на хомячка из интернета прилетало ощутимо больше его тарифного плана и этот излишек дропался шейпером. Провайдеры несли финансовые потери от такого DDoS хомяка на самого себя. | Другим побочным эффектом явилось то, что uTorrent запрашивал больше трафика чем позволял тарифный план провайдера, и от этого страдали даже те провайдеры у которых шейпер был настроен правильно: на хомячка из интернета прилетало ощутимо больше его тарифного плана и этот излишек дропался шейпером. Провайдеры несли финансовые потери от такого DDoS хомяка на самого себя.\\ |
Авторы uTorrent позже всё таки научились правильно подстраиваться под канал, но их эксперименты стоили нервов и денег. | Авторы uTorrent позже научились правильно подстраиваться под канал, но их эксперименты стоили нервов и денег.\\ |
| |
Ещё одним неприятным моментом в экспериментах с uTP на начальных этапах было то, что он генерировал большую пакетную нагрузку, <a href="http://torrentblog.ru/protokol-utp-ne-sderzhal-svoix-obeshhanij/">отправляя множество мелких UDP пакетов</a>. Позднее авторы научились заполнять пакеты с данными целиком. | Ещё одним неприятным моментом в экспериментах с uTP на начальных этапах было то, что он генерировал большую пакетную нагрузку, [[http://torrentblog.ru/protokol-utp-ne-sderzhal-svoix-obeshhanij/|отправляя множество мелких UDP пакетов]]. Позднее авторы научились заполнять пакеты с данными целиком.\\ |
Повышение пакетрейта губительно сказывается на WiFi и прочих радиолинках. | Повышение пакетрейта губительно сказывается на WiFi и прочих радиолинках.\\ |
| |
В целом, протокол оказал ощутимое влияние как на провайдеров так и на производителей железа, я бы даже сказал что он подготовил почву для HD в ютубе.</spoiler> | В целом, протокол оказал ощутимое влияние как на провайдеров так и на производителей железа, я бы даже сказал что он подготовил почву для HD в ютубе.\\ |
| |
| |
| |
Вообще довольно запутанная и странная схема установления соединения:\\ | Вообще довольно запутанная и странная схема установления соединения:\\ |
>> SYN: connid=34 - запрос на установление соединения\\ | > SYN: connid=34 - запрос на установление соединения\\ |
<< STATE: connid=34 - подтверждение\\ | < STATE: connid=34 - подтверждение\\ |
>> DATA: connid=35 - передача данных\\ | > DATA: connid=35 - передача данных\\ |
<< STATE: connid=34 - подтверждение передачи данных\\ | < STATE: connid=34 - подтверждение передачи данных\\ |
Те инициатор соединения задаёт номер соединения в первом пакете а в дальнейшем использует номер на единицу больше.\\ | Те инициатор соединения задаёт номер соединения в первом пакете а в дальнейшем использует номер на единицу больше.\\ |
| |
В начале я пробовал слать RESET с виндовой машины, перебирая connid, но это явно не работало, не совпадали адреса отправителя пакета и seq_nr, ack_nr. Это был первый неудачный опыт.\\ | В начале я пробовал слать RESET с виндовой машины, перебирая connid, но это явно не работало, не совпадали адреса отправителя пакета и seq_nr, ack_nr. Это был первый неудачный опыт.\\ |
| |
[[ru:software:freebsd:utp_ctrl_daemon|uTPControl - block uTP torrent proto]] - была первая более менее программа которую я написал под FreeBSD.\\ | [[software:freebsd:utp_ctrl_daemon|uTPControl - block uTP torrent proto]] - была первая более менее программа которую я написал под FreeBSD.\\ |
uTP протокол был любезно предоставлен в [[https://github.com/bittorrent/libutp|libuTP]] всему интернету :)\\ | uTP протокол был любезно предоставлен в [[https://github.com/bittorrent/libutp|libuTP]] всему интернету :)\\ |
| |
| |
=== Заход 2: ng_utp === | === Заход 2: ng_utp === |
[[ru:software:freebsd:ng_utp|FreeBSD uTP (udp torrent) netgraph node]]\\ | [[software:freebsd:ng_utp|FreeBSD uTP (udp torrent) netgraph node]]\\ |
Прошло полтора года, я успел покопаться в ядре FreeBSD и netgraph, лучше узнать как работает сеть и пришла мысль: uTP имеет состояния аналогичные TCP, значит чтобы его 100% определять нужно эти состояния отслеживать.\\ | Прошло полтора года, я успел покопаться в ядре FreeBSD и netgraph, лучше узнать как работает сеть и пришла мысль: uTP имеет состояния аналогичные TCP, значит чтобы его 100% определять нужно эти состояния отслеживать.\\ |
Заодно я ещё раз заглянул в libuTP и получше посмотрел за что можно зацепится.\\ | Заодно я ещё раз заглянул в [[https://github.com/bittorrent/libutp|libuTP]] и получше посмотрел за что можно зацепится.\\ |
За сигнатуры я решил не цепляться, это плохой путь с массой ложных срабатываний и мучениями по их поддержанию - авторы уже несколько раз меняли начальные константы и сигнатуры "протухали" у тех кто их использовал.\\ | За сигнатуры решил не цепляться, это плохой путь с массой ложных срабатываний и мучениями по их поддержанию - авторы уже несколько раз меняли начальные константы и сигнатуры "протухали" у тех кто их использовал.\\ |
Идеальный вариант это свой "клиент" с референсной реализацией uTP который будет выстраивать таблицу соединений на основе пролетающих через него пакетов и уже по данным этой таблицы что то можно делать.\\ | Идеальный вариант это свой "клиент" с референсной реализацией uTP который будет выстраивать таблицу соединений на основе пролетающих через него пакетов и уже по данным этой таблицы что то можно делать.\\ |
| |
В итоге получилась netgraph нода, которую можно подключать к L2 хукам типа ng_ether или L3 хукам, например ng_ipfw. В первом случае можно вообще сделать прозрачный эзернет мост из двух сетевух (не обязательно физических). Ещё можно просто поставить тазик и зеркалировать на него весь траф, но я сейчас не уверен в работоспособности такой схемы.\\ | В итоге получилась netgraph нода, которую можно подключать к L2 хукам типа ng_ether или L3 хукам, например ng_ipfw. В первом случае можно вообще сделать прозрачный эзернет мост из двух сетевух (не обязательно физических). Ещё можно просто поставить сервер и зеркалировать на него весь траф, но я сейчас не уверен в работоспособности такой схемы.\\ |
| |
Результатов замеров производительности я не сохранил.\\ | Результатов замеров производительности не сохранил.\\ |
Однако нода без проблем параллелится по ядрам, может выполнятся как контексте ISR так и потоками netgraph, взаимные блокировки потоков сведены к минимуму.\\ | Однако нода без проблем параллелится по ядрам, может выполнятся как контексте ISR так и потоками netgraph, взаимные блокировки потоков сведены к минимуму.\\ |
| |
<li>отправлять uTP - RST пакеты</li></ul> | <li>отправлять uTP - RST пакеты</li></ul> |
Чтобы сгенерировать RST пакет все данные есть: src ip:port + dst ip:port, pkt_ver, connid, ack_nr, seq_nr. | Чтобы сгенерировать RST пакет все данные есть: src ip:port + dst ip:port, pkt_ver, connid, ack_nr, seq_nr. |
Фактически у IP/UDP пакета заменяются данные, пересчитывается контрольная сумма и от отправляется дальше. | Фактически у IP/UDP пакета заменяются данные, пересчитывается контрольная сумма и от отправляется дальше.\\ |
| |
Подробнее про счётчики - по <a href="http://www.netlab.linkpc.net/forum/index.php?topic=804.0">ссылке</a>, там описание, если его мало есть код :) | Сейчас это всё ещё может быть актуальным для различных беспроводных сетей и офисных сетей, остальные уже обновились и расширились.\\ |
| |
Сейчас это всё ещё может быть актуальным для различных беспроводных сетей и офисных сетей, остальные уже обновились и расширились. | |
| |
| |
===== Сигнатуры ===== | ===== Сигнатуры ===== |
Провайдеры искали способ как быстро нормализовать работу сети и решили фильтровать uTP по сигнатурам пакетов, добавляя их то в ACL коммутаторов то в фаервол BSD/Linux роутера.\\ | Администраторы искали способ как быстро нормализовать работу сети и решили фильтровать uTP по сигнатурам пакетов, добавляя их то в ACL коммутаторов то в фаервол BSD/Linux роутера.\\ |
"Странность" ситуации в том, что сигнатуры искали анализируя пакеты.\\ | "Странность" ситуации в том, что сигнатуры искали анализируя пакеты.\\ |
Притом, что код <a href="https://github.com/bittorrent/libutp">libuTP</a> был открыт 16 мая 2010 года - через 4 месяца после выхода uTorrent 2.0 где uTP был включён.\\ | Притом, что код [[https://github.com/bittorrent/libutp|libuTP]] был открыт 16 мая 2010 года - через 4 месяца после выхода uTorrent 2.0 где uTP был включён.\\ |
| |
Спустя пару месяцев "живительные" сигнатуры путём нечеловеческих усилий по анализу пакетов были <a href="http://www.opennet.ru/tips/info/2304.shtml">получены</a>.\\ | Спустя пару месяцев "живительные" сигнатуры путём нечеловеческих усилий по анализу пакетов были [[http://www.opennet.ru/tips/info/2304.shtml|получены]].\\ |
Ещё через некоторое время авторы поменяли пару незначительных для протокола начальных значений в SYN пакете и что то <a href="http://www.linux.org.ru/forum/admin/6357142">рандомизировали</a> (connid, seq_nr - больше не смогли) :)</spoiler>\\ | Ещё через некоторое время авторы uTP поменяли пару незначительных для протокола начальных значений в SYN пакете и что то [[http://www.linux.org.ru/forum/admin/6357142|рандомизировали]]: connid и seq_nr - больше не смогли.\\ |
| |
После того как ng_utp был написан стало понятно что проверять корректность работы с помощью tcpdump без правильных сигнатур мягко говоря не удобно - слишком много лишнего приходилось пробегать глазами. | После того как ng_utp был написан стало понятно что проверять корректность работы с помощью tcpdump без правильных сигнатур мягко говоря не удобно - слишком много лишнего приходилось пробегать глазами.\\ |
Я ещё раз пробежался по коду <a href="https://github.com/bittorrent/libutp">libuTP</a> и получились такие сигнатуры, сейчас может быть они уже устарели.\\ | Я ещё раз пробежался по коду [[https://github.com/bittorrent/libutp|libuTP]] и получились такие сигнатуры, сейчас может быть они уже устарели.\\ |
| |
| |
rst - 4 bytes: | rst - 4 bytes: |
<code>udp[17] = 0 and udp[18] = 3</code> | <code>udp[17] = 0 and udp[18] = 3</code> |
31 = udp hdr len (8) + upd pkt data len | |
| |
upd header included: | upd header included: |
<code>(udp[4:2] = 31 and udp[25:2] = 0x0003)</code> | <code>(udp[4:2] = 31 and udp[25:2] = 0x0003)</code> |
syn - 14 bytes: | syn - 14 bytes: |
<code>udp[0] & 0x0f = 1 and udp[0] & 0xf0 = 0x40 and udp[1] = 2 and udp[18:2] = 0 and udp[20] = 0 and udp[21] = 8 and udp[22:4] = 0 and udp[26:4] = 0</code> | <code>udp[0] & 0x0f = 1 and udp[0] & 0xf0 = 0x40 and udp[1] = 2 and udp[18:2] = 0 and udp[20] = 0 and udp[21] = 8 and udp[22:4] = 0 and udp[26:4] = 0</code> |
| "(udp[0] & 0x0f = 1 and udp[0] & 0xf0 = 0x40)" можно преобразовать в: "udp[0] = 0x41"\\ |
"(udp[0] & 0x0f = 1 and udp[0] & 0xf0 = 0x40)" можно преобразовать в: "udp[0] = 0x41" | |
upd header included: | upd header included: |
<code>(udp[4:2] = 38 and udp[8:2] = 0x4102 and udp[26:4] = 0x00000008 and udp[30:4] = 0 and udp[34:4] = 0)</code> | <code>(udp[4:2] = 38 and udp[8:2] = 0x4102 and udp[26:4] = 0x00000008 and udp[30:4] = 0 and udp[34:4] = 0)</code> |
rst - 4 bytes: | rst - 4 bytes: |
<code>udp[0] & 0x0f = 1 and udp[0] & 0xf0 = 0x30 and udp[1] = 0</code> | <code>udp[0] & 0x0f = 1 and udp[0] & 0xf0 = 0x30 and udp[1] = 0</code> |
<code>udp[0] & 0x0f = 1 and udp[0] & 0xf0 = 0x30</code> | "udp[0] & 0x0f = 1 and udp[0] & 0xf0 = 0x30" можно преобразовать в: "udp[0] = 0x31"\\ |
можно преобразовать в: | |
<code>udp[0] = 0x31</code> | |
28 = udp hdr len (8) + upd pkt data len | |
upd header included: | upd header included: |
<code>(udp[4:2] = 28 and udp[8:2] = 0x3100)</code> | <code>(udp[4:2] = 28 and udp[8:2] = 0x3100)</code> |
| |
===== Обнаружение фильтрации ===== | ===== Обнаружение фильтрации ===== |
Проще всего, используя описание протокола, реализовать простенький клиент, который будет устанавливать соединение и пытаться отправлять данные. | Проще всего, используя описание протокола, реализовать простенький клиент, который будет устанавливать соединение и пытаться отправлять данные.\\ |
По сути нужно симулировать установление соединения, и дальше пытаться слать DATA и STATE пакеты в ответ с ext типа ACK. | По сути нужно симулировать установление соединения, и дальше пытаться слать DATA и STATE пакеты в ответ с ext типа ACK.\\ |
Дальше один клиент запускается в интернете, другой у себя и смотрим теряются ли пакеты в 100% случаев или может RESET приходят. | Дальше один клиент запускается в интернете, другой у себя и смотрим теряются ли пакеты в 100% случаев или может RESET приходят.\\ |
Сходным образом при использовании yota некоторые пакеты из l2tp на завершающем этапе согласования пропадают в 100% случаев. Так было ещё в сентябре. | Сходным образом при использовании yota некоторые пакеты из l2tp на завершающем этапе согласования пропадают в 100% случаев. Так было ещё в сентябре 2014.\\ |
| |
| |
===== Заключение ===== | ===== Заключение ===== |
1. То что <a href="https://ru.wikipedia.org/wiki/ΜTorrent">написано в вики на русском</a> - полнейший бред: uTP имеет достаточно чёткие сигнатуры и легко ловится DPI. | 1. uTP имеет достаточно чёткие сигнатуры и легко ловится DPI.\\ |
Более того, ловить сигнатуры в TCP ощутимо сложнее, поскольку для гарантированного обнаружения нужно уметь собирать несколько пакетов вместе и уже потом проверять содержимое: клиент может передавать данные по одному байту. | Более того, ловить сигнатуры в TCP ощутимо сложнее, поскольку для гарантированного обнаружения нужно уметь собирать несколько пакетов вместе и уже потом проверять содержимое: клиент может передавать данные по одному байту.\\ |
Авторы uTP либо не ставили себе цель сделать протокол без сигнатур либо даже не приблизись к цели. | Авторы uTP либо не ставили себе цель сделать протокол без сигнатур либо даже не приблизись к цели.\\ |
(На мой взгляд в начале не ставили, а потом было уже поздно и рандомизация отдельных полей не помогает). | На мой взгляд в начале не ставили, а потом было уже поздно и рандомизация отдельных полей не помогает.\\ |
<a href="http://en.wikipedia.org/wiki/Micro_Transport_Protocol">Вики на английском</a> более адекватна. | |
| |
2. Производители различных DPI уже давно добавили сигнатуры для uTP, вряд ли им это было трудно сделать. | 2. Производители различных DPI уже давно добавили сигнатуры для uTP, вряд ли им это было трудно сделать.\\ |
| |
3. В порядке слухов: для линукса вроде бы тоже есть ядерная версия для работы с uTP протоколом на базе ipp2p а может уже отдельно. Но в паблик её не выкладывали. С середины 2012 года. | 3. В порядке слухов: для линукса вроде бы тоже есть ядерная версия для работы с uTP протоколом на базе ipp2p а может уже отдельно. Но в паблик её не выкладывали. С середины 2012 года.\\ |
| |
4. Для IPv6 код не писал, на всякий случай ;) | 4. Для IPv6 код не писал, на всякий случай ;)\\ |
| |
5. uTP не лучше TCP для передачи данных, вся проблема в том, что TCP можно хоть как то управлять из приложения только на BSD/Linux - setsockopt(..., IPPROTO_TCP, TCP_CONGESTION,...) - основное что требуется, хотя и там более тонкие параметры congestion control для отдельных сокетов не настраиваются. | 5. uTP не лучше TCP для передачи данных, вся проблема в том, что TCP можно хоть как то управлять из приложения только на BSD/Linux - setsockopt(..., IPPROTO_TCP, TCP_CONGESTION,...) - основное что требуется, хотя и там более тонкие параметры congestion control для отдельных сокетов не настраиваются. |