Ник Пост Дата
serfreeman1337

Не устанавливается соединение по QUIC для зарубежных сайтов. Не приходит ответ от сервера на Initial пакет.

Проверял на сайтах google (в том числе youtube), cloudflare-quic.com и quic.nginx.org.
При этом vk.com продолжает работать по HTTP/3.

Заметил на операторах Yota, Мегафон и проводном МТС.

2022-03-04T07:41:41.789Z
Hatomen

Быстрая проверка показывает, что:

Провайдер RNet (СПб):

image

image

Мобильный Билайн:

image

image

При этом аналогичная картинка на обоих провайдерах с включенным впн:

image

image

2022-03-04T08:03:03.667Z
bolvan

Действительно, ответа на QUIC initial нет. Проверено на cloudflare-quic.com и ipv4.google.com
Но на vk.com QUIC не заблокирован

Лечится вот так :

iptables -t mangle -I POSTROUTING -p udp --dport 443 -m mark ! --mark 0x40000000/0x40000000 -m connbytes --connbytes-dir=original --connbytes-mode=packets --connbytes 1:3 -j NFQUEUE --queue-num 205 --queue-bypass
nfqws --qnum=205 ---dpi-desync=fake --dpi-desync-any-protocol --dpi-desync-cutoff=d4

Заодно и проверил работу nfqws на десинхронизацию UDP. Вполне успешно справилось
Как и ожидалось, фильтр не способен вычленить из QUIC имя хоста, поскольку ему пришлось бы применять сложный алгоритм расшифровки. Потому QUIC банится. Вероятно по white list
Так же ожидаемо DPI отстает от потока UDP , если 1-й пакет ему не показался похожим на QUIC. Либо ищется только QUIC initial. Не проверял

UPDATE. Как оказалось, движок QUIC от chromium ловит не только UDP, но и ICMP ttl expired in transit, связанные со своими UDPшками. Они приходят от фейк-пакетов с низким TTL. Как только броузер славливает такой ICMP, сеанс считает порванным, дальше ничего не проходит. Mozilla этим НЕ страдает.
Лечение : либо резать ttl expired in transit (нехорошо, поломаете трейсилки), либо отказаться от ttl fooling и заменить на любой другой, который сработает. Например, badsum.
А можно вообще убрать fooling. В этом случае фейки будут доходить до сервера, но поскольку там трэш, они будут отбрасываться процессом веб сервера.
Но если вы вдруг используете badsum и что-то на пути будет дропать пакеты с badsum (роутеры mediatek, заводские прошивки с linux), то обход не сработает
Проще и надежнее убрать fooling

2022-03-04T13:49:17.067Z
yuichi001(Никита)

есть аналогичные команды под windows и goodbye dpi?

2022-03-04T14:19:34.318Z
bolvan

Насколько мне известно, goodbye пока не поддерживает udp

2022-03-04T14:20:55.175Z
ValdikSS

Подозреваю, что протокол отключили из-за проблем с блокировкой веб-сайтов? Поддерживает ли HTTP/3 подключение только по QUIC, без TCP-соединения вовсе? Насколько понимаю, ему в любом случае нужен TCP, а уведомление о поддержке QUIC передаётся в TLS ALPN или в HTTP Alt-Svc, или я что-то упустил?

2022-03-04T16:59:05.821Z
bolvan

Технически нет никаких проблем сначала пытаться установить quic handshake, и это сработало бы аналогично ESNI, обойдя все блокировки.
Другое дело, что броузеры этого не делают. Они действительно сначала лезут по TLS, и только потом в результате процедуры апгрейда лезут по h3.
Получается, вся защита основывается лишь на “инструментальной беспомощности”. Нет элементарной функции. Но это дело поправимое. Внести небольшую правку в код, добавить переменную в about:config
Умелец выпустит модифицированный броузер, и дальше результат понятен

2022-03-04T19:14:06.474Z
serfreeman1337

Обнаружил, что Firefox можно заставить лезть сразу по h3, задав alt-svc для нужных хостов через преф:
network.http.http3.alt-svc-mapping-for-testing

Установив его в:
facebook.com;h3=:443,www.facebook.com;h3=:443,static.xx.fbcdn.net;h3=:443

удалось открыть страницу facebook.com

При обновлении без кеша (ctrl+f5 или shift+клик по иконке обновления) Firefox снова пытается открыть его через TLS, простое F5 перезагружает его через h3 без проблем.

2022-03-05T06:56:52.856Z
kelm

Немедленное рукопожатие HTTP/3 (для одного хоста) также возможно в Chrome/Chromium, запустив браузер из командной строки:

  1. Введите следующую команду:
    Chromium: chromium --enable-quic --origin-to-force-quic-on=www.facebook.com:443
    Chrome: chrome --enable-quic --origin-to-force-quic-on=www.facebook.com:443
  2. Введите адрес веб-сайта в адресную строку (используйте точное доменное имя, указанное в команде).
2022-03-06T11:39:59.343Z
ValdikSS

Фильтр работает только для пакетов с UDP-нагрузкой больше 1001 байтов (включительно).
Фильтр ищет “00 00 00 01” (hex, QUIC version) в UDP-нагрузке, начиная со второго байта.
Применяется только к UDP-пакетам на порт назначения 443. Исходящий порт значения не имеет (может быть также 443, фильтр не применится).

Псевдо-yara-правило фильтра:

rule QUIC_block_Russia_TSPU_04_mar_2022
{
    condition:
        filesize > 1000 and dport == 443 and int32be(1) == 0x00000001
}

Минимальный пакет, на который срабатывает фильтр:
quic_tspu_filtered.bin (1001 Bytes)

nping --udp -p 443 -c 1 --data "$(xxd -ps -c 999999 quic_tspu_filtered.bin)"
2022-03-09T00:55:49.310Z
bolvan

Подтверждаю. Добавлю к этому, что к входящим пакетам фильтрация не применяется и используется stateful фильтр. Если первый пакет между src_ip:src_port dst_ip:dst_port не распознан как QUIC, остальные не проверяют. Потому и работает desync=fake в nfqws

desync=ipfrag2 тоже работает , если тестировать с помощью nping со своей VPSкой или девайсом на другом российском провайдере, но на большинстве сайтов не работает, потому что сеть крайне враждебна к ip фрагментам. но все же обмануть ТСПУ этим можно, если речь пойдет о подключении к своему сервису (не обязательно веб, может быть wireguard). Естественно, ipfrag убивается первым же NAT на пути. Если от провайдера серый ип и ТСПУ находится после NAT или из-за своего роутера - неприменимо

Проверил еще хождение между 2 российскими провайдерами. Тоже заблокировано
Значит, гипотеза про white list на ВК подтверждается

2022-03-09T08:00:13.565Z
serfreeman1337

С 12 часов на Yota и Megafon наблюдаю проблемы с доступом на домены google com / google ru. Соединение устанавливается, но после получения некоторого объема данных пакеты перестаю ходить.
Странно, что такое только с доменами .google., с ютубом все ок.

google_quic_yota.pcapng (79.8 KB)
IP адрес 142.250.186.196 для google com прописан через /etc/hosts

На мобильном билайне с nfqws всё работает без проблем, как и на проводном Net By Net.

UPD:
Проблема с Firefox, с Chromium все загружается.

В firefox можно отключить quic version 1, установив network.http.http3.support_version1 в false, тогда в QUIC Version будет светиться “FF 00 00 1D” (draft-29) и фильтр пропустит его. В alt-svc преф нужно писать h3-29=:443 в этом случае.

2022-03-14T15:10:48.566Z
serfreeman1337

Обход через смену версии на draft-29 больше не работает, по крайней мере с instagram и facebook:
Следующий пакет не пропускает фильтр:
instagram_quic_initial.bin (1.3 KB)
Хотя такой же пакет для домена гугла доходит до сервера.

C nfqws все также работает.

2022-03-19T09:55:03.866Z
ValdikSS

Ваш пакет доходит до facebook.com (157.240.201.35), на провайдере с ТСПУ.

$ nping --udp -p 443 -c 1 --data "$(xxd -ps -c 999999 instagram_quic_inital.bin)" 157.240.201.35

Starting Nping 0.7.91 ( https://nmap.org/nping ) at 2022-03-20 00:31 MSK
SENT (0.0022s) UDP packet with 1357 bytes to 157.240.201.35:443
RCVD (0.0394s) UDP packet with 1232 bytes from 157.240.201.35:443
 
Max rtt: 37.137ms | Min rtt: 37.137ms | Avg rtt: 37.137ms
UDP packets sent: 1 | Rcvd: 1 | Lost: 0 (0.00%)
Nping done: 1 IP address pinged in 0.04 seconds

Как минимум у части провайдеров заблокированы часть адресов Instagram. Попробуйте порезолвить домены через разные публичные резолверы и попробовать разные IP-адреса.

2022-03-19T21:32:42.747Z
serfreeman1337

Я проверял с DigitalOcean AMS. Оператор Yota.

Тесты с 157.240.201.35:
Initial с server_name www.google.com:

$ nping --udp -p 443 -c 1 --data "$(xxd -ps -c 999999 google_quic_initial.bin)" 157.240.201.35    

Starting Nping 0.7.92 ( https://nmap.org/nping ) at 2022-03-20 11:18 MSK
SENT (0.0016s) UDP packet with 1357 bytes to 157.240.201.35:443
RCVD (0.2062s) UDP packet with 1232 bytes from 157.240.201.35:443

Max rtt: 204.642ms | Min rtt: 204.642ms | Avg rtt: 204.642ms
UDP packets sent: 1 | Rcvd: 1 | Lost: 0 (0.00%)
Nping done: 1 IP address pinged in 0.21 seconds

Initial с server_name www.instagram.com:

$ nping --udp -p 443 -c 1 --data "$(xxd -ps -c 999999 instagram_quic_inital.bin)" 157.240.201.35  

Starting Nping 0.7.92 ( https://nmap.org/nping ) at 2022-03-20 11:18 MSK
SENT (0.0015s) UDP packet with 1357 bytes to 157.240.201.35:443

Max rtt: N/A | Min rtt: N/A | Avg rtt: N/A
UDP packets sent: 1 | Rcvd: 0 | Lost: 1 (100.00%)
Nping done: 1 IP address pinged in 1.00 seconds

Тоже самое происходит и с www.facebook.com. При использовании nfqws оба server_name доходят.

2022-03-20T08:29:32.381Z
ValdikSS

Через Tele2 instagram отвечает почти всегда, но не каждый раз. На личный сервер этот пакет доходит всегда.

На Yota, действительно, есть фильтр, и на первый взгляд, он декодирует QUIC-пакет и выявляет имя домена.

2022-03-20T09:33:04.353Z
bolvan

На моем провайдере с ТСПУ начались непонятные и хаотичные отрубы QUIC сессий, пробитых с помощью nfqws --dpi-desync=fake. Пейлоад пробовал разный. Разницы никакой.

Тест : с firefox с вычищенным кэшем заходим на https://ipv4.google.com
через раз получается как на картинке
По паре ip:port перестают ходить пакеты, как если бы DPI занес UDP поток в черный список. Точно так же, как если первым пакетом пошел бы QUIC initial. Но здесь происходит отруб внезапно в середине сеанса. Всовывание фейков перед каждым пакетом не помогает.
Пробовал завертывать UDP через свой сервер. Тоже самое. Если пропустить через VPN - проблема уходит
Пробовал взять первые 2 пакета от клиента и от сервера (initial) и долбиться ими nping-ом по одной паре ip:port с сервера и клиента после начального пробития фейком. Не отрубает.
nping по блокированной паре ip:port с ограниченным TTL показывает, что блок идет на 5-хопе. Там стоит как раз ТСПУ и блокировщик сайтов
Эвристика - статистика какая-то ?

2022-03-21T09:19:59.370Z
Supp

У домру недавно наблюдались блокировки QUIC на youtube, facebook, в отличие от VK. Сейчас проверил, пока QUIC заработал на них. Тестят наверно…

2022-03-23T15:54:44.232Z
bolvan

Крайний раз, когда тестил домру около месяца назад, у них наблюдался лоад балансинг.
Часть трафика уходит через ТСПУ, а часть нет. Где нет - там простой пассивный DPI.
Потому может то работать QUIC, то не работать. По какому критерию балансируется трафик я не изучал, возможно по IP. Учитывая прыгающий характер ip от крупных сервисов, может так и получиться, что когда-то запросы идут через ТСПУ, а когда-то нет

2022-03-23T16:11:39.138Z
Bronner(Roman)

Почему после включения nfqws может совсем переставать работать http3? Если отключить nfqws, то через curl работает http3, но в хроме только http2. Проверял на quic.nginx.org и cloudflare-quic.com, ютубе и др. Если включить VPN, то в хроме начинает полноценно работать http3. В firefox работает http3 и без vpn, но частично, только cloudflare-quic.com, а на quic.nginx.org не работает, на других сайтах чаще тоже работает. В Safari совсем ситуация странная, буквально пару дней назад http3 работал везде даже лучше, чем в firefox, а сегодня даже через vpn не работает.

nfqws --dpi-desync-fwmark=0x40000000 --qnum=210 --dpi-desync=fake --debug

curl -4ILv --max-time 5 --http3 https://vk.com                                                                                                                                                                                                    28 ↵
*   Trying 87.240.190.72:443...
* Connect socket 5 over QUIC to 87.240.190.72:443
* Sent QUIC client Initial, ALPN: h3-29,h3-28,h3-27
* After 2498ms connect time, move on!
* connect to 87.240.190.72 port 443 failed: Connection timed out
*   Trying 87.240.190.67:443...
* Connect socket 6 over QUIC to 87.240.190.67:443
* Sent QUIC client Initial, ALPN: h3-29,h3-28,h3-27
* After 1249ms connect time, move on!
* connect to 87.240.190.67 port 443 failed: Connection timed out
*   Trying 87.240.190.78:443...
* Connect socket 5 over QUIC to 87.240.190.78:443
* Sent QUIC client Initial, ALPN: h3-29,h3-28,h3-27
* After 624ms connect time, move on!
* connect to 87.240.190.78 port 443 failed: Connection timed out
*   Trying 87.240.137.158:443...
* Connect socket 6 over QUIC to 87.240.137.158:443
* Sent QUIC client Initial, ALPN: h3-29,h3-28,h3-27
* After 313ms connect time, move on!
* connect to 87.240.137.158 port 443 failed: Connection timed out
*   Trying 87.240.139.194:443...
* Connect socket 5 over QUIC to 87.240.139.194:443
* Sent QUIC client Initial, ALPN: h3-29,h3-28,h3-27
* After 156ms connect time, move on!
* connect to 87.240.139.194 port 443 failed: Connection timed out
*   Trying 93.186.225.208:443...
* Connect socket 6 over QUIC to 93.186.225.208:443
* Sent QUIC client Initial, ALPN: h3-29,h3-28,h3-27
* After 78ms connect time, move on!
* connect to 93.186.225.208 port 443 failed: Connection timed out
* Failed to connect to vk.com port 443: Connection timed out
* Closing connection 0
curl: (28) Failed to connect to vk.com port 443: Connection timed out
IP4: 192.168.1.113 => 87.240.137.158 proto=udp sport=61894 dport=443
UDP: CF FF 00 00 1D 10 2C 20 B7 21 87 58 81 F7 7C 35 DD 53 A2 C5 3E 53 14 B9 69 39 3D BA 50 CD 16 54 ... : ......, .!.X..|5.S..>S..i9=.P..T ...
packet contains QUIC initial
hostname: vk.com
dpi desync src=192.168.1.113:61894 dst=87.240.137.158:443
sending fake request : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ... : ................................ ...
reinjecting original packet. len=1228 len_payload=1200
packet: id=30 drop
packet: id=31 len=1228
IP4: 192.168.1.113 => 87.240.139.194 proto=udp sport=61598 dport=443
UDP: C2 FF 00 00 1D 10 38 DB 6E CE F1 CB 56 79 07 F0 93 1A 44 1A F7 B7 14 D2 BD E2 80 6C A9 B3 09 58 ... : ......8.n...Vy....D........l...X ...
packet contains QUIC initial
hostname: vk.com
dpi desync src=192.168.1.113:61598 dst=87.240.139.194:443
sending fake request : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ... : ................................ ...
reinjecting original packet. len=1228 len_payload=1200
packet: id=31 drop
packet: id=32 len=1228
IP4: 192.168.1.113 => 93.186.225.208 proto=udp sport=60154 dport=443
UDP: CF FF 00 00 1D 10 2D F6 2E 56 03 F9 77 77 84 84 EA E7 CE D4 48 AF 14 EF E5 4F 88 92 50 04 C4 1F ... : ......-..V..ww......H....O..P... ...
packet contains QUIC initial
hostname: vk.com
dpi desync src=192.168.1.113:60154 dst=93.186.225.208:443
sending fake request : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ... : ................................ ...
reinjecting original packet. len=1228 len_payload=1200
packet: id=32 drop
2022-03-26T02:47:20.346Z
bolvan

Единственная проблема с атакой fake против QUIC, которую я нашел , это спорадическое застревание потока на середине, как описано выше. Видимо оно вызванно какими-то статистическими методами анализа на ТСПУ, срабатывающими через раз.

Но если этого не случается, то поведение броузеров на провайдерах с ТСПУ + nfqws и провайдерах без ТСПУ и без nfqws выглядит идентичным

Броузеры сейчас слишком умные. Их цель - не подключить вас по самому крутому и модному протоколу, а загрузить страницу как можно быстрее. Исходя из этих соображений они сами вольны выбирать какое подключение использовать и через какую версию ip.

У меня и на хромиуме, и на мозилле, quic.nginx.org проходит тест на QUIC, а cloudflare не проходит на обоих броузерах. Смотрим F12 и видим, что там первая часть запросов идет по http/2, вторая по http/3. Если убрать nfqws на провайдере с ТСПУ, то все запросы идут http/2

Мне сообщали, что на некоторых провайдерах (yota), они стали дешифровывать QUIC на DPI. Я не в курсе подробностей, но дело вот в чем. Сейчас у них задача - полностью забанить сам протокол QUIC, кроме white list ip (вконтакт, слишком серьезный клиент).
Если они научатся анализировать QUIC, они могут перестать банить сам протокол и убрать статистический анализ.

2022-03-26T07:38:58.571Z
bolvan

Собрал curl с quiche.
2 теста на провайдере с ТСПУ.
первый с nfqws, второй без

curll -4Iv --http3 https://cloudflare-quic.com
*   Trying 172.67.9.235:443...
*  CAfile: /etc/ssl/certs/ca-certificates.crt
*  CApath: none
* Connect socket 5 over QUIC to 172.67.9.235:443
* Sent QUIC client Initial, ALPN: h3,h3-29,h3-28,h3-27
*  subjectAltName: host "cloudflare-quic.com" matched cert's "cloudflare-quic.com"
* Verified certificate just fine
* Connected to cloudflare-quic.com () port 443 (#0)
* h2h3 [:method: HEAD]
* h2h3 [:path: /]
* h2h3 [:scheme: https]
* h2h3 [:authority: cloudflare-quic.com]
* h2h3 [user-agent: curl/7.83.0-DEV]
* h2h3 [accept: */*]
* Using HTTP/3 Stream ID: 0 (easy handle 0x7fffd6627210)
> HEAD / HTTP/3
> Host: cloudflare-quic.com
> user-agent: curl/7.83.0-DEV
> accept: */*
>
< HTTP/3 200
HTTP/3 200
< date: Sat, 26 Mar 2022 09:32:25 GMT
date: Sat, 26 Mar 2022 09:32:25 GMT
< content-type: text/html
content-type: text/html
< content-length: 109425
content-length: 109425
< expect-ct: max-age=604800, report-uri="https://report-uri.cloudflare.com/cdn-cgi/beacon/expect-ct"
expect-ct: max-age=604800, report-uri="https://report-uri.cloudflare.com/cdn-cgi/beacon/expect-ct"
< server: cloudflare
server: cloudflare
< cf-ray: 6f1ee103ee899150-FRA
cf-ray: 6f1ee103ee899150-FRA
< alt-svc: h3=":443"; ma=86400, h3-29=":443"; ma=86400
alt-svc: h3=":443"; ma=86400, h3-29=":443"; ma=86400
* Connection #0 to host cloudflare-quic.com left intact
./curll -4Iv --max-time 5 --http3 https://cloudflare-quic.com
*   Trying 104.22.9.38:443...
*  CAfile: /etc/ssl/certs/ca-certificates.crt
*  CApath: none
* Connect socket 5 over QUIC to 104.22.9.38:443
* Sent QUIC client Initial, ALPN: h3,h3-29,h3-28,h3-27
* After 2499ms connect time, move on!
* connect to 104.22.9.38 port 443 failed: No error
*   Trying 104.22.8.38:443...
*  CAfile: /etc/ssl/certs/ca-certificates.crt
*  CApath: none
* Connect socket 6 over QUIC to 104.22.8.38:443
* Sent QUIC client Initial, ALPN: h3,h3-29,h3-28,h3-27
* After 1249ms connect time, move on!
* connect to 104.22.8.38 port 443 failed: No error
*   Trying 172.67.9.235:443...
*  CAfile: /etc/ssl/certs/ca-certificates.crt
*  CApath: none
* Connect socket 5 over QUIC to 172.67.9.235:443
* Sent QUIC client Initial, ALPN: h3,h3-29,h3-28,h3-27
* After 624ms connect time, move on!
* connect to 172.67.9.235 port 443 failed: No error
* Failed to connect to cloudflare-quic.com port 443 after 4374 ms: Couldn't connect to server
* Closing connection 0
curl: (28) Failed to connect to cloudflare-quic.com port 443 after 4374 ms: Couldn't connect to server

вывод nfqws --debug

packet: id=1 len=1228
IP4: 192.168.4.2 => 172.67.9.235 proto=udp sport=51710 dport=443
UDP: C6 00 00 00 01 10 71 F8 72 8E CC 61 C9 FD BB AB FA 94 E7 C1 A6 F1 14 90 55 4D 8B D1 44 3D E1 C9 ... : ......q.r..a............UM..D=.. ...
packet contains QUIC initial
hostname: cloudflare-quic.com
dpi desync src=192.168.4.2:51710 dst=172.67.9.235:443
sending fake request : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ... : ................................ ...
reinjecting original packet. len=1228 len_payload=1200
packet: id=1 drop
2022-03-26T09:35:17.479Z
zinoid

А можно еще собрать curl с openssl-quic от мелкомягких + nghttp3 + ngtcp2. Это будет альтернативная реализация, она используется в хромиуме. Только, это непросто :slight_smile:

2022-03-26T10:54:05.576Z
bolvan

Есть еще одна мысль. Недавно такая проблема вскрылась.
Если в linux настроен сложный policy routing. Несколько аплинков, таблиц маршрутизации, ip rule , основанные на source address, то пакеты, высланные через raw socket-ы могут уходить не с того интерфейса. Что от nfqws, что от nping. При этом обычные пакеты уходят нормально.
Если это ваш случай, то надо убедиться, что пакеты идут действительно в нужный интерфейс и правильно заменяется source адрес , если используется NAT.
Пока что самое эффективное лечение этой ситуации - вносить ip rule, базированные на fwmark, который выставляет nfqws

2022-03-26T13:52:30.343Z
Elevator

Skynet, СПб
Блочится http3 до инстаграмма и фейсбука, но до гугла пропускает. Похоже стали расшифровывать заголовки.
Причем по http2 пропускает тоже. К слову у skynet нет dpi, блок идет на транзитном провайдере, скорее всего МТС

http3 до инсты

./curl -4Iv -m 5 --http3 https://instagram.com
*   Trying 31.13.72.174:443...
*  CAfile: /etc/ssl/certs/ca-certificates.crt
*  CApath: none
* Connect socket 5 over QUIC to 31.13.72.174:443
* Sent QUIC client Initial, ALPN: h3,h3-29,h3-28,h3-27
* After 2493ms connect time, move on!
* connect to 31.13.72.174 port 443 failed: No error
* Failed to connect to instagram.com port 443 after 2507 ms: Couldn't connect to server
* Closing connection 0
curl: (28) Failed to connect to instagram.com port 443 after 2507 ms: Couldn't connect to server

http3 до инсты через vpn

./curl -4Iv -m 5 --http3 https://instagram.com
*   Trying 31.13.72.174:443...
*  CAfile: /etc/ssl/certs/ca-certificates.crt
*  CApath: none
* Connect socket 5 over QUIC to 31.13.72.174:443
* Sent QUIC client Initial, ALPN: h3,h3-29,h3-28,h3-27
*  subjectAltName: host "instagram.com" matched cert's "instagram.com"
* Verified certificate just fine
* Connected to instagram.com () port 443 (#0)
* h2h3 [:method: HEAD]
* h2h3 [:path: /]
* h2h3 [:scheme: https]
* h2h3 [:authority: instagram.com]
* h2h3 [user-agent: curl/7.83.0-DEV]
* h2h3 [accept: */*]
* Using HTTP/3 Stream ID: 0 (easy handle 0x560fda7c27d0)
> HEAD / HTTP/3
> Host: instagram.com
> user-agent: curl/7.83.0-DEV
> accept: */*
>
< HTTP/3 405
HTTP/3 405

http2 до инсты

./curl -4Iv -m 5 --http2 https://instagram.com
*   Trying 31.13.72.174:443...
* Connected to instagram.com (31.13.72.174) port 443 (#0)
* ALPN: offers http/1.1
*  CAfile: /etc/ssl/certs/ca-certificates.crt
*  CApath: none
* TLSv1.2 (OUT), TLS handshake, Client hello (1):
* TLSv1.2 (IN), TLS handshake, Server hello (2):
* TLSv1.3 (OUT), TLS change cipher, Change cipher spec (1):
* TLSv1.3 (IN), TLS handshake, Encrypted Extensions (8):
* TLSv1.3 (IN), TLS handshake, Certificate (11):
* TLSv1.3 (IN), TLS handshake, CERT verify (15):
* TLSv1.3 (IN), TLS handshake, Finished (20):
* TLSv1.3 (OUT), TLS handshake, Finished (20):
* SSL connection using TLSv1.3 / TLS_AES_128_GCM_SHA256
* ALPN: server accepted http/1.1

http3 до гугла

./curl -4Iv -m 5 --http3 https://google.com
*   Trying 64.233.162.100:443...
*  CAfile: /etc/ssl/certs/ca-certificates.crt
*  CApath: none
* Connect socket 5 over QUIC to 64.233.162.100:443
* Sent QUIC client Initial, ALPN: h3,h3-29,h3-28,h3-27
*  subjectAltName: host "google.com" matched cert's "google.com"
* Verified certificate just fine
* Connected to google.com () port 443 (#0)
* h2h3 [:method: HEAD]
* h2h3 [:path: /]
* h2h3 [:scheme: https]
* h2h3 [:authority: google.com]
* h2h3 [user-agent: curl/7.83.0-DEV]
* h2h3 [accept: */*]
* Using HTTP/3 Stream ID: 0 (easy handle 0x55ae3ae897d0)
> HEAD / HTTP/3
> Host: google.com
> user-agent: curl/7.83.0-DEV
> accept: */*
>
< HTTP/3 301
HTTP/3 301
2022-04-15T11:29:43.931Z
bolvan

Они писали на форуме, что на разных тарифах разные фильтры стоят. На lite “более сильный DPI”
А может быть от адреса подключения зависит
У меня тариф “Земля”. Все нормально и по v4, и по v6

2022-04-15T12:16:09.227Z
ValdikSS

Разработчики СКАТ DPI (VAS Experts) выпустили статью о работе с QUIC в своём блоге.

2022-04-18T14:09:28.354Z
0ka(0ka)

На мобильном мегафоне возможно тоже такое есть: пришлось сменить симку в модеме на сим с другим тарифом, и прошлые настройки zapret перестали работать

2022-04-19T09:38:29.882Z
tango

Kathrin Elmenhorst, an author of “Web Censorship Measurements of HTTP/3 over QUIC”, has a repository with further tests of QUIC blocking, derived from OONI measurements. One thread of investigation is about Russia, and it has some interesting observations.

In particular, on Yota (AS 31213), there appears to be a two-layer filter. One layer blocks all QUIC version 1, except to specific servers; and a second layer blocks QUIC version 1 with with specific SNI values, no matter the server. This is interesting because the second layer means they are decrypting the initial packet protection on the packet containing the Client Hello.

The evidence for this comes from observing what happens when accessing different servers using different SNI values.

condition result
Access foreign server with correct SNI blocked
Access foreign server with vk.com SNI blocked
Access vk.com server with vk.com SNI works
Access vk.com server with www.facebook.com SNI blocked
2022-05-02T16:52:04.005Z
anonymous28(anonymous28)

Всё ещё наблюдается?
Сколько пакетов пропускает до блокировки (на картинке сквозная нумерация, число неочевидно)? Сохранились дампы?

2022-05-20T08:26:32.210Z
bolvan

Наблюдается. Там хаотичное поведение. 1-2 сессии могут пройти, 3 - застрять
сколько пакетов я не считал
2 провайдера с ТСПУ дают одинаковое поведение

2022-05-20T09:10:48.990Z
anonymous28(anonymous28)

Система может расшифровать QUIC_V1 и декодировать SNI.

Если ограничиться тестовым набором или соблюдать тестовые размеры, тогда всё работает: SNI декодируется и принимается решение.

Система не может или не хочет достать SNI из пакета, который генерирует Firefox. Возможно дело в размерах (например для структур далее по стеку). Недоступный SNI триггерит блокировку.

2022-05-21T07:11:53.451Z
ValdikSS

Приведите пример пакетов, которые фильтруются и не фильтруются. Выложите pcap’ы или содержимое пакетов.

2022-05-21T09:07:15.428Z
anonymous28(anonymous28)

blocked_firefox.bin (1.3 KB)
works_quictls.bin (1.2 KB)

2022-05-21T09:51:28.815Z
bolvan

Еще раз проверил на своем провайдере с ТСПУ
Ничего не поменялось. Нет никаких признаков в пользу предположения о декодировании SNI
Действительно, blocked_firefox.bin не проходит, а works_quictls.bin проходит
Оба они от example.com. Подозреваю, там стоит фильтр по некоторым полям или длинам без декодирования, который почему-то не срабатывает в одном случае
Пробовал curl с quiche на свой vps с разными SNI, в том числе vk.com. Ничего не проходит
На белосписочные IP от vk проходит все

./curl -4 --connect-to ::vk.com:443 --http3 https://example.com
curl: (55) SSL: no alternative certificate subject name matches target host name 'example.com'

При пробивании нулевым фейком или пакетом works_quictls.bin идентичное поведение. Хаотичный вис при загрузке сайтов

2022-05-21T16:22:34.618Z
anonymous28(anonymous28)

facebook_quictls.bin (1.2 KB)
Этот проходит?

2022-05-21T16:46:49.851Z
ValdikSS

Есть, как минимум, проверка целостности: если изменить хоть один байт в works, то пакет не доходит.
Планирую провести детальные исследования, но если кто-то готов перехватить эстафету, буду только рад.

2022-05-21T17:25:18.326Z
bolvan

Нет

Значит, все же расшифровывают. В QUIC initial нет никаких контрольных сумм, там используется GCM для аутентификации. Это AEAD шифр. Authenticated Encryption with Associated Data.
Шифрование и аутентификация завязаны в том числе и на нешифрованный хедер, чтобы любое изменение порождало неверный atag. И только полная дешифровка с проверкой atag позволяет отсечь коррупцию в любом байте пакета.
Однако, в остальных предложенных вариантах с этим тоже все в порядке.
Значит они или ориентируются на расшифрованный блок (почему не секут тогда SNI ?), или расшифровывают исключительно для проверки целки, а блочат по другим признакам типа длины
Или может быть в некоторых случаях они могут просечь SNI и блочат по нему, а в других случаях не могут (несовершенство парсера дешифрованного блока ?) и блочат, если IP не в white list
nfqws может распарсить все предложенные бинарики

2022-05-21T18:52:23.280Z
anonymous28(anonymous28)

Воспроизводится для гугла при запросе из curl+quictls, не воспроизводится для запросов из Firefox. (Внешнее различие в размерах пакетов, у Firefox они больше, а гугл-сервер в выборе размера пакетов ориентируется, в том числе, на размер QUIC initial клиента.)

До принятия решения о блокировке проходит в среднем 15 входящих пакетов. (Возможно применяется скользящее окно, поэтому не следует ориентироваться на число пакетов с начала сеанса). Выглядит как статистический анализ? Ложно триггерит правило блокировки psiphon или иного протокола (не связанного с QUIC)?

Не понятно столь широкое применение правила, возможно есть ограничение на адреса/порты/паттерны_inside.

This.

Возможно SNI успешно извлекается везде, а за блокировку по неизвестным паттернам из расшифрованного QUIC initial отвечает другое правило.

Можно сравнить пакеты от Firefox, quictls и quiche.
В коллекцию следует добавить legal_sni_quiche.bin

2022-05-22T05:37:43.566Z
bolvan

Возможно используется отложенный процессинг. Расшифровка - задача потенциально тяжелая
Видим initial, временно разрешаем, отдаем в отдельный поток, когда поток возвращает результат - принимаем решение.
Отдельный поток может ориентироваться на текущую загрузку DPI и отказываться от тяжелых операций при необходимости

2022-05-22T05:53:30.970Z
anonymous28(anonymous28)

Заполнение нулями (наружное) QUIC initial триггерит блокировку. В Firefox такое применяется. В quictls внутренний с финальными 1200 байтами. В quiche – у меня нет данных (не собирается ржавчина).

2022-05-22T08:20:30.155Z
anonymous28(anonymous28)

Хаотичные зависания могут быть вызваны большими (1400+) QUIC пакетами в середине сеанса, которые триггерят блокировку. В моем случае это был механизм pmtud на QUIC клиенте, после отключения зависаний нет. К проблемам с mtu это не имеет отношения, блокировка по тестируемым парам адреса:порты наблюдается на хопе с ТСПУ.

У Firefox нет механизма pmtud, но он может быть на сервере.

UPD:
Большой размер пакета похоже так не важен, дело в другом.

Есть скрипт, который возможно воспроизводит блокировку.

Активация блокировки:
Запрос, ответ, запрос.
Нет ответа – нет блокировки.
Размер запросов и ответа учитывается, но точно неизвестно.

2022-05-22T18:07:56.741Z
anonymous29(anonymous29)

UPD: Код бредовый. Удалил. Вызывает блокировку потому что нарушает RFC.

2022-05-24T08:24:11.746Z
anonymous30(anonymous30)

Если удалить заполняющие нули из пакета от Firefox – блокировки нет, и есть реакция на SNI.
Это новое поведение или так было?

2022-05-25T18:17:55.235Z
ValdikSS 2022-05-26T06:53:51.772Z
anonymous30(anonymous30)

Под это правило могли попадать разные сценарии:

  1. Пробует расшифровать только если размер больше X, неудача=блокировка.
  2. Пробует расшифровать всегда, неудача=блокировка если размер больше X.
2022-05-26T07:19:45.696Z
serfreeman1337

Действительно, зависаний сессии больше нет.
Сессия не зависает, если первым отправлять пакет с длиной 601 байт и “1” во 2-ом бите.

quicfix.bin (601 Bytes)

2022-05-29T19:31:01.346Z
bolvan

У меня работает такой обход

первым фейком, состоящим из нулей, пробиваем начальную проверку
далее при первом встреченном пакете с длиной >=600 и short header шлем произвольный фейк пакет тоже с short header , но другим connection id. далее можно ничего не слать, сессия похоже окончательно уходит в разрешенные

для такой хитрости сделал custom скрипт для zapret custom-nfqws-quic4all-tspu

Вариант без скриптов :

/opt/zapret/nfq/nfqws --qnum 210 --dpi-desync=fake --debug
/opt/zapret/nfq/nfqws --qnum 211 --dpi-desync=fake --dpi-desync-any-protocol --debug --dpi-desync-fake-unknown-udp=/opt/zapret/files/fake/quic_short_header.bin --dpi-desync-cutoff=d2
iptables -t mangle -I POSTROUTING -p udp --dport 443 -m connbytes --connbytes-dir=original --connbytes-mode=packets --connbytes 1:1 -m mark ! --mark 0x40000000/0x40000000 -j NFQUEUE --queue-num 210 --queue-bypass
iptables -t mangle -I POSTROUTING -p udp --dport 443 -m length --length 600:1500 -m u32 --u32 "0>>22&0x3C@8>>24&0xC0=0x40" -m mark ! --mark 0x40000000/0x40000000 -j NFQUEUE --queue-num 211 --queue-bypass

Спасибо anonymous32 за идею

2022-05-29T20:19:45.239Z
anonymous32(anonymous32)

На == 600 ТСПУ не переключает фазу проверки и ждет дальше.

2022-05-30T05:50:51.601Z
bolvan

Сперва у меня не получилось пробить висы лишь первым фейком.
Но я ошибся, использовал не тот параметр nfqws.
Все нормально. Достаточно вместо нулей послать первым фейком достаточно длинный пакет с short header. Нет нужды в дополнительных сложностях

Как-то так

nfqws --qnum=210 --user=daemon --dpi-desync-fwmark=0x40000000 --dpi-desync=fake --dpi-desync-fake-quic=/opt/zapret/files/fake/quic_short_header.bin
iptables -t mangle -I POSTROUTING -p udp --dport 443 -m connbytes --connbytes-dir=original --connbytes-mode=packets --connbytes 1:3 -m mark ! --mark 0x40000000/0x40000000 -j NFQUEUE --queue-num 210 --queue-bypass

В последней версии nfqws сделал по умолчанию quic fake , состоящий из 620 байт со всеми нулями, кроме первого байта - 0x40. Так что файл с содержимым пакета не нужен

2022-05-30T06:37:28.084Z
tango

Kathrin Elmenshort has done some tests and on Yota, at least, there seems to be a 2-layer filter.

https://github.com/net4people/bbs/issues/108#issuecomment-1115131376

One layer blocks all QUIC version 1, except to specific servers; and a second layer blocks QUIC version 1 with with specific SNI values, no matter the server.

The evidence for this comes from observing what happens when accessing different servers using different SNI values.

condition result
Access foreign server with correct SNI blocked
Access foreign server with vk.com SNI blocked
Access vk.com server with vk.com SNI works
Access vk.com server with www.facebook.com SNI blocked
2022-06-07T19:02:34.267Z
DarkEmpire

и что как щас жить с этим, есть ли универсальное решение?
а то в браузерах то я отключил QUIC и стало норм, но не везде выходит его отключить, например в приложении спотифая никак, либо на телефоне в приложениях гугла

юзаю антизапрет на роутере через openvpn

2022-06-07T23:01:29.741Z
Supp

как это на nft в openwrt будет выглядеть?

2022-06-08T17:44:57.346Z
bolvan

см тему whats new в разделе zapret. если руками то есть docs/nftables.txt

2022-06-08T18:17:49.435Z
bolvan

Сегодня на домру Ростов обнаружилась такая ситуевина.

google.com, youtube.com - quic нормально работает с curl и PC броузеров firefox, chromium (версия для Linux)
facebook.com - после пробоя блокировки TLS все то же самое, кроме chromium. С ним первый же quic initial блокируется. При попытке пробоя nfqws через fake ответ от сервера приходит, идет новый пакет от клиента, и дальше вис.

сам не проверял, но владелец подключения утверждает, что у него проблемы с quic с android/mac с броузера chrome на google.com. И для лечения он использовал nfqws, но неправильно, из-за чего он работал исключительно на блокировку QUIC. Без QUIC броузер довольно быстро выправлялся. А с ним, выходит, что застревал где-то посередине соединения. И на это жалуется не только он.

ТСПУ там тоже наблюдается. Одна из моих тор нод заблокирована. Но блокировка QUIC отличается от обычной для, скажем, tiera spb или мегафон спб.

Пробить facebook с PC хрома удалось через --dpi-desync=fake --dpi-desync-repeats=5.
То ли лимит на количество анализируемых пакетов у DPI, то ли размер буфера ограничен, но если за первые 5 пакетов бросать туда не QUIC, он отстает

2022-06-21T11:11:39.406Z
ValdikSS

Похоже, блокировка QUIC связана с попыткой блокировки программы Psiphon — она использует QUIC с разными версиями протокола и разными фингерпринтами, как один из методов обхода фильтрации.

Только вот Psiphon продолжает успешно подключаться через QUIC, хоть и не моментально, а браузеры — нет :smiley:

2022-07-14T10:18:39.443Z
bolvan

На моем провайдере tiera появился дополнительный DPI от gblnet
Обычный блокировщик и ТСПУ находятся на 5-м хопе.
gblnet-овский на 11м.

- checking nfqws --dpi-desync=fake,split --dpi-desync-ttl=3
[attempt 1] suspicious redirection 307 to : https://tiera.ru/blocked.php
[attempt 2] suspicious redirection 307 to : https://tiera.ru/blocked.php
[attempt 3] suspicious redirection 307 to : https://tiera.ru/blocked.php
UNAVAILABLE
- checking nfqws --dpi-desync=fake,split --dpi-desync-ttl=4
[attempt 1] suspicious redirection 307 to : https://tiera.ru/blocked.php
[attempt 2] suspicious redirection 307 to : https://tiera.ru/blocked.php
[attempt 3] suspicious redirection 307 to : https://tiera.ru/blocked.php
UNAVAILABLE
- checking nfqws --dpi-desync=fake,split --dpi-desync-ttl=5
[attempt 1] suspicious redirection 302 to : https://gblnet.net/blocked.php
[attempt 2] suspicious redirection 302 to : https://gblnet.net/blocked.php
[attempt 3] suspicious redirection 302 to : https://gblnet.net/blocked.php
UNAVAILABLE
- checking nfqws --dpi-desync=fake,split --dpi-desync-ttl=6
[attempt 1] suspicious redirection 302 to : https://gblnet.net/blocked.php
[attempt 2] suspicious redirection 302 to : https://gblnet.net/blocked.php
[attempt 3] suspicious redirection 302 to : https://gblnet.net/blocked.php
UNAVAILABLE
..........
- checking nfqws --dpi-desync=fake,split --dpi-desync-ttl=11
[attempt 1] AVAILABLE
[attempt 2] AVAILABLE
[attempt 3] AVAILABLE
!!!!! AVAILABLE !!!!!

Что примечательно касаемо QUIC.
Похоже, что gblnet полностью блокирует QUIC initial пакеты на udp port 443 в stateless режиме вне зависимости от IP назначения.

Если я отсылаю сначала фейк с short header, потом initial, установив пакету ttl=8, например, то приходит TTL expired in transit. Начиная с 11 хопа не приходит ничего. То есть 5-й хоп пробивается с обычным DPI, но глобал блочит все.

Проверял на свою VPSку. initial не доходят вообще. если мешать с одним src_port, то short доходят все, initial не доходят

2022-07-26T16:39:50.919Z
anonymous56(anonymous56)

Как-то далеко. Есть признаки что это сеть провайдера, а не магистраль?
Может уровень супербосса блокировок достигли.

UPD:
По ссылке на сайте c блокировкой от gblnet картинка и телефон ООО “ЕТЕЛЕКОМ”, который входит вместе с ООО “ГЛОБАЛНЕТ” в холдинг ООО “ЕТ-ГРУПП”. При этом гендир у холдинга и ООО “ТИЕРА ЦЕНТР” один, но тиера не входит в холдинг.
Спецы вышли из чата, остались 1 гендир и 2 блокировщика.

2022-07-26T17:18:42.767Z
bolvan

11-й хоп 109.239.134.66

route: 109.239.134.0/24
descr: Butlerova7 P2P Customer Network
origin: AS31500
mnt-by: MNT-GLOBAL-NET

и редирект по http идет на сайт магистрала
получается магистралов подтянули к блокировкам

2022-07-26T17:57:46.062Z
bolvan

Еще немного подробностей
Что считается QUIC initial.

  1. udp_length >=1200
  2. Старший бит первого байта установлен (long header)
  3. Байты 1…4 uint32 в network byte order - это версия QUIC. Сечется IETF QUIC и некоторые чуть более старые версии драфта

Например, такой пакет : 80 00 00 00 01 00 00 … 00 (1200 байт)
уже не проходит

У firefox в initial используются лишь несколько сотен байт в начале, остальное - паддинг нолями. Если бы уменьшить размер UDP на передающей стороне , то оно бы прошло
chromium имеет склонность фрагментировать и раздувать до большого размера нешифрованный блок за счет паддинга и пинга, что приводит к увеличению длины используемого шифрованного блока

2022-07-27T06:57:12.122Z
anonymous56(anonymous56)

“Классику” тоже дропают?
quic_vk.bin (1.2 KB)

2022-07-27T07:33:14.035Z
bolvan

дропают
похоже, наши власти обьявили QUIC полную негласную войну
анализ QUIC сопряжен с алгоритмической и нагрузочной сложностью. проще рубануть.
любой внутрироссийский сервис будет вынужден отказываться от деплоймента QUIC

на мегафоне спб смотрел. Опять появились подвисания, непонятно по какому алгоритму. Пробивка short header первым пакетом уже не надежна. Где-то норм, но ютубе скатывается на http2 после небольших тормозов. Полной стателесс блокировки нет

внедрение блокиратора на магистрале - предполагаю это вынужденная антисанкционная мера в условиях острой нехватки оборудования. не все провайдеры еще с ТСПУ, а где есть, часто бывает лоад балансинг, где не все пути оборудованы этим ДПИ. Пробный шар как прокатит, тестирование на высокой нагрузке, включение щадящих CPU режимов фильтрации (stateless)

http, кстати, тоже фильтруется stateless. Надо сечь все пакеты внутри keep alive. Обычный режим rdp.ru предполагает фильтрацию stateful

2022-07-27T07:35:30.193Z
anonymous57(anonymous57)

Локалхост в надежных руках.

Меж тем изменения ПО/правил с июня-июля:
Дефрагментирует фреймы.
Неудачную расшифровку (в т.ч. проверку размеров) и SNI-less игнорирует.

2022-07-28T19:03:37.277Z
anonymous109(anonymous109)

По интересному совпадению, rdp научился понимать фрагменты CH сразу после выпуска nDPI с фиксом.

У них в планах, нарушить работу всех ваших игрушек, десинхронизирующих nDPI.

2023-03-08T16:54:02.543Z
bolvan

Насколько я понял, цель фрагментации CH в chrome - вовсе не обман DPI, а принуждение веб серверов к отказу от предположения, что CH пойдет один блоком. Чтобы они вынуждены были учитывать такой сценарий, а не упрощать себе жизнь, тем самым не полностью поддерживая стандарт.
Собрать разбросанные фрагменты не настолько алгоритмически сложно и CPU затратно, сколько расшифровать сам пакет. Удивительно, что этого не было сделано сразу.

2023-03-09T19:14:49.609Z
bolvan

Текущая ситуация по QUIC примерно такая.
Опробовано порядка 12 провайдеров в RU из разных городов.
На большинстве из них QUIC блокируется путем анализа SNI из расшифрованного QUIC initial.
Если SNI плохой, то блокируется stateful все udp “соединение”.
Анализируется только udp port 443.

Поскольку поведение у всех примерно одинаковое, то можно сказать, что блокирует ТСПУ.
Но тут есть важная оговорка. Модуль парсера кривой.

тут есть статический curl для x86_64 и arm с поддержкой nghttp3 (curl) и quiche (curlq)
Если попробовать этими 2 курлами подергать инстаграм, то видно, что curl виснет, а curlq прокатывает.
Так же firefox после пробивки TCP (чтобы он начал переходить на QUIC) спокойно берет http3, а chrome - только http2.
Можно проверить, загнав через ncat на свой VPS : блобы из zapret:files/fake. quic_initial_facebook_com.bin не доходит, а quic_initial_facebook_com_quiche.bin доходит.

То есть вывод, что парсер сечет chrome и nghttp3, но не сечет quiche и firefox.
Без обхода блокировок по TCP броузеры все равно не пойдут на QUIC, так что разницы практической мало.

Разблокируется через nfqws --fake.

Есть и исключение у провайдеров. Tiera, как обычно. Аплинк глобалнет продолжает полностью блокировать QUIC. Больше нет никаких подвисаний сессии. Тупо режут long header в обе стороны.

2023-07-08T10:13:23.505Z
l8l

Есть ли новости какие? Просто он такой быстрый, вон авито по http3 картинки подгружает, translate.google.ru тоже отсвечивает соединениями с QUIC…

2024-11-10T13:03:41.759Z