Это старая версия документа!


Zapret - DPI bypass multi platform Topics (NFQWS)

$ amtm ep

https://github.com/bol-van/zapret

$ wget https://github.com/bol-van/zapret/releases/download/v70/zapret-v70.tar.gz
$ tar -xvzf zapret-v70.tar.gz
$ cd zapret-v70
$ ./install_easy.sh
- Y
- Y
- Y
- 1
- Y
- N
- N
- Y
- N
- 3 - br0
- 8 - eth3
- 3

Выбираем имя внутреннего сетевого интерфейса (LAN), br0 - обычно в роутере:

Но заворот трафика на nfqws происходит всегда после маршрутизации, поэтому к нему применима только фильтрация по WAN, так что LAN в этом режиме работы неважен.

Важно: выбираем режим фильтрации трафика (none, ipset, hostlist, autohostlist).
  • none - фильтрация отключена, весь трафик обрабатывается утилитой. Простейший вариант. Рекомендую его использовать, если не хотите заморачиваться настройкой списков адресов, а хотите просто, чтобы быстро и просто все работало.
  • ipset - фильтрация трафика с помощью ipset. Сложный режим, как работает читаем в инструкции.
  • hostlist - фильтрация списком хостов из файлов: /opt/zapret/ipset/zapret-hosts-user.txt - прописывайте свои домены, которые нужно обрабатывать или в файле/opt/zapret/ipset/zapret-hosts-user-exclude.txt - домены, которые нужно исключить из обработки. Пишется по одному доменному имени или IP-адресу на строчку. То что там изначально написано в файлах - удаляем. Рекомендую это режим использовать, если хотите обрабатывать только определенные адреса или наоборот если хотите исключить из обработки некоторые адреса.
  • autohostlist -режим hostlist + распознавание блокировок и ведение автоматического листа.

Режим фильтра также можно потом менять через параметр MODE_FILTER в /opt/zapret/config.

nano /opt/zapret/ipset/zapret-hosts-user.txt

www.youtube.com
youtube.com

nano /opt/zapret/init.d/sysv/zapret

#!/bin/sh
### BEGIN INIT INFO
# Provides:		zapret
# Required-Start:	$local_fs $network
# Required-Stop:	$local_fs $network
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
### END INIT INFO
 
SCRIPT=$(readlink -f "$0")
EXEDIR=$(dirname "$SCRIPT")
ZAPRET_BASE=$(readlink -f "$EXEDIR/../..")
. "$EXEDIR/functions"
 
NAME=zapret
DESC=anti-zapret
 
do_start()
{
 
   if lsmod | grep "xt_multiport " &> /dev/null ;  then
		echo "xt_multiport.ko is already loaded"
    else
        if insmod /lib/modules/$(uname -r)/xt_multiport.ko &> /dev/null; then
			echo "iptable_raw.ko loaded"
        else
			echo "Cannot find xt_multiport.ko kernel module, aborting"
			#exit 1
        fi
	fi
 
	if lsmod | grep "xt_connbytes " &> /dev/null ;  then
        echo "xt_connbytes.ko is already loaded"
    else
        if insmod /lib/modules/$(uname -r)/xt_connbytes.ko &> /dev/null; then
			echo "xt_connbytes.ko loaded"
        else
			echo "Cannot find xt_connbytes.ko kernel module, aborting"
			#exit 1
        fi
	fi
 
	if lsmod | grep "xt_NFQUEUE " &> /dev/null ;  then
        echo "xt_NFQUEUE.ko is already loaded"
    else
        if insmod /lib/modules/$(uname -r)/xt_NFQUEUE.ko &> /dev/null; then
            echo "xt_NFQUEUE.ko loaded"
        else
            echo "Cannot find xt_NFQUEUE.ko kernel module, aborting"
            #exit 1
        fi
    fi
 
	zapret_run_daemons
	[ "$INIT_APPLY_FW" != "1" ] || { zapret_apply_firewall; }
}
do_stop()
{
	zapret_stop_daemons
	[ "$INIT_APPLY_FW" != "1" ] || zapret_unapply_firewall
}
 
case "$1" in
	start)
		do_start
		;;
 
	stop)
		do_stop
		;;
 
	restart)
		do_stop
		do_start
		;;
 
	start-fw|start_fw)
		zapret_apply_firewall
		;;
	stop-fw|stop_fw)
		zapret_unapply_firewall
		;;
 
	restart-fw|restart_fw)
		zapret_unapply_firewall
		zapret_apply_firewall
		;;
 
	start-daemons|start_daemons)
		zapret_run_daemons
		;;
	stop-daemons|stop_daemons)
		zapret_stop_daemons
		;;
	restart-daemons|restart_daemons)
		zapret_stop_daemons
		zapret_run_daemons
		;;
 
	reload-ifsets|reload_ifsets)
		zapret_reload_ifsets
		;;
	list-ifsets|list_ifsets)
		zapret_list_ifsets
		;;
	list-table|list_table)
		zapret_list_table
		;;
 
  *)
	N=/etc/init.d/$NAME
	echo "Usage: $N {start|stop|restart|start-fw|stop-fw|restart-fw|start-daemons|stop-daemons|restart-daemons|reload-ifsets|list-ifsets|list-table}" >&2
	exit 1
	;;
esac
 
exit 0

nano /opt/zapret/config

# this file is included from init scripts
# change values here
 
# can help in case /tmp has not enough space
#TMPDIR=/opt/zapret/tmp
 
# redefine user for zapret daemons. required on Keenetic
WS_USER=nobody
 
# override firewall type : iptables,nftables,ipfw
FWTYPE=iptables
# nftables only : set this to 0 to use pre-nat mode. default is post-nat.
# pre-nat mode disables some bypass techniques for forwarded traffic but allows to see client IP addresses in debug log
#POSTNAT=0
 
# options for ipsets
# maximum number of elements in sets. also used for nft sets
SET_MAXELEM=522288
# too low hashsize can cause memory allocation errors on low RAM systems , even if RAM is enough
# too large hashsize will waste lots of RAM
IPSET_OPT="hashsize 262144 maxelem $SET_MAXELEM"
# dynamically generate additional ip. $1 = ipset/nfset/table name
#IPSET_HOOK="/etc/zapret.ipset.hook"
 
# options for ip2net. "-4" or "-6" auto added by ipset create script
IP2NET_OPT4="--prefix-length=22-30 --v4-threshold=3/4"
IP2NET_OPT6="--prefix-length=56-64 --v6-threshold=5"
# options for auto hostlist
AUTOHOSTLIST_RETRANS_THRESHOLD=3
AUTOHOSTLIST_FAIL_THRESHOLD=3
AUTOHOSTLIST_FAIL_TIME=60
# 1 = debug autohostlist positives to ipset/zapret-hosts-auto-debug.log
AUTOHOSTLIST_DEBUGLOG=0
 
# number of parallel threads for domain list resolves
MDIG_THREADS=30
 
# ipset/*.sh can compress large lists
GZIP_LISTS=1
# command to reload ip/host lists after update
# comment or leave empty for auto backend selection : ipset or ipfw if present
# on BSD systems with PF no auto reloading happens. you must provide your own command
# set to "-" to disable reload
#LISTS_RELOAD="pfctl -f /etc/pf.conf"
 
# mark bit used by nfqws to prevent loop
DESYNC_MARK=0x40000000
DESYNC_MARK_POSTNAT=0x20000000
 
TPWS_SOCKS_ENABLE=0
# tpws socks listens on this port on localhost and LAN interfaces
TPPORT_SOCKS=987
# use <HOSTLIST> and <HOSTLIST_NOAUTO> placeholders to engage standard hostlists and autohostlist in ipset dir
# hostlist markers are replaced to empty string if MODE_FILTER does not satisfy
# <HOSTLIST_NOAUTO> appends ipset/zapret-hosts-auto.txt as normal list
TPWS_SOCKS_OPT="
--filter-tcp=80 --methodeol <HOSTLIST> --new
--filter-tcp=443 --split-pos=1,midsld --disorder <HOSTLIST>
"
 
TPWS_ENABLE=0
TPWS_PORTS=80,443
# use <HOSTLIST> and <HOSTLIST_NOAUTO> placeholders to engage standard hostlists and autohostlist in ipset dir
# hostlist markers are replaced to empty string if MODE_FILTER does not satisfy
# <HOSTLIST_NOAUTO> appends ipset/zapret-hosts-auto.txt as normal list
TPWS_OPT="
--filter-tcp=80 --methodeol <HOSTLIST> --new
--filter-tcp=443 --split-pos=1,midsld --disorder <HOSTLIST>
"
 
NFQWS_ENABLE=1
# redirect outgoing traffic with connbytes limiter applied in both directions.
NFQWS_PORTS_TCP=80,443
NFQWS_PORTS_UDP=443
# PKT_OUT means connbytes dir original
# PKT_IN means connbytes dir reply
# this is --dpi-desync-cutoff=nX kernel mode implementation for linux. it saves a lot of CPU.
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
# redirect outgoing traffic without connbytes limiter and incoming with connbytes limiter
# normally it's needed only for stateless DPI that matches every packet in a single TCP session
# typical example are plain HTTP keep alives
# this mode can be very CPU consuming. enable with care !
#NFQWS_PORTS_TCP_KEEPALIVE=80
#NFQWS_PORTS_UDP_KEEPALIVE=
# use <HOSTLIST> and <HOSTLIST_NOAUTO> placeholders to engage standard hostlists and autohostlist in ipset dir
# hostlist markers are replaced to empty string if MODE_FILTER does not satisfy
# <HOSTLIST_NOAUTO> appends ipset/zapret-hosts-auto.txt as normal list
NFQWS_OPT="
--filter-tcp=80 --dpi-desync=fake,multisplit --dpi-desync-ttl=0 --dpi-desync-fooling=md5sig,badsum <HOSTLIST> --new
--filter-tcp=443 --dpi-desync=fake,multidisorder --dpi-desync-split-pos=method+2,midsld,5 --dpi-desync-ttl=0 --dpi-desync-fooling=md5sig,badsum,badseq --dpi-desync-repeats=15 --dpi-desync-fake-tls=/opt/zapret/files/fake/tls_clienthello_www_google_com.bin <HOSTLIST> --new
--filter-udp=443 --dpi-desync=fake --dpi-desync-repeats=15 --dpi-desync-ttl=0  --dpi-desync-any-protocol --dpi-desync-cutoff=d4 --dpi-desync-fooling=md5sig,badsum --dpi-desync-fake-quic=/opt/zapret/files/fake/quic_initial_www_google_com.bin <HOSTLIST>
"
 
# none,ipset,hostlist,autohostlist
MODE_FILTER=none
 
# openwrt only : donttouch,none,software,hardware
FLOWOFFLOAD=donttouch
 
# openwrt: specify networks to be treated as LAN. default is "lan"
#OPENWRT_LAN="lan lan2 lan3"
# openwrt: specify networks to be treated as WAN. default wans are interfaces with default route
#OPENWRT_WAN4="wan vpn"
#OPENWRT_WAN6="wan6 vpn6"
 
# for routers based on desktop linux and macos. has no effect in openwrt.
# CHOOSE LAN and optinally WAN/WAN6 NETWORK INTERFACES
# or leave them commented if its not router
# it's possible to specify multiple interfaces like this : IFACE_LAN="eth0 eth1 eth2"
# if IFACE_WAN6 is not defined it take the value of IFACE_WAN
IFACE_LAN=br0
IFACE_WAN=eth3
#IFACE_WAN6="ipsec0 wireguard0 he_net"
 
# should start/stop command of init scripts apply firewall rules ?
# not applicable to openwrt with firewall3+iptables
INIT_APPLY_FW=1
# firewall apply hooks
#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"
 
# do not work with ipv4
#DISABLE_IPV4=1
# do not work with ipv6
DISABLE_IPV6=0
 
# select which init script will be used to get ip or host list
# possible values : get_user.sh get_antizapret.sh get_combined.sh get_reestr.sh get_hostlist.sh
# comment if not required
#GETLIST
--debug=0|1: 1 = выводить отладочные сообщения
--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:" для сохранения длины пакета
--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 disorder disorder2 split split2 ipfrag2 udplen tamper
--dpi-desync-fwmark=<int|0xHEX>: бит fwmark для пометки десинхронизирующих пакетов, чтобы они повторно не падали в очередь. По умолчанию = 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 (по умолчанию) = не применять dpi desync для запросов без hostname в SNI, в частности для ESNI
--dpi-desync-split-pos=<1..1500>: (только для split*, disorder*) разбивать пакет на указанной позиции
--dpi-desync-split-http-req=method|host: разбивка HTTP request на указанном логическом месте
--dpi-desync-split-tls=sni|sniext: разбивка TLS client hello на указанном логическом месте
--dpi-desync-split-seqovl=<int>: использовать sequence overlap перед первым отсылаемым оригинальным tcp сегментом
--dpi-desync-split-seqovl-pattern=<filename>|0xHEX: чем заполнять фейковую часть overlap
--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 (по умолчанию) = работать только по HTTP request и TLS client hello, 1 = по всем непустым пакетам данных
--dpi-desync-fake-http=<filename>|0xHEX: файл, содержащий фейковый HTTP запрос для dpi-desync=fake, на замену стандартному www.iana.org
--dpi-desync-fake-tls=<filename>|0xHEX: файл, содержащий фейковый TLS client hello для 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>: применять дурение только к хостам из листа. Может быть множество листов, они объединяются. Пустой общий лист = его отсутствие
--hostlist-exclude=<filename>: не применять дурение к хостам из листа. Может быть множество листов, они объединяются
--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: начало новой стратегии
--filter-l3=ipv4|ipv6: фильтр версии ip для текущей стратегии
--filter-tcp=[~]port1[-port2]: фильтр портов tcp для текущей стратегии. ~ означает инверсию. установка фильтра tcp и неустановка фильтра udp запрещает udp.
--filter-udp=[~]port1[-port2]: фильтр портов udp для текущей стратегии. ~ означает инверсию. установка фильтра udp и неустановка фильтра tcp запрещает udp.
$ ls -la /opt/zapret/ipset
$ cp -a /opt/zapret/init.d/custom.d.examples.linux/10-keenetic-udp-fix /opt/zapret/init.d/sysv/custom.d/10-keenetic-udp-fix
$ opkg install procps-ng-sysctl

nano /opt/etc/init.d/S00fix

#!/bin/sh
start() {
    sysctl -w net.netfilter.nf_conntrack_checksum=0 &> /dev/null
}
stop() {
    sysctl -w net.netfilter.nf_conntrack_checksum=1 &> /dev/null
}
case "$1" in
    'start')
        start
        ;;
    'stop')
        stop
        ;;
    *)
        stop
        start
        ;;
esac
exit 0
$ chmod +x /opt/etc/init.d/S00fix
$ /tmp/mnt/USB/entware/zapret/ipset/get_refilter_domains.sh
$ /opt/zapret/init.d/sysv/zapret restart
$ /opt/etc/init.d/S00fix start
$ iptables -S

nano /jffs/scripts/firewall-start

/tmp/mnt/USB/entware/zapret/ipset/get_refilter_domains.sh
/opt/etc/init.d/S00fix start
/opt/zapret/init.d/sysv/zapret restart