Быстрая обёртка над blockcheck2 для параллельного поиска стратегий(и ещё кое-что)
| blockcheck2.sh | blockcheckw | |
|---|---|---|
| Скорость | ~90 мин (TLS 1.2) | ~2 мин (1024 воркера) |
| Пропускная способность | ~1 стратегия/сек | ~150 стратегий/сек |
| Язык | Bash + curl | Rust (compiled binary) |
| TLS fingerprint | curl/OpenSSL | rustls |
| Установка | часть zapret2 | отдельный бинарь, install.sh |
Параллельный подбор стратегий — vmap dispatch через nftables, O(1) lookup. 1024 воркера работают так же быстро как 8 по nftables overhead.
Дифференциация блокировок — status автоматически определяет тип блокировки для каждого
домена: SNI blocked (DPI, zapret может обойти) vs IP blocked (нужен VPN). 1000+ доменов за 30 секунд.
youtube.com ✓ 812 Kbps
rutracker.org ✗ SNI blocked
discord.com ✗ IP blocked
16KB DPI detection — некоторые DPI пропускают TLS handshake, но обрывают соединение после ~16KB данных. check ловит это автоматически — стратегия, которая грузит страницу но ломает видео, не пройдёт верификацию.
Pipe между командами — universal → check в одну строку. JSON-отчёты совместимы между
командами.
blockcheckw -w 512 universal --domain-list blocked.txt | blockcheckw check -d rutracker.org --take 109 архитектур — x86_64, x86, arm64, arm, mips, mipsel, mips64, ppc, riscv64. Работает на роутерах с 256MB RAM.
| Команда | Что делает |
|---|---|
scan |
Параллельный поиск рабочих стратегий для одного домена |
universal |
Поиск стратегий, работающих на нескольких доменах |
check |
Верификация с data transfer (32KB+, 16KB DPI detection) |
status |
Проверка доступности + дифференциация SNI/IP блокировок |
benchmark |
Подбор оптимального числа воркеров |
--version |
Текущая версия + проверка обновлений на GitHub |
--upgrade |
Обновление до последнего релиза |
Quickstart — установка, использование, решение проблем.
scan и status сообщают тип блокировки в JSON-поле block_type — это сетевой
вердикт, по которому потребитель решает, что делать, не перепроверяя:
block_type |
Что произошло | Помогает ли десинк |
|---|---|---|
not_blocked |
доступно без обхода | — |
throttled |
HEAD проходит, но загрузка режется в ~16-19КБ (DPI-cap) | возможно |
sni_blocked |
TCP/TLS-рукопожатие прошло, данные режутся (DPI по SNI) | да |
ip_blocked |
прямой SYN не прошёл, причина не уточнялась | нет (нет рукопожатия) |
syn_blocked |
SYN дропнут на этой линии, но хост жив через прокси | нет (нужна смена egress) |
host_dead |
недостижим и напрямую, и через прокси | нет |
dns_failed |
резолв не удался | — |
Рядом — отдельное булево поле dns_spoofed (ортогонально block_type): system-DNS
отравлен (расходится с DoH на блокируемом домене). При auto-режиме скан сам
откатывается на чистые DoH-IP, поэтому block_type меряется по ним — домен может быть
dns_spoofed: true И not_blocked одновременно. Сигнал «не доверяй system-DNS, бери DoH».
Когда прямой SYN дропается, нельзя отличить «SYN режут на твоей линии, а хост жив»
от «хост мёртв». --alive-via даёт прокси, через который scan делает точечную
проверку живости IP-blocked хоста (но не маршрутизирует через него сам скан —
для этого --via). Результат: ip_blocked уточняется в syn_blocked (жив через
прокси) либо host_dead (мёртв везде). Формат эндпоинта — как у --via
(socks5://host:1080); должен быть прокси. Если прокси недостижим, разбиение
отключается и остаётся ip_blocked. Без флага поведение не меняется.
Каждый воркер получает уникальный fwmark (SO_MARK на TCP-сокете). nftables использует vmap (hash map) для маршрутизации пакетов в нужный экземпляр nfqws2 за O(1):
Worker 0: fwmark=0x20000001 → nfqws2 qnum=200
Worker 1: fwmark=0x20000002 → nfqws2 qnum=201
...
Worker N: fwmark=0x200000XX → nfqws2 qnum=200+N
Поток пакетов:
reqwest SYN (mark=0x20000001)
→ postnat: mark vmap → jump wp_200
→ wp_200: ct mark set | queue num 200 → nfqws2 десинхронизирует
→ nfqws2 реинжектит с mark=DESYNC_MARK
→ predefrag: DESYNC_MARK → notrack
SYN/ACK (incoming)
→ prenat: ct mark vmap → jump wi_200
→ wi_200: queue num 200 → nfqws2 определяет TTL (autottl)
В отличие от ванильного blockcheck2, blockcheckw не использует curl. HTTP-запросы выполняются in-process через
hyper + tokio-rustls + socket2:
- socket2 — создаёт TCP-сокет, ставит
SO_MARKдоconnect()(SYN уже помечен) - tokio-rustls — TLS handshake с контролем версии (TLS 1.2 only / TLS 1.3 only)
- hyper — HTTP/1.1 запрос поверх TLS-стрима
Это убирает ~600 fork+exec процессов curl за скан, и даёт полный контроль над сокетом.
- Скорость: 100-150x ускорение по сравнению с последовательным blockcheck2
- Масштабируемость: vmap dispatch — O(1) lookup, 512 воркеров работают так же быстро как 8
- Нет TIME_WAIT проблемы: fwmark-маршрутизация не привязана к фиксированным портам
- autottl работает: prenat vmap перехватывает SYN/ACK для определения TTL сервера
- Памяти мало: основной потребитель — nfqws2 процессы (~2-4MB каждый). 64 воркера ≈ 200MB
- Удалённый скан: флаг
--viaпозволяет сканировать через удалённый шлюз
- TLS fingerprint отличается от curl: rustls генерирует другой ClientHello, чем curl/OpenSSL
- Нужен root: SO_MARK, nftables, NFQUEUE требуют привилегий
- nfqws2 — отдельные процессы: каждый воркер спавнит nfqws2 (fork+exec), ~100ms overhead
- RAM линейно растёт с воркерами: на роутере с 256MB RAM максимум ~64 воркера
Проект основан на zapret2 — оригинальном инструменте обхода DPI от bol-van. Все стратегии и логика их генерации взяты из blockcheck2.
Если вы считаете проект полезным и желаете поддержать разработку, направляйте пожертвования на криптокошелёк :
If you find this project useful and wish to donate here is a crypto wallet :
BTC bc1qnry3qcl34qhf33469j7aaes4kp9e89v729s2x2