🧩 Что такое профиль в Zapret 2 и чем он отличается от пресета

О чём заметка

Что такое профиль в Zapret 2, из каких частей он состоит и почему настраивать обход нужно именно в профилях, а не перебором целых пресетов. Подробные справочники по отдельным флагам — filter, payload, out-range, desync, blob; как создать свой профиль в GUI — add-profile.

TL;DR

  • Пресет — весь файл настроек: общая шапка и десятки профилей подряд.
  • Профиль — один блок внутри пресета, отделённый строкой --new. Он отвечает за свою часть трафика: интерфейс YouTube, голос Discord, Telegram, сеть Cloudflare.
  • Профиль состоит из фильтров, которые решают, какие соединения ему достаются, и стратегии обхода, которая решает, что с ними делать.
  • Каждое соединение достаётся одному профилю — первому сверху, чьи фильтры совпали. Поэтому порядок профилей важен.
  • Если не работает один сайт, меняют стратегию в его профиле, а не весь пресет.

Что делает Zapret 2 и где здесь профиль

Когда вы открываете сайт по HTTPS, браузер в первом же сообщении соединения (TLS ClientHello) открытым текстом называет имя сайта. Это поле называется SNI (Server Name Indication). Оборудование провайдера — DPI (Deep Packet Inspection, глубокий анализ трафика), в России это ТСПУ, — читает его и рвёт или замедляет соединения с запрещёнными именами.

Zapret 2 перехватывает исходящие пакеты до того, как они уйдут в сеть, и меняет их так, чтобы DPI не смог прочитать имя сайта, а настоящий сервер получил данные без искажений. Такие приёмы называют стратегиями обхода, или дурением (desync); каталог стратегий — в desync.

Разные сайты блокируют по-разному, и одна стратегия на весь трафик не годится: то, что пробивает YouTube, может сломать банк или игру. Поэтому настройки делят на части. Каждая часть говорит: «вот эти соединения обрабатывай вот так». Такая часть и есть профиль, а файл, в котором профили лежат по порядку вместе с общими настройками, — пресет.

Пресет и профиль — в чём разница

ПонятиеЧто этоПример
Пресет (preset)Один .txt-файл: общая шапка и набор профилейDefault v1 (game filter)
ПрофильОдин блок внутри пресета, до следующего --newyoutube.com (интерфейс), Telegram, Cloudflare UDP

В файле пресет выглядит как длинный список флагов, где профили идут друг за другом и разделяются строкой --new:

( шапка пресета: --lua-init, --blob, --wf-tcp-out … )

--name=youtube.com (интерфейс)      ← профиль конкретного сайта
--filter-tcp=80,443
--hostlist=lists/youtube.txt
--lua-desync=multisplit:...
--new                               ← разделитель
--name=Исключения айпи (RU сайты)   ← профиль-исключение
--filter-tcp=80,443-65535
--ipset=lists/ipset-ru.txt
--lua-desync=pass
--new                               ← разделитель
--name=Cloudflare TCP               ← широкий профиль по сети CDN
--filter-tcp=80,443-65535
--ipset=lists/ipset-cloudflare.txt
--lua-desync=hostfakesplit:...
...

Пресет сам ничего не решает: это контейнер, который хранит профили по порядку. Успех обхода конкретного сайта зависит от того, какой профиль забрал его соединения и какая стратегия в этом профиле стоит.

Анатомия профиля

Профиль — это несколько флагов до следующего --new. Разберём реальный блок из пресета Default v1 (game filter) (версия пресета 2.40, август 2026):

--name=youtube.com (интерфейс)
--filter-tcp=80,443
--hostlist=lists/youtube.txt
--out-range=-d8
--payload=tls_client_hello
--lua-desync=multisplit:pos=1,host+2,sld+2,sld+5,sniext+1,sniext+2,endhost-2:seqovl=1

Читается так: «профиль youtube.com (интерфейс) забирает TCP-соединения на порты 80 и 443 к доменам из youtube.txt. В этих соединениях на TLS ClientHello среди первых восьми пакетов с данными выполняется стратегия multisplit: сообщение режется на части в нескольких местах вокруг имени сайта, а к первой части добавляется перекрытие в 1 байт (seqovl)».

Флаги здесь делятся на три роли, и путать их нельзя: от роли зависит, что происходит, когда условие не выполнено.

Фильтры профиля: какие соединения ему достаются

ФлагЧто проверяетВ примереПодробнее
--filter-tcp / --filter-udpТранспорт и порты. Если задан только TCP, UDP-трафик этому профилю не достаётся, и наоборотTCP 80,443filter
--filter-l7Протокол приложения: http, tls, quic, wireguard, discord, stun, mtproto и другиене заданfilter
--hostlist / --hostlist-excludeИмя сайта (из SNI или заголовка Host) по списку доменов; поддомены учитываются автоматическидомены из lists/youtube.txthostlist
--ipset / --ipset-excludeIP-адрес сервера по списку адресов и подсетейне заданipset

Все фильтры профиля действуют вместе: соединение достаётся профилю, только если совпали и порт, и протокол, и списки. Если не совпало хоть что-то, движок проверяет следующий профиль. Как именно идёт этот перебор — ниже, в разделе про порядок.

Внутрипрофильные условия: к каким пакетам применять стратегию

ФлагЧто ограничиваетВ примереПодробнее
--out-range / --in-rangeНа каких по счёту пакетах соединения работать. d — пакеты с данными, n — все пакеты; -d8 — с начала по восьмой пакет с данными-d8out-range
--payloadНа какой тип содержимого реагировать: tls_client_hello, http_req, quic_initial, all. На уровне профиля по умолчанию all; многие стратегии дополнительно сами берут только известные типы (known)tls_client_hellopayload

Эти флаги не участвуют в выборе профиля. Официальная документация zapret2 называет их внутрипрофильными фильтрами: они действуют на идущие после них вызовы --lua-desync внутри уже выбранного профиля. Если пакет не подошёл под --payload или --out-range, соединение не уходит к другому профилю: оно остаётся в этом, просто стратегия к этому пакету не применяется. Поэтому их место в профиле важно — они должны стоять перед --lua-desync, к которому относятся, см. последовательность аргументов.

Стратегия: что делать с пакетами

--lua-desync вызывает функцию обхода: fake, multisplit, multidisorder, hostfakesplit и другие. Строк --lua-desync может быть несколько, они выполняются по очереди для одного и того же пакета. Такие связки встречаются во многих профилях стоковых пресетов, например:

--lua-desync=send:repeats=2
--lua-desync=syndata:blob=stun_pat
--lua-desync=tls_multisplit_sni:seqovl=652:seqovl_pattern=tls_google

Это одна стратегия одного профиля. Смешать стратегии двух разных профилей на одном соединении нельзя — подробнее в profile-independence. Что делает каждая функция — в desync.

--name — просто подпись профиля в GUI и в логах, на трафик она не влияет.

Профиль-исключение: pass

Стратегия --lua-desync=pass ничего не делает: профиль забирает соединение и отправляет его как есть. Так оформляют исключения. В стоковых пресетах есть профили «Исключения айпи (RU сайты)» и «Исключения домены (RU сайты)» (до обновления пресетов в августе 2026 был один общий профиль по IP): они намеренно не трогают российские сайты, чтобы обход не сломал им соединение. В Default v1 (game filter) они стоят после профилей конкретных сайтов вроде YouTube, но выше широких профилей по сетям (Cloudflare, Hetzner, Amazon и другие). Поэтому соединения российских сайтов забирают исключения, и до широких профилей с обходом эти соединения не доходят. Чем pass-профиль отличается от exclude-списков и какие у исключений подводные камни — в exclusions.

Полный профиль целиком: разбор по строкам

Короткий пример выше показывает по одной строке каждого вида. Ниже — профиль «GitHub» целиком, как он записан в том же пресете Default v1 (game filter) (версия 2.40, август 2026). В нём есть всё сразу: подпись, фильтры выбора, внутрипрофильные условия и цепочка из трёх стратегий.

--name=GitHub
--filter-tcp=443
--hostlist=lists/github.txt
--out-range=-d8
--payload=tls_client_hello
--lua-desync=send:repeats=2
--lua-desync=syndata:blob=stun_pat
--lua-desync=tls_multisplit_sni:seqovl=652:seqovl_pattern=stun_pat
СтрокаРольЧто делает
--name=GitHubподписьИмя профиля в GUI и в логах. На трафик не влияет
--filter-tcp=443фильтр выбораТолько TCP на порт 443 (HTTPS). Соединения по QUIC (UDP 443) к GitHub этот профиль не получает
--hostlist=lists/github.txtфильтр выбораТолько домены GitHub из списка и их поддомены. Профиль выбирается, когда движок узнаёт имя сайта из ClientHello
--out-range=-d8внутрипрофильное условиеСтратегии ниже работают с начала соединения по восьмой пакет с данными
--payload=tls_client_helloвнутрипрофильное условие…и только на TLS ClientHello — сообщении, в котором браузер называет имя сайта
--lua-desync=send:repeats=2стратегияОтправляет две дополнительные копии текущего пакета (ClientHello) без изменений; сам пакет не блокирует
--lua-desync=syndata:blob=stun_patстратегияЗадумана как подмешивание данных в первый пакет соединения (SYN). В этом профиле не срабатывает — см. ниже
--lua-desync=tls_multisplit_sni:…стратегияФункция из библиотеки GUI (custom_funcs.lua): режет ClientHello примерно в 17 местах вокруг имени сайта и отправляет части в обратном порядке; seqovl=652 просит добавить перекрытие в 652 байта с шаблоном stun_pat

Как это выглядит для одного соединения с github.com:

  1. Браузер отправляет SYN — первый пакет установки соединения. Имени сайта в нём нет, поэтому профиль «GitHub» с хостлистом в выборе ещё не участвует, и SYN достаётся другому подходящему профилю или проходит без обработки.
  2. Браузер отправляет TLS ClientHello с именем github.com. Движок узнаёт имя, заново перебирает профили сверху вниз и отдаёт соединение профилю «GitHub» (если выше нет другого профиля, который тоже подходит).
  3. На этом ClientHello по очереди выполняются стратегии профиля: send отправляет две копии пакета, syndata пропускает его (это не SYN), tls_multisplit_sni режет его на части и отправляет их в обратном порядке, а оригинал блокирует.
  4. Дальнейшие пакеты соединения идут без изменений: стратегиям нужен только ClientHello.

Две строки этого профиля на деле не работают так, как записаны

Проверено на стенде (сентябрь 2026, nfqws2 на Linux, та же Lua-библиотека, что в GUI):

  • syndata не срабатывает. Ей нужен SYN, а SYN до этого профиля не доходит: пока имя сайта неизвестно, профиль с хостлистом не выбирается. Вдобавок --payload=tls_client_hello отсекает SYN, потому что в нём нет данных. На стенде SYN уходил пустым и в профиле с хостлистом, и в профиле с одним только --payload=tls_client_hello; данные в SYN появлялись только в профиле без хостлиста и без фильтра payload. Чтобы syndata работала, её ставят в профиль, который выбирается с первого пакета (по портам или по ipset), и не ограничивают --payload перед ней. Подробнее — в syndata и оговорке о смене профиля.
  • seqovl=652 часто отменяется. tls_multisplit_sni отбрасывает перекрытие, если оно не меньше позиции первого разреза, а первый разрез стоит у начала имени сайта. На стенде имя начиналось со 151-го байта ClientHello, и в логе было seqovl cancelled, too large — части ушли без перекрытия. Chrome перемешивает порядок расширений ClientHello, поэтому у него имя может оказаться и дальше 652-го байта, и тогда перекрытие сработает; значит, на части соединений оно будет, на части нет.

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

Проще говоря: читая профиль, проверяйте не только, что написано в каждой строке, но и дойдёт ли до неё нужный пакет. Фильтры выбора решают, попадёт ли соединение в профиль и с какого момента, --payload и --out-range — какие пакеты увидят стратегии, а сами стратегии срабатывают только на тех пакетах, для которых написаны.

Порядок профилей важен

Для каждого нового соединения движок перебирает профили сверху вниз и отдаёт соединение первому, у которого совпали все фильтры. Остальные профили это соединение не обрабатывают. Сравнение идёт не для каждого пакета: выбранный профиль запоминается для соединения и пересматривается, только когда становятся известны протокол или имя сайта. Подробно — в разборе выбора профиля.

Из этого три практических следствия:

  • Исключения (pass) ставят выше широких профилей с обходом, иначе соединения российских сайтов заберёт широкий профиль.
  • Узкий профиль конкретного сайта ставят выше широкого профиля (например, по всей сети Cloudflare или по всем портам), иначе широкий заберёт соединения сайта раньше.
  • Если после включения нового профиля сломался другой сайт, скорее всего, новый профиль забирает чужие соединения. Как это найти и исправить — в profile-independence.

В GUI порядок меняет кнопка «Порядок в пресете».

Шапка пресета: общие настройки

Над профилями идёт общая часть, которая действует на весь пресет и к профилям не относится:

# Preset: Default v1 (game filter)   ← метаданные для GUI: имя
# BuiltinVersion: 2.40               ← версия встроенного пресета
# IconColor: #a8c5ff                 ← цвет иконки

--lua-init=@lua/zapret-lib.lua      ; подключение Lua-библиотек со стратегиями
--lua-init=@lua/zapret-antidpi.lua
--lua-init=@lua/custom_funcs.lua    ; …и ещё несколько библиотек, в том числе функции самого GUI
--ctrack-disable=0                  ; отслеживание соединений (conntrack) включено
--ipcache-hostname=0
--wf-tcp-out=80,443,1080,2053,2083,2087,2096,5050,8443,8080,45631   ; какой TCP-трафик перехватывать (WinDivert)
--wf-udp-out=443-65535
--wf-raw-part=@windivert.filter/windivert_part.discord_media.txt    ; дополнительные фильтры WinDivert
--blob=tls_google:@bin/tls_clienthello_www_google_com.bin           ; именованные заготовки пакетов
  • --lua-init загружает библиотеки, в которых написаны функции обхода; без них --lua-desync в профилях вызывать нечего.
  • --blob объявляет именованные заготовки данных, на которые стратегии ссылаются через blob=имя (подробнее — blob).
  • --wf-tcp-out и --wf-udp-out — фильтры WinDivert: какой трафик Windows вообще передаст программе. Это отбор до профилей: соединение, которое сюда не попало, не увидит ни один профиль.

Где найти профили в GUI

Профили находятся в левом меню Zapret 2: «Настройки Запрета» → «Профили пресета». Откроется экран «Настройка пресета: …» со списком профилей активного пресета:

Профили сгруппированы по категориям (YouTube 4, Discord 6, Мессенджеры 4, Соцсети 5 — число показывает, сколько профилей в группе). Сверху — быстрые фильтры Все / TCP / UDP / Discord / Voice / Games и поиск по имени.

В каждой строке:

  • слева — иконка ресурса, имя профиля (--name), тип (TCP, UDP, Voice) и порты;
  • метка Hostlist или IPset — по списку доменов или по списку адресов профиль отбирает соединения;
  • справа — имя стратегии: Split Position, alt v9, fake_2_n2, hostfakesplit_multi, MultiDisorder Complex, pass (ничего не делает) и другие;
  • статус Не добавлен (серая точка) — профиль есть в списке, но в активный пресет не включён.

Кнопка «Что это такое?» открывает встроенную подсказку, «Порядок в пресете» меняет очерёдность профилей, + добавляет новый профиль — пошагово в add-profile.

Профиль, категория и списки — кто есть кто

Эти три понятия легко спутать:

  • Хостлист (hostlist) и ipset (ipset) — файлы со списками доменов и IP-адресов.
  • Категория — набор адресов конкретного ресурса (игры, сайта), собранный в такие файлы; как собрать — Создание своей категории.
  • Профиль связывает всё вместе: берёт списки, добавляет фильтр портов и стратегию и говорит движку, что делать с этими соединениями.

Почему настраивать нужно профили, а не перебирать пресеты

В готовом пресете у каждого профиля уже выбрана стратегия. Эти стратегии подбирали под чьих-то провайдеров, а DPI у разных провайдеров и в разных регионах настроен по-разному. Отсюда типичная картина: на одном пресете открывается YouTube, но не работает Discord, на другом — наоборот. Перебирать пресеты целиком в такой ситуации бесполезно: каждый раз меняются стратегии сразу во всех профилях, и починка одного сайта ломает другой.

Работает другой порядок. Возьмите пресет, на котором работает больше всего нужного, как основу. Найдите профиль, в который попадает неработающий сайт (как определить — в find-domain-owner и find-site-domains). И перебирайте стратегии только в нём, проверяя каждую новым соединением по verify-strategy. Фильтры и списки популярных ресурсов уже собраны и поддерживаются, их обычно трогать не нужно: от провайдера к провайдеру меняется в основном то, какая стратегия обманывает его DPI.

Режим, в котором стратегии меняют у отдельных профилей, в GUI исторически называется «Прямой запуск» (Настройки → Прямой запуск, подробнее — guide и Как пользоваться Zapret). Название сложилось давно и немного вводит в заблуждение: это не особый способ обхода, а просто возможность настраивать профили по одному.

«Запрет перестал работать» — обычно симптом

Если после обновления провайдером DPI сайт перестал открываться, чаще всего устарела стратегия одного-двух профилей, а сама программа исправна: остальные сайты ведь открываются. Как отличить это от настоящей неисправности (антивирус, конфликт с VPN, DNS) и что делать — в symptom-not-cause и Что делать, если Запрет не работает.

📚 См. также


🤖 Эти статьи открыты — можно обучать на них ИИ

При желании вы можете натренировать ИИ на наших статьях. Исходное форматирование доступно в Forgejo: исходник этой заметки · скачать весь репозиторий одним zip-архивом.