[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"project-6109":3},{"id":4,"name":5,"fullName":6,"owner":7,"repo":5,"description":8,"homepage":9,"htmlUrl":10,"language":11,"languages":10,"totalLinesOfCode":10,"stars":12,"forks":13,"watchers":14,"openIssues":15,"contributorsCount":16,"subscribersCount":16,"size":16,"stars1d":17,"stars7d":18,"stars30d":19,"stars90d":16,"forks30d":16,"starsTrendScore":20,"compositeScore":21,"rankGlobal":10,"rankLanguage":10,"license":10,"archived":22,"fork":22,"defaultBranch":23,"hasWiki":22,"hasPages":22,"topics":24,"createdAt":10,"pushedAt":10,"updatedAt":34,"readmeContent":35,"aiSummary":36,"trendingCount":16,"starSnapshotCount":16,"syncStatus":37,"lastSyncTime":38,"discoverSource":39},6109,"zapret","bol-van\u002Fzapret","bol-van","DPI bypass multi platform","",null,"C",15474,1063,202,4,0,6,64,247,33,44.08,false,"master",[25,26,27,28,29,30,31,32,33],"anti-dpi","censorship-circumvention","freebsd","linux","macos","openbsd","openwrt","russian","windows","2026-06-12 02:01:16","# ВНИМАНИЕ, остерегайтесь мошенников\n\nzapret является свободным и open source.\nВсякий, кто понуждает вас скачивать zapret только с его ресурса, требует удалить ссылки, видео, файлы, обосновывая эти требования авторскими правами, сам нарушает [лицензию](.\u002FLICENSE.txt).\nОднако, это не исключает [добровольные пожертвования](#поддержать-разработчика).\n\n# zapret2\n\nЭта версия zapret более не развивается и находится в режиме EOL (End-Of-Life). Никаких новых функций больше не будет. Только багфиксы.\n\n[Актуальная версия - zapret 2](https:\u002F\u002Fgithub.com\u002Fbol-van\u002Fzapret2)\n\n# Multilanguage README\n\n[![en](https:\u002F\u002Fimg.shields.io\u002Fbadge\u002Flang-en-red.svg)](.\u002Freadme.en.md)\n[![ru](https:\u002F\u002Fimg.shields.io\u002Fbadge\u002Flang-ru-green.svg)](.\u002Freadme.md)\n\n***\n\n  - [Зачем это нужно](#зачем-это-нужно)\n  - [Быстрый старт](#быстрый-старт)\n  - [Как это работает](#как-это-работает)\n  - [Что сейчас происходит в России](#что-сейчас-происходит-в-россии)\n  - [Как это реализовать на практике в системе linux](#как-это-реализовать-на-практике-в-системе-linux)\n  - [Когда это работать не будет](#когда-это-работать-не-будет)\n  - [nfqws](#nfqws)\n    - [АТАКА ДЕСИНХРОНИЗАЦИИ DPI](#атака-десинхронизации-dpi)\n    - [ФЕЙКИ](#фейки)\n    - [МОДИФИКАЦИЯ ФЕЙКОВ](#модификация-фейков)\n    - [TCP СЕГМЕНТАЦИЯ](#tcp-сегментация)\n    - [ПЕРЕКРЫТИЕ SEQUENCE NUMBERS](#перекрытие-sequence-numbers)\n    - [НАЗНАЧЕНИЕ IP_ID](#назначение-ip_id)\n    - [СПЕЦИФИЧЕСКИЕ РЕЖИМЫ IPV6](#специфические-режимы-ipv6)\n    - [МОДИФИКАЦИЯ ОРИГИНАЛА](#модификация-оригинала)\n    - [ДУБЛИКАТЫ](#дубликаты)\n    - [КОМБИНИРОВАНИЕ МЕТОДОВ ДЕСИНХРОНИЗАЦИИ](#комбинирование-методов-десинхронизации)\n    - [КЭШ IP](#кэш-ip)\n    - [РЕАКЦИЯ DPI НА ОТВЕТ СЕРВЕРА](#реакция-dpi-на-ответ-сервера)\n    - [РЕЖИМ SYNACK](#режим-synack)\n    - [РЕЖИМ SYNDATA](#режим-syndata)\n    - [ВИРТУАЛЬНЫЕ МАШИНЫ](#виртуальные-машины)\n    - [CONNTRACK](#conntrack)\n    - [РЕАССЕМБЛИНГ](#реассемблинг)\n    - [ПОДДЕРЖКА UDP](#поддержка-udp)\n    - [IP ФРАГМЕНТАЦИЯ](#ip-фрагментация)\n    - [МНОЖЕСТВЕННЫЕ СТРАТЕГИИ](#множественные-стратегии)\n    - [ФИЛЬТРАЦИЯ ПО WIFI](#фильтрация-по-wifi)\n    - [IPTABLES ДЛЯ NFQWS](#iptables-для-nfqws)\n    - [NFTABLES ДЛЯ NFQWS](#nftables-для-nfqws)\n    - [FLOW OFFLOADING](#flow-offloading)\n    - [ОСОБЕННОСТИ ЖЕЛЕЗОК](#особенности-железок)\n    - [ДУРЕНИЕ СО СТОРОНЫ СЕРВЕРА](#дурение-со-стороны-сервера)\n  - [tpws](#tpws)\n    - [TCP СЕГМЕНТАЦИЯ В TPWS](#tcp-сегментация-в-tpws)\n    - [TLSREC](#tlsrec)\n    - [MSS](#mss)\n    - [ДРУГИЕ ПАРАМЕТРЫ ДУРЕНИЯ](#другие-параметры-дурения)\n    - [МНОЖЕСТВЕННЫЕ СТРАТЕГИИ](#множественные-стратегии-1)\n    - [СЛУЖЕБНЫЕ ПАРАМЕТРЫ](#служебные-параметры)\n    - [IPTABLES ДЛЯ TPWS](#iptables-для-tpws)\n    - [NFTABLES ДЛЯ TPWS](#nftables-для-tpws)\n  - [ip2net](#ip2net)\n  - [mdig](#mdig)\n  - [Способы получения списка заблокированных IP](#способы-получения-списка-заблокированных-ip)\n  - [Фильтрация по именам доменов](#фильтрация-по-именам-доменов)\n  - [Режим фильтрации autohostlist](#режим-фильтрации-autohostlist)\n  - [Проверка провайдера](#проверка-провайдера)\n  - [Выбор параметров](#выбор-параметров)\n  - [Прикручивание к системе управления фаерволом или своей системе запуска](#прикручивание-к-системе-управления-фаерволом-или-своей-системе-запуска)\n  - [Вариант custom](#вариант-custom)\n  - [Простая установка](#простая-установка)\n  - [Установка под systemd](#установка-под-systemd)\n  - [Простая установка на openwrt](#простая-установка-на-openwrt)\n  - [Установка на openwrt в режиме острой нехватки места на диске](#установка-на-openwrt-в-режиме-острой-нехватки-места-на-диске)\n  - [Android](#android)\n  - [Мобильные модемы и роутеры huawei](#мобильные-модемы-и-роутеры-huawei)\n  - [FreeBSD, OpenBSD, MacOS](#freebsd-openbsd-macos)\n  - [Windows](#windows)\n  - [Другие прошивки](#другие-прошивки)\n  - [Обход блокировки через сторонний хост](#обход-блокировки-через-сторонний-хост)\n  - [Почему стоит вложиться в покупку VPS](#почему-стоит-вложиться-в-покупку-vps)\n  - [Поддержать разработчика](#поддержать-разработчика)\n***\n\n## Зачем это нужно\n\nАвтономное средство противодействия DPI, которое не требует подключения каких-либо сторонних серверов. Может помочь\nобойти блокировки или замедление сайтов HTTP(S), сигнатурный анализ TCP и UDP протоколов, например, с целью блокировки\nVPN.\n\nПроект нацелен прежде всего на маломощные embedded устройства - роутеры, работающие под OpenWrt. Поддерживаются\nтрадиционные Linux-системы, FreeBSD, OpenBSD, частично macOS. В некоторых случаях возможна самостоятельная прикрутка\nрешения к различным прошивкам.\n\nБольшая часть функционала работает на Windows.\n\n## Быстрый старт\n\n- [Linux\u002FopenWrt](.\u002Fquick_start.md)\n- [Windows](.\u002Fquick_start_windows.md)\n\n## Как это работает\n\nВ самом простейшем случае вы имеете дело с пассивным DPI. Пассивный DPI может читать трафик из потока, может инжектить\nсвои пакеты, но не может блокировать проходящие пакеты. Если запрос \"плохой\", пассивный DPI инжектит пакет RST,\nопционально дополняя его пакетом HTTP redirect. Если фейк пакет инжектится только для клиента, в этом случае можно\nобойтись командами iptables для дропа RST и\u002Fили редиректа на заглушку по определённым условиям, которые нужно подбирать\nдля каждого провайдера индивидуально. Так мы обходим последствия срабатывания триггера запрета. Если пассивный DPI\nнаправляет пакет RST в том числе и серверу, то вы ничего с этим не сможете сделать. Ваша задача — не допустить\nсрабатывания триггера запрета. Одними iptables уже не обойтись. Этот проект нацелен именно на предотвращение\nсрабатывания запрета, а не ликвидацию его последствий.\n\nАктивный DPI ставится в разрез провода и может дропать пакеты по любым критериям, в том числе распознавать TCP-потоки и\nблокировать любые пакеты, принадлежащие потоку.\n\nКак не допустить срабатывания триггера запрета? Послать то, на что DPI не рассчитывает и что ломает ему алгоритм\nраспознавания запросов и их блокировки.\n\nНекоторые DPI не могут распознать HTTP-запрос, если он разделен на TCP-сегменты. Например, запрос\nвида `GET \u002F HTTP\u002F1.1\\r\\nHost: kinozal.tv......`\nмы посылаем двумя частями: сначала идет `GET`, затем `\u002F HTTP\u002F1.1\\r\\nHost: kinozal.tv.....`. Другие DPI спотыкаются, когда\nзаголовок `Host:` пишется в другом регистре: например, `host:`. Кое-где работает добавление дополнительного пробела\nпосле метода: `GET \u002F` → `GET \u002F`\nили добавление точки в конце имени хоста: `Host: kinozal.tv.`\n\nСуществует и более продвинутая магия, направленная на преодоление DPI на пакетном уровне.\n\nПодробнее про DPI:\\\nhttps:\u002F\u002Fhabr.com\u002Fru\u002Fpost\u002F335436 или https:\u002F\u002Fweb.archive.org\u002Fweb\u002F20230331233644\u002Fhttps:\u002F\u002Fhabr.com\u002Fru\u002Fpost\u002F335436\u002F \\\nhttps:\u002F\u002Fgeneva.cs.umd.edu\u002Fpapers\u002Fgeneva_ccs19.pdf\n\n## Что сейчас происходит в России\n\nРаньше, до внедрения повсеместных систем ТСПУ, использовался зоопарк различных DPI у провайдеров. Какие-то были\nактивными, какие-то пассивными. Сейчас время простых iptables окончательно ушло. Везде активный DPI ТСПУ, но кое-где\nмогут оставаться невыключенными дополнительные старые DPI из зоопарка. В этом случае приходится обходить сразу несколько\nDPI. Все больше становится внереестровых блокировок, о которых вы узнаете только по факту недоступности чего-либо, в\nсписках этого нет. Применяются блокировки некоторых диапазонов ip адресов (автономный обход невозможен)\nи протоколов (VPN). На некоторых диапазонах IP используется более строгий фильтр, распознающий попытки обмана через\nсегментацию. Должно быть это связано с некоторыми сервисами, которые пытаются таким образом обмануть DPI.\n\n## Как это реализовать на практике в системе linux\n\nЕсли кратко, то варианты можно классифицировать по следующей схеме :\n\n1) Пассивный DPI, не отправляющий RST серверу. Помогут индивидуально настраиваемые под провайдера команды iptables. На\n   rutracker в разделе \"обход блокировок - другие способы\" по этому вопросу существует отдельная тема. В данном проекте\n   не рассматривается. Если вы не допустите срабатывание триггера запрета, то и не придется бороться с его\n   последствиями.\n2) Модификация TCP соединения на уровне потока. Реализуется через proxy или transparent proxy.\n3) Модификация TCP соединения на уровне пакетов. Реализуется через обработчик очереди NFQUEUE и raw сокеты.\n\nДля вариантов 2 и 3 реализованы программы tpws и nfqws соответственно. Чтобы они работали, необходимо их запустить с\nнужными параметрами и перенаправить на них определенный трафик средствами iptables или nftables.\n\n## Когда это работать не будет\n\n* Если подменяется DNS. С этой проблемой легко справиться.\n* Если блокировка осуществляется по IP.\n* Если соединение проходит через фильтр, способный реконструировать TCP соединение, и который следует всем стандартам.\n  Например, нас заворачивают на squid. Соединение идет через полноценный стек tcpip операционной системы.\n  Проект нацелен на обман DPI, который в силу ограниченности ресурсов и большого трафика вынужден интерпретировать его лишь ограниченно.\n  Обмануть полноценный стек ОС и полноценные серверные приложения не получится.\n\n## nfqws\n\nЭта программа - модификатор пакетов и обработчик очереди NFQUEUE. Для BSD систем существует адаптированный вариант -\ndvtws, собираемый из тех же исходников (см. [документация BSD](.\u002Fbsd.md)).\n\n```\n@\u003Cconfig_file>|$\u003Cconfig_file>                             ; читать конфигурацию из файла. опция должна быть первой. остальные опции игнорируются.\n\n--debug=0|1                                               ; 1=выводить отладочные сообщения\n--dry-run                                                 ; проверить опции командной строки и выйти. код 0 - успешная проверка.\n--version                                                 ; вывести версию и выйти\n--comment                                                 ; любой текст (игнорируется)\n--daemon                                                  ; демонизировать прогу\n--pidfile=\u003Cfile>                                          ; сохранить PID в файл\n--user=\u003Cusername>                                         ; менять uid процесса\n--uid=uid[:gid]                                           ; менять uid процесса\n--qnum=N                                                  ; номер очереди N\n--bind-fix4                                               ; пытаться решить проблему неверного выбора исходящего интерфейса для сгенерированных ipv4 пакетов\n--bind-fix6                                               ; пытаться решить проблему неверного выбора исходящего интерфейса для сгенерированных ipv6 пакетов\n--ctrack-timeouts=S:E:F[:U]                               ; таймауты внутреннего conntrack в состояниях SYN, ESTABLISHED, FIN, таймаут udp. по умолчанию 60:300:60:60\n--ctrack-disable=[0|1]                                    ; 1 или отсутствие аргумента отключает conntrack\n--ipcache-lifetime=\u003Cint>                                  ; время жизни записей кэша IP в секундах. 0 - без ограничений.\n--ipcache-hostname=[0|1]                                  ; 1 или отсутствие аргумента включают кэширование имен хостов для применения в стратегиях нулевой фазы\n--wsize=\u003Cwinsize>[:\u003Cscale_factor>]                        ; менять tcp window size на указанный размер в SYN,ACK. если не задан scale_factor, то он не меняется (устарело !)\n--wssize=\u003Cwinsize>[:\u003Cscale_factor>]                       ; менять tcp window size на указанный размер в исходящих пакетах. scale_factor по умолчанию 0. (см. conntrack !)\n--wssize-cutoff=[n|d|s]N                                  ; изменять server window size в исходящих пакетах (n), пакетах данных (d), относительных sequence (s) по номеру меньше N\n--wssize-forced-cutoff=0|1                                ; 1(default)=автоматически отключать wssize в случае обнаружения известного протокола\n--synack-split=[syn|synack|acksyn]                        ; выполнить tcp split handshake. вместо SYN,ACK отсылать только SYN, SYN+ACK или ACK+SYN\n--orig-ttl=\u003Cint>                                          ; модифицировать TTL оригинального пакета\n--orig-ttl6=\u003Cint>                                         ; модифицировать ipv6 hop limit оригинальных пакетов.  если не указано, используется значение --orig-ttl\n--orig-autottl=[\u003Cdelta>[:\u003Cmin>[-\u003Cmax>]]|-]                ; режим auto ttl для ipv4 и ipv6. по умолчанию: +5:3-64. \"0:0-0\" или \"-\" отключает функцию\n--orig-autottl6=[\u003Cdelta>[:\u003Cmin>[-\u003Cmax>]]|-]               ; переопределение предыдущего параметра для ipv6\n--orig-tcp-flags-set=\u003Cint|0xHEX|flaglist>                 ; устанавливать указанные tcp флаги (flags |= value). число , либо список через запятую : FIN,SYN,RST,PSH,ACK,URG,ECE,CWR,AE,R1,R2,R3\n--orig-tcp-flags-unset=\u003Cint|0xHEX|flaglist>               ; удалять указанные tcp флаги (flags &= ~value)\n--orig-mod-start=[n|d|s]N                                 ; применять orig-mod только в исходящих пакетах (n), пакетах данных (d), относительных sequence (s) по номеру больше или равно N\n--orig-mod-cutoff=[n|d|s]N                                ; применять orig-mod только в исходящих пакетах (n), пакетах данных (d), относительных sequence (s) по номеру меньше N\n--dup=\u003Cint>                                               ; высылать N дубликатов до оригинала\n--dup-replace=[0|1]                                       ; 1 или отсутствие аргумента блокирует отправку оригинала. отправляются только дубликаты.\n--dup-ttl=\u003Cint>                                           ; модифицировать TTL дубликатов\n--dup-ttl6=\u003Cint>                                          ; модифицировать ipv6 hop limit дубликатов. если не указано, используется значение --dup-ttl\n--dup-autottl=[\u003Cdelta>[:\u003Cmin>[-\u003Cmax>]]|-]                 ; режим auto ttl для ipv4 и ipv6. по умолчанию: +1:3-64. \"0:0-0\" или \"-\" отключает функцию\n--dup-autottl6=[\u003Cdelta>[:\u003Cmin>[-\u003Cmax>]]|-]                ; переопределение предыдущего параметра для ipv6\n--dup-tcp-flags-set=\u003Cint|0xHEX|flaglist>                  ; устанавливать указанные tcp флаги (flags |= value). число , либо список через запятую : FIN,SYN,RST,PSH,ACK,URG,ECE,CWR,AE,R1,R2,R3\n--dup-tcp-flags-unset=\u003Cint|0xHEX|flaglist>                ; удалять указанные tcp флаги (flags &= ~value)\n--dup-fooling=\u003Cfooling>                                   ; дополнительные методики как сделать, чтобы дубликат не дошел до сервера. none md5sig badseq badsum datanoack ts hopbyhop hopbyhop2\n--dup-ts-increment=\u003Cint|0xHEX>                            ; инкремент TSval для ts. по умолчанию -600000\n--dup-badseq-increment=\u003Cint|0xHEX>                        ; инкремент sequence number для badseq. по умолчанию -10000\n--dup-badack-increment=\u003Cint|0xHEX>                        ; инкремент ack sequence number для badseq. по умолчанию -66000\n--dup-ip-id=same|zero|seq|rnd                             ; режим назначения ip_id для пакетов dup\n--dup-start=[n|d|s]N                                      ; применять dup только в исходящих пакетах (n), пакетах данных (d), относительных sequence (s) по номеру больше или равно N\n--dup-cutoff=[n|d|s]N                                     ; применять dup только в исходящих пакетах (n), пакетах данных (d), относительных sequence (s) по номеру меньше N\n--hostcase                                                ; менять регистр заголовка \"Host:\" по умолчанию на \"host:\".\n--hostnospace                                             ; убрать пробел после \"Host:\" и переместить его в конец значения \"User-Agent:\" для сохранения длины пакета\n--methodeol                                               ; добавить перевод строки в unix стиле ('\\n') перед методом и убрать пробел из Host: : \"GET \u002F ... Host: domain.com\" => \"\\nGET  \u002F ... Host:domain.com\"\n--hostspell=HoST                                          ; точное написание заголовка Host (можно \"HOST\" или \"HoSt\"). автоматом включает --hostcase\n--domcase                                                 ; домен после Host: сделать таким : TeSt.cOm\n--ip-id=seq|seqgroup|rnd|zero                             ; режим назначения ip_id для генерированных пакетов\n--dpi-desync=[\u003Cmode0>,]\u003Cmode>[,\u003Cmode2]                    ; атака по десинхронизации DPI. mode : synack syndata fake fakeknown rst rstack hopbyhop destopt ipfrag1 multisplit multidisorder fakedsplit hostfakesplit fakeddisorder ipfrag2 udplen tamper\n--dpi-desync-fwmark=\u003Cint|0xHEX>                           ; бит fwmark для пометки десинхронизирующих пакетов, чтобы они повторно не падали в очередь. default = 0x40000000\n--dpi-desync-ttl=\u003Cint>                                    ; установить ttl для десинхронизирующих пакетов\n--dpi-desync-ttl6=\u003Cint>                                   ; установить ipv6 hop limit для десинхронизирующих пакетов. если не указано, используется значение --dpi-desync-ttl\n--dpi-desync-autottl=[\u003Cdelta>[:\u003Cmin>[-\u003Cmax>]]|-]          ; режим auto ttl для ipv4 и ipv6. по умолчанию: 1:3-20. \"0:0-0\" или \"-\" отключает функцию\n--dpi-desync-autottl6=[\u003Cdelta>[:\u003Cmin>[-\u003Cmax>]]|-]         ; переопределение предыдущего параметра для ipv6\n--dpi-desync-tcp-flags-set=\u003Cint|0xHEX|flaglist>           ; устанавливать указанные tcp флаги (flags |= value). число , либо список через запятую : FIN,SYN,RST,PSH,ACK,URG,ECE,CWR,AE,R1,R2,R3\n--dpi-desync-tcp-flags-unset=\u003Cint|0xHEX|flaglist>         ; удалять указанные tcp флаги (flags &= ~value)\n--dpi-desync-fooling=\u003Cfooling>                            ; дополнительные методики как сделать, чтобы фейковый пакет не дошел до сервера. none md5sig badseq badsum datanoack ts hopbyhop hopbyhop2\n--dpi-desync-repeats=\u003CN>                                  ; посылать каждый генерируемый в nfqws пакет N раз (не влияет на остальные пакеты)\n--dpi-desync-skip-nosni=0|1                               ; 1(default)=не применять dpi desync для запросов без hostname в SNI, в частности для ESNI\n--dpi-desync-split-pos=N|-N|marker+N|marker-N             ; список через запятую маркеров для tcp сегментации в режимах split и disorder\n--dpi-desync-split-seqovl=N|-N|marker+N|marker-N          ; единичный маркер, определяющий величину перекрытия sequence в режимах split и disorder. для split поддерживается только положительное число.\n--dpi-desync-split-seqovl-pattern=[+ofs]@\u003Cfilename>|0xHEX ; чем заполнять фейковую часть overlap\n--dpi-desync-fakedsplit-pattern=[+ofs]@\u003Cfilename>|0xHEX   ; чем заполнять фейки в fakedsplit\u002Ffakeddisorder\n--dpi-desync-fakedsplit-mod=mod[,mod]                     ; может быть none, altorder=0|1|2|3 + 0|8|16\n--dpi-desync-hostfakesplit-midhost=marker+N|marker-N      ; маркер дополнительного разреза сегмента с оригинальным хостом. должен попадать в пределы хоста.\n--dpi-desync-hostfakesplit-mod=mod[,mod]                  ; может быть none, host=\u003Chostname>, altorder=0|1\n--dpi-desync-ipfrag-pos-tcp=\u003C8..9216>                     ; позиция ip фрагментации tcp, начиная с транспортного заголовка. должно быть кратно 8, по умолчанию - 32.\n--dpi-desync-ipfrag-pos-udp=\u003C8..9216>                     ; позиция ip фрагментации udp, начиная с транспортного заголовка. должно быть кратно 8, по умолчанию - 8.\n--dpi-desync-ts-increment=\u003Cint|0xHEX>                     ; инкремент TSval для ts. по умолчанию -600000\n--dpi-desync-badseq-increment=\u003Cint|0xHEX>                 ; инкремент sequence number для badseq. по умолчанию -10000\n--dpi-desync-badack-increment=\u003Cint|0xHEX>                 ; инкремент ack sequence number для badseq. по умолчанию -66000\n--dpi-desync-any-protocol=0|1                             ; 0(default)=работать только по http request и tls clienthello  1=по всем непустым пакетам данных\n--dpi-desync-fake-tcp-mod=mod[,mod]                       ; список через запятую режимов runtime модификации tcp фейков (любых) : none, seq\n--dpi-desync-fake-http=[+ofs]@\u003Cfilename>|0xHEX\t          ; файл, содержащий фейковый http запрос для dpi-desync=fake, на замену стандартному www.iana.org\n--dpi-desync-fake-tls=[+ofs]@\u003Cfilename>|0xHEX|![+offset]  ; файл, содержащий фейковый tls clienthello для dpi-desync=fake, на замену стандартному. '!' = стандартный фейк\n--dpi-desync-fake-tls-mod=mod[,mod]                       ; список через запятую режимов runtime модификации фейков : none,rnd,rndsni,sni=\u003Csni>,dupsid,padencap\n--dpi-desync-fake-unknown=[+ofs]@\u003Cfilename>|0xHEX         ; файл, содержащий фейковый пейлоад неизвестного протокола для dpi-desync=fake, на замену стандартным нулям 256 байт\n--dpi-desync-fake-syndata=[+ofs]@\u003Cfilename>|0xHEX         ; файл, содержащий фейковый пейлоад пакета SYN для режима десинхронизации syndata\n--dpi-desync-fake-quic=[+ofs]@\u003Cfilename>|0xHEX            ; файл, содержащий фейковый QUIC Initial\n--dpi-desync-fake-wireguard=[+ofs]@\u003Cfilename>|0xHEX       ; файл, содержащий фейковый wireguard handshake initiation\n--dpi-desync-fake-dht=[+ofs]@\u003Cfilename>|0xHEX             ; файл, содержащий фейковый пейлоад DHT протокола для dpi-desync=fake, на замену стандартным нулям 64 байт\n--dpi-desync-fake-discord=[+ofs]@\u003Cfilename>|0xHEX         ; файл, содержащий фейковый пейлоад Discord протокола нахождения IP адреса для голосовых чатов для dpi-desync=fake, на замену стандартным нулям 64 байт\n--dpi-desync-fake-stun=[+ofs]@\u003Cfilename>|0xHEX            ; файл, содержащий фейковый пейлоад STUN протокола для dpi-desync=fake, на замену стандартным нулям 64 байт\n--dpi-desync-fake-unknown-udp=[+ofs]@\u003Cfilename>|0xHEX     ; файл, содержащий фейковый пейлоад неизвестного udp протокола для dpi-desync=fake, на замену стандартным нулям 64 байт\n--dpi-desync-udplen-increment=\u003Cint>                       ; на сколько увеличивать длину udp пейлоада в режиме udplen\n--dpi-desync-udplen-pattern=[+ofs]@\u003Cfilename>|0xHEX       ; чем добивать udp пакет в режиме udplen. по умолчанию - нули\n--dpi-desync-start=[n|d|s]N                               ; применять dpi desync только в исходящих пакетах (n), пакетах данных (d), относительных sequence (s) по номеру больше или равно N\n--dpi-desync-cutoff=[n|d|s]N                              ; применять dpi desync только в исходящих пакетах (n), пакетах данных (d), относительных sequence (s) по номеру меньше N\n--hostlist=\u003Cfilename>                                     ; действовать только над доменами, входящими в список из filename. поддомены автоматически учитываются, если хост не начинается с '^'.\n                                                          ; в файле должен быть хост на каждой строке.\n                                                          ; список читается при старте и хранится в памяти в виде иерархической структуры для быстрого поиска.\n                                                          ; при изменении времени модификации файла он перечитывается автоматически по необходимости\n                                                          ; список может быть запакован в gzip. формат автоматически распознается и разжимается\n                                                          ; списков может быть множество. пустой общий лист = его отсутствие\n                                                          ; хосты извлекаются из Host: хедера обычных http запросов и из SNI в TLS ClientHello.\n--hostlist-domains=\u003Cdomain_list>                          ; фиксированный список доменов через зяпятую. можно использовать # в начале для комментирования отдельных доменов.\n--hostlist-exclude=\u003Cfilename>                             ; не применять дурение к доменам из листа. может быть множество листов. схема аналогична include листам.\n--hostlist-exclude-domains=\u003Cdomain_list>                  ; фиксированный список доменов через зяпятую. можно использовать # в начале для комментирования отдельных доменов.\n--hostlist-auto=\u003Cfilename>                                ; обнаруживать автоматически блокировки и заполнять автоматический hostlist (требует перенаправления входящего трафика)\n--hostlist-auto-fail-threshold=\u003Cint>                      ; сколько раз нужно обнаружить ситуацию, похожую на блокировку, чтобы добавить хост в лист (по умолчанию: 3)\n--hostlist-auto-fail-time=\u003Cint>                           ; все эти ситуации должны быть в пределах указанного количества секунд (по умолчанию: 60)\n--hostlist-auto-retrans-threshold=\u003Cint>                   ; сколько ретрансмиссий запроса считать блокировкой (по умолчанию: 3)\n--hostlist-auto-debug=\u003Clogfile>                           ; лог положительных решений по autohostlist. позволяет разобраться почему там появляются хосты.\n--new                                                     ; начало новой стратегии (новый профиль)\n--skip                                                    ; не использовать этот профиль . полезно для временной деактивации профиля без удаления параметров.\n--filter-l3=ipv4|ipv6                                     ; фильтр версии ip для текущей стратегии\n--filter-tcp=[~]port1[-port2]|*                           ; фильтр портов tcp для текущей стратегии. ~ означает инверсию. установка фильтра tcp и неустановка фильтра udp запрещает udp. поддерживается список через запятую.\n--filter-udp=[~]port1[-port2]|*                           ; фильтр портов udp для текущей стратегии. ~ означает инверсию. установка фильтра udp и неустановка фильтра tcp запрещает tcp. поддерживается список через запятую.\n--filter-l7=\u003Cproto>                                       ; фильтр протокола L6-L7. поддерживается несколько значений через запятую. proto : http tls quic wireguard dht discord stun unknown\n--filter-ssid=ssid1[,ssid2,ssid3,...]                     ; фильтр по имени wifi сети (только для linux)\n--ipset=\u003Cfilename>                                        ; включающий ip list. на каждой строчке ip или cidr ipv4 или ipv6. поддерживается множество листов и gzip. перечитка автоматическая.\n--ipset-ip=\u003Cip_list>                                      ; фиксированный список подсетей через запятую. можно использовать # в начале для комментирования отдельных подсетей.\n--ipset-exclude=\u003Cfilename>                                ; исключающий ip list. на каждой строчке ip или cidr ipv4 или ipv6. поддерживается множество листов и gzip. перечитка автоматическая.\n--ipset-exclude-ip=\u003Cip_list>                              ; фиксированный список подсетей через запятую. можно использовать # в начале для комментирования отдельных подсетей.\n```\n\n`--debug` позволяет выводить подробный лог действий на консоль, в syslog или в файл. Может быть важен порядок следования\nопций. `--debug` лучше всего указывать в самом начале. Опции анализируются последовательно. Если ошибка будет при\nпроверке опции, а до анализа `--debug` еще дело не дошло, то сообщения не будут выведены в файл или syslog. При\nлогировании в файл процесс не держит файл открытым. Ради каждой записи файл открывается и потом закрывается. Так что\nфайл можно удалить в любой момент, и он будет создан заново при первом же сообщении в лог. Но имейте в виду, что если вы\nзапускаете процесс под root, то будет сменен UID на не-root. В начале на лог файл меняется owner, иначе запись будет\nневозможна. Если вы потом удалите файл, и у процесса не будет прав на создание файла в его директории, лог больше не\nбудет вестись. Вместо удаления лучше использовать truncate. В шелле это можно сделать через команду \": >filename\"\n\nМногие параметры, загружающие двоичные данные из файлов, поддерживают загрузку из hex-строки или из файла.\nhex строка начинается с \"0x\". Имя файла можно писать как есть или использовать префикс \"@\".\nЕсли перед префиксом \"@\" указано \"+\u003Cчисло>\", то это означает смещение полезных данных внутри файла.\nФайл может загружаться целиком с нулевой позиции, к нему могут применяться модификации, требующие полного файла (TLS),\nно передача пойдет с позиции offset. offset должен быть меньше длины файла. Если к блоку данных применяется мод,\nкоторый уменьшает размер данных, и offset окажется не меньше новой длины данных, будет ошибка.\n\n### АТАКА ДЕСИНХРОНИЗАЦИИ DPI\n\nСуть ее в следующем. Берется оригинальный запрос, модифицируется, добавляется поддельная информация (фейки)\nтаким образом, чтобы ОС сервера передала серверному процессу оригинальный запрос в неизменном виде, а DPI увидел другое.\nТо, что он блокировать не станет. Сервер видит одно, DPI - другое. DPI не понимает, что передается запрещенный запрос и не блокирует его.\n\nЕсть арсенал возможностей, чтобы достичь такого результата.\nЭто может быть передача фейк пакетов, чтобы они дошли до DPI, но не дошли до сервера. Может использоваться фрагментация на уровне TCP (сегментация) или на уровне IP.\nЕсть атаки, основанные на игре с tcp sequence numbers или с перепутыванием порядка следования tcp сегментов.\nМетоды могут сочетаться в различных вариантах.\n\n### ФЕЙКИ\n\nФейки - это отдельные сгенерированные nfqws пакеты, несущие ложную информацию для DPI.\nОни либо не должны дойти до сервера, либо могут дойти, но должны быть им отброшены.\nИначе получается слом tcp соединения или нарушение целостности передаваемого потока, что гарантированно приводит к поломке ресурса.\nЕсть ряд методов для решения этой задачи.\n\n* `md5sig` добавляет TCP опцию **MD5 signature**. Работает не на всех серверах. Пакеты с md5 обычно отбрасывают только linux.\n  Требуется значительное увеличение длины tcp пакета, чтобы вместить tcp option. При обработке многосегментных запросов (TLS Kyber)\n  первый пакет идет полный под MTU. При fakedsplit\u002Ffakeddisorder на небольших позициях отдельные tcp сегменты достаточно велики, чтобы внедрение\n  md5 tcp option вызвало переполнение MTU и ошибку отправки \"message too long\". `nfqws` не умеет перераспределять данные между tcp сегментами,\n  поэтому надо или отказываться от kyber, или увеличивать сплит-позицию, или отказываться от fakedsplit\u002Ffakeddisorder.\n* `badsum` портит контрольную сумму TCP. Не сработает, если ваше устройство за NAT, который не пропускает пакеты с инвалидной суммой. Наиболее\n  распространенная настройка NAT роутера в Linux их не пропускает. На Linux построено большинство домашних роутеров.\n  Непропускание обеспечивается так : настройка ядра sysctl по умолчанию\n  `net.netfilter.nf_conntrack_checksum=1` заставляет conntrack проверять tcp и udp чексуммы входящих пакетов и\n  выставлять state INVALID для пакетов с инвалидной суммой. Обычно в правилах iptables вставляется правило для дропа\n  пакетов с состоянием INVALID в цепочке FORWARD. Совместное сочетание этих факторов приводит к непрохождению badsum\n  через такой роутер. В OpenWrt из коробки `net.netfilter.nf_conntrack_checksum=0`, в других роутерах часто нет, и не\n  всегда это можно изменить. Чтобы nfqws мог работать через роутер, нужно на нем выставить указанное значение sysctl в 0.\n  nfqws на самом роутере будет работать и без этой настройки, потому что чексумма локально созданных пакетов не\n  проверяется никогда. Если роутер за другим NAT, например провайдерским, и он не пропускает invalid packets вы ничего\n  не сможете с этим сделать. Но обычно провайдеры все же пропускают badsum. На некоторых адаптерах\u002Fсвитчах\u002Fдрайверах\n  принудительно включен rx-checksum offload, badsum пакеты отсекаются еще до получения в ОС. В этом случае если что-то и\n  можно сделать, то только модифицировать драйвер, что представляется задачей крайне нетривиальной. Установлено, что так\n  себя ведут некоторые роутеры на базе mediatek. badsum пакеты уходят с клиентской ОС, но роутером не видятся в br-lan\n  через tcpdump. При этом если nfqws выполняется на самом роутере, обход может работать. badsum нормально уходят с\n  внешнего интерфейса.\n* `badseq` увеличивает TCP sequence number на определенное значение, выводя его тем самым из TCP window.\n  Такие пакеты будут наверняка отброшены принимающим узлом, но так же и DPI, если он ориентируется на sequence\n  numbers. По умолчанию смещение seq выбирается -10000. Практика показала, что некоторые DPI не пропускают seq вне\n  определенного окна. Однако, такое небольшое смещение может вызвать проблемы при существенной потоковой передаче и\n  потере пакетов. Если вы используете `--dpi-desync-any-protocol`, может понадобиться установить badseq increment\n  0x80000000. Это обеспечит надежную гарантию, что поддельный пакет не вклинится в tcp window на сервере. Так же было\n  замечено, что badseq ломает логику некоторых DPI при анализе http, вызывая зависание соединения. Причем на тех же DPI\n  TLS с badseq работает нормально.\n* `TTL` казалось бы - лучший вариант, но он требует индивидуальной настройки под каждого провайдера. Если DPI находится\n  дальше локальных сайтов провайдера, то вы можете отрезать себе доступ к ним. Ситуация усугубляется наличием ТСПУ на\n  магистралах, что вынуждает делать TTL достаточно высоким, увеличивая риск пробоя фейка до сервера. Необходим ip\n  exclude list, заполняемый вручную. Вместе с ttl можно применять md5sig. Это ничего не испортит, зато дает неплохой\n  шанс работы сайтов, до которых \"плохой\" пакет дойдет по TTL. Если не удается найти автоматическое решение,\n  воспользуйтесь файлом `zapret-hosts-user-exclude.txt`. Некоторые стоковые прошивки роутеров фиксируют исходящий TTL,\n  без отключения этой опции через них работать не будет. КАКИМ СТОИТ ВЫБИРАТЬ TTL : найдите минимальное значение, при\n  котором обход еще работает. Это и будет номер хопа вашего DPI.\n* `hopbyhop` относится только к ipv6. Добавляется ipv6 extenstion header `hop-by-hop options`. В варианте `hopbyhop2`\n  добавляются 2 хедера, что является нарушением стандарта и гарантированно отбрасывается стеком протоколов во всех ОС.\n  Один хедер hop-by-hop принимается всеми ОС, однако на некоторых каналах\u002Fпровайдерах такие пакеты могут фильтроваться и\n  не доходить. Расчет идет на то, что DPI проанализирует пакет с hop-by-hop, но он либо не дойдет до адресата в силу\n  фильтров провайдера, либо будет отброшен сервером, потому что хедера два.\n* `datanoack` высылает фейки со снятым tcp флагом ACK. Сервера такое не принимают, а DPI может принять. Эта техника\n  может ломать NAT и не всегда работает с iptables, если используется masquerade, даже с локальной системы (почти всегда\n  на роутерах ipv4). На системах c iptables без masquerade и на nftables работает без ограничений. Экспериментально\n  выяснено, что многие провайдерские NAT не отбрасывают эти пакеты, потому работает даже с внутренним провайдерским IP.\n  Но linux NAT оно не пройдет, так что за домашним роутером эта техника скорее всего не сработает, но может сработать с него.\n  Может сработать и через роутер, если подключение по проводу, и на роутере включено аппаратное ускорение.\n* Манипуляция tcp флагами с помощью `--dpi-desync-tcp-flags-set` и `--dpi-desync-tcp-flags-unset`. Можно сделать инвалидное\n  сочетание флагов, которое сервер не примет, а DPI - примет. Например, установить SYN в фейках. Но это может работать не на всех серверах.\n  `datanoack` может быть заменен `--dpi-desync-tcp-flags-unset=ACK`.\n  Пакеты с инвалидными флагами могут отбрасываться, проходя через NAT.\n* `ts` прибавляет к значению TSval таймштампа tcp значение ts increment (по умолчанию -600000). Сервера отбрасывают пакеты\n  с TSval в определенных пределах. По практическим тестам инкремент должен быть где-то от -100 до -0x80000000.\n  timestamps генерирует клиентская ОС. В linux таймштампы включены по умолчанию, в windows выключены по умолчанию.\n  Можно включить через команду `netsh interface tcp set global timestamps=enabled`.\n  ts fooling требует, чтобы таймштампы были включены, иначе работать не будет. Включать надо на каждом клиентском устройстве.\n  TSecr оставляется без изменений. Так же требуется, чтобы сервер понимал timestamps, но это в большинстве случаев так.\n* `autottl`. Суть режима в автоматическом определении TTL, чтобы пакет почти наверняка прошел DPI и немного не дошел до\n  сервера (`--dpi-desync-autottl`). Или наоборот - TTL едва хватило, чтобы он все-таки дошел до сервера (см `--dup-autottl`, `--orig-autottl`).\n  Берутся базовые значения TTL 64,128,255, смотрится входящий пакет (да, требуется направить первый входящий пакет на nfqws !).\n  Вычисляется длина пути, прибавляется `delta`. delta может быть положительной или отрицательной.\n  Чтобы задать положительную дельту, нужно указать унарный знак **+** перед числом.\n  В случае его отсутствия или при наличии унарного знака **-** дельта считается отрицательной.\n  Если TTL вне диапазона min,max, то берутся значения min,max, чтобы вписаться в\n  диапазон. Если при этом дельта отрицательная и полученный TTL больше длины пути или дельта положительная и полученный TTL меньше длины пути,\n  то автоматизм не сработал и берутся фиксированные значения : `--dpi-desync-ttl`, `--orig-ttl`, `--dup-ttl`.\n  Техника позволяет решить вопрос, когда вся сеть перегорожена шлагбаумами (DPI, ТСПУ) везде где только\n  можно, включая магистралов. Но потенциально может давать сбои. Например, при асимметрии входящего и исходящего канала\n  до конкретного сервера. Некоторые сервера выдают нестандартный TTL (google), потому на них получается полная ерунда.\n  Если не учитывать подобные исключения, то на каких-то провайдерах эта техника будет работать неплохо, на других доставит больше проблем,\n  чем пользы. Где-то может потребоваться тюнинг параметров. Лучше использовать с дополнительным ограничителем.\n\nРежимы дурения могут сочетаться в любых комбинациях. `--dpi-desync-fooling` берет множество значений через запятую.\n\nВозможно задание множества фейков через повторение параметров `--dpi-desync-fake-???`, кроме `--dpi-desync-fake-syndata`.\nФейки будут отосланы в указанном порядке. `--dpi-desync-repeats` повторяет каждый отосланный фейк.\nИтоговый порядок будет такой : `fake1 fake1 fake1 fake2 fake2 fake2 fake3 fake3 fake3 .....`\n\n### МОДИФИКАЦИЯ ФЕЙКОВ\n\nЛюбые tcp фейки отправляются с исходным sequence по умолчанию, даже если их несколько.\nЕсли задать `--dpi-desync-fake-tcp-mod=seq`, то несколько фейков будут отправлены с увеличением sequence number таким образом,\nкак будто они являются tcp сегментами одного фейка.\n\nВ nfqws зашит базовый вариант фейка для TLS. Его можно переопределить опцией `--dpi-desync-fake-tls`.\nПереопределение фейков дает возможность использовать любые данные в качестве фейка для TLS.\nМожно использовать фейковый Client Hello с любым фингерпринтом и с любым SNI.\n\nНекоторые модификации можно делать в процессе выполнения с помощью `--dpi-desync-fake-tls-mod`.\nЧасть из них работает при обработке каждого TLS Client Hello и может подстраиваться под отправляемые данные.\nМодификации требуют наличия полного валидного TLS Client Hello в качестве фейка, они не работают с произвольными данными.\n\n * `none`. Не применять никакие модификации.\n * `rnd`. Рандомизировать поля `random` и `session id`. Выполняется на каждый запрос.\n * `dupsid`. Копировать `session ID` из передаваемого TLS Client Hello. Имеет приоритет над `rnd`. Выполняется на каждый запрос.\n * `rndsni`. Рандомизировать SNI. Если SNI >=7 символов, применяется случайный домен 2 уровня с известным TLD, иначе заполняется случайными символами без точки. Выполняется один раз при старте.\n * `sni=\u003Csni>`. Заменить sni на указанное значение. Макс длина SNI - 63 байта. Общая длина TLS фейка и длины в структуре TLS Client Hello меняются. Выполняется один раз при старте. Если сочетается с `rndsni`, выполняется до него.\n * `padencap`. Расширяется padding extension на размер передаваемого TLS Client Hello (включая многопакетный вариант с kyber). Если padding отсутствует, он добавляется в конец. Если присутствует - требуется, чтобы padding шел последним extension. Правятся все длины, чтобы создать видимость включения передаваемого TLS Client Hello в padding extension. Размер фейка не изменяется. Расчет идет на DPI, который не анализирует sequence numbers должным образом. Выполняется на каждый запрос.\n\nПо умолчанию если не задан собственный фейк для TLS используются модификации `rnd,rndsni,dupsid`. Если фейк задан, используется `none`.\nЭто соответствует поведению программы более старых версий с добавлением функции `dupsid`.\n\nЕсли задан режим модификации и имеется множество TLS фейков, к каждому из них применяется последний режим модификации.\nЕсли режим модификации задан после фейка, то он замещает предыдущий режим.\nТаким образом можно использовать разные режимы модификации для разных фейков.\nПри невозможности модифицировать фейк на этапе запуска программа завершается с ошибкой.\n\nЕсли сначала идет TLS фейк, для него задан режим однократной модификации, затем идет не TLS фейк, то будет ошибка.\nНужно использовать `--dpi-desync-fake-tls-mod=none'.\n\nПример : `--dpi-desync-fake-tls=iana_org.bin --dpi-desync-fake-tls-mod=rndsni --dpi-desync-fake-tls=0xaabbccdd --dpi-desync-fake-tls-mod=none'\n\n### TCP СЕГМЕНТАЦИЯ\n\n * `multisplit`. нарезаем запрос на указанных в `--dpi-desync-split-pos` позициях.\n * `multidisorder`. нарезаем запрос на указанных в `--dpi-desync-split-pos` позициях и отправляем в обратном порядке.\n * `fakedsplit`. различные варианты замешивания фейков и оригиналов в прямом порядке\n * `fakeddisorder`. различные варианты замешивания фейков и оригиналов в обратном порядке\n * `hostfakesplit` (altorder=0). фейкование части запроса с хостом : оригинал до хоста, фейк хоста, оригинал хоста (+ опционально нарезка маркером midhost), фейк хоста, оригинал после хоста\n * `hostfakesplit` (altorder=1). фейкование части запроса с хостом : оригинал до хоста, фейк хоста, оригинал после хоста, оригинал хоста (+опционально нарезка маркером midhost)\n * `fakeddisorder`. аналогично `fakedsplit`, только в обратном порядке : фейк 2-й части, 2 часть, фейк 2-й части, фейк 1-й части, 1 часть, фейк 1 части.\n\nДля `fakedsplit` и `fakeddisorder` предусмотрены вариации порядка следования сегментов.\nПараметр `--dpi-desync-fakedsplit-mod=altorder=N` задает число, влияющее на наличие отдельных фейков :\n\nРежимы altorder для `fakedsplit` для части многопакетного запроса, где есть сплит-позиция :\n * `altorder=0`. фейк 1-й части, 1 часть, фейк 1-й части, фейк 2-й части, 2 часть, фейк 2-й части\n * `altorder=1`. 1 часть, фейк 1-й части, фейк 2-й части, 2 часть, фейк 2-й части\n * `altorder=2`. 1 часть, фейк 2-й части, 2 часть, фейк 2-й части\n * `altorder=3`. 1 часть, фейк 2-й части, 2 часть\n\nРежимы altorder для `fakeddisorder` для части многопакетного запроса, где есть сплит-позиция :\n * `altorder=0`. фейк 2-й части, 2 часть, фейк 2-й части, фейк 1-й части, 1 часть, фейк 1-й части\n * `altorder=1`. 2 часть, фейк 2-й части, фейк 1-й части, 1 часть, фейк 1-й части\n * `altorder=2`. 2 часть, фейк 1-й части, 1 часть, фейк 1-й части\n * `altorder=3`. 2 часть, фейк 1-й части, 1 часть\n\nРежимы altorder для `fakedsplit` и `fakeddisorder` для части многопакетного запроса, где нет сплит-позиции :\n * `altorder=0`. фейк, оригинал, фейк\n * `altorder=8`. оригинал, фейк\n * `altorder=16`. оригинал\n\nИтоговое число `altorder=N` вычисляется как сумма чисел из этих двух групп. По умолчанию `altorder=0`.\n\nСодержимое фейков в `fakedsplit`\u002F`fakeddisorder` определяется параметром `--dpi-desync-fakedsplit-pattern` (по умолчанию 0x00).\nДанные фейков берутся из паттерна со смещением, соответствующим смещению отсылаемых частей, учитывая смещения пакетов в многопакетных запросах.\nРазмеры фейков соответствуют длинам отсылаемых частей.\nЦель этих режимов - максимально усложнить выявление оригинальных данных среди фейков.\n\nИспользование `fakedsplit` или `fakeddisorder` на TLS kyber с md5sig fooling может привести к ошибкам \"message too long\", если позиция сплита мала,\nпоскольку будет превышение MTU из-за md5 tcp option.\n\nРежим 'hostfakesplit' имеет задачу минимального вмешательства фейком - как раз по той части запроса, на основании которой DPI принимает решение о блокировке. Конкретно - имени хоста.\nПо умолчанию фейк хоста генерируется каждый раз случайно из набора `[a-z0-9]`. При длине более 7 символов за 3 символа до конца ставится точка, имитируя TLD, а последние 3 символа заполняются одним из нескольких известных TLD.\n\nМожно переопределить шаблон генерации с помощью `--dpi-desync-hostfakesplit-mod=host=\u003Chostname>`. В последнем случае справа всегда будет указанный hostname.\nСлева он будет дополнен до размера оригинального хоста как поддомен со случайными символами. Пример : \"www.networksolutions.com\" -> \"h8xmdba4tv7a8.google.com\".\nЕсли размер оригинального хоста меньше шаблона, шаблон будет порезан : \"habr.com\" -> \"ogle.com\".\nЕсли размер оригинального хоста больше шаблона на 1, получится инвалидный пустой поддомен : \"www.xxx.com\" => \".google.com\".\nПоэтому стоит использовать максимально короткие хосты из разрешенных : \"ya.ru\", \"vk.com\".\n\n`--dpi-desync-hostfakesplit-mod=altorder=1` позволяет сменить порядок следования частей на альтернативный вариант.\n`altorder=1` шлет фрагменты в таком порядке, чтобы при последовательной сборке сегментов на DPI он получил полностью собранный оригинал запроса с подмененным хостом.\nРеальный хост идет отдельным сегментом уже после. То есть в этом варианте применяется разновидность disorder. Сервер принимает фрагменты с нарушенным порядком sequence.\n\nОпционально можно разрезать оригинальный хост. Например, `--dpi-desync-hostfakesplit-midhost=midsld`. Позиция нарезки должна попадать внутрь хоста.\nМногопакетные запросы поддерживаются только, если исходная нарезка пакетов не включает позиции имени хоста. В последнем случае дурение отменяется.\n\nВариант `fakedsplit` имеет несколько альтернативных порядков нарезки - от 0 до 3. Режим задается в параметре `--dpi-desync-fakedsplit-mod=altorder=N`.\nКаждый следующий altorder убирает часть фейков.\n\nДля определения позиций нарезки используются маркеры.\n\n* **Абсолютный положительный маркер** - числовое смещение внутри пакета или группы пакетов от начала.\n* **Абсолютный отрицательный маркер** - числовое смещение внутри пакета или группы пакетов от следующего за концом байта. -1 указывает на последний байт.\n* **Относительный маркер** - положительное или отрицательное смещение относительно логической позиции внутри пакета или группы пакетов.\n\nОтносительные позиции :\n\n* **method** - начало метода HTTP ('GET', 'POST', 'HEAD', ...). Метод обычно всегда находится на позиции 0, но может сместиться из-за `--methodeol`. Тогда позиция может стать 1 или 2.\n* **host** - начало имени хоста в известном протоколе (http, TLS)\n* **endhost** - байт, следующий за последним байтом имени хоста\n* **sld** - начало домена 2 уровня в имени хоста\n* **endsld** - байт, следующий за последним байтом домена 2 уровня в имени хоста\n* **midsld** - середина домена 2 уровня в имени хоста\n* **sniext** - начало поля данных SNI extension в TLS. Любой extension состоит из 2-байтовых полей type и length, за ними идет поле данных.\n\nПример списка маркеров : `100,midsld,sniext+1,endhost-2,-10`.\n\nПри разбиении пакета первым делом происходит ресолвинг маркеров - нахождение всех указанных относительных позиций и применение смещений.\nЕсли относительная позиция отсутствует в текущем протоколе, такие позиции не применяются и отбрасываются.\nДальше происходит нормализация позиций относительно смещения текущего пакета в группе пакетов (многопакетные запросы TLS с kyber, например).\nВыкидываются все позиции, выходящие за пределы текущего пакета. Оставшиеся сортируются в порядке возрастания и удаляются дубли.\nВ вариантах `multisplit` и `multidisorder` если не осталось ни одной позиции, разбиение не происходит.\n\nВарианты `fakedsplit` и `fakeddisorder` применяют только одну позицию сплита. Ее поиск среди списка `--dpi-desync-split-pos` осуществляется особым образом.\nСначала сверяются все относительные маркеры. Если среди них найден подходящий, применяется он. В противном случае сверяются все абсолютные маркеры.\nЕсли и среди них ничего не найдено, применяется позиция 1.\n\nНапример, можно написать `--dpi-desync-split-pos=method+2,midsld,5`. Если протокол http, разбиение будет на позиции `method+2`.\nЕсли протокол TLS - на позиции `midsld`. Если протокол неизвестен и включено `--dpi-desync-any-protocol`, разбиение будет на позиции 5.\nЧтобы все было однозначнее, можно использовать разные профили для разных протоколов и указывать только одну позицию, которая точно есть в этом протоколе.\n\n### ПЕРЕКРЫТИЕ SEQUENCE NUMBERS\n\n`seqovl` добавляет в начало одного из TCP сегментов `seqovl` байт со смещенным в минус sequence number на величину `seqovl`.\nДля `split` - в начало первого сегмента, для `disorder` - в начало предпоследнего отсылаемого сегмента (второго в оригинальном порядке следования).\n\nВ случае `split` расчет идет на то, что предыдущий отсыл, если он был, уже попал в сокет серверного приложения, поэтому новая пришедшая часть лишь частично находится в\nпределах текущего окна (in-window). Спереди фейковая часть отбрасывается, а оставшаяся часть содержит оригинал и\nначинается с начала window, поэтому попадает в сокет. Серверное приложение получает все, что реально отсылает клиент,\nотбрасывая фейковую out-of-window часть. Но DPI не может этого понять, поэтому у него происходит sequence десинхронизация.\nОбязательно, чтобы первый сегмент вместе с `seqovl` не превысили длину MTU. Эта ситуация распознается автоматически в Linux, и `seqovl` отменяется.\nВ остальных системах ситуация не распознается, и это приведет к поломке соединения. Поэтому выбирайте первую позицию сплита и `seqovl` таким образом, чтобы MTU не был превышен в любом случае.\nИначе дурение может не работать или работать хаотично.\n\nДля `disorder` overlap идет на предпоследнюю отсылаемую часть пакета. \nДля простоты будем считать, что разбиение идет на 2 части, шлются они в порядке \"2 1\" при оригинальном порядке \"1 2\".\nОбязательно, чтобы `seqovl` был меньше позиции первого сплита, иначе все отосланное будет передано в сокет сразу же, включая фейк, ломая протокол прикладного уровня.\nТакая ситуация легко обнаруживается программой, и `seqovl` отменяется. Увеличение размера пакета невозможно в принципе.\nПри соблюдении условия 2-я часть пакета является полностью in-window, поэтому серверная ОС принимает ее целиком, включая фейк.\nНо поскольку начальная часть данных из 1 пакета еще не принята, то фейк и реальные данные остаются в памяти ядра, не отправляясь в серверное приложение.\nКак только приходит 1-я часть пакета, она переписывает фейковую часть в памяти ядра.\nЯдро получает данные из 1 и 2 части, поэтому далее идет отправка в сокет приложения.\nТаково поведение всех unix ОС, кроме solaris - оставлять последние принятые данные.\nWindows оставляет старые данные, поэтому disorder с seqovl будет приводить к зависаниям соединения\nпри работе с Windows серверами. Solaris практически мертв, windows серверов очень немного.\nМожно использовать листы при необходимости.\nМетод позволяет обойтись без fooling и TTL. Фейки перемешаны с реальным данными.\n`fakedsplit\u002Ffakeddisorder` по-прежнему добавляют дополнительные отдельные фейки.\n\n`seqovl` в варианте `split` может быть только абсолютным положительным значением, поскольку применяется только в первому пакету.\nВ варианте `disorder` допустимо применение всех вариантов маркеров.\nОни автоматически нормализуются к текущему пакету в серии. Можно сплитать на `midsld` и делать seqovl на `midsld-1`.\n\n### НАЗНАЧЕНИЕ IP_ID\n\nНекоторые DPI секут поле ipv4 заголовка ip_id. Защита заключается в распознавании нехарактерного для разных ОС порядка назначения ip_id,\nно характерного для некоторого anti-DPI софта. Обычно ОС инкрементируют ip_id для каждого следующего пакета.\nНапример, на ТСПУ повторение ненулевых ip_id фейка и не фейка вызывает триггер блока на диапазонах IP `googlevideo.com`.\n\nЕсли отсылаются фейки или дополнительные tcp сегменты, то в любом случае последовательность будет нарушена, поскольку ОС ничего не будет знать о всунутых фейках\nи не увеличит свой счетчик ip_id на количество фейков или дополнительных tcp сегментов.\nЧтобы сохранить последовательность, потребовалось бы перехватывать все соединение до конца, что очень затратно по ресурсам.\nПоэтому после отработки серии генерированных пакетов ip_id возвращается к тому значению, о котором знает ОС.\n\nПараметр `ip-id` относится к профилю и задает режим назначения ip_id при отсылке генерированных в nfqws пакетов.\n\n * `seq` (по умолчанию) : взять последний ip_id реального пакета. последующие генерированыне пакеты получают увеличенные на 1 ip_id, кроме случая `multidisorder`.\n для `multidisorder` в пределах сегментов, где есть сплит-позиции, значение ip_id увеличивается на количество частей, затем уменьшается на 1 с каждой отосланной частью.\n * `seqgroup` : то же, что и `seq`, но фейки того же размера, что и оригинальные сегменты, маскирующиеся под оригинал получают те же ip_id.\n * `rnd` : всем генерированным пакетам назначать случайный ip_id\n * `zero` : всем генерированным пакетам назначать ip_id=0 . в этом случае Linux и BSD отошлют 0, Windows назначит последовательные ip_id всем пакетам (тем самым автоматически решается проблема сбоя счетчика пакетов).\n\nВ заголовках ipv6 поле ip_id отсутствует, параметр игнорируется для ipv6.\n\n### СПЕЦИФИЧЕСКИЕ РЕЖИМЫ IPV6\n\nРежимы десинхронизации `hopbyhop`, `destopt` и `ipfrag1` (не путать с fooling !) относятся только к ipv6 и заключается\nв добавлении хедера `hop-by-hop options`, `destination options` или `fragment` во все пакеты, попадающие под десинхронизацию.\nЗдесь надо обязательно понимать, что добавление хедера увеличивает размер пакета, потому не может быть применено\nк пакетам максимального размера. Это имеет место при передаче больших сообщений.\nВ случае невозможности отослать пакет дурение будет отменено, пакет будет выслан в оригинале.\nРасчет идет на то, что DPI увидит 0 в поле next header основного заголовка `ipv6` и не будет скакать по\nextension хедерам в поисках транспортного хедера. Таким образом не поймет, что это tcp или udp, и пропустит пакет\nбез анализа. Возможно, какие-то DPI на это купятся.\nМожет сочетаться с любыми режимами 2-й фазы, кроме варианта `ipfrag1+ipfrag2`.\nНапример, `hopbyhop,multisplit` означает разбить tcp пакет на несколько сегментов, в каждый из них добавить hop-by-hop.\nПри `hopbyhop,ipfrag2` последовательность хедеров будет : `ipv6,hop-by-hop`,`fragment`,`tcp\u002Fudp`.\nРежим `ipfrag1` может срабатывать не всегда без специальной подготовки. См. раздел `IP фрагментация`.\n\n### МОДИФИКАЦИЯ ОРИГИНАЛА\n\nПараметры `--orig-ttl` и `--orig-ttl6` позволяют изменить TTL оригинальных пакетов.\nЕсли дальнейшие манипуляции связаны с оригиналом, например, идет TCP сегментация, то исходными\nданными являются измененные оригинальные пакеты. То есть в данном примере TCP сегменты пойдут с измененным TTL.\n\nВариант `--orig-autottl` и `--orig-autottl6` работает аналогично `dpi-desync-autottl`, но по оригинальным пакетам.\nДельту стоит указывать положительную с унарным знаком `+`, иначе оригинал не дойдет до сервера, и вы вообще ничего не получите.\nПример : `--orig-autottl=+5:3-64`.\n\n`--orig-mod-start` и `--orig-mod-cutoff` задают ограничитель по началу и концу модификации оригинала.\nСхема аналогична `--dpi-desync-start` и `--dpi-desync-cutoff`.\n\nФункция может быть полезна, когда DPI охотится за фейками и блокирует соединение при наличии подозрительных признаков,\nв частности, измененный TTL у фейка относительно оригинала.\n\n### ДУБЛИКАТЫ\n\nДубликаты - это копии оригинальных пакетов, высылаемые перед ними. Включаются параметром `--dup=N`, где N - количество дублей,\nне включающее оригинал. `--dup-replace` отключает отсылку оригинала.\n\nОтсылка дублей имеет место только в тех случаях, когда высылается и оригинал без реконструкции.\nНапример, если случилась TCP сегментация, то оригинал фактически дропается и заменяется искусственно сконструированными сегментами.\nДубли высланы не будут. Это же касается изменения состава хедеров ipv6, режима tamper для DHT и других.\n\nВозможно применение всех вариантов дурения, как и для desync : `--dup-ttl`. `--dup-ttl6`, `--dup-fooling`. Нужно ли, чтобы эти пакеты доходили до сервера и в каком виде, решаете вы согласно задуманной стратегии.\n\nВариант `--dup-autottl` и `--dup-autottl6` работает аналогично `dpi-desync-autottl`, но по дублям.\nДельту можно указывать положительную с унарным знаком `+`, а можно и отрицательную. Зависит от вашей задумки.\nПример : `--dup-autottl=-2:3-64`.\n\n`--dup-start` и `--dup-cutoff` задают ограничитель по началу и концу применения стратегии дубликатов.\nСхема аналогична `--dpi-desync-start` и `--dpi-desync-cutoff`.\n\nФункция может помочь, когда DPI сечет разницу в характеристиках фейков и оригинала.\nДубликатами можно попытаться заставить DPI принять , что весь сеанс идет аномальным.\nНапример, у нас имеется TCP сеанс с MD5 сразу с первого SYN пакета. Значит последующие MD5 будут восприниматься нормально.\n\n### КОМБИНИРОВАНИЕ МЕТОДОВ ДЕСИНХРОНИЗАЦИИ\n\nВ параметре dpi-desync можно указать до 3 режимов через запятую.\n\n* 0 фаза - предполагает работу на этапе установления соединения : `synack`, `syndata`, `--wsize`, `--wssize`. На эту фазу не действуют фильтры по [hostlist](#множественные-стратегии), кроме случая, описанного [далее](#кэш-ip).\n* 1 фаза - отсылка чего-либо до оригинального пакета данных : `fake`, `rst`, `rstack`.\n* 2 фаза - отсылка в модифицированном виде оригинального пакета данных (например, `fakedsplit` или `ipfrag2`).\n\nРежимы требуют указания в порядке возрастания номеров фаз.\n\n### КЭШ IP\n\nipcache представляет собой структуру в памяти процесса, позволяющую по ключу IP адреса и имени интерфейса запоминать некоторую информацию,\nкоторую впоследствии можно извлечь и использовать как недостающие данные. На текущий момент это применяются в следующих ситуациях :\n\n1. IP,interface => hop count . Кэшируется количество хопов до сервера для последующего применения в autottl прямо с первого пакета, когда еще ответа не было. Пока записи в кэше нет, autottl не будет применен сразу. При повторном запросе до истечения времени жизни записи autottl будет применение сразу.\n\n2. IP => hostname . Кэшируется имя хоста, вне привязки к интерфейсу, для последующего применения в стратегиях нулевой фазы. Режим отключен по умолчанию и включается через параметры `ipcache-hostname`.\nДанная техника является экспериментальной. Ее проблема в том, что как такового нет однозначного соответствия между доменом и IP. Множество доменов могут ссылаться на тот же IP адрес.\nПри коллизии происходит замещение имени хоста на последний вариант.\nДомен может скакать по разным IP на CDN. Сейчас один адрес, через час - другой. Эта проблема решается через время жизни записей кэша : `--ipcache-lifetime`. По умолчанию 2 часа.\nОднако, может случиться и так, что в вашем случае применение техники несет больше пользы, чем проблем. Будьте готовы к непонятному на первый взгляд поведению, которое может быть исследовано только через `--debug` лог.\n\nПри подаче сигнала SIGUSR2 процесс выводит содержимое ipcache на консоль.\n\n### РЕАКЦИЯ DPI НА ОТВЕТ СЕРВЕРА\n\nЕсть DPI, которые анализируют ответы от сервера, в частности сертификат из ServerHello, где прописаны домены.\nПодтверждением доставки ClientHello является ACK пакет от сервера с номером ACK sequence, соответствующим длине ClientHello+1.\nВ варианте disorder обычно приходит сперва частичное подтверждение (SACK), потом полный ACK.\nЕсли вместо ACK или SACK идет RST пакет с минимальной задержкой, то DPI вас отсекает еще на этапе вашего запроса.\nЕсли RST идет после полного ACK спустя задержку, равную примерно пингу до сервера,\nтогда вероятно DPI реагирует на ответ сервера.\nDPI может отстать от потока, если ClientHello его удовлетворил и не проверять ServerHello.\nТогда вам повезло. Вариант fake может сработать.\nЕсли же он не отстает и упорно проверяет ServerHello, то можно попробовать заставить сервер высылать ServerHello частями\nчерез параметр `--wssize` (см. conntrack).\nЕсли и это не помогает, то сделать с этим что-либо вряд ли возможно без помощи со стороны сервера.\nЛучшее решение - включить на сервере поддержку TLS 1.3. В нем сертификат сервера передается в зашифрованном виде.\nЭто рекомендация ко всем админам блокируемых сайтов. Включайте TLS 1.3. Так вы дадите больше возможностей преодолеть DPI.\n\n### РЕЖИМ SYNACK\n\nВ документации по geneva это называется \"TCB turnaround\". Попытка ввести DPI в заблуждение относительно\nролей клиента и сервера.\n\nПоскольку режим нарушает работу NAT, техника может сработать только если между атакующим устройством\nи DPI нет NAT. Атака не сработает через NAT роутер, но может сработать с него.\nДля реализации атаки на проходящий трафик требуются nftables и схема [POSTNAT](#nftables-для-nfqws).\n\n### РЕЖИМ SYNDATA\n\nТут все просто. Добавляются данные в пакет SYN. Все ОС их игнорируют, если не используется TCP fast open (TFO),\nа DPI может воспринять, не разобравшись есть там TFO или нет.\nОригинальные соединения с TFO не трогаются, поскольку это их точно сломает.\nБез уточняющего параметра добавляются 16 нулевых байтов.\n\n### ВИРТУАЛЬНЫЕ МАШИНЫ\n\nИзнутри VM от virtualbox и vmware в режиме NAT не работают многие техники пакетной магии nfqws.\nПринудительно заменяется ttl, не проходят фейк пакеты. Необходимо настроить сеть в режиме bridge.\n\n### CONNTRACK\n\nnfqws оснащен ограниченной реализацией слежения за состоянием tcp соединений (conntrack).\nОн включается для реализации некоторых методов противодействия DPI.\nconntrack способен следить за фазой соединения : SYN,ESTABLISHED,FIN, количеством пакетов в каждую сторону,\nsequence numbers. conntrack способен \"кормиться\" пакетами в обе или только в одну сторону.\nСоединение попадает в таблицу при обнаружении пакетов с выставленными флагами SYN или SYN,ACK.\nПоэтому если необходим conntrack, в правилах перенаправления iptables соединение должно идти на nfqws с самого первого\nпакета, хотя затем может обрываться по фильтру connbytes.\nДля UDP инициатором попадания в таблицу является первый UDP пакет. Он же и определяет направление потока.\nСчитается, что первый UDP пакет исходит от клиента к серверу. Далее все пакеты с совпадающими\n`src_ip,src_port,dst_ip,dst_port` считаются принадлежащими этому потоку до истечения времени неактивности.\nconntrack - простенький, он не писался с учетом всевозможных атак на соединение, он не проверяет\nпакеты на валидность sequence numbers или чексумму. Его задача - лишь обслуживание нужд nfqws, он обычно\nкормится только исходящим трафиком, потому нечувствителен к подменам со стороны внешней сети.\nСоединение удаляется из таблицы, как только отпадает нужда в слежении за ним или по таймауту неактивности.\nСуществуют отдельные таймауты на каждую фазу соединения. Они могут быть изменены параметром `--ctrack-timeouts`.\n\n`--wssize` позволяет изменить с клиента размер tcp window для сервера, чтобы он послал следующие ответы разбитыми на части.\nЧтобы это подействовало на все серверные ОС, необходимо менять window size в каждом исходящем с клиента пакете до отсылки сообщения,\nответ на которое должен быть разбит (например, TLS ClientHello). Именно поэтому и необходим conntrack, чтобы\nзнать когда надо остановиться. Если не остановиться и все время устанавливать низкий wssize, скорость упадет катастрофически.\nВ linux это может быть купировано через connbytes, но в BSD системах такой возможности нет.\nВ случае http(s) останавливаемся сразу после отсылки первого http запроса или TLS ClientHello.\nЕсли вы имеете дело с не http(s), то вам потребуется параметр `--wssize-cutoff`. Он устанавливает предел, с которого действие\nwssize прекращается. Префикс d перед номером означает учитывать только пакеты с data payload, префикс s - relative sequence number,\nпроще говоря количество переданных клиентом байтов + 1.\nЕсли проскочит пакет с http request или TLS ClientHello, действие wssize прекращается сразу же, не дожидаясь wssize-cutoff,\nесли не указан параметр `--wssize-forced-cutoff=0`.\nЕсли ваш протокол склонен к долгому бездействию, следует увеличить таймаут фазы ESTABLISHED через параметр `--ctrack-timeouts`.\nТаймаут по умолчанию низкий - всего 5 минут.\nНе забывайте, что nfqws кормится приходящими на него пакетами. Если вы ограничили поступление пакетов через connbytes,\nто в таблице могут остаться повисшие соединения в фазе ESTABLISHED, которые отвалятся только по таймауту.\nДля диагностики состояния conntrack пошлите сигнал SIGUSR1 процессу nfqws : `killall -SIGUSR1 nfqws`.\nТекущая таблица будет выведена nfqws в stdout.\n\nОбычно в SYN пакете клиент отсылает кроме window size еще и TCP extension `scaling factor`.\n**scaling factor** представляет из себя степень двойки, на которую умножается window size : 0=>1, 1=>2, 2=>4, ..., 8=>256, ...\nВ параметре wssize scaling factor указывается через двоеточие.\nScaling factor может только снижаться, увеличение заблокировано, чтобы не допустить превышение размера окна со стороны сервера.\nДля принуждения сервера к фрагментации ServerHello, чтобы избежать просекание имени сервера из сертификата сервера на DPI,\nлучше всего использовать `--wssize=1:6`. Основное правило - делать `scale_factor` как можно больше, чтобы после восстановления\nwindow size итоговый размер окна стал максимально возможным. Если вы сделаете 64:0, будет очень медленно.\nС другой стороны нельзя допустить, чтобы ответ сервера стал достаточно большим, чтобы DPI нашел там искомое.\n\n`--wssize` не работает в профилях с хостлистами, поскольку он действует с самого начала соединения, когда еще нельзя\nпринять решение о попадании в лист. Однако, профиль с auto hostlist может содержать --wssize.\n`--wssize` может замедлять скорость и\u002Fили увеличивать время ответа сайтов, поэтому если есть другие работающие способы\nобхода DPI, лучше применять их.\n\n`--dpi-desync-cutoff` позволяет задать предел, при достижении которого прекращается применение dpi-desync.\nДоступны префиксы n,d,s по аналогии с `--wssize-cutoff`.\nПолезно совместно с `--dpi-desync-any-protocol=1`.\nНа склонных к бездействию соединениях следует изменить таймауты conntrack.\nЕсли соединение выпало из conntrack и задана опция `--dpi-desync-cutoff`, `dpi desync` применяться не будет.\n\n### РЕАССЕМБЛИНГ\n\nnfqws поддерживает реассемблинг некоторых видов запросов.\nНа текущий момент это TLS и QUIC ClientHello. Они бывают длинными, если в chrome включить пост-квантовую\nкриптографию tls-kyber, и занимают, как правило, 2 или 3 пакета. kyber включен по умолчанию, начиная с chromium 124.\nchrome рандомизирует фингерпринт TLS. SNI может оказаться как в начале, так и в конце, то есть\nпопасть в любой пакет. stateful DPI обычно реассемблирует запрос целиком, и только потом\nпринимает решение о б","zapret 是一个用于绕过深度包检测（DPI）的多平台开源工具。它通过多种技术手段实现对网络流量的混淆和伪装，从而帮助用户规避网络审查和封锁。项目支持包括 Linux、macOS、Windows 在内的多种操作系统，并且具有丰富的功能特性，如 TCP 分段、序列号重叠、IP 碎片化等，能够有效对抗 DPI 的检测。zapret 适用于需要绕过网络审查或访问受限内容的场景，尤其适合在存在严格互联网管控的环境中使用。需要注意的是，当前版本已进入维护模式，不再添加新功能，仅修复已知问题。",2,"2026-06-11 03:05:43","top_language"]