Как стать автором
Обновить

Преодоление блокировки в ТТК (Транстелеком) при помощи pf

Время на прочтение6 мин
Количество просмотров33K
После прочтения статьи уважаемого ValdikSS решил изучить DPI своего провайдера и, при благоприятном развитии событий, найти пути его обхода. Ниже — результаты моих изысканий.

Итак, провайдер — ТТК Ульяновск (бывш. 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!
Теги:
Хабы:
Всего голосов 33: ↑32 и ↓1+31
Комментарии18

Публикации

Истории

Ближайшие события

15 – 16 ноября
IT-конференция Merge Skolkovo
Москва
22 – 24 ноября
Хакатон «AgroCode Hack Genetics'24»
Онлайн
28 ноября
Конференция «TechRec: ITHR CAMPUS»
МоскваОнлайн
25 – 26 апреля
IT-конференция Merge Tatarstan 2025
Казань