Быстрая обёртка над blockcheck2 для параллельного поиска стратегий(и ещё кое-что)
Найти и проверить стратегию обхода для своей линии — одной строкой:
sudo -v && blockcheckw scan -d rutracker.org | blockcheckw check -d rutracker.org --take 3scanза минуту перебирает весь корпус (~14 тыс. стратегий) и передаёт кандидатов в пайп.checkпроверяет каждого кандидата настоящей загрузкой страницы три раза подряд и засчитывает только тех, кто довёз её целиком все три раза. На медленной линии это до получаса;--take 3останавливает поиск после трёх рабочих на протокол.- В конце — блок
Рабочие стратегии: готовые строкиnfqws2 …по протоколам. Полный отчёт — в*_check.jsonрядом.
Домен — любой, который у вас режется. sudo -v спрашивает пароль один раз заранее, иначе
его одновременно спросят оба конца пайпа; на роутере под root не нужен. Прокси и jq не
нужны, нужен zapret2 ≥ v1.0.5 (требования). Если вместо
списка check пишет «домен на этой линии не режется» — обход для этого домена не нужен.
| blockcheck2.sh | blockcheckw | |
|---|---|---|
| Скорость | ~90 мин (TLS 1.2) | ~2 мин (1024 воркера) |
| Пропускная способность | ~1 стратегия/сек | ~150 стратегий/сек |
| Язык | Bash + curl | Rust (compiled binary) |
| TLS fingerprint | curl/OpenSSL | rustls |
| Установка | часть zapret2 | отдельный бинарь, install.sh |
Параллельный подбор стратегий — один процесс nfqws2 держит до 1024 стратегий
одновременно как профили (--filter-mark), а не как отдельные процессы. Диспетчеризация —
два статических правила nftables на весь прогон, независимо от числа воркеров.
Дифференциация блокировок — status автоматически определяет тип блокировки для каждого
домена: SNI blocked (DPI, zapret может обойти) vs IP blocked (нужен VPN). 1000+ доменов за 30 секунд.
youtube.com ✓ 812 Kbps
rutracker.org ✗ SNI blocked
discord.com ✗ IP blocked
Две оси, две пробы — check мерит байты (--probe-path, M повторов, доля от
эталона объёма) отдельно от подлинности (--identity-path, один точный замер, круг
судеб admits: Good · Grinding · Mirage · Trap · Dead). working — рабочая
стратегия: подлинность не опровергнута И полная доставка состоялась КАЖДЫЙ раз из M.
Подробности — ниже.
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 |
Судит проход канала (working) и судьбу цели (admits) |
status |
Проверка доступности + дифференциация SNI/IP блокировок |
benchmark |
Подбор оптимального числа воркеров |
--version |
Текущая версия + проверка обновлений на GitHub |
--upgrade |
Обновление до последнего релиза |
У каждой команды свои флаги — таймауты, DNS-режим, число проходов:
blockcheckw <command> --helpQuickstart — таблицы всех флагов по командам, установка, решение проблем.
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. Без флага поведение не меняется.
check стал строже, и это надо прочитать раньше остального раздела. Замер на живом ТСПУ
(ISP Vimpelcom, домен rutracker.org, 37 кандидатов на TLS 1.2, эталон объёма — через
чистый egress, --reference-via) даёт три разных числа «рабочих» на одном и том же
корпусе стратегий, в зависимости только от того, КАК мерить:
| как мерили | «рабочих» |
|---|---|
один выстрел по /robots.txt (1836 б) |
21 |
| один выстрел по настоящей странице (96 КБ) | 10 |
| три замера по настоящей странице, полная доставка каждый раз | 2–3 |
Малое число рабочих стратегий — это не поломка инструмента, а конец самообмана.
Прежние двадцать галочек означали «приехали какие-то байты один раз»; нынешние две-три
означают «страница доставлена целиком три раза из трёх». Распределение по последнему
прогону: 3/3 — 2 стратегии, 2/3 — 2, 1/3 — 7, 0/3 — 10. Последние десять честно
проходят TCP/TLS-рукопожатие и умирают на объёме — это тот самый DPI-потолок, который
прежний README обещал ловить отдельной эвристикой «16KB DPI detection»; теперь он виден
напрямую, по недостающим байтам, а не по угаданному порогу.
3/3 и 2/3 — разные вещи, и check не сливает их в одно бинарное решение за человека:
строка с 2/3 тоже идёт в отчёт (см. ниже), просто с
меньшей частотой полной доставки — доверять ли частичной доставке, решает тот, кто
запускает bcw, а не вердикт.
Флапает сама линия, а не только инструмент. Два ОДИНАКОВЫХ прогона одним выстрелом по
одному и тому же пути дали 19 и 19 «рабочих» — но общих у них было только 11: половина
прежней выдачи была не сигналом, а прогонным шумом одной и той же линии. --passes
(умолчание 3) этот шум сокращает, но не убирает — троекратный замер даёт ЧАСТОТУ полной
доставки (passes_ok/passes_total), а не определённость на все времена. Поднять
--passes можно: это покупает более честную частоту ценой времени прогона, не саму
определённость.
Отсюда и разделение на две пробы: одна маленькая проба, снятая один раз, — шум. Объём
завышает результат вдвое, а разброс без повтора неотличим от сигнала. check поэтому
ставит две ПРОБЫ, а не один запрос:
| ось | проба | сколько раз | что доказывает | поля отчёта |
|---|---|---|---|---|
| байтовая (главная) | --probe-path (умолчание /) |
M (--passes) |
сколько долей эталона объёма вытянула стратегия | passes_ok/passes_total, median_share |
| подлинности (побочная) | --identity-path (умолчание /robots.txt) |
1 | тот ли ресурс вернулся | observed, admits |
Доля — вытянуто_байт / эталон_байт, где знаменатель — медиана выборок эталона
объёма, снятых по --probe-path. Порога нет: планку задаёт сам эталон. В отчёт идёт
медиана доли по M повторам (median_share) и частота полной доставки —
сколько раз из M проба уложилась в собственный разброс эталона (passes_ok/
passes_total).
working — рабочая стратегия, а не проекция круга судеб:
working = подлинность не опровергнута (круг != [Mirage])
И полная доставка состоялась КАЖДЫЙ раз из M
working: false ставится при положительном свидетельстве против: ось подлинности
разошлась с эталоном (admits: ["Mirage"]), либо хоть один из M заходов байтовой оси
не доставил страницу целиком. «Целиком» с --reference-via — объём уложился в разброс
эталона; без него — сервер сам закончил тело. Потолок DPI выглядит как брошенное ожидание
или обрыв посреди ответа, и такой заход не засчитывается ни в одном из режимов.
Эталон для working не обязателен: без --reference-via круг судеб честно остаётся
широким (заглушку провайдера не отличить от ресурса), но рабочая стратегия находится.
Почему разделены пробы, а не только поля: объём и подлинность требуют разного пути.
Байтовая ось требует ОБЪЁМА настоящего ресурса (значит /, а не статичный файл) — на
youtube.com/ объём гуляет 881678 / 890062 / 888064 байт между узлами CDN, и сверка с
эталоном по этому пути дала бы ложный Mirage. Ось подлинности требует
ДЕТЕРМИНИРОВАННОСТИ (значит /robots.txt, статичный файл) — на нём разброс эталона
вырождается в ноль, и сверка точна.
Почему «байты приехали, значит работает» — ошибка: «подлинность не доказана, значит не работает» — та же самая подмена предмета, только в другую сторону. Для инструмента ПОИСКА вторая хуже: ложная похвала стоит человеку одной проверки, ложные похороны — рабочей стратегии, которую он уже никогда не увидит.
Побочная ось, ось ПОДЛИННОСТИ. check сужает круг судеб цели по пробе
--identity-path (умолчание /robots.txt, один точный замер):
| судьба | что это | помогает ли эта стратегия |
|---|---|---|
Good |
ресурс тот самый, байты полные, лишнего не заплачено | да |
Grinding |
ресурс тот самый, но добыт повторами или с просадкой | частично |
Mirage |
байты текут, ресурса нет: заглушка, парковка | нет |
Trap |
рукопожатие есть, байтов нет | нет |
Dead |
сервер не ответил вовсе | нет |
Только эта проба может дать Mirage — байтовая ось (--probe-path) его не проверяет,
она мерит объём (см. выше).
Рядом — поле observed: что установило наблюдение. Значение Unobserved означает
«мы не досмотрели», и это не приговор цели: working: false при
observed: "Unobserved" говорит о нас, а не о домене.
Good объявляется только при --reference-via. Без чистого egress для эталона
подлинности «байты текут» и «ресурс тот самый» неразличимы, и check честно оставляет
круг из трёх судеб вместо того, чтобы утверждать больше наблюдённого. На working это
не влияет, пока байтовая ось отработала все M раз — см. выше.
Контроль. Каждый прогон check делает обе пробы без десинка и судит их ТОЙ ЖЕ
мерой, что и стратегии. Если контроль сам прошёл (полная доставка M/M и подлинность
не опровергнута), в отчёте стоит inconclusive: true: домен на этой линии не режется, и
о стратегиях прогон не говорит ничего. Хвалить десинк за доступность, которая была и без
него, check не станет.
В отчёт идёт всякая НАБЛЮДЁННАЯ ИЛИ ПРОШЕДШАЯ стратегия, а не только прошедшая. Ось
подлинности решает, что показать в admits, но не решает, показывать ли строку вообще —
это решает working: рабочая стратегия не имеет права отсутствовать в выдаче, даже если
проба подлинности флапнула и её круг судеб остался полным (observed: "Unobserved").
Порядок задаёт rank::fate_order: частота полной доставки ↓ → медиана доли ↓ → ступень
круга (Good → Grinding → не сузили → Mirage → Trap → Dead) → простота
тай-брейкером. Строки, которые не наблюдены И не работают — двойной отказ без
информативной ценности, — в список не попадают: это не последнее место, а отсутствие
места. --take N останавливает ПОИСК после N ПРОШЕДШИХ стратегий на протокол — выдачу он
не урезает, и если не прошёл никто, список всё равно выдаётся ранжированным, а не пустым.
Каждая строка отчёта несёт observed/admits (ось подлинности) и working рядом с
байтовой осью: success_rate (частота полной доставки passes_ok/passes_total),
median_latency_ms, median_speed_kbps, median_share (медиана доли вытянуто/эталон,
null без --reference-via). Поле working ОТЧЁТА — счётчик ПРОШЕДШИХ строк, а не
длина списка. median_speed_kbps — сырая справка: знаменатель включает connect и
рукопожатие, вердикта эта величина не несёт.
Два пути, две пробы. --probe-path (умолчание /) — байтовая ось, повторяется M
раз. --identity-path (умолчание /robots.txt) — ось подлинности, один точный замер.
Подробности и обоснование путей — выше.
--passes (умолчание 3) — сколько раз мерить байтовую ось (M). Не голосование:
частота полной доставки требует ВСЕХ M измерений, ранний выход на первом провале не
применяется. Умолчание несёт замер: два одинаковых прогона на живой линии разошлись 16
из 27 стратегий, устойчивое ядро по трём прогонам — 9. --passes 0 — честный исход «не
наблюдали», не паника.
blockcheckw умеет работать не только в руках человека, но и внутри продукта — на боевой
коробке, под живым трафиком, пока цель держат в карантине. Для этого есть --embedded, и с
ним подбор перестаёт вести себя как гость: он не трогает чужое ядро, отличим в нём, умирает
вместе с тем, кто его позвал, и отчитывается так, чтобы по отчёту можно было принимать
решения машинно.
blockcheckw --embedded --qnum 900 --nft-table nevod3-tune scan -d rutracker.orgЧто включает --embedded (и чего не включает --no-conflict-cleanup, оставшийся узким
ключом только про уборку чужих таблиц):
| поведение | зачем |
|---|---|
| чужие nft-таблицы и процессы не трогаются | ядром владеет вызывающий |
| пробы без десинка несут собственную марку процесса | иначе они уходят в карантин вместе с трафиком человека и «проходят» |
| вопросы человеку не задаются | человека у терминала нет |
| своя группа процессов | kill(-pgid) снимает подбор со всеми детьми одним вызовом |
| свои остатки снимаются при входе | после SIGKILL прошлый прогон не убрал за собой ничего |
| память прошлых запусков не читается и не пишется | унаследованное умолчание ломает подбор молча |
Задаются ключами, потому что у вызывающего они уже заняты:
| ключ | умолчание | что задаёт |
|---|---|---|
--qnum <N> |
200 |
боевая очередь NFQUEUE |
--nft-table <NAME> |
blockcheckw |
имя нашей таблицы |
--mark-base <MARK> |
0x20000000 |
база марки воркера |
--desync-mark <MARK> |
0x10000000 |
марка десинка |
--smoke-qnum-base <N> |
65526 |
начало диапазона из 10 очередей для преflight'а |
Раскладка марки — публичный контракт. Марка одна на всё ядро, и живём мы в ней не одни. Так она выглядит на машине, где подбор встроен в третий невод (сверено с владельцем 20.09.2026); свободных битов там не осталось вовсе:
| биты | владелец | что там лежит |
|---|---|---|
| 0–15 | blockcheckw | индекс профиля в плане |
| 0–7 | невод 3 | решение о цели — пересекается с профилем намеренно, см. ниже |
| 13–27 | приборы reflex | памятка краевого прибора |
| 28–29 | blockcheckw | марка десинка и база марки воркера |
| 30–31 | reflex | марка впрыска |
Биты 0–15 отдать нельзя: индекс профиля — это ПОТОЛОК ПЛАНА, то есть сколько стратегий держит один процесс движка. Урезание до восьми бит уронило бы его с 65535 до 255, и корпус в 13 943 стратегии поехал бы 55 планами вместо 15 — 55 перезапусков движка на прогон.
Два пересечения, и они разного свойства. Решение невода (0–7) делит биты с профилем
осознанно: разойтись негде, у нас до 65 535 профилей, у него 253 марки. Разводит их не
область, а бит 29 (WORKER_MARK_BASE) — правило meta mark and 0x20000000 != 0 → return
стоит первым на каждой его двери.
Приборная полоса (13–27) — другое дело: индекс профиля растёт снизу, и с 8192-го профиля
наша марка заезжает в биты 13–15, где прибор пишет памятку. Поэтому во встроенном режиме
--profiles-per-instance ограничен 8191: ниже этого числа развязка держится битами, а не
порядком правил в чужом рулсете. Цена нулевая — умолчание 1024 вчетверо ниже, а весь корпус
режется на два плана даже впритык к потолку.
Это стык без зазора: между нашим старшим битом (12) и чужим младшим (13) не остаётся ни
одного свободного. Запаса нет, и взять его негде — свободных битов на этой машине не
осталось вовсе. Поэтому потолок не вписан числом, а выводится из границы полосы
(space::ceiling_below): полоса у соседа настраиваемая, и сдвинься она вниз, потолок
поедет за ней, а не останется прежним молча.
Контракт читается и машинно: nfqws2::space::BCW_REGIONS даёт наши области,
FOREIGN_REGIONS — чужие, MarkRegion::overlaps отвечает на вопрос о пересечении. Сверяйте
им, а не этой таблицей.
Отчёт несёт schema (версия формата) и outcome — читать их надо ПРЕЖДЕ strategies:
outcome |
что случилось | код выхода |
|---|---|---|
not_blocked |
контроль без десинка сам прошёл: домен на этой линии не режется | 0 |
found |
есть рабочие стратегии; stopped_at называет предел, если поиск остановил --take |
0 |
nothing_works |
перебрали ВЕСЬ корпус, рабочих нет; названо число кандидатов | 0 |
censored |
перебрали НЕ весь и не нашли — это незнание, а не отрицательный ответ | 0 |
broken |
беда инструмента: nft · no_cap_net_admin · queue_busy · dns_failed · engine_start · input_unreadable |
3–7 |
Отличать broken от остальных обязательно: «цель чиста» и «прибор не смог» — это разница
между «человеку хорошо» и «человек остался без лечения из-за нашей поломки». Занятая очередь
носит собственный код 7, потому что лечится другой очередью, а не переустановкой.
Отчёт пишется ВСЕГДА, в том числе при отказе, и всегда атомарно (tmp + rename):
читателю не достанется половина файла, а отсутствие файла означает только то, что процесс
ещё идёт.
Поле run несёт ФАКТИЧЕСКИЕ условия прогона — версию, воркеров, режим DNS, очередь, таблицу,
марки, группу процессов, сколько кандидатов перебрано из скольких. Не то, что было задано, а
то, с чем прогон шёл.
Системный резолвер во встроенном режиме запрещён. --dns system отвергается, --dns auto молча становится doh: системное разрешение имени работает внешними программами
(getent, nslookup), а чужому процессу SO_MARK не поставить — запрос ушёл бы
немаркированным, тем же путём, что трафик человека. Если ваш продукт заворачивает
udp dport 53 в свою очередь, подбор оказался бы внутри мира, который меряет.
DoH ходит нашим собственным помеченным сокетом (hyper + rustls, адреса резолверов —
IP-литералы), поэтому под запретом он не оказывается. Внешних программ для разрешения имени
подборщик больше не запускает вовсе — это сторожится тестом.
Пока идёт подбор, цель держат в карантине, и человек сидит под укрытием — поэтому подтверждённая стратегия отдаётся В МОМЕНТ подтверждения, а не в конце прогона:
blockcheckw --embedded --stream --progress check -d rutracker.org --from-file candidates.txt| ключ | куда | что |
|---|---|---|
--stream |
stdout | по строке ndjson на каждую подтверждённую стратегию: {"event":"working","protocol":…,"args":…,…} |
--progress |
stderr | {"event":"progress","phase":…,"done":…,"total":…,"elapsed":…} — чтобы «встал» судилось сроком, а не гаданием |
--deadline <sec> |
— | общий срок прогона check; по истечении отдаётся то, что успело подтвердиться |
Порядок строк в потоке — ВРЕМЯ ПОДТВЕРЖДЕНИЯ, а не ранг: ранжированный по судьбе список остаётся в итоговом отчёте, он нужен человеку при разборе. Потоки разведены намеренно — результат идёт в stdout, ход работы в stderr, и разбирать одно из другого не приходится.
Срок никогда не отдаёт пустой отчёт вместо найденного: исход честно называется
found со stopped_at: deadline, либо censored, если не нашлось ничего.
Строка args в отчёте разбирается потребителем и подставляется в аргументы его собственного
nfqws2. Поэтому её синтаксис версионируется вместе с форматом: изменение — это инкремент
schema, а не «мелкая правка вывода». Без этого правила смена синтаксиса означала бы у
читателя молча поднятый слот с невалидными аргументами: движок ответит ошибкой, а продукт
отчитается, что лечение поехало.
Во встроенном режиме чужие таблицы и процессы не трогаются — но наблюдение от вмешательства
отделено: увиденное сообщается ({"event":"neighbours","tables":[…],"nfqws2_running":…} в
stderr при --progress или --stream). Для продукта это диагноз «подбору мешает мой
собственный слот», объясняющий пустой результат линией не человека, а его же обхода.
bcw.root → bcw.scan → bcw.scan.protocol уже размечены. Соберите с --features otel и
передайте TRACEPARENT в окружении процесса — спаны подбора лягут под ваш спан без правок с
нашей стороны. Без фичи привязка вырождается в no-op (на mips/ppc/riscv не собирается tonic).
Один процесс nfqws2 держит до 1024 стратегий одновременно (--profiles-per-instance,
по умолчанию 1024) — каждая стратегия становится профилем движка, а не отдельным
процессом. Профиль выбирается по метке пакета (--filter-mark), поэтому очередь
NFQUEUE и nft-правила одни на весь прогон, независимо от числа воркеров.
Каждый воркер получает уникальный fwmark (SO_MARK на TCP-сокете), но марка выбирает ПРОФИЛЬ внутри процесса, а не очередь и не процесс:
Worker 1: fwmark=0x20000001 → nfqws2 профиль 1 (--filter-mark=1/0xFFFF)
Worker 2: fwmark=0x20000002 → nfqws2 профиль 2 (--filter-mark=2/0xFFFF)
...
Worker N: fwmark=0x2000_NNNN → nfqws2 профиль N — все на ОДНОЙ очереди, в ОДНОМ процессе
Поток пакетов:
reqwest SYN (mark=0x20000001)
→ postnat: mark & DESYNC == 0, mark & 0x20000000 != 0 → ct mark = mark | DESYNC, queue num Q
→ nfqws2 видит mark, выбирает профиль по --filter-mark, десинхронизирует
→ nfqws2 реинжектит с mark=DESYNC_MARK
→ predefrag: DESYNC_MARK → notrack
SYN/ACK (incoming)
→ prenat: ct mark & 0x20000000 != 0 → meta mark = ct mark & 0x2000FFFF, queue num Q
→ nfqws2 видит восстановленную марку, определяет TTL (autottl) тем же профилем
Планов на прогон столько, сколько нужно, чтобы разложить корпус стратегий по
profiles_per_instance: например, на корпусе из 13 943 стратегий и K=1024 это 15 планов
(а не 13 943 запуска движка) — независимо от того, 8 воркеров используются или 1024.
В отличие от ванильного 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
-
Масштабируемость: диспетчеризация — два статических правила nftables на весь прогон, не карта и не цепочка на воркер; 1024 воркера не добавляют nft-правил по сравнению с 8
-
Нет TIME_WAIT проблемы: fwmark-маршрутизация не привязана к фиксированным портам
-
autottl работает: prenat-правило перехватывает SYN/ACK для определения TTL сервера
-
Памяти мало: один процесс
nfqws2держит до 1024 стратегий как профили. Замер на живом ядре (весь корпус 13 943 стратегии, ноль потерь в очереди на всех уровнях):воркеров пик Σ PSS старая → новая запусков nfqws2 старая → новая 8 8 396 → 5 442 КБ 288 → 1 64 50 190 → 7 723 КБ 2 053 → 3 1024 373 863 → 5 769 КБ (~365 → ~5,6 МБ) 12 917 → 15 На восьми воркерах выигрыш скромный — полуторакратный: обе схемы грузят память заранее, и на низком параллелизме старая ещё дёшева. Весь смысл — на высоком: старая схема растёт линейно с числом воркеров, новая грузит фиксированные 1024 профиля один раз, независимо от того, 8 воркеров или 1024
-
Удалённый скан: флаг
--viaпозволяет сканировать через удалённый шлюз
- TLS fingerprint отличается от curl: rustls генерирует другой ClientHello, чем curl/OpenSSL
- Нужен root: SO_MARK, nftables, NFQUEUE требуют привилегий
- Нужен zapret2 ≥ v1.0.5:
nfqws2из этой версии понимает--filter-mark, без него blockcheckw откажется стартовать (см. Quickstart) - Одна очередь NFQUEUE на прогон: до
--profiles-per-instance(по умолчанию 1024) стратегий в одном процессеnfqws2; корпус больше этого числа режется на несколько последовательных планов — процесс перезапускается между ними
Проект основан на zapret2 — оригинальном инструменте обхода DPI от bol-van. Все стратегии и логика их генерации взяты из blockcheck2.
Если вы считаете проект полезным и желаете поддержать разработку, направляйте пожертвования на криптокошелёк :
If you find this project useful and wish to donate here is a crypto wallet :
BTC bc1qnry3qcl34qhf33469j7aaes4kp9e89v729s2x2