NetZapret
Для тех, кому мало одного Zapret. Десинк чинит то, что тормозит провайдер, VPN берёт то, что закрыто по стране, — а NetZapret решает, что куда, для каждого сайта и сервиса.
Архив для Windows 10 и 11: распаковать и запустить NetZapret.exe, больше
ничего ставить не нужно.
Диспетчер трафика для Windows. Для каждого сервиса, домена или подсети решает, куда пустить трафик: через десинк (Zapret / winws2), через VPN (sing-box) или напрямую — и запускает движки под одним присмотром.
Заменяет собой связку Zapret + VPN-клиент и делает то, чего не делает ни одна из них по отдельности: применяет VPN точечно, не ломая десинк для всего остального.
Подписка VPN не обязательна. Без неё работают десинк, бесплатный WARP и прокси для Telegram Desktop — Telegram с фото и видео без всякого VPN.
О программе
Автор — RixyPow. Идеи и отчёты об ошибках приносят участники обсуждений и issues — туда же с новыми. Новости — в телеграм-канале.
Что едет в архиве, кроме самой программы:
| Компонент | Зачем | Лицензия | Исходники |
|---|---|---|---|
| sing-box extended | туннель: серверы подписки и WARP | GPL v3 | shtorm-7/sing-box-extended |
| Zapret 2 | десинк: winws2 и его библиотека lua | MIT | bol-van/zapret2 |
| zapret2-fork, автор — loop-uh | родная сборка winws2 под Windows, без Cygwin | MIT | zapret2-fork |
| Zapret GUI, автор — loop-uh | сценарии десинка на lua, списки доменов и адресов, пресеты, каталог адресов | MIT | wiki.zapret.moe, zapretgui |
| zapret-discord-youtube, автор — Flowseal | game filter: секции игр, список адресов ipset-all и образцы пакетов к ним |
MIT | Flowseal/zapret-discord-youtube |
| tg-ws-proxy-rs, автор — valnesfjord | прокси для Telegram Desktop без VPN; порт программы tg-ws-proxy (Flowseal) | MIT | valnesfjord/tg-ws-proxy-rs |
| WinDivert | перехват пакетов для winws2 | LGPL v3 / GPL v3 | basil00/WinDivert |
| Wintun | сетевой адаптер туннеля | проприетарная, WireGuard LLC | wintun.net |
| ZXing.Net | чтение QR-кодов с ключами | Apache 2.0 | micjahn/ZXing.Net |
То же самое показывает окно: «Ещё» → «О программе».
Скриншот главного меню
Установка
- Скачать архив со страницы релизов.
- Распаковать в обычную папку, например
C:\Program Files\NetZapret. - Запустить
NetZapret.exe.
Больше ничего ставить не нужно — ни .NET, ни sing-box, ни Zapret: всё внутри. Права администратора программа запросит сама, без них не поднимутся ни туннель, ни драйвер перехвата пакетов.
Не кладите программу в OneDrive, Dropbox, Google Диск или Яндекс Диск. «Рабочий стол» и «Документы» Windows сама переносит в OneDrive, когда включено их резервное копирование, — и человек об этом может не знать. Клиент синхронизации занимает свежие файлы и выгружает редкие: обновление не сможет заменить занятый файл, а журналы, которые движки пишут постоянно, уходят в облако. «Диагностика» скажет, если папка в облаке. Перенесли — перевключите автозапуск: задача планировщика помнит прежний путь.
Подписка и ключи
Для VPN нужна подписка или ключи — любой провайдер. Поддерживаются VLESS, VMess, Trojan, Shadowsocks, Hysteria2, Hysteria (первая версия), TUIC, AnyTLS, WireGuard и AmneziaWG.
Добавляется на вкладке «VPN» кнопкой «Добавить подписку» — отдельным окном, как в Happ:
- «Из буфера» — ссылка подписки, ключи (один или пачкой) или картинка с QR-кодом, например снимок экрана Win+Shift+S;
- «Из файла» — файл
.confWireGuard или AmneziaWG либо картинка с QR-кодом; - или вставить в поля руками. Ctrl+V на вкладке «VPN» открывает это же окно уже с тем, что в буфере.
Название подписки программа берёт у продавца и сразу говорит, сколько в ней серверов. Подписок можно держать несколько; ключи ложатся в папку «Отдельные ключи». Подписки, которые провайдер отдаёт только клиенту Happ, тоже читаются: программа сама повторит запрос под его именем и запомнит, что с этой подпиской так и надо.
Сервер выбирает автоподбор — плитка «Авто» в ленте «Быстрая смена сервера»: движок опрашивает серверы и берёт быстрейший из живых, по два с одного входа, чтобы не бить продавца залпом проверок. Отечественные выходы автоподбор не берёт, нестабильные — серверы, что отвечают через раз, — тоже, если включено «Сначала стабильные». Плитка сервера закрепляет его. Подключённый сервер проверяется раз в 30 секунд одним соединением; что делать, если он замолчал, — в «Настройках туннеля».
Ссылка и ключи равносильны паролю: по ним выдаётся доступ к серверам. Хранятся
рядом с программой в config\subscriptions.json, обратно не показываются
и никуда не отправляются.
Бесплатный WARP
На вкладке «VPN» — карточка Cloudflare WARP с выключателем. Ни почты, ни оплаты, ни ключей: движок в поставке несёт готовый клиент Cloudflare и регистрируется сам.
WARP и подписки — одно из двух. Включённый WARP — единственный выход туннеля, подписки на это время на паузе. Выключили — туннель вернётся к подпискам и к выбранному там серверу. Сам с одного на другое туннель не переходит.
Идёт по MASQUE — поверх HTTP/2 на 443 порту, оператору неотличим от обычного
веба. Поднимется там, где открыт api.cloudflareclient.com: у российских
операторов он закрыт по имени в TLS, и открыть его можно рецептом десинка
(см. «Маршруты»). После запуска ему нужно около полуминуты, прежде чем пойдёт
трафик.
Выпускает трафик в ближайшей стране — на российском подключении это Москва. От блокировок оператора спасает, от отказов по стране нет: адрес остаётся отечественным, и сервисы, закрывающиеся от РФ, откажут так же.
Под нагрузкой он неровен: один канал несёт все соединения разом, и стоит одному потоку упереться — тормозят все. 23.09 через него висели сотни соединений Telegram, не получив ни байта. Замер на живой сети: поодиночке 94–188 мс, пять запросов разом — от 281 до 4648 мс. Для повседневной работы подписка надёжнее; WARP — когда её нет или она лежит.
Первый запуск
Разделы окна:
| Раздел | О чём |
|---|---|
| Главная | Состояние движков, режим работы, запуск и автозапуск, обновление |
| VPN | Подписки, серверы, автоподбор, WARP, замер задержек |
| Десинк | Пресет Zapret, его покрытие, game filter |
| Маршруты | Куда пустить каждый сервис и свой сайт: напрямую, десинк, VPN, пин в hosts или выключить |
| TG Proxy | Прокси для Telegram Desktop: Telegram без VPN, с фото и видео, и в «Десинке» |
| Проверка блокировок | Что закрыто в этой сети и чем лечится |
| Замер скорости | Скачивание, отдача и задержка — через туннель и напрямую, рядом для сравнения |
| DNS и Файл hosts | Каким адресом окажется имя: резолверы, путь DNS, пины |
| Наблюдение | Соединения по мере появления и правило, применённое к каждому |
| Диагностика | Проверки по группам — в том числе нет ли рядом другого VPN-клиента, — ответ «куда пойдёт это соединение», отчёт для разбора и журнал движков отдельным окном |
| Оформление | Тема, фон, шрифт, размер, меню в трее |
| Ещё | Антивирус, выключатели, разбор неисправностей, обслуживание, о программе |
При первом открытии вместо «Главной» встречает мастер из пяти шагов: что делает программа, тема, подписка, режим работы (с выбором DNS и прокси Telegram), запуск и проверка сети. Пропустить можно любой шаг по отдельности, а не весь мастер разом; уйти в другой раздел — тоже закрыть мастер. Повторить — кнопка в разделе Ещё.
Без мастера порядок такой: VPN → «Добавить подписку» → там же «Замерить все» → Главная → «Запустить». Конфиг собирается сам при каждом запуске, отдельно делать ничего не надо.
Если что-то не так, начните с Проверки блокировок: она измеряет, что именно
закрыто и чем это лечится, а не гадает. Отчёт каждого прогона ложится
в reports\.
Прокси для Telegram
Вкладка «TG Proxy» — локальный прокси для Telegram Desktop. Telegram
подключается к нему на 127.0.0.1:1443, а прокси ведёт тот же зашифрованный
трафик через WebSocket по TLS к веб-адресам самого Telegram, а фото и видео —
через домены за Cloudflare. Сторонних серверов и подписки не нужно.
Нужен прежде всего в режиме «Десинк»: VPN там нет, а адреса Telegram закрыты по IP, и без прокси Telegram Desktop не подключится вовсе. Замер 07.10: без пути через Cloudflare фото и видео не грузились ни разу, с ним — грузятся. В «Гибриде» и «Туннеле» Telegram и так идёт через VPN по своим адресам; прокси там не обязателен, но и не мешает.
Как включить:
- Выключатель на вкладке «TG Proxy» (или на шаге «Режим работы NZ» мастера). При первом включении создаётся секрет прокси — дальше он не меняется.
- Перезапустить движки, если они уже работают, — окно предложит само.
- «Подключить Telegram» — ссылка прокси откроется в Telegram, и он спросит, подключиться ли. Не открылась — «Скопировать ссылку», отправить себе в «Избранное» и нажать там. Вручную: «Настройки» → «Продвинутые» → «Тип подключения» → «Прокси» → MTProto, сервер, порт и секрет — с вкладки.
Прокси поднимается и гаснет вместе с движками, в том числе при автозапуске — открывать окно не нужно. Остановили движки — Telegram с этим прокси не подключится: выключите прокси в самом Telegram или запустите движки снова. Падение прокси обход не роняет: десинк и туннель живут как жили.
Ограничения: только Telegram Desktop на этом компьютере — прокси слушает
127.0.0.1, и телефон через него не подключить. Журнал —
runtime\tg-ws-proxy.log, он же уходит в отчёт для разбора (секрет
вычищается); проверки — в «Диагностике», раздел «Прокси Telegram».
Сам прокси — tg-ws-proxy-rs (valnesfjord), порт программы tg-ws-proxy (Flowseal) на Rust, оба под MIT. Порт, а не оригинал: у оригинала под Windows есть только программа с треем и окнами, а этот консольный и встаёт под общий присмотр, как winws2 и sing-box.
Обновление
При запуске программа спрашивает GitHub о новой версии — если в «Ещё» не выключено «Искать обновления при запуске». Нашлась — окно «Доступно обновление»: что пришло во всех версиях между вашей и новой, по разделам программы, со значками из меню; справа — лента всех выпусков, щелчок по версии показывает её чейнджлог. Кнопки — «Обновить», «Позже» и «Пропустить версию». Кнопка «Проверить» в карточке «Обновление» на «Главной» открывает то же окно и тогда, когда новее версии нет.
«Обновить» сперва скачивает архив — обход в это время работает, а если поднят туннель, архив идёт через него. Потом движки останавливаются, программа закрывается, файлы заменяются, и она открывается снова. Соединения обрываются на эти секунды.
- Сохраняются настройки и подписки, свои маршруты, подставленные адреса
(
addresses.yaml), свой каталог адресов (catalog.yaml). Строки, дописанные вами в списки, переносятся в новые списки. - Заменяются программа, движки, пресеты, списки, базовые правила, снимок каталога Zapret и пины напрямую.
Не вышло — журнал замены лежит в runtime\update.log и уходит в отчёт для
разбора, а программа запускается снова.
Зачем это нужно
Десинк и VPN плохо уживаются. Под поднятым туннелем трафик выходит переоткрытым
сокетом sing-box, а WinDivert рассчитывает увидеть исходный поток приложения —
и рецепты Zapret с поддельными пакетами перестают работать. Замер это подтвердил:
голый multidisorder (YouTube) и send + syndata (Discord) туннель переживают,
а fake (Google, Claude) — нет.
Очевидное решение — вывести десинк-трафик из туннеля через route_exclude_address —
не годится: в пресете Universal V6 из двадцати секций с fake четырнадцать
сопоставляются по доменам, а поле принимает только адреса. Прикрыло бы пять из двадцати.
Здесь сделано наоборот: fakeip выдаётся только доменам с правилом proxy, и в
туннель заводится лишь то, что этими адресами адресовано. Десинк-трафик туннеля
не касается вовсе. Подробности — docs/coexistence.md.
Обратное тоже учтено: соединения туннеля к серверам подписки выведены из перехвата winws2. Замер 30.09: с ними в перехвате туннель давал 15 Мбит/с вниз при winws2 на 88–98 % ядра, без них — 113–119 при 5–6 %.
Режимы работы
Режим выбирается на «Главной», в меню значка в трее и в мастере. Книга маршрутов говорит, куда пойдёт каждый сервис, а режим — что из этого выйдет:
| Режим | «напрямую» | «десинк» | «через VPN» |
|---|---|---|---|
| Десинк — только десинк | напрямую | десинк | напрямую |
| Гибрид — десинк и VPN по маршрутам | напрямую | десинк | VPN |
| Туннель — весь трафик через VPN | напрямую | VPN | VPN |
| «Туннель» с «Игнорировать исключения» | VPN | VPN | VPN |
Гибрид — основной режим: каждый сервис идёт так, как записано в книге, российские сервисы видят домашний адрес. Без подписки и WARP он работает как «Десинк».
Туннель — как обычный VPN-клиент: адрес зарубежный, открывается всё, что открывается через ваш сервер, а мимо идёт только поставленное «напрямую». Российские сайты тоже увидят зарубежный адрес.
«Игнорировать исключения» — в «Настройках туннеля». Отправляет в туннель всё, включая «напрямую»; десинку чинить нечего, и он не поднимается. Российские сервисы через зарубежный адрес не работают — банки и госуслуги требуют подтверждений, часть отказывает наотрез, — поэтому это режим для сравнения, когда надо убедиться, что дело не в маршрутах.
«Напрямую» для десинка — это щит: первым профилем winws2 стоит список таких
имён с приёмом pass, и пакет с этим именем мимо него не пройдёт ни в одну
секцию пресета. Щит узнаёт только трафик с именем — игровой UDP по голым
адресам ведут секции пресета, как и прежде.
«Десинк» без секции по имени — не «напрямую». Секции пресета по адресам и по классификатору работают с таким трафиком по IP, и «Маршруты» так его и подписывают: «по имени секции нет, по адресам — может сработать». Перевести такую часть на «напрямую» значит выключить и эти секции: у EA и Riot это ломало вход.
«Выключено» — ещё один выбор в «Маршрутах»: часть снимается целиком, вместе с заводским правилом, и её имена решают другие правила. Нужен, когда правила спорят друг с другом.
Локальные сети и loopback остаются прямыми в любом режиме.
Прятать VPN от российских приложений
Выключатель в «Настройках туннеля». Приложения Яндекса, VK, MAX и 2ГИС узнают,
откуда вы выходите в интернет, у нескольких сервисов — ifconfig.me,
api.ipify.org, проверок Яндекса и своих счётчиков. С включённым выключателем
эти двенадцать имён всегда идут напрямую, и приложения видят домашний адрес,
а не зарубежный.
Именно напрямую, а не блокировкой, как делают другие клиенты: среди этих имён
адрес входа в Яндекс, и блокировка могла бы его сломать. Заметно в режиме
«Туннель» — там без выключателя эти имена ушли бы в VPN. При «Игнорировать
исключения» не действует: тот режим отправляет в туннель всё. Выключен
по умолчанию — иначе проверка своего адреса на ifconfig.me в «Туннеле»
показывала бы домашний адрес, и казалось бы, что VPN сломан.
Правила
Два слоя. Базовый config/rules.yaml — выверенный набор, то, что заблокировано
наверняка; ведётся вместе с программой. Пользовательский config/rules.user.yaml —
ваш выбор поверх него, его ведёт окно. Разделение затем и сделано, чтобы обновление
не затирало ваши правки.
mode: selective capture: - config/lists/ipset-telegram.txt # приложения, ходящие по голым адресам rules: - match: ipset value: config/lists/ipset-ru.txt mode: direct # российские — только напрямую - match: domain value: "*.rutracker.org" mode: proxy - match: hostlist value: config/lists/fandom.txt mode: off # снять часть вместе с заводским правилом default: mode: desync # всё остальное чинит десинк
match: process | domain | ip | ipset | hostlist.
mode: direct | proxy | desync | off.
hostlist ссылается на доменный список целиком — так устроен вид по сервисам:
«голос Discord через VPN» это config/lists/discord-media.txt, а не горсть
выписанных строк, которые устареют молча. Списки наши, из config\lists\:
правило, ссылающееся на файл чужой установки, без неё не совпадало бы ни с чем.
Сервисы
Раздел Маршруты показывает то, о чём человек думает — Discord, YouTube, Telegram, — а внутри сервиса его части:
Discord
1. Голос VPN 1 дом. <- ваш выбор
голосовые серверы; ломается отдельно от переписки
2. Текст и вход десинк 43 дом.
3. Картинки и вложения десинк 3 дом.
Каждую часть можно направить отдельно. Ради этого разделение и сделано: у Discord голос ломается иначе, чем переписка, и лечится иначе.
Голос Discord ходит по голым адресам, и их Discord меняет: 01.10 звук переехал с Google Cloud на Cloudflare. Поэтому адреса звука программа дописывает в свой список сама — из журнала самого Discord, пока голос идёт «через VPN»; новые применяются после перезапуска движков. Выключатель — «Дописывать адреса голоса Discord» в «Настройках маршрутов»; там же — «Предлагать перезапуск Discord».
Чем именно чинить имя
«Десинк» в выборе маршрута означает только «мимо туннеля». Что сделать
с рукопожатием, решает пресет — и если имя не попало ни в один его список,
не делается ничего. Хуже: попасть можно в секцию с рецептом pass, которая
имя забирает себе и пропускает нетронутым.
Поэтому при выборе «десинк» для своего домена открывается окно с рецептами. Источников два. Пресет даёт наборы, подобранные под живые блокировки, — одинаковые схлопнуты, и из полусотни секций выходит меньше десятка. Свой каталог даёт приёмы, которые движок умеет, а пресет не применяет; из него предлагаются только те, что текущий пресет потянет.
Первым в списке стоит «Не трогать (pass)» — щит для одного имени: пакеты с ним проходят мимо всего десинка, а имя остаётся на «десинке». С него удобно начинать подбор: он отвечает, открывается ли имя вовсе без десинка.
Окно умеет перебрать их и сказать, с каким имя открывается: поднимает winws2 с одним профилем и пробует. Движки при этом должны быть остановлены — работающий правил бы те же пакеты вторым слоем, а туннель открыл бы имя любым рецептом, включая пустой.
Выбранное уходит в свой профиль winws2 перед пресетовскими: движок отдаёт
пакет первому профилю, чей фильтр совпал, и дальше не смотрит. Пресет при этом
не правится — рецепт хранится в config\rules.user.yaml полем recipe.
Состав сервисов — наши списки из config\lists\; части разделены по разбору
пресетов, где они уже были разделены. Сервис — способ показа и редактирования, а не отдельная
сущность: выбор разворачивается в обычное правило hostlist, а домен,
направленный вручную, узнаётся в своём сервисе.
Приоритет по типу: сперва все process, затем domain, затем адресные, затем
default. Порядок строк внутри одного типа сохраняется. Маска *.example.com
покрывает и сам example.com.
Секция capture нужна приложениям, которые ходят по адресам без обращения к DNS —
Telegram один из них. Перехват решается по адресу назначения, и без этих подсетей
их трафик просто не дойдёт до туннеля, сколько бы правил на них ни стояло.
Куда пойдёт конкретная цель, можно спросить не запуская движков и без прав
администратора — в «Диагностике» («Куда пойдёт соединение») или инструментом
разбора nz (см. «Инструмент разбора»):
nz where rutracker.org
rutracker.org
в правилах: VPN (#0 domain:*.rutracker.org -> proxy)
при выключателях: VPN («Гибрид» — десинк и VPN по маршрутам)
Строки две, потому что правило и то, что с ним сделает режим, — разное:
в «Десинке» «через VPN» идёт напрямую. Ниже nz where пишет ещё, через что
разрешится имя: hosts, перехват резолверов, правило DNS движка.
Программы
Обход по программе — на переработке. Кнопка «Добавить программу» в «Маршрутах» неактивна, а прежние правила по программе сняты один раз при обновлении.
Причина — в устройстве Windows: движок туннеля видит, какой программе принадлежит соединение, только когда оно уже внутри туннеля. В «Гибриде» туннель заводит лишь адреса из правил, и «через VPN» для программы уводило в туннель только то, что и так шло туда по другим правилам, — а серверы игр шли мимо. Обещать такое правило было бы нечестно. Как его переделать, решается.
Наблюдение
Раздел показывает соединения по мере их появления и правило, которое к каждому применилось бы: время, куда пошло, чей процесс, какое назначение, какое правило сработало. Ничего не перенаправляет и ни на что не влияет — только читает события ядра.
Отвечает на вопрос, на который не отвечает ничто другое: почему это пошло не туда. Маршруты показывают, как правила записаны, проверка блокировок — что закрыто снаружи, а здесь видно, какое правило досталось настоящему соединению настоящей программы. Расхождение между первым и третьим и есть та ошибка, которую иначе ищут наугад.
Имя известно не у всех соединений: браузеры ходят со своим резолвером мимо службы DNS-клиента, и наблюдать за их запросами нечем. Счётчик внизу говорит, скольким именам его удалось узнать.
Проверка блокировок
Раздел Проверка блокировок отвечает на вопрос, ради которого программу и открывают: почему не работает и что с этим делать. Она открывает настоящие соединения и смотрит не на то, что не вышло, а как не вышло — каждый способ вмешательства лечится своим.
TCP TLS HTTP ДАННЫЕ вердикт
twitter.com ок RST ок — DPI по TLS
steamcommunity.com ок ок ок нет обрыв после рукопожатия
rutor.info чз ок нет ок — DPI по TLS
tr.rbxcdn.com нет — — — оборванный CNAME
Столбец ДАННЫЕ важнее прочих. Рукопожатие само по себе ничего не доказывает:
steamcommunity.com проходил все остальные проверки и при этом не открывался —
приходило 14381 байт, и поток замирал. Поэтому проверка качает данные и следит
за молчанием, а не за объёмом: у страниц он разный.
Метка «чз» — цель уже идёт через туннель, и её строка описывает туннель, а не сеть. TCP там всегда «ок»: соединение принимает sing-box, ещё не дозвонившись до хоста.
Отчёт открывается тем, чем он снят — режим, пресет, сервер, резолвер. Без этого два прогона не сравнить: проверка снимает не свойства сети, а поведение сети под конкретной настройкой. У каждого имени — ссылка на его маршрут в «Маршрутах».
Пробы идут разом, их можно прервать и увидеть набранное. Отчёт сохраняется
в reports\ — его можно приложить к issue целиком.
Проверять надо при остановленных движках: с включённым обходом видно сеть уже вылеченной. Программа предупреждает и в таком случае не советует спускаться на ступень ниже — доступное сейчас может быть доступно как раз благодаря обходу.
Чего проверка не решает
Часть отказов приходит не от оператора, и маршрутом они не лечатся.
Сайт отказывает по стране. ChatGPT, Spotify и другие сами закрываются от российских адресов. Связь при этом исправна: рукопожатие проходит, страница приходит — с кодом 403 и надписью «недоступно в вашей стране». Десинк влияет на то, как соединение выглядит для DPI, а решение принимает сайт, уже разобрав запрос. Помогает только выход в другой стране — VPN или пин на посредника.
У имени нет адреса. tr.rbxcdn.com, по которому Roblox отдаёт превью, —
CNAME на имя без записи A. Соединяться не с чем. Такое лечится подстановкой
адреса — см. ниже.
Наше приветствие TLS не такое, как у браузера. Проба ходит через SChannel,
и в его ClientHello нет ни GREASE, ни половины расширений, которые шлёт Chrome.
Часть площадок это отвергает: замер на speedtest.net и i.scdn.co показал,
что собранное по образцу Chrome приветствие там принимают, а наше — нет.
Поэтому отвергнутое рукопожатие переспрашивается вторым, собранным байтами по образцу Chrome. Если ему отвечают ServerHello, строка так и называется — «наше приветствие TLS отвергнуто», — и лечить по ней нечего: в браузере сайт откроется. Если же браузерное постигает та же участь, значит дело не в составе приветствия, и вердикт остаётся про вмешательство.
Свои адреса и списки
config\addresses.yaml — адреса для имён, у которых своего нет:
addresses: image.tmdb.org: 138.199.36.8
Отвечает наш резолвер, системный hosts не трогается. Разница существенная:
правки в hosts требуют администратора, переживают удаление программы и видны
всем приложениям, а это снимается вместе с конфигом.
Поставляется файл пустым, и намеренно. Адреса сетей доставки живут днями:
у image.tmdb.org живой узел сменился трижды за четверо суток, а tr.rbxcdn.com
успел вовсе перестать нуждаться в подстановке — Roblox перевёл имя на другую
сеть, и вписанный когда-то адрес стал не помощью, а помехой. Число, попавшее
в релиз, устаревает раньше, чем релиз скачают.
Поэтому адрес берётся на вашей машине и в нужный момент — пином в hosts (см. ниже), где есть «спросить честный резолвер сейчас» и автоподбор. Строки здесь остаются для того, что вы ставите сами.
config\lists\ — все доменные и адресные списки, на которые ссылаются
правила. При сборке они едут к движку как lists\nz-*.txt: приставка не даёт
нашему discord.txt молча подменить одноимённый файл Zapret, на который
ссылается пресет. Строки, дописанные вами в эти списки, обновление переносит
в новые; вычеркнутое — нет.
Пин в hosts
Ещё один способ направить сервис, наравне с «напрямую», десинком и VPN. Нужен там, где мешает не канал, а ответ: сайт закрывается от страны либо резолвер отдаёт заглушку.
В «Маршрутах» это пункт «Закрепить адрес в hosts» в окне выбора пути, рядом с «Напрямую», «Десинк» и «Через VPN». Дальше окно спрашивает, чей адрес поставить:
- Подобрать автоматически — проверяет живым запросом настоящий адрес, свой каталог и посредников и берёт для каждого имени того, кто отвечает сам и не отказывает по стране. Настоящий адрес — первым, если он работает. В сети без IPv6 берётся адрес IPv4.
- Спросить честный резолвер сейчас — настоящий адрес по DoH, взятый в момент
закрепления. Лечит заглушки (
image.tmdb.org), но бесполезен против отказа по стране: честный адрес там самый настоящий, и отказ придёт с него же. - Свой каталог —
config\catalog.yaml, записи, которые ведёте вы. - Каталог Zapret — чужие публичные прокси из снимка
config\catalog.zapret.yaml. Годятся, когда сайт отказывает по стране, но живут ровно столько, сколько живёт узел за ними; снимок едет с программой и обновляется вместе с ней.
Закрепление переводит сервис на «напрямую». Это не довесок, а условие:
оставить пин под правилом proxy — значит записать в системный файл строку,
которая ни на что не влияет.
Пины двух родов, и десинк обязан их различать. Пин на посредника (XBOX DNS и подобные) идёт мимо десинка: подставленный адрес winws2 не трогает. Пин на адрес самого сервиса — наоборот, под десинком: замер 06.10 — Instagram, прибитый к адресам Meta, со щитом не открылся ни разу из 22, под рецептом своей секции — 6 из 6. Такие пины — в разделе «Пины напрямую» в настройках «Маршрутов»: готовые решения из каталога Zapret GUI для Instagram, X, YouTube, Discord и других; их строки в hosts помечены, и десинк их не обходит. Решения, которым нужен IPv6, без IPv6 недоступны. Пины, вписанные в hosts другими программами, по-прежнему идут мимо десинка.
Адреса посредников меняются, и пин на умерший узел просто перестаёт работать. Кнопка «Проверить актуальные адреса» на вкладке «DNS» спрашивает посредников — XBOX DNS, Comss, AstraCat, GeoHide — и заменяет умершие пины. Только кнопкой: сама программа их не проверяет. Если не ответила больше половины имён, это сбой сети, а не смерть адресов, и ничего не меняется.
Как файл правится:
- Свои записи — в блоке
# >>> netzapret begin >>>, и он ставится выше остальных: при двух строках на одно имя читается первая. - Чужие строки — отдельным списком, и удаляются по одной. Файл ведёт не только человек: редактор hosts есть в Zapret GUI, записи ставит антивирус, и часть из них может быть нужна для обхода. Поэтому перед каждым удалением спрашивают, а кнопки «почистить всё» нет. Если на прибиваемое имя есть чужая запись, о ней сообщается сразу: пока она на месте, имя разрешается дважды.
- Перед каждой правкой — копия рядом с файлом, следом
ipconfig /flushdns. Для удаления это единственный способ отката: нажатием его не отменить. - Раздел «Файл hosts» показывает весь файл, прибивает имя к адресу вручную, снимает свои записи, удаляет чужие и открывает файл на правку руками. Там же — поиск дублей: имена, записанные в файле больше одного раза, и какая из строк на деле читается.
Что мешает перехвату
Три вещи обходят маршрутизацию по домену молча, и все три уже встречались.
DNS over HTTPS. Windows 11 сама поднимает запрос до DoH, и он уходит по TCP/443 мимо перехвата: домен резолвится по-настоящему, fakeip не выдаётся, трафик идёт напрямую под блокировку. NetZapret закрывает DoH к системным резолверам внутри туннеля, и Windows возвращается на обычный UDP. Браузер со своим DoH (Firefox, Chrome с «безопасным DNS») этим не закрывается и в «Гибриде» может ходить мимо туннеля.
Файл hosts. Он бьёт любой резолв, включая наш: имя ищется в нём до DNS,
и прибитый там домен fakeip не получит никогда. Совпадение точное, без зон —
строка example.com не покрывает www.example.com, отсюда списки на сотни
строк. После правки нужен ipconfig /flushdns: Windows держит записи в своём
кэше с огромным сроком жизни.
Но маршрут пин не отменяет, и это стоит понимать точно. Пин задаёт адрес; дорогу задаёт правило, а имя TUN узнаёт из рукопожатия, и правило по домену срабатывает поверх прибитого адреса.
Разошлось это на живом случае. Один и тот же прибитый адрес отдавал сертификат
и настоящий ответ на deepl.com, strava.com и jetbrains.com — правил у них
нет, — и молчал на chatgpt.com, у которого правило proxy уводило соединение
в туннель, а туннель в тот час не работал. Адрес был жив и числился мёртвым.
Отсюда правило: пин и правило proxy на одном имени — всегда ошибка
настройки. Проверка блокировок выносит такие случаи отдельным разделом
и говорит, кто из двоих выигрывает.
IPv6. Без адреса IPv6 у TUN auto_route не ставит ни одного маршрута IPv6,
и резолвер провайдера остаётся снаружи, отвечая настоящими адресами в обход fakeip.
Перехват при этом выглядит исправным — обход идёт по второму протоколу.
Путь DNS: напрямую, через туннель или авто
Резолвер движка спрашивает имена по DoH. С августа 2026 российские операторы начали ограничивать DoH и DoT, и отказ апстрима выглядит как «перестало открываться вообще всё». Поэтому путь DNS выбирается — на вкладке «DNS» и в мастере:
- Авто (по умолчанию) — при запуске напрямую; как только туннель пропускает трафик, имена спрашиваются через него, а замолчал туннель — снова напрямую. Переключения пишутся в журнал sing-box.
- Спрашивать напрямую — DNS не зависит от туннеля: заминка сервера не уносит с собой имена всей машины.
- Спрашивать через туннель — когда прямой DoH уже отказал, а не заранее: пока туннель не поднялся, не открывается ничего, включая то, что прекрасно работало на десинке.
Цена пути через туннель — адреса у выхода. Через туннель спрашиваются имена,
которые идут мимо VPN, и сеть доставки отдаёт им адреса рядом с сервером VPN,
а соединяются они напрямую — дольше. Замер 06.10, выход в Италии:
i.ytimg.com с адресами от DNS через туннель — TLS 141–151 мс, от прямого
DoH — 65–73 мс. Вкладка «DNS» говорит это рядом с выбором.
Там же — резолверы туннеля с задержкой и автовыбором по ней, свой резолвер
(config\dns.user.json) и обзор резолверов: кто отвечает на открытый UDP
и что подменяется. Открытый DNS на 53 порту к публичным резолверам у части
операторов подменяется — с поднятым туннелем запросы Windows поэтому забирает
движок и спрашивает по DoH.
Оформление
Раздел «Оформление». В поставке одиннадцать тем: тёмная, светлая, серая, тёмно-синяя, фиолетовая, морская, кофейная, розовая, кремовая и две с артом — «Слойка 1» и Blissfield. Свою можно собрать прямо в программе — «Создать тему»: цвета выбираются как в Telegram, правка видна сразу, а нечитаемое сочетание программа покажет и предложит поправить. Тема может нести картинку фона и свои шрифты; «Выгрузить в файл…» кладёт её в один .zip, «Загрузить из файла…» ставит такой файл, полученный от другого.
Общие для всех тем настройки там же: показывать ли фон, размытие под карточками, затемнение, шрифт всей программы, размер, «Главная» на всю ширину окна, вид меню в трее — размытие под ним и плотность подложки. Формат темы — в themes/README.md.
Антивирусы
Значок в шапке ведёт на отчёт VirusTotal по архиву 0.14.4
(SHA-256 2b883f12a96e492cd69ad92352541131cc2519bd0d3be00bb1011c831df1c0d3).
Хэш архива каждой версии стоит в примечаниях к выпуску: сверьте со скачанным
файлом.
Срабатывают на средства обхода, а не на вредоносный код. Архив 0.14.4 даёт 2 срабатывания из 64:
- Elastic —
Windows.Rootkit.WinDivert: это WinDivert, драйвер перехвата пакетов. Без него обход DPI невозможен, и та же картина у Zapret и GoodbyeDPI. - Kaspersky —
Not-a-virus:UDS:NetTool.Win64.CloudTunnel.a: сам Kaspersky пишет «не вирус» и относит находку к сетевым инструментам — так он помечает программы, которые строят туннели.
Чтобы Defender не трогал движки, папку программы можно добавить в его исключения — кнопкой в «Ещё». Сам Defender программа не выключает и не трогает ничего, кроме исключения для своей папки.
Программа не подписана сертификатом издателя, поэтому Windows покажет SmartScreen.
Из поставляемых файлов подписаны двое: wintun.dll — WireGuard LLC, и драйвер
Monkey64.sys — сторонней организацией, не связанной с проектом WinDivert.
Подробности в docs/THIRD-PARTY.md.
Диагностика и отчёт
Раздел «Диагностика» проверяет всё, от чего зависит работа: права, движки, правила, конфиг, резолвер, супервизор, другие VPN-клиенты рядом, папку программы (не в облаке ли она), прокси Telegram. Красное чинить первым — остальное часто следствие.
Там же:
- «Собрать отчёт для разбора» — журналы движков, настройки, свои маршруты, последняя проверка блокировок, все проверки «Диагностики», голос Discord, файл hosts, проверки серверов туннеля одним архивом. Его и прикладывают к сообщению о неполадке. Ссылки подписок, ключи серверов, секрет прокси Telegram, имя учётной записи Windows и домашний адрес вычищаются.
- «Открыть журнал» — журналы sing-box, winws2, супервизора и окна отдельным окном, с отбором «только ошибки». Его можно держать рядом с разделом, где что-то не работает.
- «Куда пойдёт соединение» — имя, программа или адрес: какое правило сработает и через что пойдёт.
Инструмент разбора
В архив релиза не входит. Поставляется только окно. Для разбора
неисправностей из исходников собирается nz. Прав администратора не просит
и своей логики не держит — зовёт те же библиотеки, что и окно, поэтому
отвечает ровно так, как решит программа:
nz status # что сейчас поднято: режим, пресет, движки nz doctor # те же проверки, что раздел «Диагностика» nz where <цель> # куда пойдёт и через что разрешится имя, программа или адрес nz routes # противоречия в своих маршрутах и пинах nz fix <сайт> # не открывается: пробует как есть, напрямую, через VPN nz dns # что отвечают DNS-провайдеры и что подменяется nz dns-mode [авто|напрямую|туннель] # путь DNS движка; с аргументом — сменить nz voice # голос Discord: адреса звука из его журнала против списка nz report # отчёт для разбора архивом в reports\ nz catalog # снимок рабочих записей каталога Zapret, несколько минут
Поднять и погасить движки без окна может сама программа: NetZapret.exe --start
и --stop. Им права администратора нужны — ставится драйвер перехвата.
Сборка из исходников
Нужна, только если вы собираетесь менять код — для работы достаточно архива из релизов.
1. .NET SDK 8 или новее.
winget install Microsoft.DotNet.SDK.8
2. sing-box extended — для VPN. Скачать сборку windows-amd64 с
shtorm-7/sing-box-extended
и распаковать в tools\ целиком, вместе с wintun.dll — без неё не поднимется
TUN. Нужна именно extended: обычный sing-box не знает xhttp, выхода MASQUE
для WARP и маскировки AmneziaWG. Проверялось на 1.14.1-extended-2.7.2.
3. Zapret 2 — для десинка. Ставится отдельно, в C:\Zapret или
C:\Zapret\Dev; build.cmd берёт из установки только то, что читает движок:
exe, lists, lua, bin, windivert.filter. Пресеты и свои списки
из установки не берутся — они наши и лежат в presets\ и config\lists\.
winws2.exe новее, чем в установке, кладётся в tools\ и едет поверх.
Сейчас это родная сборка без Cygwin —
zapret2-fork
от loop-uh, выпуск v1.0.5.2-41-g204fd66-native; почему она и как проверять
новый выпуск — в tools/README.md.
4. tg-ws-proxy-rs — для вкладки «TG Proxy». Сборку
tg-ws-proxy-x86_64-pc-windows-gnu.zip с
valnesfjord/tg-ws-proxy-rs
распаковать с файлом LICENSE в tools\tg-ws-proxy-rs-<версия>\; проверялось
на 2.5.2. build.cmd соберёт и без него, pack.cmd — нет.
Без sing-box работает всё, кроме VPN. Без Zapret — всё, кроме десинка. Без прокси — всё, кроме вкладки «TG Proxy». Что именно нашлось, показывает раздел «Диагностика».
Дальше:
dotnet build
dotnet testЭто библиотеки, nz и их тесты. Тесты на окно живут в своём решении — в общее
оно не входит, чтобы WPF не попадал в сборку библиотек:
dotnet test gui/NetZapret.Gui.slnbuild.cmd
build.cmd останавливает движки, раскладывает результат в build\ и складывает
туда же движки, так что собранная копия работает сама по себе. Запуск из bin\
ломал бы пересборку: MSBuild пишет в тот же каталог, где лежат загруженные сборки.
Что именно копируется и почему не через репозиторий — в tools/README.md.
Готовый архив и публикация релиза:
pack.cmd
release.cmd 0.1.0
Устройство
| Модуль | Что делает |
|---|---|
NetZapret.Core |
Модель правил, режимы, движок сопоставления, настройки, обновление |
NetZapret.Subscriptions |
Разбор ссылок и подписок, квота и срок из заголовков |
NetZapret.Proxy |
Генерация конфига sing-box, DNS, hosts, проверка серверов |
NetZapret.Zapret |
Разбор пресетов winws2, сборка его командной строки |
NetZapret.Supervisor |
Запуск движков, слежение за живостью, перезапуск, диагностика, отчёт |
NetZapret.Etw |
Наблюдение за соединениями и DNS через ETW |
tools\nz |
Инструмент разбора. В архив не входит |
NetZapret.Gui |
Окно. Собственное решение gui\NetZapret.Gui.sln |
Окно — второй вид поверх тех же библиотек, а не отдельная программа: правила,
подписки, конфиг и супервизор живут в них. Своего в окне только показ, сборка
конфига перед запуском и подъём супервизора перезапуском себя с ключом
--supervisor.
Принуждение выполняет route-движок sing-box, а не собственный код. NetZapret
владеет правилами и их семантикой, sing-box — исполнением. Своего WFP-callout'а
в проекте нет: кастомная классификация и ALE_CONNECT_REDIRECT живут только
в kernel-mode драйвере, а тот требует WDK, EV-сертификата и attestation-подписи.
Движки — winws2, sing-box и прокси Telegram — работают под супервизором в Job
Object с KILL_ON_JOB_CLOSE: осиротевший sing-box удерживает TUN-адаптер,
осиротевший winws2 — WinDivert, и следующий запуск падает неочевидно. Десинк
поднимается раньше туннеля: иначе первые соединения туннеля уходили мимо
десинка и замерзали. Двух супервизоров разом не бывает: новый сменяет прежнего
по замку runtime\supervisor.lock, а не гасит его движки наперегонки.
Почему наблюдение на ETW, а не на WFP
Наблюдение изначально подписывалось на net-events WFP. На Windows 11 26200 события
FWPM_NET_EVENT_TYPE_CLASSIFY_ALLOW не приходят вообще: сбор включён, ключевое
слово принято, подкатегория аудита включена — а событий нет, и записей 5156
в журнале безопасности тоже нет. Доходят только CLASSIFY_DROP, по которым
диспетчер не построить. Реализация на WFP ушла вместе с консолью.
Известные ограничения
- Обход по программе на переработке — см. «Программы»;
- серверы VLESS + REALITY у некоторых провайдеров не подключаются — ограничение sing-box, поддержка Xray вторым движком запланирована;
- WARP не поднимается на чистой машине. Движок сам ходит за учётной
записью на
api.cloudflareclient.com, и этот запрос не проходит: рецепт десинка для домена выверен на приветствии Windows, а движок написан на Go. Регистрация нужна один раз — дальше она живёт вruntime\engine-cache.db, и пока кэш цел, WARP работает. Потерявшему кэш придётся ждать рецепта под Go; - WARP неровен под нагрузкой: один канал HTTP/2 на все соединения, общий контроль перегрузки. Для повседневной работы подписка надёжнее;
- прокси Telegram — только для Telegram Desktop на этом компьютере: телефон через него не подключить;
- TUIC, Hysteria первой версии, AnyTLS, WireGuard и AmneziaWG проверены тем, что собранный конфиг принимает сам движок, но не на живых серверах: своих серверов этих протоколов у проекта нет. Не подключается — пришлите отчёт («Диагностика» → «Собрать отчёт для разбора»);
- установщика нет, только архив; обновляется программа сама — окном «Доступно обновление», когда выйдет новая версия;
- окно покрыто тестами частично: 229 проверок против 1411 на начинку. Есть сборка конфига, создание каждого раздела и окна, имена стилей в разметке, темы, меню трея, порядок пресетов, список подписок, разделы чейнджлога против меню и место подсказки в полях ввода. Цикл надзора проверяется на подставной службе — запуск, перезапуск, отказ; настоящие sing-box, winws2 и прокси в тестах не поднимаются: им нужны права администратора и драйвер;
- проверка блокировок не пробует пути, которыми цель ещё не ходит — вывод «нужен VPN» сделан по тому, что не работает напрямую, а не по тому, что заработает через туннель. Имена, которым туннель не довёз, она при этом умеет пустить в него нарочно — через служебный вход движка.
Поддержать
Программа бесплатная и останется такой: лицензия MIT это и закрепляет.
Лицензия
MIT — берите, меняйте, распространяйте, в том числе в составе коммерческих продуктов. Единственное требование: сохранить уведомление об авторстве.
Движки, входящие в сборку, остаются на своих условиях: sing-box — GPL v3,
Zapret — MIT, tg-ws-proxy-rs — MIT, WinDivert — LGPL, wintun.dll —
проприетарная лицензия WireGuard LLC. Они запускаются отдельными процессами
и на лицензию NetZapret не влияют. Разбор — в docs/THIRD-PARTY.md.
Сценарии десинка на lua, списки доменов и адресов, пресеты и каталог адресов, на которых стоит десинк, — работа loop-uh, автора Zapret GUI (MIT). Без них от Zapret здесь был бы один winws2.
Game filter — выключатель для игр на вкладке «Десинк» — перенесён
с zapret-discord-youtube
Flowseal (MIT); его же список адресов ipset-all, по которому секции
игр отбирают трафик.
Прокси для Telegram — tg-ws-proxy-rs valnesfjord (MIT), порт программы tg-ws-proxy Flowseal (MIT); обе лицензии лежат в архиве рядом с прокси.
QR-коды с ключами читает ZXing.Net (Apache 2.0) — библиотека встроена в программу, её лицензия лежит в архиве рядом с ней.
Дальше
Планы — в docs/roadmap.md, а что обсуждается, но не решено, — в docs/ideas.md. Ближайшее из открытого — переделка обхода по программе и доведение автоподбора маршрута до конца: сейчас проверка говорит, что сервис не работает напрямую, но не проверяет, заработает ли через туннель.
Разбор неисправностей — вкладкой «Диагностика» и командой nz (выше).
Разбор sing-box и формат ссылок подписки — в docs/singbox.md.