Zapret est gratuit et open source. Quiconque vous oblige à télécharger Zapret uniquement à partir de sa ressource nécessite de supprimer des liens, des vidéos, des fichiers, justifiant ces exigences de droit d'auteur, lui-même viole la licence.
DPI de contre-DPI autonome, qui ne nécessite pas de connexion de serveurs tiers. Il peut aider à contourner les verrous ou la décélération des sites HTTP (s), l'analyse signature des protocoles TCP et UDP, par exemple, dans le but de bloquer le VPN.
Le projet vise principalement les dispositifs intégrés à faible puissance - routeurs travaillant sous OpenWRT. Les systèmes Linux traditionnels, FreeBSD, OpenBSD, partiellement macOS sont pris en charge. Dans certains cas, un vision indépendant de la solution à divers firmware est possible.
La plupart des fonctionnalités fonctionnent sur Windows.
Dans le cas le plus simple, vous avez affaire à un DPI passif. Le DPI passif peut lire le trafic à partir du flux, peut injecter ses packages, mais ne peut pas bloquer les packages de passage. Si la demande est "mauvaise", l'injection de DPI passive du premier package, la complétant éventuellement avec le package de redirection HTTP. Si le faux package est injecté uniquement pour le client, dans ce cas, vous pouvez vous débrouiller avec les commandes iptables pour la chute de RST et / ou rediriger vers la prise en fonction de certaines conditions qui doivent être sélectionnées pour chaque fournisseur individuellement. Nous faisons donc le tour des conséquences de l’opération du déclencheur. Si un DPI passif dirige le premier package, y compris le serveur, vous ne pouvez rien y faire. Votre tâche consiste à empêcher le déclencheur du déclencheur du déclencheur. Les iptables seuls ne se débrouilleront pas. Ce projet vise précisément à empêcher l'interdiction et à ne pas éliminer ses conséquences.
Le DPI actif est placé dans une incision du fil et peut supprimer les packages en fonction de tous les critères, y compris reconnaître les flux TCP et bloquer tous les packages appartenant à l'écoulement.
Comment empêcher le déclencheur de l'interdiction de l'interdiction? Envoyez quelque chose sur lequel DPI ne compte pas et que l'algorithme pour la reconnaissance des demandes et leur blocage le brise.
Certains DPI ne peuvent pas reconnaître la demande HTTP s'il est divisé en segments TCP. Par exemple, une demande du type GET / HTTP/1.1rnHost: kinozal.tv...... nous envoyons 2 parties: d'abord il y a GET , alors / HTTP/1.1rnHost: kinozal.tv..... autre DPI stémasse lorsque l'en-tête Host: est écrit dans un autre registre: par exemple, host: . À certains endroits, l'ajout d'un écart supplémentaire après la méthode: GET / => GET / ou ajout d'un point à la fin du nom d'hôte: Host: kinozal.tv.
Il existe également une magie plus avancée visant à surmonter le DPI au niveau du package.
En savoir plus sur DPI:
https://habr.com/en/post/335436 ou https://web.archive.org/web/2023033123644/https://habr.com/en/post/335436/
https://geneva.cs.umd.edu/papers/geneva_ccs19.pdf
Auparavant, avant l'introduction de systèmes Universal TSPU, un zoo de divers DPI pour les fournisseurs a été utilisé. Certains étaient actifs, une sorte de passive. Maintenant, le temps des iptables simples a finalement disparu. Partout, il y a un DPI TSPU actif, mais à certains endroits, un ancien DPI supplémentaire du zoo peut rester inutile. Dans ce cas, vous devez faire le tour de plusieurs DPI à la fois. De plus en plus de serrures confiées sont en train de devenir, dont vous n'apprendrez que par le fait de l'inaccessibilité de quelque chose, ce n'est pas dans les listes. Des cloutes de certaines des adresses IP sont utilisées (le contournement autonome est impossible) et les protocoles (VPN). Certaines gammes IP utilisent un filtre plus strict qui reconnaît les tentatives de tricher par segmentation. Cela doit être dû à certains services qui tentent de tromper DPI de cette manière.
En bref, les options peuvent être classées selon le schéma suivant:
Pour les options 2 et 3, les programmes TPWS et NFQWS sont mis en œuvre, respectivement. Pour qu'ils fonctionnent, il est nécessaire de les exécuter avec les paramètres souhaités et de rediriger un certain trafic vers eux par les iptables ou les nftabals.
Ce programme est un modificateur de package et le gestionnaire de file d'attente NFQueue. Pour les systèmes BSD, il existe une version adaptée - DVTWS, collectée à partir des mêmes sources (voir la documentation BSD).
@<config_file>|$<config_file> ; читать конфигурацию из файла. опция должна быть первой. остальные опции игнорируются.
--debug=0|1 ; 1=выводить отладочные сообщения
--dry-run ; проверить опции командной строки и выйти. код 0 - успешная проверка.
--comment ; любой текст (игнорируется)
--daemon ; демонизировать прогу
--pidfile=<file> ; сохранить PID в файл
--user=<username> ; менять uid процесса
--uid=uid[:gid] ; менять uid процесса
--qnum=N ; номер очереди N
--bind-fix4 ; пытаться решить проблему неверного выбора исходящего интерфейса для сгенерированных ipv4 пакетов
--bind-fix6 ; пытаться решить проблему неверного выбора исходящего интерфейса для сгенерированных ipv6 пакетов
--wsize=<winsize>[:<scale_factor>] ; менять tcp window size на указанный размер в SYN,ACK. если не задан scale_factor, то он не меняется (устарело !)
--wssize=<winsize>[:<scale_factor>] ; менять tcp window size на указанный размер в исходящих пакетах. scale_factor по умолчанию 0. (см. conntrack !)
--wssize-cutoff=[n|d|s]N ; изменять server window size в исходящих пакетах (n), пакетах данных (d), относительных sequence (s) по номеру меньше N
--ctrack-timeouts=S:E:F[:U] ; таймауты внутреннего conntrack в состояниях SYN, ESTABLISHED, FIN, таймаут udp. по умолчанию 60:300:60:60
--hostcase ; менять регистр заголовка "Host:" по умолчанию на "host:".
--hostnospace ; убрать пробел после "Host:" и переместить его в конец значения "User-Agent:" для сохранения длины пакета
--methodeol ; добавить перевод строки в unix стиле ('n') перед методом и убрать пробел из Host: : "GET / ... Host: domain.com" => "nGET / ... Host:domain.com"
--hostspell=HoST ; точное написание заголовка Host (можно "HOST" или "HoSt"). автоматом включает --hostcase
--domcase ; домен после Host: сделать таким : TeSt.cOm
--dpi-desync=[<mode0>,]<mode>[,<mode2] ; атака по десинхронизации DPI. mode : synack syndata fake fakeknown rst rstack hopbyhop destopt ipfrag1 multisplit multidisorder fakedsplit fakeddisorder ipfrag2 udplen tamper
--dpi-desync-fwmark=<int|0xHEX> ; бит fwmark для пометки десинхронизирующих пакетов, чтобы они повторно не падали в очередь. default = 0x40000000
--dpi-desync-ttl=<int> ; установить ttl для десинхронизирующих пакетов
--dpi-desync-ttl6=<int> ; установить ipv6 hop limit для десинхронизирующих пакетов. если не указано, используется значение ttl
--dpi-desync-autottl=[<delta>[:<min>[-<max>]]] ; режим auto ttl для ipv4 и ipv6. по умолчанию: 1:3-20. delta=0 отключает функцию.
--dpi-desync-autottl6=[<delta>[:<min>[-<max>]]] ; переопределение предыдущего параметра для ipv6
--dpi-desync-fooling=<fooling> ; дополнительные методики как сделать, чтобы фейковый пакет не дошел до сервера. none md5sig badseq badsum datanoack hopbyhop hopbyhop2
--dpi-desync-repeats=<N> ; посылать каждый генерируемый в nfqws пакет N раз (не влияет на остальные пакеты)
--dpi-desync-skip-nosni=0|1 ; 1(default)=не применять dpi desync для запросов без hostname в SNI, в частности для ESNI
--dpi-desync-split-pos=N|-N|marker+N|marker-N ; список через запятую маркеров для tcp сегментации в режимах split и disorder
--dpi-desync-split-seqovl=N|-N|marker+N|marker-N ; единичный маркер, определяющий величину перекрытия sequence в режимах split и disorder. для split поддерживается только положительное число.
--dpi-desync-split-seqovl-pattern=<filename>|0xHEX ; чем заполнять фейковую часть overlap
--dpi-desync-fakedsplit-pattern=<filename>|0xHEX ; чем заполнять фейки в fakedsplit/fakeddisorder
--dpi-desync-badseq-increment=<int|0xHEX> ; инкремент sequence number для badseq. по умолчанию -10000
--dpi-desync-badack-increment=<int|0xHEX> ; инкремент ack sequence number для badseq. по умолчанию -66000
--dpi-desync-any-protocol=0|1 ; 0(default)=работать только по http request и tls clienthello 1=по всем непустым пакетам данных
--dpi-desync-fake-http=<filename>|0xHEX ; файл, содержащий фейковый http запрос для dpi-desync=fake, на замену стандартному www.iana.org
--dpi-desync-fake-tls=<filename>|0xHEX ; файл, содержащий фейковый tls clienthello для dpi-desync=fake, на замену стандартному
--dpi-desync-fake-unknown=<filename>|0xHEX ; файл, содержащий фейковый пейлоад неизвестного протокола для dpi-desync=fake, на замену стандартным нулям 256 байт
--dpi-desync-fake-syndata=<filename>|0xHEX ; файл, содержащий фейковый пейлоад пакета SYN для режима десинхронизации syndata
--dpi-desync-fake-quic=<filename>|0xHEX ; файл, содержащий фейковый QUIC Initial
--dpi-desync-fake-dht=<filename>|0xHEX ; файл, содержащий фейковый пейлоад DHT протокола для dpi-desync=fake, на замену стандартным нулям 64 байт
--dpi-desync-fake-unknown-udp=<filename>|0xHEX ; файл, содержащий фейковый пейлоад неизвестного udp протокола для dpi-desync=fake, на замену стандартным нулям 64 байт
--dpi-desync-udplen-increment=<int> ; насколько увеличивать длину udp пейлоада в режиме udplen
--dpi-desync-udplen-pattern=<filename>|0xHEX ; чем добивать udp пакет в режиме udplen. по умолчанию - нули
--dpi-desync-start=[n|d|s]N ; применять dpi desync только в исходящих пакетах (n), пакетах данных (d), относительных sequence (s) по номеру больше или равно N
--dpi-desync-cutoff=[n|d|s]N ; применять dpi desync только в исходящих пакетах (n), пакетах данных (d), относительных sequence (s) по номеру меньше N
--hostlist=<filename> ; действовать только над доменами, входящими в список из filename. поддомены автоматически учитываются.
; в файле должен быть хост на каждой строке.
; список читается при старте и хранится в памяти в виде иерархической структуры для быстрого поиска.
; при изменении времени модификации файла он перечитывается автоматически по необходимости
; список может быть запакован в gzip. формат автоматически распознается и разжимается
; списков может быть множество. пустой общий лист = его отсутствие
; хосты извлекаются из Host: хедера обычных http запросов и из SNI в TLS ClientHello.
--hostlist-domains=<domain_list> ; фиксированный список доменов через зяпятую. можно использовать # в начале для комментирования отдельных доменов.
--hostlist-exclude=<filename> ; не применять дурение к доменам из листа. может быть множество листов. схема аналогична include листам.
--hostlist-exclude-domains=<domain_list> ; фиксированный список доменов через зяпятую. можно использовать # в начале для комментирования отдельных доменов.
--hostlist-auto=<filename> ; обнаруживать автоматически блокировки и заполнять автоматический hostlist (требует перенаправления входящего трафика)
--hostlist-auto-fail-threshold=<int> ; сколько раз нужно обнаружить ситуацию, похожую на блокировку, чтобы добавить хост в лист (по умолчанию: 3)
--hostlist-auto-fail-time=<int> ; все эти ситуации должны быть в пределах указанного количества секунд (по умолчанию: 60)
--hostlist-auto-retrans-threshold=<int> ; сколько ретрансмиссий запроса считать блокировкой (по умолчанию: 3)
--hostlist-auto-debug=<logfile> ; лог положительных решений по autohostlist. позволяет разобраться почему там появляются хосты.
--new ; начало новой стратегии (новый профиль)
--skip ; не использовать этот профиль . полезно для временной деактивации профиля без удаления параметров.
--filter-l3=ipv4|ipv6 ; фильтр версии ip для текущей стратегии
--filter-tcp=[~]port1[-port2]|* ; фильтр портов tcp для текущей стратегии. ~ означает инверсию. установка фильтра tcp и неустановка фильтра udp запрещает udp. поддерживается список через запятую.
--filter-udp=[~]port1[-port2]|* ; фильтр портов udp для текущей стратегии. ~ означает инверсию. установка фильтра udp и неустановка фильтра tcp запрещает tcp. поддерживается список через запятую.
--filter-l7=[http|tls|quic|wireguard|dht|unknown] ; фильтр протокола L6-L7. поддерживается несколько значений через запятую.
--ipset=<filename> ; включающий ip list. на каждой строчке ip или cidr ipv4 или ipv6. поддерживается множество листов и gzip. перечитка автоматическая.
--ipset-ip=<ip_list> ; фиксированный список подсетей через запятую. можно использовать # в начале для комментирования отдельных подсетей.
--ipset-exclude=<filename> ; исключающий ip list. на каждой строчке ip или cidr ipv4 или ipv6. поддерживается множество листов и gzip. перечитка автоматическая.
--ipset-exclude-ip=<ip_list> ; фиксированный список подсетей через запятую. можно использовать # в начале для комментирования отдельных подсетей.
--debug vous permet d'afficher un journal détaillé d'actions à la console, dans syslog ou à un fichier. La procédure pour suivre les options peut être importante. --debug est mieux indiqué au tout début. Les options sont analysées séquentiellement. Si l'erreur vérifie l'option et que le cas n'a pas encore atteint l' --debug , les messages ne seront pas affichés dans le fichier ou le syslog. Lors de la connexion dans le fichier, le processus ne maintient pas le fichier ouvert. Pour le bien de chaque enregistrement, le fichier s'ouvre puis se ferme. Ainsi, le fichier peut être supprimé à tout moment, et il sera à nouveau créé au premier message du journal. Mais gardez à l'esprit que si vous commencez le processus sous la racine, vous serez remplacé par UID en non-racine. Au début, le fichier modifie le journal, sinon l'enregistrement sera impossible. Si vous supprimez ensuite le fichier et que le processus n'aura pas le droit de créer un fichier dans son répertoire, le journal ne sera plus réalisé. Au lieu de retirer, il est préférable d'utiliser Truncate. Dans Shel, cela peut être fait via la commande ":> nom de fichier"
Son essence est la suivante. Une demande d'origine est prise, modifiée, de fausses informations (contrefaçons) est ajoutée afin que le système d'exploitation du serveur transfère la demande d'origine au processus de serveur inchangé et que le DPI en a vu un autre. Le fait qu'il ne bloque pas. Le serveur voit une chose, DPI en est une autre. DPI ne comprend pas que la demande interdite est transmise et ne le bloque pas.
Il existe un arsenal d'opportunités pour atteindre un tel résultat. Cela peut être le transfert de faux packages afin qu'ils atteignent DPI, mais n'atteignent pas le serveur. La fragmentation au niveau du TCP (segmentation) ou au niveau IP peut être utilisée. Il y a des attaques basées sur le jeu avec des numéros de séquence TCP ou avec un ordre déroutant de segments TCP. Les méthodes peuvent être combinées dans différentes versions.
Les contrefaçons sont des packages générés NFQWS distincts qui transportent de fausses informations pour DPI. Ils ne devraient pas atteindre le serveur, ou peuvent atteindre, mais ils doivent leur être rejetés. Sinon, la ventilation de la connexion TCP ou la violation de l'intégrité du flux transmis, qui est garantie pour briser la ressource. Il existe un certain nombre de méthodes pour résoudre ce problème.
md5sig ajoute l'option de signature MD5 TCP. Cela ne fonctionne pas sur tous les serveurs. Les packages MD5 sont généralement jetés uniquement Linux.badsum gâche la quantité de contrôle de TCP. Cela ne fonctionnera pas si votre appareil est pour NAT, qui ne manque pas de sacs avec un fauteuil roulant. La configuration la plus courante du routeur NAT dans Linux ne les manque pas. La plupart des routeurs domestiques sont construits sur Linux. La nidification est assurée comme suit: Syssctl Tuning par défaut net.netfilter.nf_conntrack_checksum=1 fait que ConnTrack vérifie les caisses TCP et UDP de packages entrants et définir l'état non valide pour les packages avec un fauteuil roulant. Habituellement, dans les règles iptables, une règle pour les baisses de packages avec l'état de non valide dans la chaîne avant est insérée. Une combinaison conjointe de ces facteurs conduit à un manque de badsum à travers un tel routeur. Dans OpenWrt à partir de la boîte de vitesses net.netfilter.nf_conntrack_checksum=0 , il n'y a souvent pas d'autres routeurs, et cela ne peut pas toujours être modifié. Pour que NFQWS fonctionne via un routeur, vous devez définir la valeur sysctl spécifiée à 0. NFQWS sur le routeur lui-même fonctionnera sans cette configuration, car le chexumma des packages créés localement n'est jamais vérifié. Si le routeur après un autre NAT, par exemple, le fournisseur, et qu'il ne manque pas de paquets non valides, vous ne pouvez rien y faire. Mais généralement, les fournisseurs manquent encore Badsum. Sur certains adaptateurs / pulls molletonnés / pilotes, le déchargement Rx-Checksum, les packages Badsum sont obligés d'être retirés avant de recevoir dans le système d'exploitation. Dans ce cas, si quelque chose peut être fait, modifiez uniquement le pilote, ce qui semble extrêmement non trivial. Il a été établi que certains routeurs sur la base de Mediatek se comportent de cette façon. Les forfaits Badsum quittent le système d'exploitation client, mais le routeur n'est pas vu dans BR-LAN via TCPDUmp. De plus, si NFQWS est effectué sur le routeur lui-même, le contournement peut fonctionner. Badsum quitte normalement l'interface externe.badseq augmente le numéro de séquence TCP à une certaine valeur, le retirant ainsi de la fenêtre TCP. Ces packages seront probablement rejetés par le nœud de réception, mais également DPI s'il se concentre sur les numéros de séquence. Par défaut, le déplacement SEQ est sélectionné -10000. La pratique a montré que certains DPI ne manquent pas le SEQ à l'extérieur d'une fenêtre spécifique. Cependant, un si petit déplacement peut entraîner des problèmes avec un streaming significatif et une perte de packages. Si vous utilisez --dpi-desync-any-protocol , vous devrez peut-être installer l'incrément Badseq 0x80000000. Cela fournira une garantie fiable qu'un faux package ne se courra pas dans la fenêtre TCP sur le serveur. Il a également été noté que Badseq rompt la logique de certains DPI pendant l'analyse HTTP, provoquant la congélation de la connexion. De plus, sur le même DPI TLS avec Badseq fonctionne bien.TTL semblait être la meilleure option, mais cela nécessite un réglage individuel pour chaque fournisseur. Si le DPI est plus loin que les sites locaux du fournisseur, vous pouvez leur couper l'accès. La situation est aggravée par la présence de TSPU sur les autoroutes, ce qui oblige TTL à rendre TTL assez élevé, augmentant le risque de panne du faux au serveur. La liste IP Exclude est requise, remplie manuellement. Avec TTL, vous pouvez utiliser md5sig. Cela ne gâtera rien, mais donne une bonne chance de travailler sur lesquels le "mauvais" sac atteindra TTL. Si vous ne trouvez pas de solution automatique, utilisez le fichier zapret-hosts-user-exclude.txt . Certains firmwares d'origine des routeurs fixent le TTL sortant, sans déconnecter cette option, ne fonctionnera pas à travers eux. Qu'est-ce qu'il vaut la peine de choisir TTL: Trouvez la valeur minimale à laquelle le contournement fonctionne toujours. Ce sera le numéro de votre DPI Hop.hopbyhop fait référence uniquement à IPv6. IPv6 Extensine hop-by-hop options est ajoutée. Dans la version de hopbyhop2 2 Heders sont ajoutés, ce qui constitue une violation de la norme et est garantie d'être rejetée par la pile de protocoles dans tous les OS. Un Heder Hop-by-Hop est accepté par tous les OS, mais sur certains canaux / fournisseurs, ces packages peuvent être filtrés et ne pas atteindre. Le calcul est que le DPI analysera le package avec hop-by-hop, mais il n'atteindra pas le destinataire des filtres du fournisseur, ou sera renvoyé par le serveur, car il y a deux têtes.datanoack envoie des contrefaçons avec un drapeau ACK TCP. Les serveurs ne sont pas acceptés et DPI peut accepter. Cette technique peut casser NAT et ne fonctionne pas toujours avec des iptables si Masquarade est utilisée, même à partir du système local (presque toujours sur les routeurs IPv4). Sur les systèmes C iptables sans masquarade et nftables, il fonctionne sans restrictions. Il a été constaté expérimentalement que de nombreux fournisseurs NAT ne rejettent pas ces packages, donc il fonctionne même avec l'IP du fournisseur interne. Mais il ne passera pas à Linux Nat, donc cette technique est probablement ne pas fonctionner derrière le routeur domestique, mais cela peut fonctionner à partir de celle-ci. Il peut fonctionner sur un routeur si la connexion est connectée, et sur le routeur, l'accélération matérielle est activée.autottl . L'essence du régime dans la définition automatique de TTL afin qu'elle passe presque certainement DPI et n'atteint pas un peu le serveur. Les valeurs de base de TTL 64.128,255 sont prises, le package entrant semble (oui, il est nécessaire de diriger le premier package entrant sur NFQWS!). La longueur de la piste est calculée, delta est pris (1 par défaut). Si TTL est hors de la plage (min, max - 3,20 par défaut), alors les valeurs max, sont prises pour s'intégrer dans la plage. Si le TTL résultant est supérieur à la longueur du chemin, l'automatisme n'a pas fonctionné et les valeurs TTL fixes pour l'attaque sont prises. La technique vous permet de résoudre la question lorsque l'ensemble du réseau est bloqué par les barrières (DPI, TSPU) dans la mesure du possible, y compris les autoroutes. Mais potentiellement peut échouer. Par exemple, avec l'asymétrie d'un canal entrant et sortant vers un serveur particulier. Sur certains fournisseurs, cette technique fonctionnera bien, sur d'autres, elle prendra plus de problèmes que de bien. Quelque part, il peut prendre un réglage des paramètres. Il est préférable d'utiliser avec un limiteur supplémentaire. Les modes de district peuvent être combinés dans toutes les combinaisons. --dpi-desync-fooling prend de nombreuses valeurs à travers une virgule.
multisplit . Nous réduisons la demande aux positions indiquées dans --dpi-desync-split-pos .multidisorder . Nous réduisons la demande aux positions indiquées dans --dpi-desync-split-pos et envoyons l'ordre inverse.fakedsplit . Nous avons coupé la demande de 2 parties, encadrant chaque partie avec des faux: faux de la 1ère partie, 1 partie, faux de la 1ère partie, faux de la 2ème partie, 2 partie, faux de la 2ème partiefakeddisorder . De façon similaire à fakedsplit , seulement dans l'ordre inverse: faux de la 2ème partie, 2 partie, faux de la 2ème partie, faux de la 1ère partie, 1 partie, fausse partie 1 partie. Le contenu des contrefaçons dans fakedsplit / fakeddisorder est déterminé par le paramètre --dpi-desync-fakedsplit-pattern (par défaut 0x00). Ces contrefaçons sont tirées du motif avec un déplacement correspondant au déplacement des pièces référées. Les tailles de faux correspondent aux longueurs des pièces envoyées. Le but de ces modes est de compliquer l'identification des données d'origine entre les contrefaçons.
Pour déterminer les positions de coupe, des marqueurs sont utilisés.
Positions relatives:
--methodeol . Alors la position peut être de 1 ou 2. Un exemple de liste de marqueurs: 100,midsld,sniext+1,endhost-2,-10 .
Lors de la rupture de l'emballage, la première chose est les marqueurs de résolution - trouver toutes ces positions relatives et l'utilisation de déplacements. Si une position relative est absente dans le protocole de courant, ces positions ne sont pas appliquées et jetées. Ensuite, il y a une normalisation des positions concernant le déplacement du package actuel dans le groupe de packages (requêtes multi-paquets TLS avec Kyber, par exemple). Toutes les positions s'étendant au-delà des limites du package actuel sont jetées. Les autres sont triés dans une augmentation d'une augmentation de la duplication. Dans les variantes de multisplit et multidisorder s'il ne reste plus de position, la panne ne se produit pas.
Les options fakedsplit et fakeddisorder utilisent une seule position fendue. Sa recherche parmi la liste --dpi-desync-split-pos est effectuée de manière spéciale. Tout d'abord, tous les marqueurs relatifs sont vérifiés. Si un approprié se trouve parmi eux, il est utilisé. Sinon, tous les marqueurs absolus sont vérifiés. Si rien n'est trouvé parmi eux, la position 1 est appliquée.
Par exemple, vous pouvez écrire --dpi-desync-split-pos=method+2,midsld,5 . Si le protocole HTTP, la panne sera en position de method+2 . Si le protocole TLS est dans midsld . Si le protocole est inconnu et inclusif --dpi-desync-any-protocol , la panne sera à la position 5. Pour rendre tout plus sans ambiguïté, vous pouvez utiliser différents profils pour différents protocoles et indiquer une seule position qui se trouve définitivement dans ce protocole.
seqovl ajoute seqovl au début de l'un des segments TCP avec le numéro de séquence déplacé en seqovl . Pour split - au début du premier segment, pour disorder - au début de l'avant-dernier segment (le second de l'ordre suivant d'origine).
Dans le cas de split le calcul est sur le fait que la référence précédente, si elle l'était, a déjà saisi le coquet de l'application du serveur, de sorte que le nouveau qui est arrivé n'est que partiellement dans la fenêtre actuelle (intraveineuse). Devant, la fausse partie est jetée, et le reste de celui contient l'original et commence par le début de la fenêtre, donc il entre dans la prise. L'application serveur reçoit tout ce que le client envoie vraiment, en éliminant la fausse partie de la fenêtre. Mais DPI ne peut pas comprendre cela, il a donc une séquence de désinchronisation. Il est impératif que le premier segment avec seqovl ne dépasse pas la longueur de MTU. Cette situation est automatiquement reconnue dans Linux et seqovl est annulé. Dans d'autres systèmes, la situation n'est pas reconnue, ce qui entraînera une rupture de la connexion. Par conséquent, choisissez la première position divisée et seqovl afin que MTU ne soit pas dépassé en aucun cas. Sinon, la spiritualisation peut ne pas fonctionner ou fonctionner au hasard.
Pour le chevauchement disorder , il va à l'avant-dernière partie du package. Pour plus de simplicité, nous supposerons que la division va en 2 parties, elles seront en ordre "2 1" avec l'ordre d'origine "1 2". Il est nécessaire que seqovl soit inférieur à la position de la première scission, sinon tout ce qui envoyé sera transféré immédiatement à la prise, y compris le faux, brisant le protocole du niveau appliqué. Cette situation est facilement détectée par le programme et seqovl est annulé. Une augmentation de la taille de l'emballage est impossible en principe. Sous réserve de l'état de la 2ème partie du package est entièrement dans la fenêtre, donc le système d'exploitation du serveur l'accepte entièrement, y compris les faux. Mais comme la partie initiale des données de 1 pack de 1 pack n'a pas encore été adoptée, les données fausses et réelles restent dans la mémoire du noyau sans aller à l'application du serveur. Dès que la 1ère partie du package arrive, elle réécrit la fausse partie de la mémoire du noyau. Le noyau reçoit des données de 1 et 2 parties, donc l'application est envoyée au socket d'application. Tel est le comportement de tous les système d'exploitation Unix, à l'exception de Solaris, de laisser les dernières données adoptées. Windows laisse les vieilles données, donc le désordre avec Seqovl entraînera des renforts lorsque vous travaillez avec les serveurs Windows. Solaris est presque mort, il y a très peu de serveurs Windows. Vous pouvez utiliser des feuilles si nécessaire. La méthode vous permet de faire sans tromper et TTL. Les contrefaçons sont mélangées avec des données réelles. fakedsplit/fakeddisorder ajoute toujours des contrefaçons séparées supplémentaires.
seqovl dans la version split ne peut être qu'une valeur positive absolue, car elle n'est utilisée que dans le premier package. Dans la version disorder , toutes les options de marqueurs sont autorisées. Ils se normalisent automatiquement dans le package actuel de la série. Vous pouvez tisser sur midsld et faire seqovl sur midsld-1 .
Les modes hopbyhop , destopt et ipfrag1 deinghronisation (à ne pas confondre avec le fololage!) Se rapportent uniquement à IPv6 et consiste à ajouter les hop-by-hop options , destination options ou fragment dans tous les packages qui relèvent de lachronisation. Ici, il est nécessaire de comprendre que l'ajout d'un en-tête augmente la taille de l'emballage, il ne peut donc pas être appliqué aux paquets de la taille maximale. C'est le cas lors de la transmission de gros messages. S'il est impossible d'envoyer le colis, l'esprit de l'esprit sera annulé, le package sera expulsé dans l'original. Le calcul est que le DPI verra 0 dans le champ d'en-tête suivant du titre ipv6 principal et ne sautera pas sur l'extension Heders à la recherche d'un en-tête de transport. Ainsi, il ne comprendra pas qu'il est TCP ou UDP, et manquera un package sans analyse. Peut-être que certains DPI l'achèteront. Il peut être combiné avec tous les modes de la 2ème phase, à l'exception de ipfrag1+ipfrag2 . Par exemple, hopbyhop,multisplit signifie diviser le package TCP en plusieurs segments, ajouter du hop-by-hop à chacun d'eux. Avec hopbyhop,ipfrag2 la séquence d'en-tête sera: ipv6,hop-by-hop , fragment , tcp/udp . Le mode ipfrag1 peut ne pas toujours fonctionner sans préparation spéciale. Voir la section IP фрагментация .
Dans le paramètre DPI-Desync, vous pouvez spécifier jusqu'à 3 modes via une virgule.
synack , syndata , --wsize , --wssize . Les filtres sur HostList ne fonctionnent pas sur cette phase.fake , rst , rstack .fakedsplit ou ipfrag2 ).Les modes nécessitent une indication dans l'ordre d'augmenter les nombres de phases.
Il existe des DPI qui analysent les réponses du serveur, en particulier, un certificat de ServerHello, où les domaines sont enregistrés. La confirmation de la livraison ClientHello est un package ACK Server avec séquence ACK, correspondant à la longueur de ClientHello + 1. Dans la version des troubles, la confirmation partielle (sac) vient généralement en premier, puis un ACK complet. Si au lieu de ACK ou du sac, il y a un premier package avec un retard minimum, DPI vous coupe au stade de votre demande. Si le premier va après un ACK complet après un retard égal au ping au serveur, le DPI réagit probablement à la réponse du serveur. DPI peut être à la traîne du flux si ClientHello le satisfait et ne pas vérifier ServerHello. Alors vous avez de la chance. La fausse option peut fonctionner. S'il ne tient pas à la traîne et vérifie obstinément ServerHello, vous pouvez essayer de forcer le serveur à envoyer ServerHello en parties via le paramètre - wssize (voir Conntrack). Si cela n'aide pas, alors quelque chose est peu susceptible de le faire sans l'aide du serveur. La meilleure solution consiste à activer la prise en charge de TLS 1.3 sur le serveur. Dans ce document, le certificat de serveur est transmis sous une forme chiffrée. Ceci est une recommandation pour tous les administrateurs de sites bloqués. Allumez TLS 1.3. Vous allez donc donner plus d'occasions de surmonter le DPI.
Dans la documentation de Genève, cela s'appelle "TCB Turnaround". Une tentative d'induire en erreur DPI concernant les rôles d'un client et d'un serveur.
Étant donné que le mode viole les travaux de NAT, l'équipement ne peut fonctionner que s'il n'y a pas de NAT entre le dispositif d'attaque et le DPI. L'attaque ne fonctionnera pas à travers Nat un routeur, mais elle peut en fonctionner. Pour mettre en œuvre une attaque sur le passage du trafic, le schéma NFTABLE et POSTNAT est nécessaire.
Tout est simple ici. Des données sont ajoutées au package SYN. Tout le système d'exploitation les ignore si TCP Fast Open (TFO) n'est pas utilisé, et DPI peut percevoir sans comprendre qu'il y en avait ou non. Les connexions originales avec TFO ne touchent pas, car cela les brisera certainement. Sans paramètre de clarification, 16 octets zéro sont ajoutés.
De l'intérieur de la machine virtuelle de VirtualBox et VMware dans NAT, de nombreuses techniques de package NFQWS ne fonctionnent pas en mode NAT. TTL est remplacé de force, les faux packages ne passent pas. Vous devez configurer le réseau en mode pont.
NFQWS est équipé d'une implémentation limitée du suivi des composés TCP. Il est excité pour la mise en œuvre de certaines méthodes de contrecarrière DPI. Connetrack est capable de surveiller la phase de connexion: syn, établie, FIN, le nombre de packages dans chaque direction, les numéros de séquence. Connetrack est capable de "se nourrir" avec les deux sacs d'une seule voie ou seulement dans une seule direction. La connexion entre dans le tableau lorsque vous trouvez des packages avec des drapeaux définis par syn ou syn, ack. Par conséquent, si vous avez besoin de Conntrack, dans les règles de redirection iptables, la connexion doit passer à NFQWS à partir du tout premier package, bien qu'il puisse ensuite percer le filtre Connbytes. Pour UDP, l'initiateur d'entrer dans la table est le premier package UDP. Il détermine également la direction de l'écoulement. On pense que le premier package UDP provient du client vers le serveur. Ensuite, tous les packages avec coïncidant src_ip,src_port,dst_ip,dst_port sont considérés comme appartenant à ce flux avant l'expiration du temps de l'inactivité. Conntrack est simple, il n'a pas été écrit en tenant compte de toutes sortes d'attaques sur la connexion, il ne vérifie pas les packages pour la validité des numéros de séquence ou du Chekumm. Sa tâche est uniquement de maintenir les besoins des NFQW, il se nourrit généralement uniquement du trafic sortant, il est donc insensible aux substitutions du réseau externe. La connexion est supprimée de la table dès que la nécessité de le suivre ou dans un timout inactif disparaît. Il y a des délais d'expiration distincts pour chaque phase de la connexion. Ils peuvent être modifiés par le paramètre --ctrack-timeouts .
--wssize vous permet de modifier la taille de la fenêtre TCP pour le serveur du client afin qu'il envoie les réponses suivantes aux pièces. Pour que cela affecte tout le système d'exploitation du serveur, il est nécessaire de modifier la taille de la fenêtre dans chaque package provenant du client avant d'envoyer le message, dont la réponse doit être divisée (par exemple, TLS ClientHello). C'est pourquoi il est nécessaire de savoir quand s'arrêter. Si vous ne vous arrêtez pas et n'installez pas un WSSSIZE faible tout le temps, la vitesse tombera catastrophiquement. Dans Linux, cela peut être arrêté via Connbytes, mais dans les systèmes BSD, il n'y a pas de telle possibilité. Dans le cas de HTTP (s), nous nous arrêtons immédiatement après avoir envoyé la première demande HTTP ou TLS ClientHello. Si vous n'êtes pas affaire à HTTP (s), vous aurez besoin d'un paramètre --wssize-cutoff . Il fixe la limite à partir de laquelle s'arrête l'action WSSSIZE. Préfixe D Avant que le nombre ne signifie uniquement les packages avec la charge utile de données, le numéro de séquence relatif du préfixe, en d'autres termes, le nombre d'octets transférés par le client + 1. Si le package avec la demande HTTP ou le client TLS, l'action WSSize s'arrête immédiatement, sans attendre sans attendre WSSSIZE-CUTOFF. Si votre protocole est sujette à une longue inaction, la phase établie est augmentée par --ctrack-timeouts . La valeur par défaut est faible - seulement 5 minutes. N'oubliez pas que NFQWS se nourrit de packages en y venant. Si vous avez limité l'apport de packages via Connbytes, le tableau peut rester des composés suspendus dans la phase établie, qui ne tombera que par Timout. Pour diagnostiquer ConnTrack, envoyez le signal SIGUSR1 à NFQWS: killall -SIGUSR1 nfqws . Le tableau actuel sera affiché par NFQWS dans STDOUT.
Habituellement, dans le package SYN, le client se réfère, en plus de la taille de la fenêtre, également scaling factor de l'extension TCP. Le facteur de mise à l'échelle est le degré de digne, qui est multiplié par la taille de la fenêtre: 0 => 1, 1 => 2, 2 => 4, ..., 8 => 256, ... dans le paramètre du facteur de mise à l'échelle WSSSIZE est indiqué par le côlon. Le facteur de mise à l'échelle ne peut que diminuer, l'augmentation est bloquée pour éviter de dépasser la taille de la fenêtre du serveur. Pour forcer le serveur à la fragmentation de Serverhello, pour éviter la compensation du nom du serveur à partir du certificat de serveur sur DPI, il est préférable d'utiliser --wssize=1:6 . La règle principale consiste à faire de scale_factor autant que possible afin qu'après la restauration de la taille de la fenêtre, la taille finale de la fenêtre devient possible. Si vous faites 64: 0, ce sera très lent. D'un autre côté, il est impossible de permettre à la réponse du serveur de devenir suffisamment grande pour que DPI y trouve souhaité.
--wssize ne fonctionne pas dans les profils avec des listes d'hôtes, car il agit dès le début de la connexion, alors qu'il est toujours impossible de décider d'entrer dans la feuille. Cependant, le profil avec Auto HostList peut contenir - wssize. --wssize peut ralentir la vitesse et / ou augmenter le temps de réponse des sites, donc s'il existe d'autres méthodes de travail pour contourner le DPI, il est préférable de les utiliser.
--dpi-desync-cutoff vous permet de définir la limite, lorsque le DPI-Desync est atteint. Les préfixes N, D, S sont disponibles par analogie C --wssize-cutoff . Utile avec --dpi-desync-any-protocol=1 . Sur les composés sujets à l'inaction, les délais d'attente de Conntrack doivent être modifiés. Si la connexion est tombée de Conntrack et que l'option est définie --dpi-desync-cutoff , dpi desync ne sera pas appliqué.
NFQWS soutient le remontée de certains types de demandes. Pour le moment, c'est TLS et Quic Clienthello. Ils sont longs si vous incluez la cryptographie post-Quantum de TLS-KYBER dans Chrome, et occupe généralement 2 ou 3 forfaits. Kyber est activé par défaut, en commençant par Chromium 124. Chrome est randomisé par TLS Fingerprinnt. SNI peut être à la fois au début et à la fin, c'est-à-dire entrer dans n'importe quel package. Le DPI avec état rythme remonte généralement la demande entièrement, et ce n'est qu'alors que la décision de bloquer. In the case of obtaining a TLS or QUIC package with a partial Clienthello, the assembly process begins, and the packages are delayed and are not sent until its end. At the end of the assembly, the package passes through the desynchronization on the basis of the fully collected Clienthello. In case of any error during the assembly process, the detained packages are immediately sent to the network, and the desinchronization is canceled.
Есть специальная поддержка всех вариантов tcp сплита для многосегментного TLS. Если указать позицию сплита больше длины первого пакета, то разбивка происходит не обязательно первого пакета, а того, на который пришлась итоговая позиция. Если, допустим, клиент послал TLS ClientHello длиной 2000, SNI начинается с 1700, и заданы опции fake,multisplit , то перед первым пакетом идет fake, затем первый пакет в оригинале, а последний пакет разбивается на 2 сегмента. В итоге имеем фейк в начале и 3 реальных сегмента.
Атаки на udp более ограничены в возможностях. udp нельзя фрагментировать иначе, чем на уровне ip. Для UDP действуют только режимы десинхронизации fake , hopbyhop , destopt , ipfrag1 , ipfrag2 , udplen , tamper . Возможно сочетание fake , hopbyhop , destopt с ipfrag2 , fake , fakeknown с udplen и tamper. udplen увеличивает размер udp пакета на указанное в --dpi-desync-udplen-increment количество байтов. Паддинг заполняется нулями по умолчанию, но можно задать свой паттерн. Предназначено для обмана DPI, ориентирующегося на размеры пакетов. Может сработать, если пользовательский протокол не привязан жестко к размеру udp пейлоада. Режим tamper означает модификацию пакетов известных протоколов особенным для протокола образом. На текущий момент работает только с DHT. Поддерживается определение пакетов QUIC Initial с расшифровкой содержимого и имени хоста, то есть параметр --hostlist будет работать. Определяются пакеты wireguard handshake initiation и DHT (начинается с 'd1', кончается 'e'). Для десинхронизации других протоколов обязательно указывать --dpi-desync-any-protocol . Реализован conntrack для udp. Можно пользоваться --dpi-desync-cutoff. Таймаут conntrack для udp можно изменить 4-м параметром в --ctrack-timeouts . Атака fake полезна только для stateful DPI, она бесполезна для анализа на уровне отдельных пакетов. По умолчанию fake наполнение - 64 нуля. Можно указать файл в --dpi-desync-fake-unknown-udp .
Современная сеть практически не пропускает фрагментированные tcp на уровне ip. На udp с этим дело получше, поскольку некоторые udp протоколы могут опираться на этот механизм (IKE старых версий). Однако, кое-где бывает, что режут и фрагментированный udp. Роутеры на базе linux могут самопроизвольно собирать или перефрагментировать пакеты. Позиция фрагментации задается отдельно для tcp и udp. По умолчанию 24 и 8 соответственно, должна быть кратна 8. Смещение считается с транспортного заголовка.
Существует ряд моментов вокруг работы с фрагментами на Linux, без понимания которых может ничего не получиться.
ipv4 : Linux дает отсылать ipv4 фрагменты, но стандартные настройки iptables в цепочке OUTPUT могут вызывать ошибки отправки.
ipv6 : Нет способа для приложения гарантированно отослать фрагменты без дефрагментации в conntrack. На разных системах получается по-разному. Где-то нормально уходят, где-то пакеты дефрагментируются. Для ядер <4.16 похоже, что нет иного способа решить эту проблему, кроме как выгрузить модуль nf_conntrack , который подтягивает зависимость nf_defrag_ipv6 . Он то как раз и выполняет дефрагментацию. Для ядер 4.16+ ситуация чуть лучше. Из дефрагментации исключаются пакеты в состоянии NOTRACK. Чтобы не загромождать описание, смотрите пример решения этой проблемы в blockcheck.sh .
Иногда требуется подгружать модуль ip6table_raw с параметром raw_before_defrag=1 . В openwrt параметры модулей указываются через пробел после их названий в файлах /etc/modules.d . В традиционных системах посмотрите используется ли iptables-legacy или iptables-nft . Если legacy, то нужно создать файл /etc/modprobe.d/ip6table_raw.conf с содержимым :
options ip6table_raw raw_before_defrag=1
В некоторых традиционных дистрибутивах можно изменить текущий ip6tables через : update-alternatives --config ip6tables Если вы хотите оставаться на iptables-nft, вам придется пересобрать патченную версию. Патч совсем небольшой. В nft.c найдите фрагмент:
{
.name = "PREROUTING",
.type = "filter",
.prio = -300, /* NF_IP_PRI_RAW */
.hook = NF_INET_PRE_ROUTING,
},
{
.name = "OUTPUT",
.type = "filter",
.prio = -300, /* NF_IP_PRI_RAW */
.hook = NF_INET_LOCAL_OUT,
},
и замените везде -300 на -450.
Это нужно сделать вручную, никакой автоматики в blockcheck.sh нет.
Либо можно раз и навсегда избавиться от этой проблемы, используя nftables . Там можно создать netfilter hook с любым приоритетом. Используйте приоритет -401 и ниже.
При использовании iptables и NAT, похоже, что нет способа прицепить обработчик очереди после NAT. Пакет попадает в nfqws с source адресом внутренней сети, затем фрагментируется и уже не обрабатывается NAT. Так и уходит во внешюю сеть с src ip 192.168.xx Следовательно, метод не срабатывает. Видимо единственный рабочий метод - отказаться от iptables и использовать nftables. Хук должен быть с приоритетом 101 или выше.
nfqws способен по-разному реагировать на различные запросы и применять разные стратегии дурения. Это реализовано посредством поддержки множества профилей дурения. Профили разделяются в командной строке параметром --new . Первый профиль создается автоматически. Для него не нужно --new . Каждый профиль имеет фильтр. По умолчанию он пуст, то есть профиль удовлетворяет любым условиям. Фильтр может содержать жесткие параметры: версия ip протокола, ipset и порты tcp/udp. Они всегда однозначно идентифицируются даже на нулевой фазе десинхронизации, когда еще хост и L7 неизвестны. В качестве мягкого фильтра могут выступать хост-листы и протокол прикладного уровня (l7). L7 протокол становится известен обычно после первого пакета с данными. При поступлении запроса идет проверка профилей в порядке от первого до последнего до достижения первого совпадения с фильтром. Жесткие параметры фильтра сверяются первыми. При несовпадении идет сразу же переход к следующему профилю. Если какой-то профиль удовлетворяет жесткому фильтру и L7 фильтру и содержит авто-хостлист, он выбирается сразу. Если профиль удовлетворяет жесткому фильтру и L7 фильтру, для него задан хостлист, и у нас еще нет имени хоста, идет переход к следующему профилю. В противном случае идет проверка по хостлистам этого профиля. Если имя хоста удовлетворяет листам, выбирается этот профиль. Иначе идет переход к следующему. Может так случиться, что до получения имени хоста или узнавания L7 протокола соединение идет по одному профилю, а при выяснении этих параметров профиль меняется на лету. Это может произойти даже дважды - при выяснении L7 и имени хоста. Чаще всего это выяснение совмещается в одно действие, поскольку по одному пакету как правило узнается и L7, и хост. Поэтому если у вас есть параметры дурения нулевой фазы, тщательно продумывайте что может произойти при переключении стратегии. Смотрите debug log, чтобы лучше понять что делает nfqws. Нумерация профилей идет с 1 до N. Последним в цепочке создается пустой профиль с номером 0. Он используется, когда никакие условия фильтров не совпали.
Important
Множественные стратегии создавались только для случаев, когда невозможно обьединить имеющиеся стратегии для разных ресурсов. Копирование стратегий из blockcheck для разных сайтов во множество профилей без понимания как они работают приведет к нагромождению параметров, которые все равно не покроют все возможные заблокированные ресурсы. Вы только увязните в этой каше.
Important
user-mode реализация ipset создавалась не как удобная замена *nix версии, реализованной в ядре. Вариант в ядре работает гораздо эффективнее. Это создавалось для систем без подержки ipset в ядре. Конкретно - Windows и ядра Linux, собранные без nftables и ipset модулей ядра. Например, в android нет ipset.
iptables для задействования атаки на первые пакеты данных в tcp соединении :
iptables -t mangle -I POSTROUTING -o <внешний_интерфейс> -p tcp -m multiport --dports 80,443 -m connbytes --connbytes-dir=original --connbytes-mode=packets --connbytes 1:6 -m mark ! --mark 0x40000000/0x40000000 -j NFQUEUE --queue-num 200 --queue-bypass
Этот вариант применяем, когда DPI не следит за всеми запросами http внутри keep-alive сессии. Если следит, направляем только первый пакет от https и все пакеты от http :
iptables -t mangle -I POSTROUTING -o <внешний_интерфейс> -p tcp --dport 443 -m connbytes --connbytes-dir=original --connbytes-mode=packets --connbytes 1:6 -m mark ! --mark 0x40000000/0x40000000 -j NFQUEUE --queue-num 200 --queue-bypass
iptables -t mangle -I POSTROUTING -o <внешний_интерфейс> -p tcp --dport 80 -m mark ! --mark 0x40000000/0x40000000 -j NFQUEUE --queue-num 200 --queue-bypass
mark нужен, чтобы сгенерированный поддельный пакет не попал опять к нам на обработку. nfqws выставляет fwmark при его отсылке. хотя nfqws способен самостоятельно различать помеченные пакеты, фильтр в iptables по mark нужен при использовании connbytes, чтобы не допустить изменения порядка следования пакетов. Процессинг очереди - процесс отложенный. Если ядро имеет пакеты на отсылку вне очереди - оно их отправляет незамедлительно. Изменение правильного порядка следования пакетов при десинхронизации ломает всю идею. Так же были замечены дедлоки при достаточно большой отсылке пакетов из nfqws и отсутствии mark фильтра. Процесс может зависнуть. Поэтому наличие фильтра по mark в ip/nf tables можно считать обязательным.
Почему --connbytes 1:6 :
Для режима autottl необходимо перенаправление входящего SYN,ACK пакета или первого пакета соединения (что обычно есть тоже самое). Для режима autohostlist необходимы входящие RST и http redirect. Можно построить фильтр на tcp flags для выделения SYN,ACK и модуле u32 для поиска характерных паттернов http redirect, но проще использовать connbytes для выделения нескольких начальных входящих пакетов.
iptables -t mangle -I PREROUTING -i <внешний интерфейс> -p tcp -m multiport --sports 80,443 -m connbytes --connbytes-dir=reply --connbytes-mode=packets --connbytes 1:3 -m mark ! --mark 0x40000000/0x40000000 -j NFQUEUE --queue-num 200 --queue-bypass
Для quic :
iptables -t mangle -I POSTROUTING -o <внешний_интерфейс> -p udp --dport 443 -m connbytes --connbytes-dir=original --connbytes-mode=packets --connbytes 1:6 -m mark ! --mark 0x40000000/0x40000000 -j NFQUEUE --queue-num 200 --queue-bypass
6 пакетов берется, чтобы покрыть случаи возможных ретрансмиссий quic initial в случае плохой связи или если сервер плохо себя чувствует, а приложение настаивает именно на quic, не переходя на tcp. А так же для работы autohostlist по quic. Однако, autohostlist для quic не рекомендуется.
Можно начать с базовой конфигурации.
IFACE_WAN=wan
nft create table inet ztest
nft add chain inet ztest post "{type filter hook postrouting priority mangle;}"
nft add rule inet ztest post oifname $IFACE_WAN meta mark and 0x40000000 == 0 tcp dport "{80,443}" ct original packets 1-6 queue num 200 bypass
nft add rule inet ztest post oifname $IFACE_WAN meta mark and 0x40000000 == 0 udp dport 443 ct original packets 1-6 queue num 200 bypass
# auto hostlist with avoiding wrong ACK numbers in RST,ACK packets sent by russian DPI
sysctl net.netfilter.nf_conntrack_tcp_be_liberal=1
nft add chain inet ztest pre "{type filter hook prerouting priority filter;}"
nft add rule inet ztest pre iifname $IFACE_WAN tcp sport "{80,443}" ct reply packets 1-3 queue num 200 bypass
Для задействования IP фрагментации и datanoack на проходящие пакеты требуется особая конфигурация цепочек, перенаправляющая пакеты после NAT. В скриптах zapret эта схема называется POSTNAT , и она возможна только на nftables. Сгенерированные nfqws пакеты требуется на раннем этапе помечать как notrack , чтобы они не были испорчены NAT.
IFACE_WAN=wan
nft create table inet ztest
nft add chain inet ztest postnat "{type filter hook postrouting priority srcnat+1;}"
nft add rule inet ztest postnat oifname $IFACE_WAN meta mark and 0x40000000 == 0 tcp dport "{80,443}" ct original packets 1-6 queue num 200 bypass
nft add rule inet ztest postnat oifname $IFACE_WAN meta mark and 0x40000000 == 0 udp dport 443 ct original packets 1-6 queue num 200 bypass
nft add chain inet ztest predefrag "{type filter hook output priority -401;}"
nft add rule inet ztest predefrag "mark & 0x40000000 != 0x00000000 notrack"
Удаление тестовой таблицы :
nft delete table inet ztest
Если ваше устройство поддерживает аппаратное ускорение (flow offloading, hardware nat, hardware acceleration), то iptables могут не работать. При включенном offloading пакет не проходит по обычному пути netfilter. Необходимо или его отключить, или выборочно им управлять.
В новых ядрах присутствует software flow offloading (SFO). Пакеты, проходящие через SFO, так же проходят мимо большей части механизмов iptables. При включенном SFO работает DNAT/REDIRECT (tpws). Эти соединения исключаются из offloading. Однако, остальные соединения идут через SFO, потому NFQUEUE будет срабатывать только до помещения соединения в flowtable. Практически это означает, что почти весь функционал nfqws работать не будет. Offload включается через специальный target в iptables FLOWOFFLOAD . Не обязательно пропускать весь трафик через offload. Можно исключить из offload соединения, которые должны попасть на tpws или nfqws. openwrt не предусматривает выборочного управления offload. Поэтому скрипты zapret поддерживают свою систему выборочного управления offload в openwrt.
iptables target FLOWOFFLOAD - это проприетарное изобретение openwrt. Управление offload в nftables реализовано в базовом ядре linux без патчей.
tpws - это transparent proxy.
@<config_file>|$<config_file> ; читать конфигурацию из файла. опция должна быть первой. остальные опции игнорируются.
--debug=0|1|2|syslog|@<filename> ; 0,1,2 = логирование на косоль : 0=тихо, 1(default)=подробно, 2=отладка.
--debug-level=0|1|2 ; указать уровень логирования для syslog и @<filename>
--dry-run ; проверить опции командной строки и выйти. код 0 - успешная проверка.
--daemon ; демонизировать прогу
--pidfile=<file> ; сохранить PID в файл
--user=<username> ; менять uid процесса
--uid=uid[:gid] ; менять uid процесса
--bind-addr ; на каком адресе слушать. может быть ipv4 или ipv6 адрес
; если указан ipv6 link local, то требуется указать с какого он интерфейса : fe80::1%br-lan
--bind-linklocal=no|unwanted|prefer|force ; no : биндаться только на global ipv6
; unwanted (default) : предпочтительно global, если нет - LL
; prefer : предпочтительно LL, если нет - global
; force : биндаться только на LL
--bind-iface4=<iface> ; слушать на первом ipv4 интерфейса iface
--bind-iface6=<iface> ; слушать на первом ipv6 интерфейса iface
--bind-wait-ifup=<sec> ; ждать до N секунд появления и поднятия интерфейса
--bind-wait-ip=<sec> ; ждать до N секунд получения IP адреса (если задан --bind-wait-ifup - время идет после поднятия интерфейса)
--bind-wait-ip-linklocal=<sec>
; имеет смысл только при задании --bind-wait-ip
; --bind-linklocal=unwanted : согласиться на LL после N секунд
; --bind-linklocal=prefer : согласиться на global address после N секунд
--bind-wait-only ; подождать все бинды и выйти. результат 0 в случае успеха, иначе не 0.
--connect-bind-addr ; с какого адреса подключаться во внешнюю сеть. может быть ipv4 или ipv6 адрес
; если указан ipv6 link local, то требуется указать с какого он интерфейса : fe80::1%br-lan
; опция может повторяться для v4 и v6 адресов
; опция не отменяет правил маршрутизации ! выбор интерфейса определяется лишь правилами маршрутизации, кроме случая v6 link local.
--socks ; вместо прозрачного прокси реализовать socks4/5 proxy
--no-resolve ; запретить ресолвинг имен через socks5
--resolve-threads ; количество потоков ресолвера
--port=<port> ; на каком порту слушать
--maxconn=<max_connections> ; максимальное количество соединений от клиентов к прокси
--maxfiles=<max_open_files> ; макс количество файловых дескрипторов (setrlimit). мин требование (X*connections+16), где X=6 в tcp proxy mode, X=4 в режиме тамперинга.
; стоит сделать запас с коэффициентом как минимум 1.5. по умолчанию maxfiles (X*connections)*1.5+16
--max-orphan-time=<sec> ; если вы запускаете через tpws торрент-клиент с множеством раздач, он пытается установить очень много исходящих соединений,
; большая часть из которых отваливается по таймауту (юзера сидят за NAT, firewall, ...)
; установление соединения в linux может длиться очень долго. локальный конец отвалился, перед этим послав блок данных,
; tpws ждет подключения удаленного конца, чтобы отослать ему этот блок, и зависает надолго.
; настройка позволяет сбрасывать такие подключения через N секунд, теряя блок данных. по умолчанию 5 сек. 0 означает отключить функцию
; эта функция не действует на успешно подключенные ранее соединения
--local-rcvbuf=<bytes> ; SO_RCVBUF для соединений client-proxy
--local-sndbuf=<bytes> ; SO_SNDBUF для соединений client-proxy
--remote-rcvbuf=<bytes> ; SO_RCVBUF для соединений proxy-target
--remote-sndbuf=<bytes> ; SO_SNDBUF для соединений proxy-target
--nosplice ; не использовать splice на linux системах
--skip-nodelay ; не устанавливать в исходящих соединения TCP_NODELAY. несовместимо со split.
--local-tcp-user-timeout=<seconds> ; таймаут соединений client-proxy (по умолчанию : 10 сек, 0 = оставить системное значение)
--remote-tcp-user-timeout=<seconds> ; таймаут соединений proxy-target (по умолчанию : 20 сек, 0 = оставить системное значение)
--fix-seg=<int> ; исправлять неудачи tcp сегментации ценой задержек для всех клиентов и замедления. ждать до N мс. по умолчанию 30 мс.
--split-pos=N|-N|marker+N|marker-N ; список через запятую маркеров для tcp сегментации
--split-any-protocol ; применять сегментацию к любым пакетам. по умолчанию - только к известным протоколам (http, TLS)
--disorder[=http|tls] ; путем манипуляций с сокетом вынуждает отправлять первым второй сегмент разделенного запроса
--oob[=http|tls] ; отправить байт out-of-band data (OOB) в конце первой части сплита
--oob-data=<char>|0xHEX ; переопределить байт OOB. по умолчанию 0x00.
--hostcase ; менять регистр заголовка "Host:". по умолчанию на "host:".
--hostspell=HoST ; точное написание заголовка Host (можно "HOST" или "HoSt"). автоматом включает --hostcase
--hostdot ; добавление точки после имени хоста : "Host: kinozal.tv."
--hosttab ; добавление табуляции после имени хоста : "Host: kinozal.tvt"
--hostnospace ; убрать пробел после "Host:"
--hostpad=<bytes> ; добавить паддинг-хедеров общей длиной <bytes> перед Host:
--domcase ; домен после Host: сделать таким : TeSt.cOm
--methodspace ; добавить пробел после метода : "GET /" => "GET /"
--methodeol ; добавить перевод строки перед методом : "GET /" => "rnGET /"
--unixeol ; конвертировать 0D0A в 0A и использовать везде 0A
--tlsrec=N|-N|marker+N|marker-N ; разбивка TLS ClientHello на 2 TLS records на указанной позиции. Минимальное смещение - 6.
--mss=<int> ; установить MSS для клиента. может заставить сервер разбивать ответы, но существенно снижает скорость
--tamper-start=[n]<pos> ; начинать дурение только с указанной байтовой позиции или номера блока исходяшего потока (считается позиция начала принятого блока)
--tamper-cutoff=[n]<pos> ; закончить дурение на указанной байтовой позиции или номере блока исходящего потока (считается позиция начала принятого блока)
--hostlist=<filename> ; действовать только над доменами, входящими в список из filename. поддомены автоматически учитываются.
; в файле должен быть хост на каждой строке.
; список читается при старте и хранится в памяти в виде иерархической структуры для быстрого поиска.
; при изменении времени модификации файла он перечитывается автоматически по необходимости
; список может быть запакован в gzip. формат автоматически распознается и разжимается
; списков может быть множество. пустой общий лист = его отсутствие
; хосты извлекаются из Host: хедера обычных http запросов и из SNI в TLS ClientHello.
--hostlist-domains=<domain_list> ; фиксированный список доменов через зяпятую. можно использовать # в начале для комментирования отдельных доменов.
--hostlist-exclude=<filename> ; не применять дурение к доменам из листа. может быть множество листов. схема аналогична include листам.
--hostlist-exclude-domains=<domain_list> ; фиксированный список доменов через зяпятую. можно использовать # в начале для комментирования отдельных доменов.
--hostlist-auto=<filename> ; обнаруживать автоматически блокировки и заполнять автоматический hostlist (требует перенаправления входящего трафика)
--hostlist-auto-fail-threshold=<int> ; сколько раз нужно обнаружить ситуацию, похожую на блокировку, чтобы добавить хост в лист (по умолчанию: 3)
--hostlist-auto-fail-time=<int> ; все эти ситуации должны быть в пределах указанного количества секунд (по умолчанию: 60)
--hostlist-auto-debug=<logfile> ; лог положительных решений по autohostlist. позволяет разобраться почему там появляются хосты.
--new ; начало новой стратегии (новый профиль)
--skip ; не использовать этот профиль . полезно для временной деактивации профиля без удаления параметров.
--filter-l3=ipv4|ipv6 ; фильтр версии ip для текущей стратегии
--filter-tcp=[~]port1[-port2]|* ; фильтр портов tcp для текущей стратегии. ~ означает инверсию. поддерживается список через запятую.
--filter-l7=[http|tls|quic|wireguard|dht|unknown] ; фильтр протокола L6-L7. поддерживается несколько значений через запятую.
--ipset=<filename> ; включающий ip list. на каждой строчке ip или cidr ipv4 или ipv6. поддерживается множество листов и gzip. перечитка автоматическая.
--ipset-ip=<ip_list> ; фиксированный список подсетей через запятую. можно использовать # в начале для комментирования отдельных подсетей.
--ipset-exclude=<filename> ; исключающий ip list. на каждой строчке ip или cidr ipv4 или ipv6. поддерживается множество листов и gzip. перечитка автоматическая.
--ipset-exclude-ip=<ip_list> ; фиксированный список подсетей через запятую. можно использовать # в начале для комментирования отдельных подсетей.
tpws, как и nfqws, поддерживает множественную сегментацию запросов. Сплит позиции задаются в --split-pos . Указываются маркеры через запятую. Описание маркеров см в разделе nfqws.
На прикладном уровне в общем случае нет гарантированного средства заставить ядро выплюнуть блок данных, порезанным в определенном месте. ОС держит буфер отсылки (SNDBUF) у каждого сокета. Если у сокета включена опция TCP_NODELAY и буфер пуст, то каждый send приводит к отсылке отдельного ip пакета или группы пакетов, если блок не вмещается в один ip пакет. Однако, если в момент send уже имеется неотосланный буфер, то ОС присоединит данные к нему, никакой отсылки отдельным пакетом не будет. Но в этом случае и так нет никакой гарантии, что какой-то блок сообщения пойдет в начале пакета, на что собственно и заточены DPI. Разбиение будет производится согласно MSS, который зависит от MTU исходящего интерфейса. Таким образом DPI, смотрящие в начало поля данных TCP пакета, будут поломаны в любом случае. Протокол http относится к запрос-ответным протоколам. Новое сообщение посылается только тогда, когда сервер получил запрос и полностью вернул ответ. Значит запрос фактически был не только отослан, но и принят другой стороной, а следовательно буфер отсылки пуст, и следующие 2 send приведут к отсылке сегментов данных разными ip пакетами.
Таким образом tpws обеспечивает сплит только за счет раздельных вызовов send, и это обычно работает надежно, если разбивать не на слишком много частей и не на слишком мелкие подряд следующие части. В последнем случае Linux все же может обьединить некоторые части, что приведет к несоответствию реальной сегментации указанным сплит позициям. Другие ОС в этом вопросе ведут себя более предсказуемо. Спонтанного обьединения замечено не было. Поэтому не стоит злоупотреблять сплитами и в особенности мелкими соседними пакетами.
Как показывается практика, проблемы могут начаться , если количество сплит позиций превышает 8. При неудаче сегментации будет выводиться сообщение WARNING ! segmentation failed . Если вы его видите, это повод снизить количество сплит позиций. Если это не вариант, для ядер Linux >=4.6 есть параметр --fix-seg . Он позволяет подождать завершение отсылки перед отправкой следующей части. Но этот вариант ломает модель асинхронной обработки событий. Пока идет ожидание, все остальные соединения не обрабатываются и кратковременно подвисают. На практике это может быть совсем небольшое ожидание - менее 10 мс. И производится оно только , если происходит split, и в ожидании есть реальная необходимость. В высоконагруженных системах данный вариант не рекомендуется. Но для домашнего использования может подойти, и вы эти задержки даже не заметите.
Если вы пытаетесь сплитнуть массивную передачу с --split-any-protocol , когда информация поступает быстрее отсылки, то без --fix-seg ошибки сегментации будут сыпаться сплошным потоком. Работа по массивному потоку без ограничителей --tamper-start и --tamper-cutoff обычно лишена смысла.
tpws работает на уровне сокетов, поэтому длинный запрос, не вмещающийся в 1 пакет (TLS с kyber), он получает целым блоком. На каждую сплит часть он делает отдельный вызов send() . Но ОС не сможет отослать данные в одном пакете, если размер превысит MTU. В случае слишком большого сегмента ОС дополнительно его порежет на более мелкие. Результат должен быть аналогичен nfqws.
--disorder заставляет слать каждый 2-й пакет с TTL=1, начиная с первого. К серверу приходят все четные пакеты сразу. На остальные ОС делает ретрансмиссию, и они приходят потом. Это само по себе создает дополнительную задержку (200 мс в linux для первой ретрансмиссии). Иным способом сделать disorder в сокет варианте не представляется возможным. Итоговый порядок для 6 сегментов получается 2 4 6 1 3 5 .
--oob высылает 1 байт out-of-band data после первого сплит сегмента. oob в каждом сегменте сплита показал себя ненадежным. Сервер получает oob в сокет.
Сочетание oob и disorder возможно только в Linux. Остальные ОС не умеют с таким справляться. Флаг URG теряется при ретрансмиссиях. Сервер получает oob в сокет. Сочетание этих параметров в ос, кроме Linux, вызывает ошибку на этапе запуска.
--tlsrec позволяют внутри одного tcp сегмента разрезать TLS ClientHello на 2 TLS records. Можно использовать стандартный механизм маркеров для задания относительных позиций.
--tlsrec ломает значительное количество сайтов. Криптобиблиотеки (openssl, ...) на оконечных http серверах без проблем принимают разделенные tls сегменты, но мидлбоксы - не всегда. К мидлбоксам можно отнести CDN или системы ddos-защиты. Поэтому применение --tlsrec без ограничителей вряд ли целесообразно. В РФ --tlsrec обычно не работает с TLS 1.2, потому что цензор парсит сертификат сервера из ServerHello. Работает только с TLS 1.3, поскольку там эта информация шифруется. Впрочем, сейчас сайтов, не поддерживающих TLS 1.3, осталось немного.
--mss устанавливает опцию сокета TCP_MAXSEG. Клиент выдает это значение в tcp опциях SYN пакета. Сервер в ответ в SYN,ACK выдает свой MSS. На практике сервера обычно снижают размеры отсылаемых ими пакетов, но они все равно не вписываются в низкий MSS, указанный клиентом. Обычно чем больше указал клиент, тем больше шлет сервер. На TLS 1.2 если сервер разбил заброс так, чтобы домен из сертификата не попал в первый пакет, это может обмануть DPI, секущий ответ сервера. Схема может значительно снизить скорость и сработать не на всех сайтах. С фильтром по hostlist совместимо только в режиме socks при включенном удаленном ресолвинге хостов. (firefox network.proxy.socks_remote_dns). Это единственный вариант, когда tpws может узнать имя хоста еще на этапе установления соединения. Применяя данную опцию к сайтам TLS1.3, если броузер тоже поддерживает TLS1.3, то вы делаете только хуже. Но нет способа автоматически узнать когда надо применять, когда нет, поскольку MSS идет только в 3-way handshake еще до обмена данными, а версию TLS можно узнать только по ответу сервера, который может привести к реакции DPI. Использовать только когда нет ничего лучше или для отдельных ресурсов. Для http использовать смысла нет, поэтому заводите отдельный desync profile с фильтром по порту 443. Работает только на Linux, не работает на BSD и MacOS.
Параметр --hostpad=<bytes> добавляет паддинг-хедеров перед Host: на указанное количество байтов. Если размер <bytes> слишком большой, то идет разбивка на разные хедеры по 2K. Общий буфер приема http запроса - 64K, больший паддинг не поддерживается, да и http сервера такое уже не принимают. Полезно против DPI, выполняющих реассемблинг TCP с ограниченным буфером. Если техника работает, то после некоторого количества bytes http запрос начнет проходить до сайта. Если при этом критический размер padding около MTU, значит скорее всего DPI не выполняет реассемблинг пакетов, и лучше будет использовать обычные опции TCP сегментации. Если все же реассемблинг выполняется, то критический размер будет около размера буфера DPI. Он может быть 4K или 8K, возможны и другие значения.
Работают аналогично nfqws , кроме некоторых моментов. Нет параметра --filter-udp , поскольку tpws udp не поддерживает. Методы нулевой фазы ( --mss ) могут работать по хостлисту в одном единственном случае: если используется режим socks и удаленный ресолвинг хостов через прокси. То есть работоспособность вашей настройки в одном и том же режиме может зависеть от того, применяет ли клиент удаленный ресолвинг. Это может быть неочевидно. В одной программе работает, в другой - нет. Если вы используете профиль с хостлистом , и вам нужен mss, укажите mss в профиле с хостлистом, создайте еще один профиль без хостлиста, если его еще нет, и в нем еще раз укажите mss. Тогда при любом раскладе будет выполняться mss. Используйте curl --socks5 и curl --socks5-hostname для проверки вашей стратегии. Смотрите вывод --debug , чтобы убедиться в правильности настроек.
--debug allows you to display a detailed log of actions to the console, in Syslog or to a file. The procedure for following the options may be important. --debug is best indicated at the very beginning. Options are analyzed sequentially. If the error is checking the option, and the case has not yet reached the --debug , then the messages will not be displayed to the file or Syslog. --debug=0|1|2 allow you to immediately include logistics on the console in one parameter and indicate the level. Saved for compatibility with older versions. To select a level in Syslog or File, use a separate parameter --debug-level . If in these --debug modes do not indicate the level through --debug-level , then level 1 is automatically assigned. When logging into the file, the process does not hold the file open. For the sake of each recording, the file opens and then closes. So the file can be deleted at any time, and it will be created again at the first message in the log. But keep in mind that if you start the process under the Root, you will be replaced by UID to non-ROOT. In the beginning, the file changes on the log, otherwise the recording will be impossible. If you then delete the file, and the process will not have the right to create a file in its directory, the log will no longer be conducted. Instead of removal, it is better to use truncate. In Shel, this can be done through the command ":> Filename"
tpws может биндаться на множество интерфейсов и IP адресов (до 32 шт). Порт всегда только один. Параметры --bind-iface* и --bind-addr создают новый бинд. Остальные параметры --bind-* относятся к последнему бинду. Для бинда на все ipv4 укажите --bind-addr "0.0.0.0" , на все ipv6 - "::" . --bind-addr="" - биндаемся на все ipv4 и ipv6. Выбор режима использования link local ipv6 адресов ( fe80::/8 ) :
--bind-iface6 --bind-linklocal=no : сначала приватный адрес fc00::/7, затем глобальный адрес
--bind-iface6 --bind-linklocal=unwanted : сначала приватный адрес fc00::/7, затем глобальный адрес, затем link local.
--bind-iface6 --bind-linklocal=prefer : сначала link local, затем приватный адрес fc00::/7, затем глобальный адрес.
--bind-iface6 --bind-linklocal=force : только link local
Если не указано ни одного бинда, то создается бинд по умолчанию на все адреса всех интерфейсов. Для бинда на конкретный link-local address делаем так : --bind-iface6=fe80::aaaa:bbbb:cccc:dddd%iface-name Параметры --bind-wait* могут помочь в ситуациях, когда нужно взять IP с интерфейса, но его еще нет, он не поднят или не сконфигурирован. В разных системах события ifup ловятся по-разному и не гарантируют, что интерфейс уже получил IP адрес определенного типа. В общем случае не существует единого механизма повеситься на событие типа "на интерфейсе X появился link local address". Для бинда на известный ip, когда еще интерфейс не сконфигурирован, нужно делать так: --bind-addr=192.168.5.3 --bind-wait-ip=20 В режиме transparent бинд возможен на любой несуществующий адрес, в режиме socks - только на существующий.
Параметры rcvbuf и sndbuf позволяют установить setsockopt SO_RCVBUF SO_SNDBUF для локального и удаленного соединения.
--skip-nodelay может быть полезен, когда tpws используется без дурения, чтобы привести MTU к MTU системы, на которой работает tpws. Это может быть полезно для скрытия факта использования VPN. Пониженный MTU - 1 из способов обнаружения подозрительного подключения. С tcp proxy ваши соединения неотличимы от тех, что сделал бы сам шлюз.
--local-tcp-user-timeout и --remote-tcp-user-timeout устанавливают значение таймаута в секундах для соединений клиент-прокси и прокси-сервер. Этот таймаут соответствует опции сокета linux TCP_USER_TIMEOUT. Под таймаутом подразумевается время, в течение которого буферизированные данные не переданы или на переданные данные не получено подтверждение (ACK) от другой стороны. Этот таймаут никак не касается времени отсутствия какой-либо передачи через сокет лишь потому, что данных для передачи нет. Полезно для сокращения время закрытия подвисших соединений. Поддерживается только на Linux и MacOS.
Режим --socks не требует повышенных привилегий (кроме бинда на привилегированные порты 1..1023). Поддерживаются версии socks 4 и 5 без авторизации. Версия протокола распознается автоматически. Подключения к IP того же устройства, на котором работает tpws, включая localhost, запрещены. socks5 позволяет удаленно ресолвить хосты (curl : --socks5-hostname firefox : socks_remote_dns=true). tpws поддерживает эту возможность асинхронно, не блокируя процессинг других соединений, используя многопоточный пул ресолверов. Количество потоков определяется автоматически в зависимости от --maxconn , но можно задать и вручную через параметр --resolver-threads . Запрос к socks выставляется на паузу, пока домен не будет преобразован в ip адрес в одном из потоков ресолвера. Ожидание может быть более длинным, если все потоки заняты. Если задан параметр --no-resolve , то подключения по именам хостов запрещаются, а пул ресолверов не создается. Тем самым экономятся ресурсы.
Для перенаправления tcp соединения на transparent proxy используются команды следующего вида :
iptables -t nat -I OUTPUT -o <внешний_интерфейс> -p tcp --dport 80 -m owner ! --uid-owner tpws -j DNAT --to 127.0.0.127:988
iptables -t nat -I PREROUTING -i <внутренний_интерфейс> -p tcp --dport 80 -j DNAT --to 127.0.0.127:988
Первая команда для соединений с самой системы, вторая - для проходящих через роутер соединений.
DNAT на localhost работает в цепочке OUTPUT, но не работает в цепочке PREROUTING без включения параметра route_localnet :
sysctl -w net.ipv4.conf.<внутренний_интерфейс>.route_localnet=1
Можно использовать -j REDIRECT --to-port 988 вместо DNAT, однако в этом случае процесс transparent proxy должен слушать на ip адресе входящего интерфейса или на всех адресах. Слушать на всех - не есть хорошо с точки зрения безопасности. Слушать на одном (локальном) можно, но в случае автоматизированного скрипта придется его узнавать, потом динамически вписывать в команду. В любом случае требуются дополнительные усилия. Использование route_localnet тоже имеет потенциальные проблемы с безопасностью. Вы делаете доступным все, что висит на 127.0.0.0/8 для локальной подсети < внутренний_интерфейс>. Службы обычно привязываются к 127.0.0.1 , поэтому можно средствами iptables запретить входящие на 127.0.0.1 не с интерфейса lo, либо повесить tpws на любой другой IP из из 127.0.0.0/8 , например на 127.0.0.127 , и разрешить входящие не с lo только на этот IP.
iptables -A INPUT ! -i lo -d 127.0.0.127 -j ACCEPT
iptables -A INPUT ! -i lo -d 127.0.0.0/8 -j DROP
Фильтр по owner необходим для исключения рекурсивного перенаправления соединений от самого tpws. tpws запускается под пользователем tpws , для него задается исключающее правило.
IP6Tables work almost in the same way as IPV4, but there are a number of important nuances. In Dnat, you should take the address --to in square brackets. Par exemple :
ip6tables -t nat -I OUTPUT -o <внешний_интерфейс> -p tcp --dport 80 -m owner ! --uid-owner tpws -j DNAT --to [::1]:988
Параметра route_localnet не существует для ipv6. DNAT на localhost (::1) возможен только в цепочке OUTPUT. В цепочке PREROUTING DNAT возможен на любой global address или на link local address того же интерфейса, откуда пришел пакет. NFQUEUE работает без изменений.
Базовая конфигурация :
IFACE_WAN=wan
IFACE_LAN=br-lan
sysctl -w net.ipv4.conf.$IFACE_LAN.route_localnet=1
nft create table inet ztest
nft create chain inet ztest localnet_protect
nft add rule inet ztest localnet_protect ip daddr 127.0.0.127 return
nft add rule inet ztest localnet_protect ip daddr 127.0.0.0/8 drop
nft create chain inet ztest input "{type filter hook input priority filter - 1;}"
nft add rule inet ztest input iif != "lo" jump localnet_protect
nft create chain inet ztest dnat_output "{type nat hook output priority dstnat;}"
nft add rule inet ztest dnat_output meta skuid != tpws oifname $IFACE_WAN tcp dport { 80, 443 } dnat ip to 127.0.0.127:988
nft create chain inet ztest dnat_pre "{type nat hook prerouting priority dstnat;}"
nft add rule inet ztest dnat_pre meta iifname $IFACE_LAN tcp dport { 80, 443 } dnat ip to 127.0.0.127:988
Удаление таблицы :
nft delete table inet ztest
!!! NFTables cannot work with IPSET-am. Own similar mechanism requires a huge amount of RAM !!! To download large sheets. For example, even 256 MB is not enough for a 100K post in NFSET. !!! If you need large sheets on home routers, roll back to the iPtables+IPSET.
ipset/zapret-hosts-user.txt и запустите ipset/get_user.sh На выходе получите ipset/zapret-ip-user.txt с IP адресами.Cкрипты с названием get_reestr_* оперируют дампом реестра заблокированных сайтов :
ipset/get_reestr_resolve.sh получает список доменов от rublacklist и дальше их ресолвит в ip адреса в файл ipset/zapret-ip.txt.gz. В этом списке есть готовые IP адреса, но судя во всему они там в точности в том виде, что вносит в реестр РосКомПозор. Адреса могут меняться, позор не успевает их обновлять, а провайдеры редко банят по IP : вместо этого они банят http запросы с "нехорошим" заголовком "Host:" вне зависимости от IP адреса. Поэтому скрипт ресолвит все сам, хотя это и занимает много времени. Используется мультипоточный ресолвер mdig (собственная разработка).
ipset/get_reestr_preresolved.sh . то же самое, что и 2), только берется уже заресолвленый список со стороннего ресурса.
ipset/get_reestr_preresolved_smart.sh . то же самое, что и 3), с добавлением всего диапазона некоторых автономных систем (прыгающие IP адреса из cloudflare, facebook, ...) и некоторых поддоменов блокируемых сайтов
Cкрипты с названием get_antifilter_* оперируют списками адресов и масок подсетей с сайтов antifilter.network и antifilter.download :
ipset/get_antifilter_ip.sh . получает лист https://antifilter.download/list/ip.lst.
ipset/get_antifilter_ipsmart.sh . получает лист https://antifilter.network/download/ipsmart.lst. умная суммаризация отдельных адресов из ip.lst по маскам от /32 до /22
ipset/get_antifilter_ipsum.sh . получает лист https://antifilter.download/list/ipsum.lst. суммаризация отдельных адресов из ip.lst по маске /24
ipset/get_antifilter_ipresolve.sh . получает лист https://antifilter.download/list/ipresolve.lst. пре-ресолвленный список, аналогичный получаемый при помощи get_reestr_resolve. только ipv4.
ipset/get_antifilter_allyouneed.sh . получает лист https://antifilter.download/list/allyouneed.lst. Суммарный список префиксов, созданный из ipsum.lst и subnet.lst.
ipset/get_refilter_ipsum.sh . Список берется отсюда : https://github.com/1andrevich/Re-filter-lists
Все варианты рассмотренных скриптов автоматически создают и заполняют ipset. Варианты 2-10 дополнительно вызывают вариант 1.
ipset/get_config.sh . этот скрипт вызывает то, что прописано в переменной GETLIST из файла config Если переменная не определена, то ресолвятся лишь листы для ipset nozapret/nozapret6.Листы РКН все время изменяются. Возникают новые тенденции. Требования к RAM могут меняться. Поэтому необходима нечастая, но все же регулярная ревизия что же вообще у вас происходит на роутере. Или вы можете узнать о проблеме лишь когда у вас начнет постоянно пропадать wifi, и вам придется его перезагружать каждые 2 часа (метод кувалды).
Самые щадящие варианты по RAM - get_antifilter_allyouneed.sh , get_antifilter_ipsum.sh , get_refilter_*.sh .
Листы zapret-ip.txt и zapret-ipban.txt сохраняются в сжатом виде в файлы .gz. Это позволяет снизить их размер во много раз и сэкономить место на роутере. Отключить сжатие листов можно параметром конфига GZIP_LISTS=0.
На роутерах не рекомендуется вызывать эти скрипты чаще раза за 2 суток, поскольку сохранение идет либо во внутреннюю флэш память роутера, либо в случае extroot - на флэшку. В обоих случаях слишком частая запись может убить флэшку, но если это произойдет с внутренней флэш памятью, то вы просто убьете роутер.
Принудительное обновление ipset выполняет скрипт ipset/create_ipset.sh . Если передан параметр no-update , скрипт не обновляет ipset , а только создает его при его отсутствии и заполняет. Это полезно, когда могут случиться несколько последовательных вызовов скрипта. Нет смысла несколько раз перезаполнять ipset , это длительная операция на больших листах. Листы можно обновлять раз в несколько суток, и только тогда вызывать create_ipset без параметра no-update . Во всех остальных случаях стоит применять no-update .
Список РКН уже достиг внушительных размеров в сотни тысяч IP адресов. Поэтому для оптимизации ipset применяется утилита ip2net . Она берет список отдельных IP адресов и пытается интеллектуально создать из него подсети для сокращения количества адресов. ip2net отсекает неправильные записи в листах, гарантируя отсутствие ошибок при их загрузке. ip2net написан на языке C, поскольку операция ресурсоемкая. Иные способы роутер может не потянуть.
Можно внести список доменов в ipset/zapret-hosts-user-ipban.txt . Их ip адреса будут помещены в отдельный ipset ipban . Он может использоваться для принудительного завертывания всех соединений на прозрачный proxy redsocks или на VPN.
IPV6 : если включен ipv6, то дополнительно создаются листы с таким же именем, но с "6" на конце перед расширением. zapret-ip.txt => zapret-ip6.txt Создаются ipset-ы zapret6 и ipban6. Листы с antifilter не содержат список ipv6 адресов.
СИСТЕМА ИСКЛЮЧЕНИЯ IP . Все скрипты ресолвят файл zapret-hosts-user-exclude.txt , создавая zapret-ip-exclude.txt и zapret-ip-exclude6.txt . Они загоняются в ipset-ы nozapret и nozapret6. Все правила, создаваемые init скриптами, создаются с учетом этих ipset. Помещенные в них IP не участвуют в процессе. zapret-hosts-user-exclude.txt может содержать домены, ipv4 и ipv6 адреса или подсети.
FreeBSD . Скрипты ipset/*.sh работают так же на FreeBSD. Вместо ipset они создают lookup таблицы ipfw с аналогичными именами. ipfw таблицы в отличие от ipset могут содержать как ipv4, так и ipv6 адреса и подсети в одной таблице, поэтому разделения нет.
Параметр конфига LISTS_RELOAD задает произвольную команду для перезагрузки листов. Это особенно полезно на BSD системах с PF. LISTS_RELOAD=- отключает перезагрузку листов.
Утилита ip2net предназначена для преобразования ipv4 или ipv6 списка ip в список подсетей с целью сокращения размера списка. Входные данные берутся из stdin, выходные выдаются в stdout .
-4 ; лист - ipv4 (по умолчанию)
-6 ; лист - ipv6
--prefix-length=min[-max] ; диапазон рассматриваемых длин префиксов. например : 22-30 (ipv4), 56-64 (ipv6)
--v4-threshold=mul/div ; ipv4 : включать подсети, в которых заполнено по крайней мере mul/div адресов. например : 3/4
--v6-threshold=N ; ipv6 : минимальное количество ip для создания подсети
В списке могут присутствовать записи вида ip/prefix и ip1-ip2. Такие записи выкидываются в stdout без изменений. Они принимаются командой ipset. ipset умеет для листов hash:net из ip1-ip2 делать оптимальное покрытие ip/prefix. ipfw из FreeBSD понимает ip/prefix, но не понимает ip1-ip2. ip2net фильтрует входные данные, выкидывая неправильные IP адреса.
Выбирается подсеть, в которой присутствует указанный минимум адресов. Для ipv4 минимум задается как процент от размера подсети (mul/div. например, 3/4), для ipv6 минимум задается напрямую.
Размер подсети выбирается следующим алгоритмом: Сначала в указанном диапазоне длин префиксов ищутся подсети, в которых количество адресов - максимально. Если таких сетей найдено несколько, берется наименьшая сеть (префикс больше). Например, заданы параметры v6_threshold=2 prefix_length=32-64, имеются следующие ipv6 :
1234:5678:aaaa::5
1234:5678:aaaa::6
1234:5678:aaac::5
Результат будет :
1234:5678:aaa8::/45
Эти адреса так же входят в подсеть /32. Однако, нет смысла проходиться ковровой бомбардировкой, когда те же самые адреса вполне влезают в /45 и их ровно столько же. Если изменить v6_threshold=4, то результат будет:
1234:5678:aaaa::5
1234:5678:aaaa::6
1234:5678:aaac::5
То есть ip не объединятся в подсеть, потому что их слишком мало. Если изменить prefix_length=56-64 , результат будет:
1234:5678:aaaa::/64
1234:5678:aaac::5
Требуемое процессорное время для вычислений сильно зависит от ширины диапазона длин префиксов, размера искомых подсетей и длины листа. Если ip2net думает слишком долго, не используйте слишком большие подсети и уменьшите диапазон длин префиксов. Учтите, что арифметика mul/div - целочисленная. При превышении разрядной сетки 32 bit результат непредсказуем. Не надо делать такое: 5000000/10000000. 1/2 - гораздо лучше.
Программа предназначена для многопоточного ресолвинга больших листов через системный DNS. Она берет из stdin список доменов и выводит в stdout результат ресолвинга. Ошибки выводятся в stderr.
--threads=<threads_number> ; количество потоков. по умолчанию 1.
--family=<4|6|46> ; выбор семейства IP адресов : ipv4, ipv6, ipv4+ipv6
--verbose ; дебаг-лог на консоль
--stats=N ; выводить статистику каждые N доменов
--log-resolved=<file> ; сохранять успешно отресолвленные домены в файл
--log-failed=<file> ; сохранять неудачно отресолвленные домены в файл
--dns-make-query=<domain> ; вывести в stdout бинарный DNS запрос по домену. если --family=6, запрос будет AAAA, иначе A.
--dns-parse-query ; распарсить бинарный DNS ответ и выдать все ivp4 и ipv6 адреса из него в stdout
Параметры --dns-make-query и --dns-parse-query позволяют провести ресолвинг одного домена через произвольный канал. Например, следующим образом можно выполнить DoH запрос, используя лишь mdig и curl :
mdig --family=6 --dns-make-query=rutracker.org | curl --data-binary @- -H "Content-Type: application/dns-message" https://cloudflare-dns.com/dns-query | mdig --dns-parse-query
Альтернативой ipset является использование tpws или nfqws со списком доменов. Оба демона принимают неограниченное количество листов include ( --hostlist ) и exclude ( --hostlist-exclude ). Прежде всего проверяются exclude листы. При вхождении в них происходит отказ от дурения. Далее при наличии include листов проверяется домен на вхождение в них. При невхождении в список отказ от дурения. Если все include листы пустые, это приравнивается к отсутствию include листов. Ограничение перестает работать. В иных случаях происходит дурение. Нет ни одного списка - дурение всегда. Есть только exclude список - дурение всех, кроме. Есть только include список - дурение только их. Есть оба - дурение только include, кроме exclude.
В системе запуска это обыграно следующим образом. Присутствуют 2 include списка : ipset/zapret-hosts-users.txt.gz или ipset/zapret-hosts-users.txt , ipset/zapret-hosts.txt.gz или ipset/zapret-hosts.txt и 1 exclude список ipset/zapret-hosts-users-exclude.txt.gz или ipset/zapret-hosts-users-exclude.txt
При режимах фильтрации MODE_FILTER=hostlist или MODE_FILTER=autohostlist система запуска передает nfqws или tpws все листы, файлы которых присутствуют. Передача происходит через замену маркеров <HOSTLIST> и <HOSTLIST_NOAUTO> на реальные параметры --hostlist , --hostlist-exclude , --hostlist-auto . Если вдруг листы include присутствуют, но все они пустые, то работа аналогична отсутствию include листа. Файл есть, но не смотря на это дурится все, кроме exclude. Если вам нужен именно такой режим - не обязательно удалять zapret-hosts-users.txt . Достаточно сделать его пустым.
Поддомены учитываются автоматически. Например, строчка "ru" вносит в список " .ru". Строчка " .ru" в списке не сработает.
Список доменов РКН может быть получен скриптами
ipset/get_reestr_hostlist.sh
ipset/get_antizapret_domains.sh
ipset/get_reestr_resolvable_domains.sh
ipset/get_refilter_domains.sh
Он кладется в ipset/zapret-hosts.txt.gz .
При изменении времени модификации файлов списки перечитываются автоматически.
При фильтрации по именам доменов демон должен запускаться без фильтрации по ipset. tpws и nfqws решают нужно ли применять дурение в зависимости от хоста, полученного из протокола прикладного уровня (http, tls, quic). При использовании больших списков, в том числе списка РКН, оцените объем RAM на роутере ! Если после запуска демона RAM под завязку или случаются oom, значит нужно отказаться от таких больших списков.
Этот режим позволяет проанализировать как запросы со стороны клиента, так и ответы от сервера. Если хост еще не находится ни в каких листах и обнаруживается ситуация, похожая на блокировку, происходит автоматическое добавление хоста в список autohostlist как в памяти, так и в файле. nfqws или tpws сами ведут этот файл. Чтобы какой-то хост не смог попась в autohostlist используйте hostlist-exclude . Если он все-же туда попал - удалите запись из файла вручную. Процессы автоматически перечитают файл. tpws / nfqws сами назначают владельцем файла юзера, под которым они работают после сброса привилегий, чтобы иметь возможность обновлять лист.
В случае nfqws данный режим требует перенаправления в том числе и входящего трафика. Крайне рекомендовано использовать ограничитель connbytes , чтобы nfqws не обрабатывал гигабайты. По этой же причине не рекомендуется использование режима на BSD системах. Там нет фильтра connbytes .
На linux системах при использовании nfqws и фильтра connbytes может понадобится : sysctl net.netfilter.nf_conntrack_tcp_be_liberal=1 Было замечено, что некоторые DPI в России возвращают RST с неверным ACK. Это принимается tcp/ip стеком linux, но через раз приобретает статус INVALID в conntrack. Поэтому правила с connbytes срабатывают через раз, не пересылая RST пакет nfqws .
Как вообще могут вести себя DPI, получив "плохой запрос" и приняв решение о блокировке:
nfqws и tpws могут сечь варианты 1-3, 4 они не распознают. Всилу специфики работы с отдельными пакетами или с TCP каналом tpws и nfqws распознают эти ситуации по-разному. Что считается ситуацией, похожей на блокировку :
Чтобы снизить вероятность ложных срабатываний, имеется счетчик ситуаций, похожих на блокировку. Если за определенное время произойдет более определенного их количества, хост считается заблокированным и заносится в autohostlist . По нему сразу же начинает работать стратегия по обходу блокировки. Если в процессе счета вебсайт отвечает без признаков блокировки, счетчик сбрасывается. Вероятно, это был временный сбой сайта.
На практике работа с данным режимом выглядит так. Первый раз пользователь заходит на сайт и получает заглушку, сброс соединения или броузер подвисает, вываливаясь по таймауту с сообщением о невозможности загрузить страницу. Надо долбить F5, принуждая броузер повторять попытки. После некоторой попытки сайт начинает работать, и дальше он будет работать всегда.
С этим режимом можно использовать техники обхода, ломающие значительное количество сайтов. Если сайт не ведет себя как заблокированный, значит обход применен не будет. В противном случае терять все равно нечего. Однако, могут быть временные сбои сервера, приводящие к ситуации, аналогичной блокировке. Могут происходит ложные срабатывания. Если такое произошло, стратегия может начать ломать незаблокированный сайт. Эту ситуацию, увы, придется вам контролировать вручную. Заносите такие домены в ipset/zapret-hosts-user-exclude.txt , чтобы избежать повторения. Чтобы впоследствии разобраться почему домен был занесен в лист, можно включить autohostlist debug log . Он полезен тем, что работает без постоянного просмотра вывода nfqws в режиме debug. В лог заносятся только основные события, ведущие к занесению хоста в лист. По логу можно понять как избежать ложных срабатываний и подходит ли вообще вам этот режим.
Можно использовать один autohostlist с множеством процессов. Все процессы проверяют время модификации файла. Если файл был изменен в другом процессе, происходит его перечитывание. Все процессы должны работать под одним uid, чтобы были права доступа на файл.
Скрипты zapret ведут autohostlist в ipset/zapret-hosts-auto.txt . install_easy.sh при апгрейде zapret сохраняет этот файл. Режим autohostlist включает в себя режим hostlist . Можно вести ipset/zapret-hosts-user.txt , ipset/zapret-hosts-user-exclude.txt .
Перед настройкой нужно провести исследование какую бяку устроил вам ваш провайдер.
Нужно выяснить не подменяет ли он DNS и какой метод обхода DPI работает. В этом вам поможет скрипт blockcheck.sh .
Если DNS подменяется, но провайдер не перехватывает обращения к сторонним DNS, поменяйте DNS на публичный. Например: 8.8.8.8, 8.8.4.4, 1.1.1.1, 1.0.0.1, 9.9.9.9 Если DNS подменяется и провайдер перехватывает обращения к сторонним DNS, настройте dnscrypt . Еще один эффективный вариант - использовать ресолвер от yandex 77.88.8.88 на нестандартном порту 1253. Многие провайдеры не анализируют обращения к DNS на нестандартных портах. blockcheck если видит подмену DNS автоматически переключается на DoH сервера.
Следует прогнать blockcheck по нескольким заблокированным сайтам и выявить общий характер блокировок. Разные сайты могут быть заблокированы по-разному, нужно искать такую технику, которая работает на большинстве. Чтобы записать вывод blockcheck.sh в файл, выполните: ./blockcheck.sh | tee /tmp/blockcheck.txt .
Проанализируйте какие методы дурения DPI работают, в соответствии с ними настройте /opt/zapret/config .
Имейте в виду, что у провайдеров может быть несколько DPI или запросы могут идти через разные каналы по методу балансировки нагрузки. Балансировка может означать, что на разных ветках разные DPI или они находятся на разных хопах. Такая ситуация может выражаться в нестабильности работы обхода. Дернули несколько раз curl. То работает, то connection reset или редирект. blockcheck.sh выдает странноватые результаты. То split работает на 2-м. хопе, то на 4-м. Достоверность результата вызывает сомнения. В этом случае задайте несколько повторов одного и того же теста. Тест будет считаться успешным только, если все попытки пройдут успешно.
При использовании autottl следует протестировать как можно больше разных доменов. Эта техника может на одних провайдерах работать стабильно, на других потребуется выяснить при каких параметрах она стабильна, на третьих полный хаос, и проще отказаться.
Blockcheck имеет 3 уровня сканирования.
quick - максимально быстро найти хоть что-то работающее.standard дает возможность провести исследование как и на что реагирует DPI в плане методов обхода.force дает максимум проверок даже в случаях, когда ресурс работает без обхода или с более простыми стратегиями.Есть ряд других параметров, которые не будут спрашиваться в диалоге, но которые можно переопределить через переменные.
CURL - замена программы curl
CURL_MAX_TIME - время таймаута curl в секундах
CURL_MAX_TIME_QUIC - время таймаута curl для quic. если не задано, используется значение CURL_MAX_TIME
CURL_CMD=1 - показывать команды curl
CURL_OPT - дополнительные параметры curl. `-k` - игнор сертификатов. `-v` - подробный вывод протокола
DOMAINS - список тестируемых доменов через пробел
HTTP_PORT, HTTPS_PORT, QUIC_PORT - номера портов для соответствующих протоколов
SKIP_DNSCHECK=1 - отказ от проверки DNS
SKIP_TPWS=1 - отказ от тестов tpws
SKIP_PKTWS=1 - отказ от тестов nfqws/dvtws/winws
PKTWS_EXTRA, TPWS_EXTRA - дополнительные параметры nfqws/dvtws/winws и tpws
PKTWS_EXTRA_1 .. PKTWS_EXTRA_9, TPWS_EXTRA_1 .. TPWS_EXTRA_9 - отдельно дополнительные параметры, содержащие пробелы
SECURE_DNS=0|1 - принудительно выключить или включить DoH
DOH_SERVERS - список URL DoH через пробел для автоматического выбора работающего сервера
DOH_SERVER - конкретный DoH URL, отказ от поиска
UNBLOCKED_DOM - незаблокированный домен, который используется для тестов IP block
Пример запуска с переменными:
SECURE_DNS=1 SKIP_TPWS=1 CURL_MAX_TIME=1 CURL=/tmp/curl ./blockcheck.sh
СКАН ПОРТОВ
Если в системе присутствует совместимый netcat (ncat от nmap или openbsd ncat. в openwrt по умолчанию нет), то выполняется сканирование портов http или https всех IP адресов домена. Если ни один IP не отвечает, то результат очевиден. Можно останавливать сканирование. Автоматически оно не остановится, потому что netcat-ы недостаточно подробно информируют о причинах ошибки. Если доступна только часть IP, то можно ожидать хаотичных сбоев, т.к. подключение идет к случайному адресу из списка.
ПРОВЕРКА НА ЧАСТИЧНЫЙ IP block
Под частичным блоком подразумевается ситуация, когда коннект на порты есть, но по определенному транспортному или прикладному протоколу всегда идет реакция DPI вне зависимости от запрашиваемого домена. Эта проверка так же не выдаст автоматического вердикта/решения, потому что может быть очень много вариаций. Вместо этого анализ происходящего возложен на самого пользователя или тех, кто будет читать лог. Суть этой проверки в попытке дернуть неблокированный IP с блокированным доменом и наоборот, анализируя при этом реакцию DPI. Реакция DPI обычно проявляется в виде таймаута (зависание запроса), connection reset или http redirect на заглушку. Любой другой вариант скорее всего говорит об отсутствии реакции DPI. В частности, любые http коды, кроме редиректа, ведущего именно на заглушку, а не куда-то еще. На TLS - ошибки handshake без задержек. Ошибка сертификата может говорить как о реакции DPI с MiTM атакой (подмена сертификата), так и о том, что принимающий сервер неблокированного домена все равно принимает ваш TLS handshake с чужим доменом, пытаясь при этом выдать сертификат без запрошенного домена. Требуется дополнительный анализ. Если на заблокированный домен есть реакция на всех IP адресах, значит есть блокировка по домену. Если на неблокированный домен есть реакция на IP адресах блокированного домена, значит имеет место блок по IP. Соответственно, если есть и то, и другое, значит есть и блок по IP, и блок по домену. Неблокированный домен первым делом проверяется на доступность на оригинальном адресе. При недоступности тест отменяется, поскольку он будет неинформативен.
Если выяснено, что есть частичный блок по IP на DPI, то скорее всего все остальные тесты будут провалены вне зависимости от стратегий обхода. Но бывают и некоторые исключения. Например, пробитие через ipv6 option headers . Или сделать так, чтобы он не мог распознать протокол прикладного уровня. Дальнейшие тесты могут быть не лишены смысла.
ПРИМЕРЫ БЛОКИРОВКИ ТОЛЬКО ПО ДОМЕНУ БЕЗ БЛОКА ПО IP
> testing iana.org on it's original
!!!!! AVAILABLE !!!!!
> testing rutracker.org on 192.0.43.8 (iana.org)
curl: (28) Operation timed out after 1002 milliseconds with 0 bytes received
> testing iana.org on 172.67.182.196 (rutracker.org)
HTTP/1.1 409 Conflict
> testing iana.org on 104.21.32.39 (rutracker.org)
HTTP/1.1 409 Conflict
> testing iana.org on it's original ip
!!!!! AVAILABLE !!!!!
> testing rutracker.org on 192.0.43.8 (iana.org)
curl: (28) Connection timed out after 1001 milliseconds
> testing iana.org on 172.67.182.196 (rutracker.org)
curl: (35) OpenSSL/3.2.1: error:0A000410:SSL routines::ssl/tls alert handshake failure
> testing iana.org on 104.21.32.39 (rutracker.org)
curl: (35) OpenSSL/3.2.1: error:0A000410:SSL routines::ssl/tls alert handshake failure
> testing iana.org on it's original ip
!!!!! AVAILABLE !!!!!
> testing rutracker.org on 192.0.43.8 (iana.org)
HTTP/1.1 307 Temporary Redirect
Location: https://www.gblnet.net/blocked.php
> testing iana.org on 172.67.182.196 (rutracker.org)
HTTP/1.1 409 Conflict
> testing iana.org on 104.21.32.39 (rutracker.org)
HTTP/1.1 409 Conflict
> testing iana.org on it's original ip
!!!!! AVAILABLE !!!!!
> testing rutracker.org on 192.0.43.8 (iana.org)
curl: (35) Recv failure: Connection reset by peer
> testing iana.org on 172.67.182.196 (rutracker.org)
curl: (35) OpenSSL/3.2.1: error:0A000410:SSL routines::ssl/tls alert handshake failure
> testing iana.org on 104.21.32.39 (rutracker.org)
curl: (35) OpenSSL/3.2.1: error:0A000410:SSL routines::ssl/tls alert handshake failure
ПРИМЕР ПОЛНОГО IP БЛОКА ИЛИ БЛОКА TCP ПОРТА ПРИ ОТСУТСТВИИ БЛОКА ПО ДОМЕНУ
* port block tests ipv4 startmail.com:80
ncat -z -w 1 145.131.90.136 80
145.131.90.136 does not connect. netcat code 1
ncat -z -w 1 145.131.90.152 80
145.131.90.152 does not connect. netcat code 1
* curl_test_http ipv4 startmail.com
- checking without DPI bypass
curl: (28) Connection timed out after 2002 milliseconds
UNAVAILABLE code=28
- IP block tests (requires manual interpretation)
> testing iana.org on it's original ip
!!!!! AVAILABLE !!!!!
> testing startmail.com on 192.0.43.8 (iana.org)
HTTP/1.1 302 Found
Location: https://www.iana.org/
> testing iana.org on 145.131.90.136 (startmail.com)
curl: (28) Connection timed out after 2002 milliseconds
> testing iana.org on 145.131.90.152 (startmail.com)
curl: (28) Connection timed out after 2002 milliseconds
Файл /opt/zapret/config используется различными компонентами системы и содержит основные настройки. Его нужно просмотреть и при необходимости отредактировать.
На linux системах можно выбрать использовать iptables или nftables . По умолчанию на традиционных linux выбирается nftables , если установлен nft. На openwrt по умолчанию выбирается nftables на новых версиях с firewall4.
FWTYPE=iptables
На nftables можно отключить стандартную схему перехвата трафика после NAT и перейти на перехват до NAT. Это сделает невозможным применение некоторых методов дурения на проходящем трафике как в случае с iptables . nfqws начнет получать адреса пакетов из локальной сети и отображать их в логах.
POSTNAT=0
Существует 3 стандартных опции запуска, настраиваемых раздельно и независимо: tpws-socks , tpws , nfqws . Их можно использовать как по отдельности, так и вместе. Например, вам надо сделать комбинацию из методов, доступных только в tpws и только в nfqws . Их можно задействовать вместе. tpws будет прозрачно локализовывать трафик на системе и применять свое дурение, nfqws будет дурить трафик, исходящий с самой системы после обработки на tpws . А можно на эту же систему повесить без параметров socks proxy, чтобы получать доступ к обходу блокировок через прокси. Таким образом, все 3 режима вполне могут задействоваться вместе. Так же безусловно и независимо, в добавок к стандартным опциям, применяются все custom скрипты в init.d/{sysv,openwrt,macos}/custom.d .
Однако, при комбинировании tpws и nfqws с пересечением по L3/L4 протоколам не все так просто , как может показаться на первый взгляд. Первым всегда работает tpws, за ним - nfqws. На nfqws попадает уже "задуренный" трафик от tpws. Получается, что дурилка дурит дурилку, и дурилка не срабатывает, потому что ее задурили. Вот такой веселый момент. nfqws перестает распознавать протоколы и применять методы. Некоторые методы дурения от tpws nfqws в состоянии распознать и отработать корректно, но большинство - нет. Решение - использование --dpi-desync-any-protocol в nfqws и работа как с неизвестным протоколом. Комбинирование tpws и nfqws является продвинутым вариантом, требующим глубокого понимания происходящего. Очень желательно проанализировать действия nfqws по --debug логу. Все ли так, как вы задумали.
Одновременное использование tpws и nfqws без пересечения по L3/L4 (то есть nfqws - udp, tpws - tcp или nfqws - port 443, tpws - port 80 или nfqws - ipv4, tpws - ipv6) проблем не представляет.
tpws-socks требует настройки параметров tpws , но не требует перехвата трафика. Остальные опции требуют раздельно настройки перехвата трафика и опции самих демонов. Каждая опция предполагает запуск одного инстанса соответствующего демона. Все различия методов дурения для http , https , quic и т.д. должны быть отражены через схему мультистратегий. В этом смысле настройка похожа на вариант winws на Windows, а перенос конфигов не должен представлять больших сложностей. Основное правило настройки перехвата - перехватывайте только необходимый минимум. Любой перехват лишнего - это бессмысленная нагрузка на вашу систему. Опции демонов --ipset использовать запрещено. Это сделано намеренно и искусственно, чтобы не поощрять простой и работающий, но неэффективный метод на *nix системах. Используйте ipset -ы режима ядра. При необходимости пишите и задействуйте custom scripts . Настройки демонов можно для удобства писать на нескольких строках, используя двойные или одинарные кавычки. Чтобы задействовать стандартные обновляемые хост-листы из ipset , используйте маркер . Он будет заменен на параметры, соответствующие режиму MODE_FILTER, и будут подставлены реально существующие файлы. Если MODE_FILTER не предполагает стандартного хостлиста, будет заменен на пустую строку. Стандартные хостлисты следует вставлять в финальных стратегиях (стратегиях по умолчанию), закрывающих цепочки по группе параметров фильтра. Таких мест может быть несколько. Не нужно использовать в узких специализациях и в тех профилях, по которым точно не будет проходить трафик с известными протоколами, откуда поддерживается извлечение имени хоста ( http , tls , quic ). <HOSTLIST_NOAUTO> - это вариация, при которой стандартный автолист используется как обычный. То есть на этом профиле не происходит автоматическое добавление заблокированных доменов. Но если на другом профиле что-то будет добавлено, то этот профиль примет изменения автоматически.
Включение стандартной опции tpws в режиме socks
TPWS_SOCKS_ENABLE=0
На каком порту будет слушать tpws socks. прослушивается только localhost и LAN
TPPORT_SOCKS=987
Параметры tpws для режима socks
TPWS_SOCKS_OPT="
--filter-tcp=80 --methodeol <HOSTLIST> --new
--filter-tcp=443 --split-pos=1,midsld --disorder <HOSTLIST>"
Включение стандартной опции tpws в прозрачном режиме
TPWS_ENABLE=0
Какие tcp порты следует перенаправлять на tpws
TPWS_PORTS=80,443
Параметры tpws для прозрачного режима
TPWS_OPT="
--filter-tcp=80 --methodeol <HOSTLIST> --new
--filter-tcp=443 --split-pos=1,midsld --disorder <HOSTLIST>"
Включение стандартной опции nfqws
NFQWS_ENABLE=0
Какие tcp и udp порты следует перенаправлять на nfqws с использованием connbytes ограничителя
connbytes позволяет из каждого соединения перенаправить только заданное количество начальных пакетов по каждому направлению - на вход и на выход. Это более эффективная kernel-mode замена параметра nfqws --dpi-desync-cutoff=nX .
NFQWS_PORTS_TCP=80,443
NFQWS_PORTS_UDP=443
Сколько начальных входящих и исходящих пакетов нужно перенаправлять на nfqws по каждому направлению
NFQWS_TCP_PKT_OUT=$((6+$AUTOHOSTLIST_RETRANS_THRESHOLD))
NFQWS_TCP_PKT_IN=3
NFQWS_UDP_PKT_OUT=$((6+$AUTOHOSTLIST_RETRANS_THRESHOLD))
NFQWS_UDP_PKT_IN=0
Задать порты для перенаправления на nfqws без connbytes ограничителя
Есть трафик, исходящий сеанс для которого необходимо перенаправлять весь без ограничителей. Типичное применение - поддержка http keepalives на stateless DPI. Это существенно нагружает процессор. Использовать только если понимаете зачем. Чаще всего это не нужно. Входящий трафик ограничивается по connbytes через параметры PKT_IN. Если указываете здесь какие-то порты, желательно их убрать из версии с connbytes ограничителем
NFQWS_PORTS_TCP_KEEPALIVE=80
NFQWS_PORTS_UDP_KEEPALIVE=
Параметры nfqws
NFQWS_OPT="
--filter-tcp=80 --dpi-desync=fake,multisplit --dpi-desync-split-pos=method+2 --dpi-desync-fooling=md5sig <HOSTLIST> --new
--filter-tcp=443 --dpi-desync=fake,multidisorder --dpi-desync-split-pos=1,midsld --dpi-desync-fooling=badseq,md5sig <HOSTLIST> --new
--filter-udp=443 --dpi-desync=fake --dpi-desync-repeats=6 <HOSTLIST_NOAUTO>
Режим фильтрации хостов:
none - применять дурение ко всем хостам
ipset - ограничить дурение ipset-ом zapret/zapret6
hostlist - ограничить дурение списком хостов из файла
autohostlist - режим hostlist + распознавание блокировок и ведение автоматического листа
MODE_FILTER=none
Настройка системы управления выборочным traffic offload (только если поддерживается)
donttouch: выборочное управление отключено, используется системная настройка, простой инсталлятор выключает системную настройку, если она не совместима с выбранным режимом
none: выборочное управление отключено, простой инсталлятор выключает системную настройку
software: выборочное управление включено в режиме software, простой инсталлятор выключает системную настройку
hardware: выборочное управление включено в режиме hardware, простой инсталлятор выключает системную настройку
FLOWOFFLOAD=donttouch
Параметр GETLIST указывает инсталлятору install_easy.sh какой скрипт дергать для обновления списка заблокированных ip или хостов. Он же вызывается через get_config.sh из запланированных заданий (crontab или systemd timer). Поместите сюда название скрипта, который будете использовать для обновления листов. Если не нужно, то параметр следует закомментировать.
Можно индивидуально отключить ipv4 или ipv6. Если параметр закомментирован или не равен "1", использование протокола разрешено.
DISABLE_IPV4=1
DISABLE_IPV6=1
Количество потоков для многопоточного DNS ресолвера mdig (1..100). Чем их больше, тем быстрее, но не обидится ли на долбежку ваш DNS сервер?
MDIG_THREADS=30
Место для хранения временных файлов. При скачивании огромных реестров в /tmp места может не хватить. Если файловая система на нормальном носителе (не встроенная память роутера), то можно указать место на флэшке или диске. TMPDIR=/opt/zapret/tmp
Опции для создания ipset-ов и nfset-ов
SET_MAXELEM=262144
IPSET_OPT="hashsize 262144 maxelem 2097152"
Хук, позволяющий внести ip адреса динамически. $1 = имя таблицы
Адреса выводятся в stdout. В случае nfset автоматически решается проблема возможного пересечения интервалов.
IPSET_HOOK="/etc/zapret.ipset.hook"
ПРО РУГАНЬ в dmesg по поводу нехватки памяти.
Может так случиться, что памяти в системе достаточно, но при попытке заполнить огромный ipset ядро начинает громко ругаться, ipset заполняется не полностью.
Вероятная причина в том, что превышается hashsize , заданный при создании ipset (create_ipset.sh). Происходит переаллокация списка, не находится непрерывных фрагментов памяти нужной длины. Это лечится увеличением hashsize . Но чем больше hashsize , тем больше занимает ipset в памяти. Задавать слишком большой hashsize для недостаточно больших списков нецелесообразно.
Опции для вызова ip2net. Отдельно для листов ipv4 и ipv6.
IP2NET_OPT4="--prefix-length=22-30 --v4-threshold=3/4"
IP2NET_OPT6="--prefix-length=56-64 --v6-threshold=5"
Настройка режима autohostlist.
При увеличении AUTOHOSTLIST_RETRANS_THRESHOLD и использовании nfqws следует пересмотреть значения параметров NFQWS_TCP_PKT_OUT и NFQWS_UDP_PKT_OUT. Все ретрансмиссии должны быть получены nfqws, иначе триггер "зависание запроса" не сработает.
AUTOHOSTLIST_RETRANS_THRESHOLD=3
AUTOHOSTLIST_FAIL_THRESHOLD=3
AUTOHOSTLIST_FAIL_TIME=60
AUTOHOSTLIST_DEBUG=0
Включить или выключить сжатие больших листов в скриптах ipset/*.sh.
GZIP_LISTS=1
Команда для перезагрузки ip таблиц фаервола.
Если не указано или пустое, выбирается автоматически ipset или ipfw при их наличии. На BSD системах с PF нет автоматической загрузки. Там нужно указать команду явно: pfctl -f /etc/pf.conf На более новых pfctl (есть в новых FreeBSD, нет в OpenBSD 6.8) можно дать команду загрузки только таблиц: pfctl -Tl -f /etc/pf.conf "-" означает отключение загрузки листов даже при наличии поддерживаемого backend.
LISTS_RELOAD="pfctl -f /etc/pf.conf"
LISTS_RELOAD=-
В openwrt существует сеть по умолчанию 'lan'. Только трафик с этой сети будет перенаправлен на tpws. Но возможно задать другие сети или список сетей:
OPENWRT_LAN="lan lan2 lan3"
В openwrt в качестве wan берутся интерфейсы, имеющие default route. Отдельно для ipv4 и ipv6. Это можно переопределить:
OPENWRT_WAN4="wan4 vpn"
OPENWRT_WAN6="wan6 vpn6"
Параметр INIT_APPLY_FW=1 разрешает init скрипту самостоятельно применять правила iptables.
При иных значениях или если параметр закомментирован, правила применены не будут.
Это полезно, если у вас есть система управления фаерволом, в настройки которой и следует прикрутить правила.
На openwrt неприменимо при использовании firewall3+iptables.
Следующие настройки не актуальны для openwrt:
Если ваша система работает как роутер, то нужно вписать названия внутренних и внешних интерфейсов:
IFACE_LAN=eth0
IFACE_WAN=eth1
IFACE_WAN6="henet ipsec0"
Несколько интерфейсов могут быть вписаны через пробел. Если IFACE_WAN6 не задан, то берется значение IFACE_WAN.
Important
Настройка маршрутизации, маскарада и т.д. не входит в задачу zapret. Включаются только режимы, обеспечивающие перехват транзитного трафика. Возможно определить несколько интерфейсов следующим образом:
IFACE_LAN="eth0 eth1 eth2"
Если вы используете какую-то систему управления фаерволом, то она может вступать в конфликт с имеющимся скриптом запуска. При повторном применении правил она могла бы поломать настройки iptables от zapret. В этом случае правила для iptables должны быть прикручены к вашему фаерволу отдельно от запуска tpws или nfqws.
Следующие вызовы позволяют применить или убрать правила iptables отдельно:
/opt/zapret/init.d/sysv/zapret start_fw
/opt/zapret/init.d/sysv/zapret stop_fw
/opt/zapret/init.d/sysv/zapret restart_fw
А так можно запустить или остановить демоны отдельно от фаервола:
/opt/zapret/init.d/sysv/zapret start_daemons
/opt/zapret/init.d/sysv/zapret stop_daemons
/opt/zapret/init.d/sysv/zapret restart_daemons
nftables сводят практически на нет конфликты между разными системами управления, поскольку позволяют использовать независимые таблицы и хуки. Используется отдельная nf-таблица "zapret". Если ваша система ее не будет трогать, скорее всего все будет нормально.
Для nftables предусмотрено несколько дополнительных вызовов:
Посмотреть set-ы интерфейсов, относящихся к lan, wan и wan6. По ним идет завертывание трафика. А так же таблицу flow table с именами интерфейсов ingress hook.
/opt/zapret/init.d/sysv/zapret list_ifsets
Обновить set-ы интерфейсов, относящихся к lan, wan и wan6. Для традиционных linux список интерфейсов берется из переменных конфига IFACE_LAN, IFACE_WAN. Для openwrt определяется автоматически. Множество lanif может быть расширено параметром OPENWRT_LAN. Все интерфейсы lan и wan так же добавляются в ingress hook от flow table.
/opt/zapret/init.d/sysv/zapret reload_ifsets
Просмотр таблицы без содержимого set-ов. Вызывает nft -t list table inet zapret
/opt/zapret/init.d/sysv/zapret list_table
Так же возможно прицепиться своим скриптом к любой стадии применения и снятия фаервола со стороны zapret скриптов:
INIT_FW_PRE_UP_HOOK="/etc/firewall.zapret.hook.pre_up"
INIT_FW_POST_UP_HOOK="/etc/firewall.zapret.hook.post_up"
INIT_FW_PRE_DOWN_HOOK="/etc/firewall.zapret.hook.pre_down"
INIT_FW_POST_DOWN_HOOK="/etc/firewall.zapret.hook.post_down"
Эти настройки доступны в config. Может быть полезно, если вам нужно использовать nftables set-ы, например ipban / ipban6 . nfset-ы принадлежат только одной таблице, следовательно вам придется писать правила для таблицы zapret, а значит нужно синхронизироваться с применением/снятием правил со стороны zapret скриптов.
custom скрипты - это маленькие shell программы, управляющие нестандартными режимами применения zapret или частными случаями, которые не могут быть интегрированы в основную часть без загромождения и замусоривания кода. Для применеия custom следует помещать файлы в следующие директории в зависимости от вашей системы:
/opt/zapret/init.d/sysv/custom.d
/opt/zapret/init.d/openwrt/custom.d
/opt/zapret/init.d/macos/custom.d
Директория будет просканирована в алфавитном порядке, и каждый скрипт будет применен.
В init.d имеется custom.d.examples.linux , в init.d/macos - custom.d.examples . Это готовые скрипты, которые можно копировать в custom.d . Их можно взять за основу для написания собственных.
Для linux пишется код в функции
zapret_custom_daemons
zapret_custom_firewall
zapret_custom_firewall_nft
zapret_custom_firewall_nft_flush
Для macos
zapret_custom_daemons
zapret_custom_firewall_v4
zapret_custom_firewall_v6
zapret_custom_daemons поднимает демоны nfqws / tpws в нужном вам количестве и с нужными вам параметрами. В первом параметре передается код операции: 1 = запуск, 0 = останов. Схема запуска демонов в openwrt отличается - используется procd. Поэтому логика останова отсутствует за ненадобностью, останов никогда не вызывается.
zapret_custom_firewall поднимает и убирает правила iptables . В первом параметре передается код операции: 1 = запуск, 0 = останов.
zapret_custom_firewall_nft поднимает правила nftables. Логика останова отсутствует за ненадобностью. Стандартные цепочки zapret удаляются автоматически. Однако, sets и правила из ваших собственных цепочек не удаляются. Их нужно подчистить в zapret_custom_firewall_nft_flush. Если set-ов и собственных цепочек у вас нет, функцию можно не определять или оставить пустой.
Если вам не нужны iptables или nftables - можете не писать соответствующую функцию.
В linux можно использовать локальные переменные FW_EXTRA_PRE и FW_EXTRA_POST .
FW_EXTRA_PRE добавляет код к правилам ip/nf tables до кода, генерируемого функциями-хелперами.
FW_EXTRA_POST добавляет код после.
В linux функции-хелперы добавляют правило в начало цепочек, то есть перед уже имеющимися. Поэтому специализации должны идти после более общих вариантов. Для macos правило обратное. Там правила добавляются в конец. По этой же причине фаервол в Linux сначала применяется в стандартном режиме, потом custom, а в MacOS сначала custom, потом стандартный режим.
В macos firewall-функции ничего сами никуда не заносят. Их задача - лишь выдать текст в stdout, содержащий правила для pf-якоря. Остальное сделает обертка.
Особо обратите внимание на номер демона в функциях run_daemon , do_daemon , do_tpws , do_tpws_socks , do_nfqws , номера портов tpws и очередей nfqueue . Они должны быть уникальными во всех скриптах. При накладке будет ошибка. Поэтому используйте функции динамического получения этих значений из пула.
custom скрипты могут использовать переменные из config . Можно помещать в config свои переменные и задействовать их в скриптах. Можно использовать функции-хелперы. Они являются частью общего пространства функций shell. Полезные функции можно взять из примеров скриптов. Так же смотрите common/*.sh . Используя хелпер функции, вы избавитесь от необходимости учитывать все возможные случаи типа наличия/отсутствия ipv6, является ли система роутером, имена интерфейсов, ...Хелперы это учитывают. Вам нужно сосредоточиться лишь на фильтрах {ip,nf}tables и параметрах демонов.
install_easy.sh автоматизирует ручные варианты процедур установки. Он поддерживает OpenWRT, linux системы на базе systemd или openrc и MacOS.
Для более гибкой настройки перед запуском инсталлятора следует выполнить раздел "Выбор параметров".
Если система запуска поддерживается, но используется не поддерживаемый инсталлятором менеджер пакетов или названия пакетов не соответствуют прописанным в инсталлятор, пакеты нужно установить вручную. Всегда требуется curl. ipset - только для режима iptables , для nftables - не нужен.
Для совсем обрезанных дистрибутивов (alpine) требуется отдельно установить iptables и ip6tables , либо nftables .
В комплекте идут статические бинарники для большинства архитектур. Какой-то из них подойдет с вероятностью 99%. Но если у вас экзотическая система, инсталлятор попробует собрать бинарники сам через make. Для этого нужны gcc, make и необходимые -dev пакеты. Можно форсировать режим компиляции следующим вызовом:
install_easy.sh make
Под openwrt все уже сразу готово для использования системы в качестве роутера. Имена интерфейсов WAN и LAN известны из настроек системы. Под другими системами роутер вы настраиваете самостоятельно. Инсталлятор в это не вмешивается. инсталлятор в зависимости от выбранного режима может спросить LAN и WAN интерфейсы. Нужно понимать, что заворот проходящего трафика на tpws в прозрачном режиме происходит до выполнения маршрутизации, следовательно возможна фильтрация по LAN и невозможна по WAN. Решение о завороте на tpws локального исходящего трафика принимается после выполнения маршрутизации, следовательно ситуация обратная: LAN не имеет смысла, фильтрация по WAN возможна. Заворот на nfqws происходит всегда после маршрутизации, поэтому к нему применима только фильтрация по WAN. Возможность прохождения трафика в том или ином направлении настраивается вами в процессе конфигурации роутера.
Деинсталляция выполняется через uninstall_easy.sh . После выполнения деинсталляции можно удалить каталог /opt/zapret .
Работает только если у вас на роутере достаточно места.
Копируем zapret на роутер в /tmp .
Запускаем установщик:
sh /tmp/zapret/install_easy.sh
Он скопирует в /opt/zapret только необходимый минимум файлов.
После успешной установки можно удалить zapret из tmp для освобождения RAM:
rm -r /tmp/zapret
Для более гибкой настройки перед запуском инсталлятора следует выполнить раздел "Выбор параметров".
Система простой инсталяции заточена на любое умышленное или неумышленное изменение прав доступа на файлы. Устойчива к репаку под windows. После копирования в /opt права будут принудительно восстановлены.
Требуется около 120-200 кб на диске. Придется отказаться от всего, кроме tpws .
Инструкция для openwrt 22 и выше с nftables
Никаких зависимостей устанавливать не нужно.
Installation:
init.d/openwrt-minimal/tpws/* в корень openwrt./usr/bin/tpws .chmod 755 /etc/init.d/tpws /usr/bin/tpws/etc/config/tpws/etc/nftables.d/90-tpws.nft и закомментируйте строки с редиректом ipv6./etc/init.d/tpws enable/etc/init.d/tpws startfw4 restartПолное удаление:
/etc/init.d/tpws disable/etc/init.d/tpws stoprm -f /etc/nftables.d/90-tpws.nft /etc/firewall.user /etc/init.d/tpws /usr/bin/tpwsfw4 restartИнструкция для openwrt 21 и ниже с iptables
Установите зависимости:
opkg updateopkg install iptables-mod-extraopkg install ip6tables-mod-nat Убедитесь, что в /etc/firewall.user нет ничего значимого. Если есть - не следуйте слепо инструкции. Объедините код или создайте свой firewall include в /etc/config/firewall .
Installation:
init.d/openwrt-minimal/tpws/* в корень openwrt./usr/bin/tpws .chmod 755 /etc/init.d/tpws /usr/bin/tpws/etc/config/tpws/etc/init.d/tpws enable/etc/init.d/tpws startfw3 restartПолное удаление:
/etc/init.d/tpws disable/etc/init.d/tpws stoprm -f /etc/nftables.d/90-tpws.nft /etc/firewall.user /etc/init.d/tpwstouch /etc/firewall.userfw3 restart Без рута забудьте про nfqws и tpws в режиме transparent proxy. tpws будет работать только в режиме --socks .
Ядра Android имеют поддержку NFQUEUE. nfqws работает.
В стоковых ядрах нет поддержки ipset. В общем случае сложность задачи по поднятию ipset варьируется от "не просто" до "почти невозможно". Если только вы не найдете готовое собранное ядро под ваш девайс.
tpws будет работать в любом случае, он не требует чего-либо особенного.
Хотя linux варианты под Android работают, рекомендуется использовать специально собранные под bionic бинарники. У них не будет проблем с DNS, с локальным временем и именами юзеров и групп.
Рекомендуется использовать gid 3003 (AID_INET). Иначе можете получить permission denied на создание сокета. Например: --uid 1:3003
В iptables укажите: ! --uid-owner 1 вместо ! --uid-owner tpws .
Напишите шелл скрипт с iptables и tpws, запускайте его средствами вашего рут менеджера. Скрипты автозапуска лежат тут:
magisk : /data/adb/service.d
supersu: /system/su.d
nfqws может иметь такой глюк. При запуске с uid по умолчанию (0x7FFFFFFF) при условии работы на сотовом интерфейсе и отключенном кабеле внешнего питания система может частично виснуть. Перестает работать тач и кнопки, но анимация на экране может продолжаться. Если экран был погашен, то включить его кнопкой power невозможно. Изменение UID на низкий (--uid 1 подойдет) позволяет решить эту проблему. Глюк был замечен на android 8.1 на девайсе, основанном на платформе mediatek.
Ответ на вопрос куда поместить tpws на android без рута, чтобы потом его запускать из приложений. Файл заливаем через adb shell в /data/local/tmp/, лучше всего в субфолдер.
mkdir /data/local/tmp/zapret
adb push tpws /data/local/tmp/zapret
chmod 755 /data/local/tmp/zapret /data/local/tmp/zapret/tpws
chcon u:object_r:system_file:s0 /data/local/tmp/zapret/tpws
Как найти стратегию обхода сотового оператора: проще всего раздать инет на комп. Для этого подойдет любая поддерживаемая ОС. Подключите android через USB кабель к компу и включите режим модема. Прогоните стандартную процедуру blockcheck. При переносе правил на телефон уменьшить TTL на 1, если правила с TTL присутствуют в стратегии. Если проверялось на windows, убрать параметры --wf-* .
Работа blockcheck в android shell не поддерживается, но имея рута можно развернуть rootfs какого-нибудь дистрибутива linux. Это лучше всего делать с компа через adb shell. Если компа нет, то развертка chroot - единственный вариант, хотя и неудобный. Подойдет что-то легковесное, например, alpine или даже openwrt. Если это не эмулятор android, то универсальная архитектура - arm (любой вариант). Если вы точно знаете, что ОС у вас 64-разрядная, то лучше вместо arm - aarch64. Выяснить архитектуру можно командой uname -a .
mount --bind /dev /data/linux/dev
mount --bind /proc /data/linux/proc
mount --bind /sys /data/linux/sys
chroot /data/linux
Первым делом вам нужно будет один раз настроить DNS. Сам он не заведется.
echo nameserver 1.1.1.1 >/etc/resolv.conf
Далее нужно средствами пакетного менеджера установить iptables-legacy. Обязательно НЕ iptables-nft, который, как правило, присутствует по умолчанию. В ядре android нет nftables.
ls -la $(which iptables)
Линк должен указывать на legacy вариант. Если нет, значит устанавливайте нужные пакеты вашего дистрибутива, и убеждайтесь в правильности ссылок.
iptables -S
Так можно проверить, что ваш iptables увидел то, что туда насовал android. iptables-nft выдаст ошибку. Далее качаем zapret в /opt/zapret . Обычные действия с install_prereq.sh , install_bin.sh , blockcheck.sh .
Учтите, что стратегии обхода сотового оператора и домашнего wifi вероятно будут разные. Выделить сотового оператора легко через параметр iptables -o <имя интерфейса> . Имя может быть, например, ccmni0 . Его легко увидеть через ifconfig . Wifi сеть - обычно wlan0 .
Переключать blockcheck между оператором и wifi можно вместе со всем инетом - включив или выключив wifi. Если найдете стратегию для wifi и впишите ее в автостарт, то при подключении к другому wifi она может не сработать или вовсе что-то поломать, потому подумайте стоит ли. Может быть лучше сделать скрипты типа "запустить обход домашнего wifi", "снять обход домашнего wifi", и пользоваться ими по необходимости из терминала. Но домашний wifi лучше все-же обходить на роутере.
Устройства типа E3372, E8372, E5770 разделяют общую идеологию построения системы. Имеются 2 вычислительных ядра. Одно ядро выполняет vxworks, другое - linux. На 4pda имеются модифицированные прошивки с telnet и adb. Их и нужно использовать.
Дальнейшие утверждения проверены на E8372. На других может быть аналогично или похоже. Присутствуют дополнительные аппаратные блоки для offload-а сетевых функций. Не весь трафик идет через linux. Исходящий трафик с самого модема проходит цепочку OUTPUT нормально, на FORWARD =>wan часть пакетов выпадает из tcpdump.
tpws работает обычным образом.
nfqueue поломан, можно собрать фиксящий модуль https://github.com/im-0/unfuck-nfqueue-on-e3372h, используя исходники с huawei open source. Исходники содержат тулчейн и полусобирающееся, неактуальное ядро. Конфиг можно взять с рабочего модема из /proc/config.gz . С помощью этих исходников умельцы могут собрать модуль unfuck_nfqueue.ko . После его применения NFQUEUE и nfqws для arm работают нормально.
Чтобы избежать проблемы с offload-ом при использовании nfqws, следует комбинировать tpws в режиме tcp proxy и nfqws. Правила NFQUEUE пишутся для цепочки OUTPUT. connbytes придется опускать, поскольку модуля в ядре нет. Но это не смертельно.
Скрипт автозапуска - /system/etc/autorun.sh . Создайте свой скрипт настройки zapret, запускайте из конца autorun.sh через "&". Скрипт должен в начале делать sleep 5, чтобы дождаться поднятия сети и iptables от huawei.
Avertissement
На этом модеме происходят хаотические сбросы соединений tcp по непонятным причинам. Выглядит это так, если запускать curl с самого модема:
curl www.ru
curl: (7) Failed to connect to www.ru port 80: Host is unreachable
Возникает ошибка сокета EHOSTUNREACH (errno -113). То же самое видно в tpws. В броузере не подгружаются части веб страниц, картинки, стили. В tcpdump на внешнем интерфейсе eth_x виден только единственный и безответный SYN пакет, без сообщений ICMP. ОС каким-то образом узнает о невозможности установить TCP соединение и выдает ошибку. Если выполнять подключение с клиента, то SYN пропадают, соединение не устанавливается. ОС клиента проводит ретрансмиссию, и с какого-то раза подключение удается. Поэтому без tcp проксирования в этой ситуации сайты тупят, но загружаются, а с проксированием подключение выполняется, но вскоре сбрасывается без каких-либо данных, и броузеры не пытаются установить его заново. Поэтому качество броузинга с tpws может быть хуже, но дело не в tpws. Частота сбросов заметно возрастает, если запущен торент клиент, имеется много tcp соединений. Однако, причина не в переполнении таблицы conntrack. Увеличение лимитов и очистка conntrack не помогают. Предположительно эта особенность связана с обработкой пакетов сброса соединения в hardware offload. Точного ответа на вопрос у меня нет. Если вы знаете - поделитесь, пожалуйста. Чтобы не ухудшать качество броузинга, можно фильтровать заворот на tpws по ip фильтру. Поддержка ipset отсутствует. Значит, все, что можно сделать - создать индивидуальные правила на небольшое количество хостов.
Некоторые наброски скриптов присутствуют в files/huawei. Не готовое решение! Смотрите, изучайте, приспосабливайте.
Здесь можно скачать готовые полезные статические бинарники для arm, включая curl : https://github.com/bol-van/bins
Описано в документации BSD
Описано в документации Windows
Для статических бинариков не имеет значения на чем они запущены: PC, android, приставка, роутер, любой другой девайс. Подойдет любая прошивка, дистрибутив linux. Статические бинарники запустятся на всем. Им нужно только ядро с необходимыми опциями сборки или модулями. Но кроме бинариков в проекте используются еще и скрипты, в которых задействуются некоторые стандартные программы.
Основные причины почему нельзя просто так взять и установить эту систему на что угодно:
Если в вашей прошивке есть все необходимое, то вы можете адаптировать zapret под ваш девайс в той или иной степени. Может быть у вас не получится поднять все части системы, однако вы можете хотя бы попытаться поднять tpws и завернуть на него через -j REDIRECT весь трафик на порт 80. Если вам есть куда записать tpws, есть возможность выполнять команды при старте, то как минимум это вы сделать сможете. Скорее всего поддержка REDIRECT в ядре есть. Она точно есть на любом роутере, на других устройствах под вопросом. NFQUEUE, ipset на большинстве прошивок отсутствуют из-за ненужности.
Пересобрать ядро или модули для него будет скорее всего достаточно трудно. Для этого вам необходимо будет по крайней мере получить исходники вашей прошивки. User mode компоненты могут быть привнесены относительно безболезненно, если есть место куда их записать. Специально для девайсов, имеющих область r/w, существует проект entware. Некоторые прошивки даже имеют возможность его облегченной установки через веб интерфейс. entware содержит репозиторий user-mode компонент, которые устанавливаются в /opt. С их помощью можно компенсировать недостаток ПО основной прошивки, за исключением ядра.
Можно попытаться использовать sysv init script таким образом, как это описано в разделе "Прикручивание к системе управления фаерволом или своей системе запуска". В случае ругани на отсутствие каких-то базовых программ, их следует восполнить посредством entware. Перед запуском скрипта путь к дополнительным программам должен быть помещен в PATH.
Подробное описание настроек для других прошивок выходит за рамки данного проекта.
Openwrt является одной из немногих относительно полноценных linux систем для embedded devices. Она характеризуется следующими вещами, которые и послужили основой выбора именно этой прошивк:
Если не работает автономный обход, приходится перенаправлять трафик через сторонний хост. Предлагается использовать прозрачный редирект через socks5 посредством iptables+redsocks , либо iptables+iproute+vpn . Настройка варианта с redsocks на openwrt описана в redsocks.txt. Настройка варианта с iproute+wireguard - в wireguard_iproute_openwrt.txt.
VPS - это виртуальный сервер. Существует огромное множество датацентров, предлагающих данную услугу. На VPS могут выполняться какие угодно задачи. От простого веб сайта до навороченной системы собственной разработки. Можно использовать VPS и для поднятия собственного vpn или прокси. Сама широта возможных способов применения, распространенность услуги сводят к минимуму возможности регуляторов по бану сервисов такого типа. Да, если введут белые списки, то решение загнется, но это будет уже другая реальность, в которой придется изобретать иные решения. Пока этого не сделали, никто не будет банить хостинги просто потому, что они предоставляют хостинг услуги. Вы как индивидуум скорее всего никому не нужны. Подумайте чем вы отличаетесь от известного VPN провайдера. VPN провайдер предоставляет простую и доступную услугу по обходу блокировок для масс. Этот факт делает его первоочередной целью блокировки. РКН направит уведомление, после отказа сотрудничать заблокирует VPN. Предоплаченная сумма пропадет. У регуляторов нет и никогда не будет ресурсов для тотальной проверки каждого сервера в сети. Возможен китайский расклад, при котором DPI выявляет vpn протоколы и динамически банит IP серверов, предоставляющих нелицензированный VPN. Но имея знания, голову, вы всегда можете обфусцировать vpn трафик или применить другие типы VPN, более устойчивые к анализу на DPI или просто менее широкоизвестные, а следовательно с меньшей вероятностью обнаруживаемые регулятором. У вас есть свобода делать на вашем VPS все что вы захотите, адаптируясь к новым условиям. Да, это потребует знаний. Вам выбирать учиться и держать ситуацию под контролем, когда вам ничего запретить не могут, или покориться системе.
VPS можно прибрести в множестве мест. Существуют специализированные на поиске предложений VPS порталы.
Например, вот этот. Для персонального VPN сервера обычно достаточно самой минимальной конфигурации, но с безлимитным трафиком или с большим лимитом по трафику (терабайты). Важен и тип VPS. Openvz подойдет для openvpn, но вы не поднимете на нем wireguard, ipsec, то есть все, что требует kernel mode. Для kernel mode требуется тип виртуализации, предполагающий запуск полноценного экземпляра ОС linux вместе с ядром. Подойдут kvm, xen, hyper-v, vmware.
По цене можно найти предложения, которые будут дешевле готовой VPN услуги, но при этом вы сам хозяин в своей лавке и не рискуете попасть под бан регулятора, разве что "заодно" под ковровую бомбардировку с баном миллионов IP. Кроме того, если вам совсем все кажется сложным, прочитанное вызывает ступор и вы точно знаете, что ничего из описанного сделать не сможете, то вы сможете хотя бы использовать динамическое перенаправление портов ssh для получения шифрованного socks proxy и прописать его в броузер. Знания linux не нужны совсем. Это вариант наименее напряжный для чайников, хотя и не самый удобный в использовании.
USDT
0x3d52Ce15B7Be734c53fc9526ECbAB8267b63d66E
BTC
bc1qhqew3mrvp47uk2vevt5sctp7p2x9m7m5kkchve