Итак, провайдер — ТТК Ульяновск (бывш. DARS Telecom), PPPoE-подключение с выделением внешнего IP на время сессии. Блокировка осуществляется заворачиванием заблокированных подсетей/хостов на свой DPI. DNS не подменяется.
% traceroute ya.ru
traceroute to ya.ru (87.250.250.242), 64 hops max, 40 byte packets
1 bras.ulttk.ru (79.132.125.1) 0.899 ms 0.787 ms 0.817 ms
2 ulk06.ulk26.transtelecom.net (217.150.41.98) 1.552 ms 1.536 ms 1.536 ms
3 * * *
4 Yandex-gw.transtelecom.net (188.43.3.213) 21.828 ms 15.955 ms 17.003 ms
% traceroute rutracker.org
traceroute to rutracker.org (195.82.146.214), 64 hops max, 40 byte packets
1 bras.ulttk.ru (79.132.125.1) 1.778 ms 0.843 ms 0.751 ms
2 ulk06.ulk26.transtelecom.net (217.150.41.98) 1.656 ms 1.698 ms 1.439 ms
3 * * *
4 188.43.0.18 (188.43.0.18) 16.589 ms
BlackList-gw.transtelecom.net (188.43.30.130) 16.435 ms
BL-gw.transtelecom.net (188.43.31.170) 16.377 ms
5 Filter-gw.transtelecom.net (188.43.30.33) 17.006 ms 16.859 ms 17.080 ms
% traceroute kinozal.tv
traceroute: Warning: kinozal.tv has multiple addresses; using 104.24.107.53
traceroute to kinozal.tv (104.24.107.53), 64 hops max, 40 byte packets
1 bras.ulttk.ru (79.132.125.1) 0.810 ms 0.809 ms 0.739 ms
2 ulk06.ulk26.transtelecom.net (217.150.41.98) 1.653 ms 1.802 ms 1.736 ms
3 * * *
4 Filter-gw.transtelecom.net (188.43.30.34) 16.451 ms
BL-gw.transtelecom.net (188.43.31.170) 16.405 ms 16.418 ms
5 Filter-gw.transtelecom.net (188.43.30.33) 99.751 ms 78.541 ms 17.021 ms
6 Cloudflare-msk-gw.transtelecom.net (188.43.3.65) 212.754 ms 107.803 ms 117.062 ms
7 104.24.107.53 (104.24.107.53) 28.015 ms 17.216 ms 17.357 ms
Причем некоторые сайты просто и незатейливо заблокированы по IP (спасибо хоть RST присылают). Например, bt-анонсеры Рутрекера:
02:48:58.530078 IP (tos 0x0, ttl 64, id 0, offset 0, flags [DF], proto TCP (6), length 60)
ip109.176.ulttk.ru.22099 > bt.rutracker.org.http: Flags [S], cksum 0xd538 (correct), seq 3425095266, win 65535, options [mss 1452,nop,wscale 6,sackOK,TS val 1991139339 ecr 0], length 0
02:48:58.546482 IP (tos 0x0, ttl 61, id 0, offset 0, flags [DF], proto TCP (6), length 40)
bt.rutracker.org.http > ip109.176.ulttk.ru.22099: Flags [R.], cksum 0x13b9 (correct), seq 0, ack 3425095267, win 0, length 0
Для тех же сайтов, где нужно показать страничку блокировки работает пассивный DPI. Рассмотрим на примере Рутрекера:
02:27:28.605860 IP (tos 0x0, ttl 64, id 0, offset 0, flags [DF], proto TCP (6), length 60)
ip109.176.ulttk.ru.27338 > rutracker.org.http: Flags [S], cksum 0xeafc (correct), seq 3703194126, win 65535, options [mss 1452,nop,wscale 6,sackOK,TS val 1989849414 ecr 0], length 0
02:27:28.646812 IP (tos 0x0, ttl 58, id 0, offset 0, flags [DF], proto TCP (6), length 48)
rutracker.org.http > ip109.176.ulttk.ru.27338: Flags [S.], cksum 0x81d2 (correct), seq 2683499593, ack 3703194127, win 14600, options [mss 1400,nop,wscale 8], length 0
02:27:28.646913 IP (tos 0x0, ttl 64, id 0, offset 0, flags [DF], proto TCP (6), length 40)
ip109.176.ulttk.ru.27338 > rutracker.org.http: Flags [.], cksum 0xe266 (correct), seq 1, ack 1, win 1028, length 0
02:27:28.647281 IP (tos 0x0, ttl 64, id 0, offset 0, flags [DF], proto TCP (6), length 117)
ip109.176.ulttk.ru.27338 > rutracker.org.http: Flags [P.], cksum 0xb1d5 (correct), seq 1:78, ack 1, win 1028, length 77: HTTP, length: 77
GET / HTTP/1.1
Host: rutracker.org
User-Agent: curl/7.56.0
Accept: */*
02:27:28.663665 IP (tos 0x0, ttl 61, id 0, offset 0, flags [DF], proto TCP (6), length 286)
rutracker.org.http > ip109.176.ulttk.ru.27338: Flags [FP.], cksum 0xf88c (correct), seq 1:247, ack 78, win 0, length 246: HTTP, length: 246
HTTP/1.1 301 Moved Permanently
02:27:28.663724 IP (tos 0x0, ttl 64, id 0, offset 0, flags [DF], proto TCP (6), length 40)
ip109.176.ulttk.ru.27338 > rutracker.org.http: Flags [.], cksum 0xe126 (correct), seq 78, ack 248, win 1024, length 0
02:27:28.664047 IP (tos 0x0, ttl 64, id 0, offset 0, flags [DF], proto TCP (6), length 40)
ip109.176.ulttk.ru.27338 > rutracker.org.http: Flags [F.], cksum 0xe121 (correct), seq 78, ack 248, win 1028, length 0
02:27:28.695429 IP (tos 0x0, ttl 64, id 0, offset 0, flags [DF], proto TCP (6), length 60)
ip109.176.ulttk.ru.42348 > dib-filtr-gw.transtelecom.net.http: Flags [S], cksum 0x0556 (correct), seq 2835326510, win 65535, options [mss 1452,nop,wscale 6,sackOK,TS val 1989849504 ecr 0], length 0
Посмотрим на данный вывод подробнее. С момента 605860 до 646913 клиент осуществляет тройное рукопожатие с «настоящим» Рутрекером. В 647281 клиент посылает HTTP-запрос Рутрекеру длинной 77 байт, но вместо обычного ACK получает от «поддельного» Рутрекера FPA с HTTP-перенаправлением длинной 246 байт. Причем, заметьте, с корректным ACK 78, но левым, в рамках данного TCP-соединения, номером последовательности SEQ. Далее клиент закрывает соединение и переходит куда сказали. ACK и HTTP-ответ от Рутрекера так и не приходят.
В принципе, понятно зачем провайдеру потребовался этот странный TCP с флагами FPA: FIN для начала завершения соединения со стороны клиента, PUSH для проталкивания этого сегмента в TCP-очереди клиента, а корректный ACK чтоб всё выглядело красиво и этот «поддельный» TCP-сегмент не был отброшен TCP\IP-стеком клиента. Но этот FPA его же и погубил.
Итак, основная стратегия — отбрасывать TCP-сегменты с установленными флагами FPA, как-бы приходящие с адресов заблокированных ресурсов.
В качестве роутера в моей домашней сети трудится FreeBSD на старом Атоме, пакетным фильтром работает pf. Основной проблемой стало то, что pf — это statefull-фаервол, т.е. после первого же нашего разрешенного исходящего SYN в адрес Рутрекера в таблицу состояний фаервола заносится запись (state) и все последующие запросы и, что нам особенно важно, ответы в пределах данного TCP-соединения ни через какие правила фаервола более не проходят, они все разрешены.
Подобное поведение сильно увеличивает производительность брандмауэра и сокращает количество правил, но в нашем случае препятствует эффективной фильтрации. Поэтому все запросы/ответы к заблокированным ресурсам будем производить в stateless-режиме, т.е. без сохранения состояния. В pf правила получились такие:
WAN="ng0"
LAN="re0"
Blocked="{ заблок.IP1, заблок.IP2, заблок.IP3, и т.д. }"
...
# -UNBLOCK-
# for LAN hosts
pass in quick on $LAN proto tcp from $LAN:network to $Blocked no state
block drop out quick on $LAN proto tcp from $Blocked to $LAN:network flags FPA/FPA
pass out quick on $LAN proto tcp from $Blocked to $LAN:network no state
# -UNBLOCK-
# for me (router itself, for testing)
pass out quick on $WAN proto tcp from ($WAN) to $Blocked no state
block drop in quick on $WAN proto tcp from $Blocked to ($WAN) flags FPA/FPA
pass in quick on $WAN proto tcp from $Blocked to ($WAN) no state
...
Директива no state в разрешающих правилах запрещает сохранение состояния, первое правило в блоке UNBLOCK разрешает исходящие на заблокированный ресурс, второе правило блокирует «поддельные» входящие с установленными флагами FPA, третье — разрешает все остальные входящие. Директива quick во всех правилах прекращает просмотр фаерволом всех последующих правил фильтрации при совпадении с данным правилом. Результат (тройное рукопожатие пропущено):
01:48:10.221343 IP (tos 0x0, ttl 64, id 0, offset 0, flags [DF], proto TCP (6), length 117)
ip109.176.ulttk.ru.42714 > rutracker.org.http: Flags [P.], cksum 0xccb6 (correct), seq 1:78, ack 1, win 1028, length 77: HTTP, length: 77
GET / HTTP/1.1
Host: rutracker.org
User-Agent: curl/7.56.0
Accept: */*
01:48:10.237686 IP (tos 0x0, ttl 61, id 0, offset 0, flags [DF], proto TCP (6), length 286)
rutracker.org.http > ip109.176.ulttk.ru.42714: Flags [FP.], cksum 0x136e (correct), seq 1:247, ack 78, win 0, length 246: HTTP, length: 246
HTTP/1.1 301 Moved Permanently
01:48:10.563977 IP (tos 0x0, ttl 64, id 0, offset 0, flags [DF], proto TCP (6), length 117)
ip109.176.ulttk.ru.42714 > rutracker.org.http: Flags [P.], cksum 0xccb6 (correct), seq 1:78, ack 1, win 1028, length 77: HTTP, length: 77
GET / HTTP/1.1
Host: rutracker.org
User-Agent: curl/7.56.0
Accept: */*
01:48:10.604853 IP (tos 0x0, ttl 58, id 42669, offset 0, flags [DF], proto TCP (6), length 40)
rutracker.org.http > ip109.176.ulttk.ru.42714: Flags [.], cksum 0x00c5 (correct), seq 1, ack 78, win 58, length 0
01:48:10.605043 IP (tos 0x0, ttl 58, id 42670, offset 0, flags [DF], proto TCP (6), length 422)
rutracker.org.http > ip109.176.ulttk.ru.42714: Flags [P.], cksum 0x9bc5 (correct), seq 1:383, ack 78, win 58, length 382: HTTP, length: 382
HTTP/1.1 301 Moved Permanently
Server: nginx
Date: Thu, 26 Oct 2017 21:48:10 GMT
Content-Type: text/html
Content-Length: 178
Location: http://rutracker.org/forum/index.php
Connection: keep-alive
221343 — HTTP-запрос к Рутрекеру
237686 — ответ от провайдерского DPI с флагами FPA (дамп с внешнего интерфейса роутера, поэтому он тут виден; клиент его не получает)
563977 — клиент ответа так и не дождался, повторяет запрос
604853 — настоящий Рутрекер присылает ACK
605043 — настоящий Рутрекер присылает HTTP-ответ
P.S. То же самое можно проделать с помощью любого современного фаервола, pf здесь только потому, что я его использую. Так же внимательный читатель мог заметить, что IP-спуфинг, осуществляемый DPI провайдера, элементарно детектируется по IP TTL (58 против 61). Но pf не умеет фильтровать все поля IP-пакетов, только основные. При использовании других фаерволов несовпадение IP TTL можно использовать как дополнительный признак «поддельного» пакета, наряду с TCP FPA.
That's All Folks!
Комментарии (18)
KluchnikovAleksey
30.10.2017 15:02-8Ну молодец. Умный умный. А никто и не знал. Только вот узнал такое и сидеть надо тихо, чтобы не портить другим людям.
EvilGenius18
30.10.2017 15:20taurusbusy у вас в Ульяновске ТТК тоже не дает использовать Google DNS?
В Питере вместо Google DNS, резолвит через те же:
BL-gw.transtelecom.net
Filter-gw.transtelecom.net
taurusbusy Автор
30.10.2017 18:19У нас Google DNS так же заворачиваются на Filter-gw, но ответы не подменяются:
# host rutracker.org rutracker.org has address 195.82.146.214 rutracker.org has IPv6 address 2a02:4680:22::214 rutracker.org mail is handled by 5 mail.rutracker.org. # host rutracker.org 8.8.8.8 Using domain server: Name: 8.8.8.8 Address: 8.8.8.8#53 Aliases: rutracker.org has address 195.82.146.214 rutracker.org has IPv6 address 2a02:4680:22::214 rutracker.org mail is handled by 5 mail.rutracker.org.
Первый запрос ходит не через провайдерский DNS, а через unbound с такой записью:
forward-zone: name: "rutracker.org" forward-addr: 77.88.8.8 forward-addr: 193.58.251.251
rippy
31.10.2017 10:31да все ТТК-улн подменяет
[evk:prtech:~]>host rutracker.org
rutracker.org has address 62.33.207.197
rutracker.org has address 62.33.207.196
rutracker.org has IPv6 address 2a00:1e48:99:6::2:2
rutracker.org has IPv6 address 2a00:1e48:99:6::2:3
[evk:prtech:~]>host rutracker.org 8.8.8.8
Using domain server:
Name: 8.8.8.8
Address: 8.8.8.8#53
Aliases:
rutracker.org has address 195.82.146.214
rutracker.org has IPv6 address 2a02:4680:22::214
rutracker.org mail is handled by 5 mail.rutracker.org.taurusbusy Автор
31.10.2017 10:48Совершенно верно, если выставлены провайдерские DNS, то картина, возможно, именно такая. Но ТТК не подменяет ответы от других публично доступных DNS-серверов, а уж разрулить запросы по форвардерам умеет любой кеширующий DNS, будь то unbound, bind или др. Разумеется, удобнее всего делать это на границе подконтрольной вам сети, например, на домашнем роутере.
Для борьбы с подменой вообще всех DNS-ответов существует dnscrypt.
bravo-ej
30.10.2017 19:20Интересно, спасибо. Только это не DPI. Он бы таким не занимался. На самом деле схема эта очевидная и работает банально на случае, кто быстрее ответит. На маршрутизаторе оператора зеркалится трафик на небольшой сервачок и если система увидит запрос к ресурсу из списка — она вот такое вытворяет. Пакет от заблокированного ресурса вам наверное прилетит, только вы его уже не будете ждать.
Что будет, когда списки вырастут ещё больше — сложно представить. Мы у себя внедряли такое (шибко подробностей не знаю, другой отдел), и налетали на штрафы от ркн за пропуски больше допустимого процента — банально система не успевала срабатывать в ответ на запросы ревизора от ркн. В итоге мы их перепробовали несколько и на чём то остановились по результатам тестов. Но принцип у них у всех один и тот же. Иначе это должна быть железка, через которую надо пропускать весь пиринг с операторами — а это совсем дорого уже только по железу, не говоря уже о софте и внедрение.
Для подстраховки оператор может организовать для ревизора лаг на секундочку, что б наверняка )) но мы без этого обошлись естественно (иначе нафиг на такую систему блокировки тратить деньги).taurusbusy Автор
31.10.2017 10:12Пакет от заблокированного ресурса вам наверное прилетит, только вы его уже не будете ждать.
После провайдерского FPA ни ACK, ни HTTP-ответ от заблокированного ресурса уже не приходят. Специально tcpdump-ом искал их на внешнем интерфейсе роутера.
На маршрутизаторе оператора зеркалится трафик на небольшой сервачок и если система увидит запрос к ресурсу из списка — она вот такое вытворяет.
ЕМНИП трафик зеркалируется только для СОРМа, блокировки каждый провайдер реализует в меру своих технических возможностей. У ТТК возможностей хоть отбавляй, поэтому не удивлюсь, если они под свой DPI зарегистрировали отдельную AS и глобально сливают туда весь трафик к заблокированным ресурсам. Для них — это проще всего.bravo-ej
31.10.2017 15:53Пообсуждали с коллегой. Стало понятно (мне), что принцип хоть и одинаков (или сильно похож), но методы и алгоритмы действия при этом у каждого продукта «фильтрации» свои. Тут мы правды не найдём, хотя бы потому, что никто из нас не знает, как оно у ТТК на самом деле (особенно в обособленном бизнесе в той локации). Да и тема не моя.
madixi
30.10.2017 21:59У меня такой же провайдер, на роутере openwrt, всего одно слово ipv6.
rippy
31.10.2017 10:31ipv6 не спасает от подмены DNS, я выше привел резолвинг через DNS ТТК
Bonio
31.10.2017 15:02В моем случае спасает. Все запросы на любые ipv4 dns сервера перехватываются провайдером и подменяются, а на ipv6 dns сервера, через туннель, не подменяются.
Правда я все равно пользуюсь dnscrypt для скрытия dns трафика от провайдера. Трафик через туннель хоть пока и не перехватывается, но идет в открытом виде, что, теоретически, не мешает начать его анализировать какими-нибудь dpi.
К тем провайдерам, которые предоставляют нативную поддержку ipv6 это, наверное, не относится.
scruff
31.10.2017 12:35Не много не понятен механизм подделки Рутрекера — как в принципе можно подделать его IP да так, чтобы FPA принял клиент как за оргинальный?
taurusbusy Автор
01.11.2017 16:10Принцип атаки, осуществляемой ТТК, довольно подробно описан здесь (способ с TCP-битом RST). Т.к. ТТК является провайдером доступа в Интернет, то для него осуществлять подобный вид MITM-атаки не представляет никакой технической или организационной сложности.
Pochemuk
Все хорошо, но можно ли обойтись без упоминания в правилах адресов/ссылок на заблокированные ресурсы? Как изменится поведение фильтра без первого правила?
taurusbusy Автор
Спасибо. Поправил.