Skip to content

Repository files navigation

Blockcheck Wrapper

CI GitHub Release License: MIT Downloads

Быстрая обёртка над blockcheck2 для параллельного поиска стратегий(и ещё кое-что)

TL;DR

Найти и проверить стратегию обхода для своей линии — одной строкой:

sudo -v && blockcheckw scan -d rutracker.org | blockcheckw check -d rutracker.org --take 3
  • scan за минуту перебирает весь корпус (~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 10

9 архитектур — 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> --help

Quickstart — таблицы всех флагов по командам, установка, решение проблем.

Классификация блокировки (block_type)

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».

Флаг --alive-via <endpoint> (только scan)

Когда прямой 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, статичный файл) — на нём разброс эталона вырождается в ноль, и сверка точна.

Почему «байты приехали, значит работает» — ошибка: «подлинность не доказана, значит не работает» — та же самая подмена предмета, только в другую сторону. Для инструмента ПОИСКА вторая хуже: ложная похвала стоит человеку одной проверки, ложные похороны — рабочей стратегии, которую он уже никогда не увидит.

Судьба цели (observed и admits)

Побочная ось, ось ПОДЛИННОСТИ. 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 — часть контракта

Строка 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.

Что НЕ делает curl

В отличие от ванильного 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.

Поддержать разработчика. Donations

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

If you find this project useful and wish to donate here is a crypto wallet :

BTC bc1qnry3qcl34qhf33469j7aaes4kp9e89v729s2x2

About

`blockcheck2.sh` wrapper for better scanning speed (and more)

Resources

Contributing

Security policy

Stars

191 stars

Watchers

3 watching

Forks

Releases

Packages

Contributors

Languages