├── .gitattributes ├── .github ├── ISSUE_TEMPLATE │ ├── config.yml │ └── issue-warning.md └── workflows │ ├── build.yml │ └── libnetfilter_queue-android.patch ├── .gitignore ├── Makefile ├── blockcheck.sh ├── common ├── base.sh ├── custom.sh ├── dialog.sh ├── elevate.sh ├── fwtype.sh ├── installer.sh ├── ipt.sh ├── linux_daemons.sh ├── linux_fw.sh ├── linux_iphelper.sh ├── list.sh ├── nft.sh ├── pf.sh ├── queue.sh └── virt.sh ├── config.default ├── docs ├── LICENSE.txt ├── bsd.en.md ├── bsd.md ├── bsdfw.txt ├── changes.txt ├── compile │ ├── build_howto_openwrt.txt │ ├── build_howto_unix.txt │ ├── build_howto_windows.txt │ └── openwrt │ │ └── package │ │ └── zapret │ │ ├── ip2net │ │ ├── Makefile │ │ └── readme.txt │ │ ├── mdig │ │ ├── Makefile │ │ └── readme.txt │ │ ├── nfqws │ │ ├── Makefile │ │ └── readme.txt │ │ └── tpws │ │ ├── Makefile │ │ └── readme.txt ├── iptables.txt ├── nftables.txt ├── nftables_notes.txt ├── quick_start.md ├── quick_start_windows.md ├── readme.en.md ├── readme.md ├── redsocks.txt ├── windows.en.md ├── windows.md └── wireguard_iproute_openwrt.txt ├── files ├── fake │ ├── dht_find_node.bin │ ├── dht_get_peers.bin │ ├── discord-ip-discovery-with-port.bin │ ├── discord-ip-discovery-without-port.bin │ ├── dtls_clienthello_w3_org.bin │ ├── http_iana_org.bin │ ├── isakmp_initiator_request.bin │ ├── quic_initial_facebook_com.bin │ ├── quic_initial_facebook_com_quiche.bin │ ├── quic_initial_rr1---sn-xguxaxjvh-n8me_googlevideo_com_kyber_1.bin │ ├── quic_initial_rr1---sn-xguxaxjvh-n8me_googlevideo_com_kyber_2.bin │ ├── quic_initial_rr2---sn-gvnuxaxjvh-o8ge_googlevideo_com.bin │ ├── quic_initial_rutracker_org.bin │ ├── quic_initial_rutracker_org_kyber_1.bin │ ├── quic_initial_rutracker_org_kyber_2.bin │ ├── quic_initial_vk_com.bin │ ├── quic_initial_www_google_com.bin │ ├── quic_short_header.bin │ ├── stun.bin │ ├── tls_clienthello_gosuslugi_ru.bin │ ├── tls_clienthello_iana_org.bin │ ├── tls_clienthello_rutracker_org_kyber.bin │ ├── tls_clienthello_sberbank_ru.bin │ ├── tls_clienthello_vk_com.bin │ ├── tls_clienthello_vk_com_kyber.bin │ ├── tls_clienthello_www_google_com.bin │ ├── wireguard_initiation.bin │ ├── wireguard_response.bin │ ├── zero_1024.bin │ ├── zero_256.bin │ └── zero_512.bin └── huawei │ └── E8372 │ ├── run-zapret-hostlist │ ├── run-zapret-ip │ ├── unfuck_nfqueue.ko │ ├── unzapret │ ├── unzapret-ip │ ├── zapret │ └── zapret-ip ├── init.d ├── custom.d.examples.linux │ ├── 10-keenetic-udp-fix │ ├── 20-fw-extra │ ├── 50-dht4all │ ├── 50-nfqws-ipset │ ├── 50-tpws-ipset │ └── 50-wg4all ├── macos │ ├── custom.d.examples │ │ └── 50-extra-tpws │ ├── custom.d │ │ └── .keep │ ├── functions │ ├── zapret │ └── zapret.plist ├── openrc │ └── zapret ├── openwrt-minimal │ ├── readme.txt │ └── tpws │ │ └── etc │ │ ├── config │ │ └── tpws │ │ ├── firewall.user │ │ ├── init.d │ │ └── tpws │ │ └── nftables.d │ │ └── 90-tpws.nft ├── openwrt │ ├── 90-zapret │ ├── custom.d │ │ └── .keep │ ├── firewall.zapret │ ├── functions │ └── zapret ├── pfsense │ └── zapret.sh ├── runit │ └── zapret │ │ ├── finish │ │ └── run ├── s6 │ └── zapret │ │ ├── down │ │ ├── type │ │ └── up ├── systemd │ ├── nfqws@.service │ ├── tpws@.service │ ├── zapret-list-update.service │ ├── zapret-list-update.timer │ └── zapret.service └── sysv │ ├── custom.d │ └── .keep │ ├── functions │ └── zapret ├── install_bin.sh ├── install_easy.sh ├── install_prereq.sh ├── ip2net ├── Makefile ├── ip2net.c ├── qsort.c └── qsort.h ├── ipset ├── antifilter.helper ├── clear_lists.sh ├── create_ipset.sh ├── def.sh ├── get_antifilter_allyouneed.sh ├── get_antifilter_ip.sh ├── get_antifilter_ipresolve.sh ├── get_antifilter_ipsmart.sh ├── get_antifilter_ipsum.sh ├── get_antizapret_domains.sh ├── get_config.sh ├── get_exclude.sh ├── get_ipban.sh ├── get_reestr_hostlist.sh ├── get_reestr_preresolved.sh ├── get_reestr_preresolved_smart.sh ├── get_reestr_resolvable_domains.sh ├── get_reestr_resolve.sh ├── get_refilter_domains.sh ├── get_refilter_ipsum.sh ├── get_user.sh └── zapret-hosts-user-exclude.txt.default ├── mdig ├── Makefile └── mdig.c ├── nfq ├── BSDmakefile ├── Makefile ├── checksum.c ├── checksum.h ├── conntrack.c ├── conntrack.h ├── crypto │ ├── aes-gcm.c │ ├── aes-gcm.h │ ├── aes.c │ ├── aes.h │ ├── gcm.c │ ├── gcm.h │ ├── hkdf.c │ ├── hmac.c │ ├── sha-private.h │ ├── sha.h │ ├── sha224-256.c │ └── usha.c ├── darkmagic.c ├── darkmagic.h ├── desync.c ├── desync.h ├── gzip.c ├── gzip.h ├── helpers.c ├── helpers.h ├── hostlist.c ├── hostlist.h ├── ipset.c ├── ipset.h ├── kavl.h ├── nfqws.c ├── nfqws.h ├── packet_queue.c ├── packet_queue.h ├── params.c ├── params.h ├── pools.c ├── pools.h ├── protocol.c ├── protocol.h ├── sec.c ├── sec.h ├── uthash.h ├── win.c ├── win.h └── windows │ ├── res │ ├── 32 │ │ ├── winicon.o │ │ └── winmanifest.o │ └── 64 │ │ ├── winicon.o │ │ └── winmanifest.o │ └── windivert │ ├── libwindivert32.a │ ├── libwindivert64.a │ └── windivert.h ├── tmp └── .keep ├── tpws ├── BSDmakefile ├── Makefile ├── andr │ ├── _musl_license.txt │ ├── getifaddrs.c │ ├── ifaddrs.h │ ├── netlink.c │ └── netlink.h ├── epoll-shim │ ├── include │ │ └── sys │ │ │ └── epoll.h │ └── src │ │ ├── epoll.c │ │ ├── epoll_shim_ctx.c │ │ ├── epoll_shim_ctx.h │ │ ├── epollfd_ctx.c │ │ ├── epollfd_ctx.h │ │ ├── eventfd_ctx.h │ │ ├── fix.c │ │ ├── fix.h │ │ ├── signalfd_ctx.h │ │ └── timerfd_ctx.h ├── gzip.c ├── gzip.h ├── helpers.c ├── helpers.h ├── hostlist.c ├── hostlist.h ├── ipset.c ├── ipset.h ├── kavl.h ├── linux_compat.h ├── macos │ ├── net │ │ └── pfvar.h │ └── sys │ │ └── tree.h ├── params.c ├── params.h ├── pools.c ├── pools.h ├── protocol.c ├── protocol.h ├── redirect.c ├── redirect.h ├── resolver.c ├── resolver.h ├── sec.c ├── sec.h ├── socks.h ├── tamper.c ├── tamper.h ├── tpws.c ├── tpws.h ├── tpws_conn.c ├── tpws_conn.h └── uthash.h └── uninstall_easy.sh /.gitattributes: -------------------------------------------------------------------------------- 1 | * text=auto eol=lf 2 | *.cmd eol=crlf 3 | *.bat eol=crlf 4 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/config.yml: -------------------------------------------------------------------------------- 1 | blank_issues_enabled: false -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/issue-warning.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: bugs 3 | about: do not write lame questions 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | 1. Здесь не место для вопросов, касающихся компьютерной грамотности и навыков использования ОС 11 | 2. Здесь не место для вопросов "у меня не работает" без технических подробностей 12 | 3. Здесь не место для вопросов "как мне открыть ютуб", "что писать в ...", "перестало открываться". 13 | 4. Здесь не место для обсуждения сборок 14 | 5. Вирусов здесь нет. У вас либо чья-то сборка, либо ваш антивирус давно пора отправить на покой. Антивирусы в основном жалуются на upx и windivert, которые убраны НЕ будут. upx - это паковщик для сокращения требуемого места на openwrt, windivert - замена iptables для windows, потенциальный инструмент хакера или компонент зловредной программы, но сам по себе вирусом не является. Не согласны - удаляйте софт. За агрессивные наезды "почему автор распространяет вирусы" молча схватите бан. 15 | 16 | Все означенное обсуждать в дискуссиях или на форумах. 17 | При нарушении будет закрываться или конвертироваться в дискуссии. 18 | Issue только для обсуждения проблем самого софта. Неработа стратегии или ваше неумение настроить - это ваша проблема, а не проблема софта. 19 | Однокнопочные решения дают только сборщики, поэтому "открытие сайта" не является функцией программы, и нет смысла жаловаться, что он не открывается. Но можно это обсудить в дискуссиях. Не захламляйте issues ! 20 | -------------------------------------------------------------------------------- /.github/workflows/libnetfilter_queue-android.patch: -------------------------------------------------------------------------------- 1 | --- a/src/extra/pktbuff.c 2 | +++ b/src/extra/pktbuff.c 3 | @@ -14,7 +14,7 @@ 4 | #include /* for memcpy */ 5 | #include 6 | 7 | -#include 8 | +#include 9 | #include 10 | #include 11 | 12 | --- a/src/nlmsg.c 13 | +++ b/src/nlmsg.c 14 | @@ -21,7 +21,7 @@ 15 | 16 | #include 17 | 18 | -#include 19 | +// #include 20 | 21 | #include "internal.h" 22 | 23 | --- a/src/extra/tcp.c 24 | +++ b/src/extra/tcp.c 25 | @@ -139,12 +139,16 @@ void nfq_tcp_compute_checksum_ipv6(struc 26 | * (union is compatible to any of its members) 27 | * This means this part of the code is -fstrict-aliasing safe now. 28 | */ 29 | +#ifndef __ANDROID__ 30 | union tcp_word_hdr { 31 | struct tcphdr hdr; 32 | uint32_t words[5]; 33 | }; 34 | +#endif 35 | 36 | +#ifndef tcp_flag_word 37 | #define tcp_flag_word(tp) ( ((union tcp_word_hdr *)(tp))->words[3]) 38 | +#endif 39 | 40 | /** 41 | * nfq_pkt_snprintf_tcp_hdr - print tcp header into one buffer in a humnan 42 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /config 2 | ip2net/ip2net 3 | mdig/mdig 4 | nfq/dvtws 5 | nfq/nfqws 6 | nfq/winws.exe 7 | nfq/WinDivert* 8 | tpws/tpws 9 | binaries/my/ 10 | ipset/zapret-ip*.txt 11 | ipset/zapret-ip*.gz 12 | ipset/zapret-hosts*.txt 13 | ipset/zapret-hosts*.gz 14 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | DIRS := nfq tpws ip2net mdig 2 | DIRS_MAC := tpws ip2net mdig 3 | TGT := binaries/my 4 | 5 | all: clean 6 | @mkdir -p "$(TGT)"; \ 7 | for dir in $(DIRS); do \ 8 | find "$$dir" -type f \( -name "*.c" -o -name "*.h" -o -name "*akefile" \) -exec chmod -x {} \; ; \ 9 | $(MAKE) -C "$$dir" || exit; \ 10 | for exe in "$$dir/"*; do \ 11 | if [ -f "$$exe" ] && [ -x "$$exe" ]; then \ 12 | mv -f "$$exe" "${TGT}" ; \ 13 | ln -fs "../${TGT}/$$(basename "$$exe")" "$$exe" ; \ 14 | fi \ 15 | done \ 16 | done 17 | 18 | systemd: clean 19 | @mkdir -p "$(TGT)"; \ 20 | for dir in $(DIRS); do \ 21 | find "$$dir" -type f \( -name "*.c" -o -name "*.h" -o -name "*akefile" \) -exec chmod -x {} \; ; \ 22 | $(MAKE) -C "$$dir" systemd || exit; \ 23 | for exe in "$$dir/"*; do \ 24 | if [ -f "$$exe" ] && [ -x "$$exe" ]; then \ 25 | mv -f "$$exe" "${TGT}" ; \ 26 | ln -fs "../${TGT}/$$(basename "$$exe")" "$$exe" ; \ 27 | fi \ 28 | done \ 29 | done 30 | 31 | android: clean 32 | @mkdir -p "$(TGT)"; \ 33 | for dir in $(DIRS); do \ 34 | find "$$dir" -type f \( -name "*.c" -o -name "*.h" -o -name "*akefile" \) -exec chmod -x {} \; ; \ 35 | $(MAKE) -C "$$dir" android || exit; \ 36 | for exe in "$$dir/"*; do \ 37 | if [ -f "$$exe" ] && [ -x "$$exe" ]; then \ 38 | mv -f "$$exe" "${TGT}" ; \ 39 | ln -fs "../${TGT}/$$(basename "$$exe")" "$$exe" ; \ 40 | fi \ 41 | done \ 42 | done 43 | 44 | bsd: clean 45 | @mkdir -p "$(TGT)"; \ 46 | for dir in $(DIRS); do \ 47 | find "$$dir" -type f \( -name "*.c" -o -name "*.h" -o -name "*akefile" \) -exec chmod -x {} \; ; \ 48 | $(MAKE) -C "$$dir" bsd || exit; \ 49 | for exe in "$$dir/"*; do \ 50 | if [ -f "$$exe" ] && [ -x "$$exe" ]; then \ 51 | mv -f "$$exe" "${TGT}" ; \ 52 | ln -fs "../${TGT}/$$(basename "$$exe")" "$$exe" ; \ 53 | fi \ 54 | done \ 55 | done 56 | 57 | mac: clean 58 | @mkdir -p "$(TGT)"; \ 59 | for dir in $(DIRS_MAC); do \ 60 | find "$$dir" -type f \( -name "*.c" -o -name "*.h" -o -name "*akefile" \) -exec chmod -x {} \; ; \ 61 | $(MAKE) -C "$$dir" mac || exit; \ 62 | for exe in "$$dir/"*; do \ 63 | if [ -f "$$exe" ] && [ -x "$$exe" ]; then \ 64 | mv -f "$$exe" "${TGT}" ; \ 65 | ln -fs "../${TGT}/$$(basename "$$exe")" "$$exe" ; \ 66 | fi \ 67 | done \ 68 | done 69 | 70 | clean: 71 | @[ -d "$(TGT)" ] && rm -rf "$(TGT)" ; \ 72 | for dir in $(DIRS); do \ 73 | $(MAKE) -C "$$dir" clean; \ 74 | done 75 | -------------------------------------------------------------------------------- /common/custom.sh: -------------------------------------------------------------------------------- 1 | custom_runner() 2 | { 3 | # $1 - function name 4 | # $2+ - params 5 | 6 | [ "$DISABLE_CUSTOM" = 1 ] && return 0 7 | 8 | local n script FUNC=$1 9 | 10 | shift 11 | 12 | [ -d "$CUSTOM_DIR/custom.d" ] && { 13 | dir_is_not_empty "$CUSTOM_DIR/custom.d" && { 14 | for script in "$CUSTOM_DIR/custom.d/"*; do 15 | [ -f "$script" ] || continue 16 | unset -f $FUNC 17 | . "$script" 18 | existf $FUNC && $FUNC "$@" 19 | done 20 | } 21 | } 22 | } 23 | 24 | alloc_tpws_port() 25 | { 26 | # $1 - target var name 27 | alloc_num NUMPOOL_TPWS_PORT $1 910 979 28 | } 29 | alloc_qnum() 30 | { 31 | # $1 - target var name 32 | alloc_num NUMPOOL_QNUM $1 65400 65499 33 | } 34 | alloc_dnum() 35 | { 36 | # alloc daemon number 37 | # $1 - target var name 38 | alloc_num NUMPOOL_DNUM $1 1000 1999 39 | } 40 | -------------------------------------------------------------------------------- /common/dialog.sh: -------------------------------------------------------------------------------- 1 | read_yes_no() 2 | { 3 | # $1 - default (Y/N) 4 | local A 5 | read A 6 | [ -z "$A" ] || ([ "$A" != "Y" ] && [ "$A" != "y" ] && [ "$A" != "N" ] && [ "$A" != "n" ]) && A=$1 7 | [ "$A" = "Y" ] || [ "$A" = "y" ] || [ "$A" = "1" ] 8 | } 9 | ask_yes_no() 10 | { 11 | # $1 - default (Y/N or 0/1) 12 | # $2 - text 13 | local DEFAULT=$1 14 | [ "$1" = "1" ] && DEFAULT=Y 15 | [ "$1" = "0" ] && DEFAULT=N 16 | [ -z "$DEFAULT" ] && DEFAULT=N 17 | printf "$2 (default : $DEFAULT) (Y/N) ? " 18 | read_yes_no $DEFAULT 19 | } 20 | ask_yes_no_var() 21 | { 22 | # $1 - variable name for answer : 0/1 23 | # $2 - text 24 | local DEFAULT 25 | eval DEFAULT="\$$1" 26 | if ask_yes_no "$DEFAULT" "$2"; then 27 | eval $1=1 28 | else 29 | eval $1=0 30 | fi 31 | } 32 | ask_list() 33 | { 34 | # $1 - mode var 35 | # $2 - space separated value list 36 | # $3 - (optional) default value 37 | local M_DEFAULT 38 | eval M_DEFAULT="\$$1" 39 | local M_ALL=$M_DEFAULT 40 | local M="" 41 | local m 42 | 43 | [ -n "$3" ] && { find_str_in_list "$M_DEFAULT" "$2" || M_DEFAULT="$3" ;} 44 | 45 | n=1 46 | for m in $2; do 47 | echo $n : $m 48 | n=$(($n+1)) 49 | done 50 | printf "your choice (default : $M_DEFAULT) : " 51 | read m 52 | [ -n "$m" ] && M=$(echo $2 | cut -d ' ' -f$m 2>/dev/null) 53 | [ -z "$M" ] && M="$M_DEFAULT" 54 | echo selected : $M 55 | eval $1="\"$M\"" 56 | 57 | [ "$M" != "$M_OLD" ] 58 | } 59 | -------------------------------------------------------------------------------- /common/elevate.sh: -------------------------------------------------------------------------------- 1 | require_root() 2 | { 3 | local exe preserve_env 4 | echo \* checking privileges 5 | [ $(id -u) -ne "0" ] && { 6 | echo root is required 7 | exe="$EXEDIR/$(basename "$0")" 8 | exists sudo && { 9 | echo elevating with sudo 10 | exec sudo -E sh "$exe" 11 | } 12 | exists su && { 13 | echo elevating with su 14 | case "$UNAME" in 15 | Linux) 16 | preserve_env="--preserve-environment" 17 | ;; 18 | FreeBSD|OpenBSD|Darwin) 19 | preserve_env="-m" 20 | ;; 21 | esac 22 | exec su $preserve_env root -c "sh \"$exe\"" 23 | } 24 | echo su or sudo not found 25 | exitp 2 26 | } 27 | HAVE_ROOT=1 28 | } 29 | -------------------------------------------------------------------------------- /common/fwtype.sh: -------------------------------------------------------------------------------- 1 | linux_ipt_avail() 2 | { 3 | exists iptables && exists ip6tables 4 | } 5 | linux_maybe_iptables_fwtype() 6 | { 7 | linux_ipt_avail && FWTYPE=iptables 8 | } 9 | linux_nft_avail() 10 | { 11 | exists nft 12 | } 13 | linux_fwtype() 14 | { 15 | [ -n "$FWTYPE" ] && return 16 | 17 | FWTYPE=unsupported 18 | 19 | linux_get_subsys 20 | if [ "$SUBSYS" = openwrt ] ; then 21 | # linux kernel is new enough if fw4 is there 22 | if [ -x /sbin/fw4 ] && linux_nft_avail ; then 23 | FWTYPE=nftables 24 | else 25 | linux_maybe_iptables_fwtype 26 | fi 27 | else 28 | SUBSYS= 29 | # generic linux 30 | # flowtable is implemented since kernel 4.16 31 | if linux_nft_avail && linux_min_version 4 16; then 32 | FWTYPE=nftables 33 | else 34 | linux_maybe_iptables_fwtype 35 | fi 36 | fi 37 | 38 | export FWTYPE 39 | } 40 | 41 | get_fwtype() 42 | { 43 | [ -n "$FWTYPE" ] && return 44 | 45 | local UNAME="$(uname)" 46 | 47 | case "$UNAME" in 48 | Linux) 49 | linux_fwtype 50 | ;; 51 | FreeBSD) 52 | if exists ipfw ; then 53 | FWTYPE=ipfw 54 | else 55 | FWTYPE=unsupported 56 | fi 57 | ;; 58 | *) 59 | FWTYPE=unsupported 60 | ;; 61 | esac 62 | 63 | export FWTYPE 64 | } 65 | -------------------------------------------------------------------------------- /common/linux_daemons.sh: -------------------------------------------------------------------------------- 1 | standard_mode_tpws_socks() 2 | { 3 | # $1 - 1 - run, 0 - stop 4 | local opt 5 | [ "$TPWS_SOCKS_ENABLE" = 1 ] && { 6 | opt="--port=$TPPORT_SOCKS $TPWS_SOCKS_OPT" 7 | filter_apply_hostlist_target opt 8 | do_tpws_socks $1 2 "$opt" 9 | } 10 | } 11 | standard_mode_tpws() 12 | { 13 | # $1 - 1 - run, 0 - stop 14 | local opt 15 | [ "$TPWS_ENABLE" = 1 ] && check_bad_ws_options $1 "$TPWS_OPT" && { 16 | opt="--port=$TPPORT $TPWS_OPT" 17 | filter_apply_hostlist_target opt 18 | do_tpws $1 1 "$opt" 19 | } 20 | } 21 | standard_mode_nfqws() 22 | { 23 | # $1 - 1 - run, 0 - stop 24 | local opt 25 | [ "$NFQWS_ENABLE" = 1 ] && check_bad_ws_options $1 "$NFQWS_OPT" && { 26 | opt="--qnum=$QNUM $NFQWS_OPT" 27 | filter_apply_hostlist_target opt 28 | do_nfqws $1 3 "$opt" 29 | } 30 | } 31 | standard_mode_daemons() 32 | { 33 | # $1 - 1 - run, 0 - stop 34 | 35 | standard_mode_tpws_socks $1 36 | standard_mode_tpws $1 37 | standard_mode_nfqws $1 38 | } 39 | zapret_do_daemons() 40 | { 41 | # $1 - 1 - run, 0 - stop 42 | 43 | standard_mode_daemons $1 44 | custom_runner zapret_custom_daemons $1 45 | 46 | return 0 47 | } 48 | zapret_run_daemons() 49 | { 50 | zapret_do_daemons 1 "$@" 51 | } 52 | zapret_stop_daemons() 53 | { 54 | zapret_do_daemons 0 "$@" 55 | } 56 | -------------------------------------------------------------------------------- /common/linux_fw.sh: -------------------------------------------------------------------------------- 1 | set_conntrack_liberal_mode() 2 | { 3 | [ -n "$SKIP_CONNTRACK_LIBERAL_MODE" ] || sysctl -w net.netfilter.nf_conntrack_tcp_be_liberal=$1 4 | } 5 | zapret_do_firewall() 6 | { 7 | linux_fwtype 8 | 9 | [ "$1" = 1 -a -n "$INIT_FW_PRE_UP_HOOK" ] && $INIT_FW_PRE_UP_HOOK 10 | [ "$1" = 0 -a -n "$INIT_FW_PRE_DOWN_HOOK" ] && $INIT_FW_PRE_DOWN_HOOK 11 | 12 | case "$FWTYPE" in 13 | iptables) 14 | zapret_do_firewall_ipt "$@" 15 | ;; 16 | nftables) 17 | zapret_do_firewall_nft "$@" 18 | ;; 19 | esac 20 | 21 | # russian DPI sends RST,ACK with wrong ACK. 22 | # this is sometimes treated by conntrack as invalid and connbytes fw rules do not pass RST packet to nfqws. 23 | # switch on liberal mode on zapret firewall start and switch off on zapret firewall stop 24 | # this is only required for processing incoming bad RSTs. incoming rules are only applied in autohostlist mode 25 | # calling this after firewall because conntrack module can be not loaded before applying conntrack firewall rules 26 | [ "$MODE_FILTER" = "autohostlist" ] && set_conntrack_liberal_mode $1 27 | 28 | [ "$1" = 1 -a -n "$INIT_FW_POST_UP_HOOK" ] && $INIT_FW_POST_UP_HOOK 29 | [ "$1" = 0 -a -n "$INIT_FW_POST_DOWN_HOOK" ] && $INIT_FW_POST_DOWN_HOOK 30 | 31 | return 0 32 | } 33 | zapret_apply_firewall() 34 | { 35 | zapret_do_firewall 1 "$@" 36 | } 37 | zapret_unapply_firewall() 38 | { 39 | zapret_do_firewall 0 "$@" 40 | } 41 | -------------------------------------------------------------------------------- /common/linux_iphelper.sh: -------------------------------------------------------------------------------- 1 | # there's no route_localnet for ipv6 2 | # the best we can is to route to link local of the incoming interface 3 | # OUTPUT - can DNAT to ::1 4 | # PREROUTING - can't DNAT to ::1. can DNAT to link local of -i interface or to any global addr 5 | # not a good idea to expose tpws to the world (bind to ::) 6 | 7 | # max wait time for the link local ipv6 on the LAN interface 8 | LINKLOCAL_WAIT_SEC=${LINKLOCAL_WAIT_SEC:-5} 9 | 10 | get_ipv6_linklocal() 11 | { 12 | # $1 - interface name. if empty - any interface 13 | if exists ip ; then 14 | local dev 15 | [ -n "$1" ] && dev="dev $1" 16 | ip addr show $dev | sed -e 's/^.*inet6 \([^ ]*\)\/[0-9]* scope link.*$/\1/;t;d' | head -n 1 17 | else 18 | ifconfig $1 | sed -re 's/^.*inet6 addr: ([^ ]*)\/[0-9]* Scope:Link.*$/\1/;t;d' | head -n 1 19 | fi 20 | } 21 | get_ipv6_global() 22 | { 23 | # $1 - interface name. if empty - any interface 24 | if exists ip ; then 25 | local dev 26 | [ -n "$1" ] && dev="dev $1" 27 | ip addr show $dev | sed -e 's/^.*inet6 \([^ ]*\)\/[0-9]* scope global.*$/\1/;t;d' | head -n 1 28 | else 29 | ifconfig $1 | sed -re 's/^.*inet6 addr: ([^ ]*)\/[0-9]* Scope:Global.*$/\1/;t;d' | head -n 1 30 | fi 31 | } 32 | 33 | iface_is_up() 34 | { 35 | # $1 - interface name 36 | [ -f /sys/class/net/$1/operstate ] || return 37 | local state 38 | read state file "/opt/zapret/ipset/zapret-ip.txt" 79 | table file "/opt/zapret/ipset/zapret-ip-user.txt" 80 | table file "/opt/zapret/ipset/zapret-ip-exclude.txt" 81 | pass out quick on em0 inet proto tcp to port {80,443} 82 | pass in quick on em0 inet proto tcp from port {80,443} flags SA/SA divert-packet port 989 no state 83 | pass in quick on em0 inet proto tcp from port {80,443} no state 84 | pass out quick on em0 inet proto tcp to port {80,443} divert-packet port 989 no state 85 | pass in quick on em0 inet proto tcp from port {80,443} flags SA/SA divert-packet port 989 no state 86 | pass in quick on em0 inet proto tcp from port {80,443} no state 87 | pass out quick on em0 inet proto tcp to port {80,443} divert-packet port 989 no state 88 | table file "/opt/zapret/ipset/zapret-ip6.txt" 89 | table file "/opt/zapret/ipset/zapret-ip-user6.txt" 90 | table file "/opt/zapret/ipset/zapret-ip-exclude6.txt" 91 | pass out quick on em0 inet6 proto tcp to port {80,443} 92 | pass in quick on em0 inet6 proto tcp from port {80,443} flags SA/SA divert-packet port 989 no state 93 | pass in quick on em0 inet6 proto tcp from port {80,443} no state 94 | pass out quick on em0 inet6 proto tcp to port {80,443} divert-packet port 989 no state 95 | pass in quick on em0 inet6 proto tcp from port {80,443} flags SA/SA divert-packet port 989 no state 96 | pass in quick on em0 inet6 proto tcp from port {80,443} no state 97 | pass out quick on em0 inet6 proto tcp to port {80,443} divert-packet port 989 no state 98 | -------------------------------------------------------------------------------- /docs/compile/build_howto_openwrt.txt: -------------------------------------------------------------------------------- 1 | How to compile native programs for use in openwrt 2 | ------------------------------------------------- 3 | 4 | 1) Install required packages to the host system : 5 | 6 | debian,ubuntu : apt install build-essential patch libncurses-dev python3-distutils unzip gawk wget git 7 | fedora: dnf install make patch gcc g++ ncurses-devel git perl 8 | 9 | Other packages may be required on your distribution. Look for the errors. 10 | 11 | 2) Download latest SDK for your target platform from https://downloads.openwrt.org 12 | 13 | examples : 14 | 15 | curl -o - https://downloads.openwrt.org/releases/23.05.5/targets/x86/64/openwrt-sdk-23.05.5-x86-64_gcc-12.3.0_musl.Linux-x86_64.tar.xz | tar -Jxv 16 | cd openwrt-sdk-23.05.5-x86-64_gcc-12.3.0_musl.Linux-x86_64 17 | 18 | curl -o - https://downloads.openwrt.org/snapshots/targets/x86/64/openwrt-sdk-x86-64_gcc-13.3.0_musl.Linux-x86_64.tar.zst | tar --zstd -xv 19 | cd openwrt-sdk-x86-64_gcc-13.3.0_musl.Linux-x86_64 20 | 21 | 3) Install required libs 22 | 23 | ./scripts/feeds update base packages 24 | ./scripts/feeds install libnetfilter-queue zlib libcap 25 | 26 | 4) Prepare openwrt package definitions 27 | 28 | cp -R /opt/zapret/docs/compile/openwrt/. . 29 | cp -R /opt/zapret/tpws package/zapret/tpws 30 | cp -R /opt/zapret/nfq package/zapret/nfqws 31 | cp -R /opt/zapret/mdig package/zapret/mdig 32 | cp -R /opt/zapret/ip2net package/zapret/ip2net 33 | rm -f package/zapret/tpws/tpws/tpws package/zapret/nfqws/nfq/nfqws package/zapret/mdig/mdig/mdig package/zapret/ip2net/ip2net/ip2net 34 | 35 | 5) Prepare .config 36 | 37 | make defconfig 38 | 39 | If you only need bins without packages comment 'CONFIG_AUTOREMOVE=y' line in .config 40 | 41 | 6) Compile 42 | 43 | dynamic build : make package/{tpws,nfqws,mdig,ip2net}/compile 44 | static build : make CFLAGS=-static package/{tpws,nfqws,mdig,ip2net}/compile 45 | 46 | 7) Get result 47 | 48 | executables only : build_dir/target/ 49 | ipk or apk packages : bin/packages/*/base 50 | 51 | 8) Installing to openwrt to use with zapret 52 | 53 | zapret with or without binaries should be already installed in /opt/zapret. 54 | Install ipk's or apk's with all compiled progs using opkg or apk. 55 | Bins are placed to /opt/zapret/binaries/my. 56 | Or copy binaries there manually and set chmod 755 to them. 57 | Run install_bin.sh or install_easy.sh. They will use bins in 'my' folder. 58 | -------------------------------------------------------------------------------- /docs/compile/build_howto_unix.txt: -------------------------------------------------------------------------------- 1 | debian,ubuntu : 2 | 3 | apt install make gcc zlib1g-dev libcap-dev libnetfilter-queue-dev libsystemd-dev 4 | make -C /opt/zapret systemd 5 | 6 | FreeBSD : 7 | 8 | make -C /opt/zapret 9 | 10 | OpenBSD : 11 | 12 | make -C /opt/zapret bsd 13 | 14 | MacOS : 15 | 16 | make -C /opt/zapret mac 17 | -------------------------------------------------------------------------------- /docs/compile/build_howto_windows.txt: -------------------------------------------------------------------------------- 1 | Windows x64 2 | 3 | 1) Download latest cygwin for windows 7 4 | 5 | curl -O https://www.cygwin.com/setup-x86_64.exe 6 | setup-x86_64.exe --allow-unsupported-windows --no-verify --site http://ctm.crouchingtigerhiddenfruitbat.org/pub/cygwin/circa/64bit/2024/01/30/231215 7 | 8 | 2) During setup install packages : make gcc-core zlib-devel 9 | 10 | 3) Run Cygwin.bat 11 | 12 | 4) cd to %ZAPRET_BASE%/nfq 13 | 14 | cd C:/Users/user/Downloads/zapret/nfq 15 | 16 | 5) Compile 17 | 18 | make cygwin64 19 | 20 | use winws.exe 21 | 22 | 6) Take windivert.dll and windivert64.sys here : https://reqrypt.org/download 23 | Choose version 2.2.2 for Windows 10 and 2.2.0 for Windows 7. 24 | 25 | 7) Copy cygwin1.dll, winws.exe, windivert.dll and windivert64.sys to one folder. 26 | 27 | 8) Run winws.exe from cmd.exe running as administrator. 28 | winws will not run from cygwin shell with cygwin1.dll copy in it's folder. 29 | winws will not run without cygwin1.dll outside of cygwin shell. 30 | -------------------------------------------------------------------------------- /docs/compile/openwrt/package/zapret/ip2net/Makefile: -------------------------------------------------------------------------------- 1 | # 2 | 3 | include $(TOPDIR)/rules.mk 4 | 5 | PKG_NAME:=ip2net 6 | PKG_RELEASE:=1 7 | 8 | include $(INCLUDE_DIR)/package.mk 9 | 10 | define Package/ip2net 11 | SECTION:=net 12 | CATEGORY:=Network 13 | TITLE:=ip2net 14 | SUBMENU:=Zapret 15 | endef 16 | 17 | define Build/Prepare 18 | mkdir -p $(PKG_BUILD_DIR) 19 | $(CP) ./ip2net/* $(PKG_BUILD_DIR)/ 20 | endef 21 | 22 | define Build/Compile 23 | $(MAKE) -C $(PKG_BUILD_DIR) $(TARGET_CONFIGURE_OPTS) 24 | endef 25 | 26 | define Package/ip2net/install 27 | $(INSTALL_DIR) $(1)/opt/zapret/binaries/my 28 | $(INSTALL_BIN) $(PKG_BUILD_DIR)/ip2net $(1)/opt/zapret/binaries/my 29 | endef 30 | 31 | $(eval $(call BuildPackage,ip2net)) 32 | 33 | -------------------------------------------------------------------------------- /docs/compile/openwrt/package/zapret/ip2net/readme.txt: -------------------------------------------------------------------------------- 1 | Copy "ip2net" folder here ! 2 | -------------------------------------------------------------------------------- /docs/compile/openwrt/package/zapret/mdig/Makefile: -------------------------------------------------------------------------------- 1 | # 2 | 3 | include $(TOPDIR)/rules.mk 4 | 5 | PKG_NAME:=mdig 6 | PKG_RELEASE:=1 7 | 8 | include $(INCLUDE_DIR)/package.mk 9 | 10 | define Package/mdig 11 | SECTION:=net 12 | CATEGORY:=Network 13 | TITLE:=mdig 14 | SUBMENU:=Zapret 15 | endef 16 | 17 | define Build/Prepare 18 | mkdir -p $(PKG_BUILD_DIR) 19 | $(CP) ./mdig/* $(PKG_BUILD_DIR)/ 20 | endef 21 | 22 | define Build/Compile 23 | $(MAKE) -C $(PKG_BUILD_DIR) $(TARGET_CONFIGURE_OPTS) 24 | endef 25 | 26 | define Package/mdig/install 27 | $(INSTALL_DIR) $(1)/opt/zapret/binaries/my 28 | $(INSTALL_BIN) $(PKG_BUILD_DIR)/mdig $(1)/opt/zapret/binaries/my 29 | endef 30 | 31 | $(eval $(call BuildPackage,mdig)) 32 | 33 | -------------------------------------------------------------------------------- /docs/compile/openwrt/package/zapret/mdig/readme.txt: -------------------------------------------------------------------------------- 1 | Copy "mdig" folder here ! 2 | -------------------------------------------------------------------------------- /docs/compile/openwrt/package/zapret/nfqws/Makefile: -------------------------------------------------------------------------------- 1 | # 2 | 3 | include $(TOPDIR)/rules.mk 4 | 5 | PKG_NAME:=nfqws 6 | PKG_RELEASE:=1 7 | 8 | include $(INCLUDE_DIR)/package.mk 9 | 10 | define Package/nfqws 11 | SECTION:=net 12 | CATEGORY:=Network 13 | TITLE:=nfqws 14 | SUBMENU:=Zapret 15 | DEPENDS:=+libnetfilter-queue +libcap +zlib 16 | endef 17 | 18 | define Build/Prepare 19 | mkdir -p $(PKG_BUILD_DIR) 20 | $(CP) ./nfq/* $(PKG_BUILD_DIR)/ 21 | endef 22 | 23 | define Build/Compile 24 | $(MAKE) -C $(PKG_BUILD_DIR) $(TARGET_CONFIGURE_OPTS) 25 | endef 26 | 27 | define Package/nfqws/install 28 | $(INSTALL_DIR) $(1)/opt/zapret/binaries/my 29 | $(INSTALL_BIN) $(PKG_BUILD_DIR)/nfqws $(1)/opt/zapret/binaries/my 30 | endef 31 | 32 | $(eval $(call BuildPackage,nfqws)) 33 | 34 | 35 | -------------------------------------------------------------------------------- /docs/compile/openwrt/package/zapret/nfqws/readme.txt: -------------------------------------------------------------------------------- 1 | Copy "nfq" folder here ! 2 | -------------------------------------------------------------------------------- /docs/compile/openwrt/package/zapret/tpws/Makefile: -------------------------------------------------------------------------------- 1 | # 2 | 3 | include $(TOPDIR)/rules.mk 4 | 5 | PKG_NAME:=tpws 6 | PKG_RELEASE:=1 7 | 8 | include $(INCLUDE_DIR)/package.mk 9 | 10 | define Package/tpws 11 | SECTION:=net 12 | CATEGORY:=Network 13 | TITLE:=tpws 14 | SUBMENU:=Zapret 15 | DEPENDS:=+zlib +libcap 16 | endef 17 | 18 | define Build/Prepare 19 | mkdir -p $(PKG_BUILD_DIR) 20 | $(CP) ./tpws/* $(PKG_BUILD_DIR)/ 21 | endef 22 | 23 | define Build/Compile 24 | $(MAKE) -C $(PKG_BUILD_DIR) $(TARGET_CONFIGURE_OPTS) 25 | endef 26 | 27 | define Package/tpws/install 28 | $(INSTALL_DIR) $(1)/opt/zapret/binaries/my 29 | $(INSTALL_BIN) $(PKG_BUILD_DIR)/tpws $(1)/opt/zapret/binaries/my 30 | endef 31 | 32 | $(eval $(call BuildPackage,tpws)) 33 | 34 | -------------------------------------------------------------------------------- /docs/compile/openwrt/package/zapret/tpws/readme.txt: -------------------------------------------------------------------------------- 1 | Copy "tpws" folder here ! 2 | -------------------------------------------------------------------------------- /docs/iptables.txt: -------------------------------------------------------------------------------- 1 | For window size changing : 2 | 3 | iptables -t mangle -I PREROUTING -p tcp --sport 80 --tcp-flags SYN,ACK SYN,ACK -j NFQUEUE --queue-num 200 --queue-bypass 4 | iptables -t mangle -I PREROUTING -p tcp --sport 80 --tcp-flags SYN,ACK SYN,ACK -m set --match-set zapret src -j NFQUEUE --queue-num 200 --queue-bypass 5 | 6 | For dpi desync attack : 7 | 8 | iptables -t mangle -I POSTROUTING -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 9 | iptables -t mangle -I POSTROUTING -p tcp --dport 443 -m mark ! --mark 0x40000000/0x40000000 -j NFQUEUE --queue-num 200 --queue-bypass 10 | iptables -t mangle -I POSTROUTING -p udp --dport 443 -m mark ! --mark 0x40000000/0x40000000 -j NFQUEUE --queue-num 200 --queue-bypass 11 | 12 | # auto hostlist with avoiding wrong ACK numbers in RST,ACK packets sent by russian DPI 13 | sysctl net.netfilter.nf_conntrack_tcp_be_liberal=1 14 | iptables -t mangle -I POSTROUTING -p tcp -m multiport --dports 80,443 -m connbytes --connbytes-dir=original --connbytes-mode=packets --connbytes 1:12 -m mark ! --mark 0x40000000/0x40000000 -j NFQUEUE --queue-num 200 --queue-bypass 15 | iptables -t mangle -I PREROUTING -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 16 | 17 | 18 | For TPROXY : 19 | 20 | sysctl -w net.ipv4.ip_forward=1 21 | iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE 22 | 23 | ip -f inet rule add fwmark 1 lookup 100 24 | ip -f inet route add local default dev lo table 100 25 | # prevent loop 26 | iptables -t filter -I INPUT -p tcp --dport 988 -j REJECT 27 | iptables -t mangle -A PREROUTING -i eth1 -p tcp --dport 80 -j MARK --set-mark 1 28 | iptables -t mangle -A PREROUTING -i eth1 -p tcp --dport 80 -j TPROXY --tproxy-mark 0x1/0x1 --on-port 988 29 | 30 | iptables -t mangle -A PREROUTING -i eth1 -p tcp --dport 80 -m set --match-set zapret dst -j MARK --set-mark 1 31 | iptables -t mangle -A PREROUTING -i eth1 -p tcp --dport 80 -m mark --mark 0x1/0x1 -j TPROXY --tproxy-mark 0x1/0x1 --on-port 988 32 | 33 | For DNAT : 34 | 35 | # run tpws as user "tpws". its required to avoid loops. 36 | sysctl -w net.ipv4.conf.eth1.route_localnet=1 37 | iptables -t nat -I PREROUTING -p tcp --dport 80 -j DNAT --to 127.0.0.127:988 38 | iptables -t nat -I OUTPUT -p tcp --dport 80 -m owner ! --uid-owner tpws -j DNAT --to 127.0.0.127:988 39 | 40 | 41 | Reset all iptable rules : 42 | 43 | iptables -F 44 | iptables -X 45 | iptables -t nat -F 46 | iptables -t nat -X 47 | iptables -t mangle -F 48 | iptables -t mangle -X 49 | iptables -t raw -F 50 | iptables -t raw -X 51 | 52 | Reset iptable policies : 53 | 54 | iptables -P INPUT ACCEPT 55 | iptables -P FORWARD ACCEPT 56 | iptables -P OUTPUT ACCEPT 57 | iptables -t mangle -P POSTROUTING ACCEPT 58 | iptables -t mangle -P PREROUTING ACCEPT 59 | iptables -t mangle -P INPUT ACCEPT 60 | iptables -t mangle -P FORWARD ACCEPT 61 | iptables -t mangle -P OUTPUT ACCEPT 62 | iptables -t raw -P PREROUTING ACCEPT 63 | iptables -t raw -P OUTPUT ACCEPT 64 | -------------------------------------------------------------------------------- /docs/nftables.txt: -------------------------------------------------------------------------------- 1 | nftables test cheat sheet 2 | simplified rules to test nfqws and tpws 3 | 4 | 5 | For DNAT : 6 | 7 | # run tpws as user "tpws". its required to avoid loops. 8 | 9 | nft delete table inet ztest 10 | nft create table inet ztest 11 | nft add chain inet ztest pre "{type nat hook prerouting priority dstnat;}" 12 | nft add rule inet ztest pre tcp dport "{80,443}" redirect to :988 13 | nft add chain inet ztest out "{type nat hook output priority -100;}" 14 | nft add rule inet ztest out tcp dport "{80,443}" skuid != tpws redirect to :988 15 | 16 | 17 | For dpi desync attack : 18 | 19 | nft delete table inet ztest 20 | nft create table inet ztest 21 | nft add chain inet ztest post "{type filter hook postrouting priority mangle;}" 22 | nft add rule inet ztest post meta mark and 0x40000000 == 0 tcp dport "{80,443}" ct original packets 1-6 queue num 200 bypass 23 | nft add rule inet ztest post meta mark and 0x40000000 == 0 udp dport 443 ct original packets 1-6 queue num 200 bypass 24 | 25 | # auto hostlist with avoiding wrong ACK numbers in RST,ACK packets sent by russian DPI 26 | sysctl net.netfilter.nf_conntrack_tcp_be_liberal=1 27 | nft add chain inet ztest pre "{type filter hook prerouting priority filter;}" 28 | nft add rule inet ztest pre tcp sport "{80,443}" ct reply packets 1-3 queue num 200 bypass 29 | 30 | 31 | show rules : nft list table inet ztest 32 | delete table : nft delete table inet ztest 33 | -------------------------------------------------------------------------------- /files/fake/dht_find_node.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bol-van/zapret/30a947b42bad60a8807831160ef6d45b34e426e2/files/fake/dht_find_node.bin -------------------------------------------------------------------------------- /files/fake/dht_get_peers.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bol-van/zapret/30a947b42bad60a8807831160ef6d45b34e426e2/files/fake/dht_get_peers.bin -------------------------------------------------------------------------------- /files/fake/discord-ip-discovery-with-port.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bol-van/zapret/30a947b42bad60a8807831160ef6d45b34e426e2/files/fake/discord-ip-discovery-with-port.bin -------------------------------------------------------------------------------- /files/fake/discord-ip-discovery-without-port.bin: -------------------------------------------------------------------------------- 1 | F̯ -------------------------------------------------------------------------------- /files/fake/dtls_clienthello_w3_org.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bol-van/zapret/30a947b42bad60a8807831160ef6d45b34e426e2/files/fake/dtls_clienthello_w3_org.bin -------------------------------------------------------------------------------- /files/fake/http_iana_org.bin: -------------------------------------------------------------------------------- 1 | GET / HTTP/1.1 2 | Host: www.iana.org 3 | Connection: keep-alive 4 | Upgrade-Insecure-Requests: 1 5 | User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4300.0 Safari/537.36 6 | Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9 7 | Accept-Encoding: gzip, deflate 8 | Accept-Language: en-US,en;q=0.9,ru;q=0.8 9 | 10 | -------------------------------------------------------------------------------- /files/fake/isakmp_initiator_request.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bol-van/zapret/30a947b42bad60a8807831160ef6d45b34e426e2/files/fake/isakmp_initiator_request.bin -------------------------------------------------------------------------------- /files/fake/quic_initial_facebook_com.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bol-van/zapret/30a947b42bad60a8807831160ef6d45b34e426e2/files/fake/quic_initial_facebook_com.bin -------------------------------------------------------------------------------- /files/fake/quic_initial_facebook_com_quiche.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bol-van/zapret/30a947b42bad60a8807831160ef6d45b34e426e2/files/fake/quic_initial_facebook_com_quiche.bin -------------------------------------------------------------------------------- /files/fake/quic_initial_rr1---sn-xguxaxjvh-n8me_googlevideo_com_kyber_1.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bol-van/zapret/30a947b42bad60a8807831160ef6d45b34e426e2/files/fake/quic_initial_rr1---sn-xguxaxjvh-n8me_googlevideo_com_kyber_1.bin -------------------------------------------------------------------------------- /files/fake/quic_initial_rr1---sn-xguxaxjvh-n8me_googlevideo_com_kyber_2.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bol-van/zapret/30a947b42bad60a8807831160ef6d45b34e426e2/files/fake/quic_initial_rr1---sn-xguxaxjvh-n8me_googlevideo_com_kyber_2.bin -------------------------------------------------------------------------------- /files/fake/quic_initial_rr2---sn-gvnuxaxjvh-o8ge_googlevideo_com.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bol-van/zapret/30a947b42bad60a8807831160ef6d45b34e426e2/files/fake/quic_initial_rr2---sn-gvnuxaxjvh-o8ge_googlevideo_com.bin -------------------------------------------------------------------------------- /files/fake/quic_initial_rutracker_org.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bol-van/zapret/30a947b42bad60a8807831160ef6d45b34e426e2/files/fake/quic_initial_rutracker_org.bin -------------------------------------------------------------------------------- /files/fake/quic_initial_rutracker_org_kyber_1.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bol-van/zapret/30a947b42bad60a8807831160ef6d45b34e426e2/files/fake/quic_initial_rutracker_org_kyber_1.bin -------------------------------------------------------------------------------- /files/fake/quic_initial_rutracker_org_kyber_2.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bol-van/zapret/30a947b42bad60a8807831160ef6d45b34e426e2/files/fake/quic_initial_rutracker_org_kyber_2.bin -------------------------------------------------------------------------------- /files/fake/quic_initial_vk_com.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bol-van/zapret/30a947b42bad60a8807831160ef6d45b34e426e2/files/fake/quic_initial_vk_com.bin -------------------------------------------------------------------------------- /files/fake/quic_initial_www_google_com.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bol-van/zapret/30a947b42bad60a8807831160ef6d45b34e426e2/files/fake/quic_initial_www_google_com.bin -------------------------------------------------------------------------------- /files/fake/quic_short_header.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bol-van/zapret/30a947b42bad60a8807831160ef6d45b34e426e2/files/fake/quic_short_header.bin -------------------------------------------------------------------------------- /files/fake/stun.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bol-van/zapret/30a947b42bad60a8807831160ef6d45b34e426e2/files/fake/stun.bin -------------------------------------------------------------------------------- /files/fake/tls_clienthello_gosuslugi_ru.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bol-van/zapret/30a947b42bad60a8807831160ef6d45b34e426e2/files/fake/tls_clienthello_gosuslugi_ru.bin -------------------------------------------------------------------------------- /files/fake/tls_clienthello_iana_org.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bol-van/zapret/30a947b42bad60a8807831160ef6d45b34e426e2/files/fake/tls_clienthello_iana_org.bin -------------------------------------------------------------------------------- /files/fake/tls_clienthello_rutracker_org_kyber.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bol-van/zapret/30a947b42bad60a8807831160ef6d45b34e426e2/files/fake/tls_clienthello_rutracker_org_kyber.bin -------------------------------------------------------------------------------- /files/fake/tls_clienthello_sberbank_ru.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bol-van/zapret/30a947b42bad60a8807831160ef6d45b34e426e2/files/fake/tls_clienthello_sberbank_ru.bin -------------------------------------------------------------------------------- /files/fake/tls_clienthello_vk_com.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bol-van/zapret/30a947b42bad60a8807831160ef6d45b34e426e2/files/fake/tls_clienthello_vk_com.bin -------------------------------------------------------------------------------- /files/fake/tls_clienthello_vk_com_kyber.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bol-van/zapret/30a947b42bad60a8807831160ef6d45b34e426e2/files/fake/tls_clienthello_vk_com_kyber.bin -------------------------------------------------------------------------------- /files/fake/tls_clienthello_www_google_com.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bol-van/zapret/30a947b42bad60a8807831160ef6d45b34e426e2/files/fake/tls_clienthello_www_google_com.bin -------------------------------------------------------------------------------- /files/fake/wireguard_initiation.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bol-van/zapret/30a947b42bad60a8807831160ef6d45b34e426e2/files/fake/wireguard_initiation.bin -------------------------------------------------------------------------------- /files/fake/wireguard_response.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bol-van/zapret/30a947b42bad60a8807831160ef6d45b34e426e2/files/fake/wireguard_response.bin -------------------------------------------------------------------------------- /files/fake/zero_1024.bin: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /files/fake/zero_256.bin: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /files/fake/zero_512.bin: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /files/huawei/E8372/run-zapret-hostlist: -------------------------------------------------------------------------------- 1 | #!/system/bin/busybox sh 2 | 3 | # download hostlist from http(s) (need curl, its absent by default), 4 | # feed it to zapret. save flash write cycles 5 | 6 | u="https://your.host.com/censorship/hoslist.txt" 7 | 8 | SCRIPT=$(readlink -f "$0") 9 | EXEDIR=$(dirname "$SCRIPT") 10 | 11 | d=/data/censorship 12 | [ -d $d ] || mkdir $d 13 | f=$d/hostlist.txt 14 | t=/hostlist.txt 15 | 16 | curl -k --fail --max-time 10 -o "$t" "$u" && { 17 | if [ -s "$t" ]; then 18 | m1=$(md5sum "$t" | cut -d ' ' -f 1) 19 | m2=$(md5sum "$f" | cut -d ' ' -f 1) 20 | echo $m1 $m2 21 | if [ -z "$m2" ] || [ "$m1" != "$m2" ]; then 22 | echo updating hostlist 23 | cp -f "$t" "$f" 24 | else 25 | echo hostlist was not changed. keeping old copy 26 | fi 27 | else 28 | echo downloaded hostlist is empty. disabling zapret 29 | rm "$f" 30 | fi 31 | } 32 | 33 | rm -f "$t" 34 | "$EXEDIR/unzapret" 35 | [ -s "$f" ] && exec "$EXEDIR/zapret" "--hostlist=$f" 36 | -------------------------------------------------------------------------------- /files/huawei/E8372/run-zapret-ip: -------------------------------------------------------------------------------- 1 | #!/system/bin/busybox sh 2 | 3 | # download hostlist from http(s) (need curl, its absent by default), 4 | # resolve to ip list, feed to zapret-ip. save flash write cycles 5 | 6 | u="https://your.host.com/censorship/hoslist.txt" 7 | 8 | SCRIPT=$(readlink -f "$0") 9 | EXEDIR=$(dirname "$SCRIPT") 10 | 11 | d=/data/censorship 12 | [ -d $d ] || mkdir $d 13 | f=$d/hostlist.txt 14 | t=/hostlist.txt 15 | i=/iplist.txt 16 | 17 | curl -k --fail --max-time 10 -o "$t" "$u" && { 18 | if [ -s "$t" ]; then 19 | m1=$(md5sum "$t" | cut -d ' ' -f 1) 20 | m2=$(md5sum "$f" | cut -d ' ' -f 1) 21 | echo $m1 $m2 22 | if [ -z "$m2" ] || [ "$m1" != "$m2" ]; then 23 | echo updating hostlist 24 | cp -f "$t" "$f" 25 | else 26 | echo hostlist was not changed. keeping old copy 27 | fi 28 | else 29 | echo downloaded hostlist is empty. disabling zapret 30 | rm "$f" 31 | fi 32 | } 33 | 34 | rm -f "$t" 35 | "$EXEDIR/unzapret-ip" 36 | [ -s "$f" ] && { 37 | mdig --threads=10 --family=4 <"$f" >"$i" 38 | [ -s "$i" ] && exec "$EXEDIR/zapret-ip" "$i" 39 | } 40 | -------------------------------------------------------------------------------- /files/huawei/E8372/unfuck_nfqueue.ko: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bol-van/zapret/30a947b42bad60a8807831160ef6d45b34e426e2/files/huawei/E8372/unfuck_nfqueue.ko -------------------------------------------------------------------------------- /files/huawei/E8372/unzapret: -------------------------------------------------------------------------------- 1 | #!/system/bin/busybox sh 2 | 3 | rule="PREROUTING -t nat -i br0 ! -d 192.168.0.0/16 -p tcp -m multiport --dports 80,443 -j REDIRECT --to-port 1" 4 | iptables -C $rule 2>/dev/null && iptables -D $rule 5 | killall tpws 6 | 7 | rule="OUTPUT -t mangle -o wan0 -p tcp -m multiport --dports 80,443 -m mark ! --mark 0x40000000/0x40000000 -j NFQUEUE --queue-num 200 --queue-bypass" 8 | iptables -C $rule 2>/dev/null && iptables -D $rule 9 | killall nfqws 10 | -------------------------------------------------------------------------------- /files/huawei/E8372/unzapret-ip: -------------------------------------------------------------------------------- 1 | #!/system/bin/busybox sh 2 | 3 | rule="PREROUTING -t nat -i br0 -p tcp -m multiport --dports 80,443 -j tpws" 4 | iptables -C $rule 2>/dev/null && iptables -D $rule 5 | iptables -F tpws -t nat 6 | iptables -X tpws -t nat 7 | killall tpws 8 | 9 | rule="OUTPUT -t mangle -o wan0 -p tcp -m multiport --dports 80,443 -m mark ! --mark 0x40000000/0x40000000 -j NFQUEUE --queue-num 200 --queue-bypass" 10 | iptables -C $rule 2>/dev/null && iptables -D $rule 11 | killall nfqws 12 | -------------------------------------------------------------------------------- /files/huawei/E8372/zapret: -------------------------------------------------------------------------------- 1 | #!/system/bin/busybox sh 2 | 3 | # $1 - additional parameters for nfqws 4 | 5 | insmod /online/modules/unfuck_nfqueue.ko 2>/dev/null 6 | 7 | rule="PREROUTING -t nat -i br0 ! -d 192.168.0.0/16 -p tcp -m multiport --dports 80,443 -j REDIRECT --to-port 1" 8 | iptables -C $rule 2>/dev/null || iptables -I $rule 9 | 10 | tpws --uid 1:3003 --port=1 --daemon 11 | 12 | rule="OUTPUT -t mangle -o wan0 -p tcp -m multiport --dports 80,443 -m mark ! --mark 0x40000000/0x40000000 -j NFQUEUE --queue-num 200 --queue-bypass" 13 | iptables -C $rule 2>/dev/null || iptables -I $rule 14 | 15 | nfqws --uid 2 --qnum=200 --dpi-desync=disorder --dpi-desync-ttl=8 --dpi-desync-fooling=md5sig --daemon $1 16 | -------------------------------------------------------------------------------- /files/huawei/E8372/zapret-ip: -------------------------------------------------------------------------------- 1 | #!/system/bin/busybox sh 2 | 3 | # $1 - ip list file. create individual rules for tpws redirection. ipset is not available 4 | 5 | [ -z "$1" ] && { 6 | echo need iplist file as parameter 7 | exit 1 8 | } 9 | 10 | insmod /online/modules/unfuck_nfqueue.ko 2>/dev/null 11 | 12 | tpws --maxconn=1024 --uid 1:3003 --port=1 --daemon 13 | 14 | 15 | REDIR="-j REDIRECT --to-port 1" 16 | 17 | iptables -F tpws -t nat 18 | iptables -X tpws -t nat 19 | iptables -N tpws -t nat 20 | iptables -A tpws -t nat -d 192.168.0.0/16 -j RETURN 21 | 22 | while read ip; do 23 | echo redirecting $ip 24 | iptables -A tpws -t nat -d $ip -p tcp $REDIR 25 | done <"$1" 26 | 27 | 28 | rule="PREROUTING -t nat -i br0 -p tcp -m multiport --dports 80,443 -j tpws" 29 | iptables -C $rule 2>/dev/null || iptables -I $rule 30 | 31 | nfqws --uid 2 --qnum=200 --dpi-desync=disorder --dpi-desync-ttl=8 --dpi-desync-fooling=md5sig --daemon 32 | 33 | rule="OUTPUT -t mangle -o wan0 -p tcp -m multiport --dports 80,443 -m mark ! --mark 0x40000000/0x40000000 -j NFQUEUE --queue-num 200 --queue-bypass" 34 | iptables -C $rule 2>/dev/null || iptables -I $rule 35 | -------------------------------------------------------------------------------- /init.d/custom.d.examples.linux/10-keenetic-udp-fix: -------------------------------------------------------------------------------- 1 | # This script fixes keenetic issue with nfqws generated udp packets 2 | # Keenetic uses proprietary ndmmark and does not masquerade without this mark 3 | # If not masqueraded packets go to WAN with LAN IP and get dropped by ISP 4 | 5 | # It's advised to set IFACE_WAN in config 6 | 7 | zapret_custom_firewall() 8 | { 9 | # $1 - 1 - add, 0 - stop 10 | 11 | local wan wanif rule 12 | 13 | [ "$DISABLE_IPV4" = "1" ] || { 14 | # use IFACE_WAN if defined. if not - search for interfaces with default route. 15 | wanif=${IFACE_WAN:-$(sed -nre 's/^([^\t]+)\t00000000\t[0-9A-F]{8}\t[0-9A-F]{4}\t[0-9]+\t[0-9]+\t[0-9]+\t00000000.*$/\1/p' /proc/net/route | sort -u | xargs)} 16 | for wan in $wanif; do 17 | rule="-o $wan -p udp -m mark --mark $DESYNC_MARK/$DESYNC_MARK" 18 | ipt_print_op $1 "$rule" "keenetic udp fix" 19 | ipt_add_del $1 POSTROUTING -t nat $rule -j MASQUERADE 20 | done 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /init.d/custom.d.examples.linux/20-fw-extra: -------------------------------------------------------------------------------- 1 | # this custom script runs standard mode with extra firewall rules 2 | 3 | # config: use TPWS_ENABLE_OVERRIDE, NFQWS_ENABLE_OVERRIDE to enable standard mode daemons 4 | # standard and override switches cannot be enabled simultaneously ! 5 | 6 | TPWS_ENABLE_OVERRIDE=${TPWS_ENABLE_OVERRIDE:-0} 7 | NFQWS_ENABLE_OVERRIDE=${NFQWS_ENABLE_OVERRIDE:-0} 8 | 9 | # config: some if these values must be set in config. not setting any of these makes this script meaningless. 10 | # pre vars put ipt/nft code to the rule beginning 11 | #FW_EXTRA_PRE_TPWS_IPT= 12 | #FW_EXTRA_PRE_TPWS_NFT= 13 | #FW_EXTRA_PRE_NFQWS_IPT="-m mark --mark 0x10000000/0x10000000" 14 | #FW_EXTRA_PRE_NFQWS_NFT="mark and 0x10000000 != 0" 15 | # post vars put ipt/nft code to the rule end 16 | #FW_EXTRA_POST_TPWS_IPT= 17 | #FW_EXTRA_POST_TPWS_NFT= 18 | #FW_EXTRA_POST_NFQWS_IPT= 19 | #FW_EXTRA_POST_NFQWS_NFT= 20 | 21 | check_std_intersect() 22 | { 23 | [ "$TPWS_ENABLE_OVERRIDE" = 1 -a "$TPWS_ENABLE" = 1 ] && { 24 | echo "ERROR ! both TPWS_ENABLE_OVERRIDE and TPWS_ENABLE are enabled" 25 | return 1 26 | } 27 | [ "$NFQWS_ENABLE_OVERRIDE" = 1 -a "$NFQWS_ENABLE" = 1 ] && { 28 | echo "ERROR ! both NFQWS_ENABLE_OVERRIDE and NFQWS_ENABLE are enabled" 29 | return 1 30 | } 31 | return 0 32 | } 33 | 34 | zapret_custom_daemons() 35 | { 36 | # $1 - 1 - add, 0 - stop 37 | 38 | check_std_intersect || return 39 | 40 | local TPWS_SOCKS_ENABLE=0 TPWS_ENABLE=$TPWS_ENABLE_OVERRIDE NFQWS_ENABLE=$NFQWS_ENABLE_OVERRIDE 41 | standard_mode_daemons "$1" 42 | } 43 | zapret_custom_firewall() 44 | { 45 | # $1 - 1 - run, 0 - stop 46 | 47 | check_std_intersect || return 48 | 49 | local FW_EXTRA_PRE FW_EXTRA_POST TPWS_ENABLE=$TPWS_ENABLE_OVERRIDE NFQWS_ENABLE=$NFQWS_ENABLE_OVERRIDE 50 | FW_EXTRA_PRE="$FW_EXTRA_PRE_TPWS_IPT" FW_EXTRA_POST="$FW_EXTRA_POST_TPWS_IPT" 51 | zapret_do_firewall_standard_tpws_rules_ipt $1 52 | FW_EXTRA_PRE="$FW_EXTRA_PRE_NFQWS_IPT" FW_EXTRA_POST="$FW_EXTRA_POST_NFQWS_IPT" 53 | zapret_do_firewall_standard_nfqws_rules_ipt $1 54 | } 55 | zapret_custom_firewall_nft() 56 | { 57 | # stop logic is not required 58 | 59 | check_std_intersect || return 60 | 61 | local FW_EXTRA_PRE FW_EXTRA_POST TPWS_ENABLE=$TPWS_ENABLE_OVERRIDE NFQWS_ENABLE=$NFQWS_ENABLE_OVERRIDE 62 | FW_EXTRA_PRE="$FW_EXTRA_PRE_TPWS_NFT" FW_EXTRA_POST="$FW_EXTRA_POST_TPWS_NFT" 63 | zapret_apply_firewall_standard_tpws_rules_nft 64 | FW_EXTRA_PRE="$FW_EXTRA_PRE_NFQWS_NFT" FW_EXTRA_POST="$FW_EXTRA_POST_NFQWS_NFT" 65 | zapret_apply_firewall_standard_nfqws_rules_nft 66 | } 67 | -------------------------------------------------------------------------------- /init.d/custom.d.examples.linux/50-dht4all: -------------------------------------------------------------------------------- 1 | # this custom script runs desync to DHT packets with udp payload length 101..399 , without ipset/hostlist filtering 2 | 3 | # can override in config : 4 | NFQWS_OPT_DESYNC_DHT="${NFQWS_OPT_DESYNC_DHT:---dpi-desync=tamper}" 5 | 6 | alloc_dnum DNUM_DHT4ALL 7 | alloc_qnum QNUM_DHT4ALL 8 | 9 | zapret_custom_daemons() 10 | { 11 | # $1 - 1 - add, 0 - stop 12 | 13 | local opt="--qnum=$QNUM_DHT4ALL $NFQWS_OPT_DESYNC_DHT" 14 | do_nfqws $1 $DNUM_DHT4ALL "$opt" 15 | } 16 | zapret_custom_firewall() 17 | { 18 | # $1 - 1 - run, 0 - stop 19 | 20 | local f uf4 uf6 21 | local first_packet_only="$ipt_connbytes 1:1" 22 | 23 | f='-p udp -m length --length 109:407 -m u32 --u32' 24 | uf4='0>>22&0x3C@8>>16=0x6431' 25 | uf6='48>>16=0x6431' 26 | fw_nfqws_post $1 "$f $uf4 $first_packet_only" "$f $uf6 $first_packet_only" $QNUM_DHT4ALL 27 | } 28 | zapret_custom_firewall_nft() 29 | { 30 | # stop logic is not required 31 | 32 | local f 33 | local first_packet_only="$nft_connbytes 1" 34 | 35 | f="meta length 109-407 meta l4proto udp @th,64,16 0x6431" 36 | nft_fw_nfqws_post "$f $first_packet_only" "$f $first_packet_only" $QNUM_DHT4ALL 37 | } 38 | -------------------------------------------------------------------------------- /init.d/custom.d.examples.linux/50-tpws-ipset: -------------------------------------------------------------------------------- 1 | # this custom script demonstrates how to launch extra tpws instance limited by ipset 2 | 3 | # can override in config : 4 | TPWS_MY1_OPT="${TPWS_MY1_OPT:---oob --split-pos=midsld}" 5 | TPWS_MY1_PORTS=${TPWS_MY1_PORTS:-$TPWS_PORTS} 6 | TPWS_MY1_SUBNETS4="${TPWS_MY1_SUBNETS4:-142.250.0.0/15 64.233.160.0/19 172.217.0.0/16 173.194.0.0/16 108.177.0.0/17 74.125.0.0/16 209.85.128.0/17 216.58.192.0/19}" 7 | TPWS_MY1_SUBNETS6="${TPWS_MY1_SUBNETS6:-2607:F8B0::/32 2a00:1450:4000::/37}" 8 | 9 | TPWS_MY1_IPSET_SIZE=${TPWS_MY1_IPSET_SIZE:-4096} 10 | TPWS_MY1_IPSET_OPT="${TPWS_MY1_IPSET_OPT:-hash:net hashsize 8192 maxelem $TPWS_MY1_IPSET_SIZE}" 11 | 12 | alloc_dnum DNUM_TPWS_MY1 13 | alloc_tpws_port PORT_TPWS_MY1 14 | TPWS_MY1_NAME4=my1tpws4 15 | TPWS_MY1_NAME6=my1tpws6 16 | 17 | zapret_custom_daemons() 18 | { 19 | # $1 - 1 - run, 0 - stop 20 | 21 | local opt="--port=$PORT_TPWS_MY1 $TPWS_MY1_OPT" 22 | do_tpws $1 $DNUM_TPWS_MY1 "$opt" 23 | } 24 | 25 | zapret_custom_firewall() 26 | { 27 | # $1 - 1 - run, 0 - stop 28 | 29 | local f4 f6 subnet 30 | local PORTS_IPT=$(replace_char - : $TPWS_MY1_PORTS) 31 | 32 | [ "$1" = 1 -a "$DISABLE_IPV4" != 1 ] && { 33 | ipset create $TPWS_MY1_NAME4 $TPWS_MY1_IPSET_OPT family inet 2>/dev/null 34 | ipset flush $TPWS_MY1_NAME4 35 | for subnet in $TPWS_MY1_SUBNETS4; do 36 | echo add $TPWS_MY1_NAME4 $subnet 37 | done | ipset -! restore 38 | } 39 | [ "$1" = 1 -a "$DISABLE_IPV6" != 1 ] && { 40 | ipset create $TPWS_MY1_NAME6 $TPWS_MY1_IPSET_OPT family inet6 2>/dev/null 41 | ipset flush $TPWS_MY1_NAME6 42 | for subnet in $TPWS_MY1_SUBNETS6; do 43 | echo add $TPWS_MY1_NAME6 $subnet 44 | done | ipset -! restore 45 | } 46 | 47 | f4="-p tcp -m multiport --dports $PORTS_IPT -m set --match-set" 48 | f6="$f4 $TPWS_MY1_NAME6 dst" 49 | f4="$f4 $TPWS_MY1_NAME4 dst" 50 | fw_tpws $1 "$f4" "$f6" $PORT_TPWS_MY1 51 | 52 | [ "$1" = 1 ] || { 53 | ipset destroy $TPWS_MY1_NAME4 2>/dev/null 54 | ipset destroy $TPWS_MY1_NAME6 2>/dev/null 55 | } 56 | } 57 | 58 | zapret_custom_firewall_nft() 59 | { 60 | local f4 f6 subnets 61 | 62 | [ "$DISABLE_IPV4" != 1 ] && { 63 | make_comma_list subnets $TPWS_MY1_SUBNETS4 64 | nft_create_set $TPWS_MY1_NAME4 "type ipv4_addr; size $TPWS_MY1_IPSET_SIZE; auto-merge; flags interval;" 65 | nft_flush_set $TPWS_MY1_NAME4 66 | nft_add_set_element $TPWS_MY1_NAME4 "$subnets" 67 | } 68 | [ "$DISABLE_IPV6" != 1 ] && { 69 | make_comma_list subnets $TPWS_MY1_SUBNETS6 70 | nft_create_set $TPWS_MY1_NAME6 "type ipv6_addr; size $TPWS_MY1_IPSET_SIZE; auto-merge; flags interval;" 71 | nft_flush_set $TPWS_MY1_NAME6 72 | nft_add_set_element $TPWS_MY1_NAME6 "$subnets" 73 | } 74 | 75 | f4="tcp dport {$TPWS_MY1_PORTS}" 76 | f6="$f4 ip6 daddr @$TPWS_MY1_NAME6" 77 | f4="$f4 ip daddr @$TPWS_MY1_NAME4" 78 | nft_fw_tpws "$f4" "$f6" $PORT_TPWS_MY1 79 | } 80 | 81 | zapret_custom_firewall_nft_flush() 82 | { 83 | # this function is called after all nft fw rules are deleted 84 | # however sets are not deleted. it's desired to clear sets here. 85 | 86 | nft_del_set $TPWS_MY1_NAME4 2>/dev/null 87 | nft_del_set $TPWS_MY1_NAME6 2>/dev/null 88 | } 89 | -------------------------------------------------------------------------------- /init.d/custom.d.examples.linux/50-wg4all: -------------------------------------------------------------------------------- 1 | # this custom script runs desync to all wireguard handshake initiation packets 2 | 3 | # can override in config : 4 | NFQWS_OPT_DESYNC_WG="${NFQWS_OPT_DESYNC_WG:---dpi-desync=fake}" 5 | 6 | alloc_dnum DNUM_WG4ALL 7 | alloc_qnum QNUM_WG4ALL 8 | 9 | zapret_custom_daemons() 10 | { 11 | # $1 - 1 - add, 0 - stop 12 | 13 | local opt="--qnum=$QNUM_WG4ALL $NFQWS_OPT_DESYNC_WG" 14 | do_nfqws $1 $DNUM_WG4ALL "$opt" 15 | } 16 | # size = 156 (8 udp header + 148 payload) && payload starts with 0x01000000 17 | zapret_custom_firewall() 18 | { 19 | # $1 - 1 - run, 0 - stop 20 | 21 | local f='-p udp -m u32 --u32' 22 | fw_nfqws_post $1 "$f 0>>22&0x3C@4>>16=0x9c&&0>>22&0x3C@8=0x01000000" "$f 44>>16=0x9c&&48=0x01000000" $QNUM_WG4ALL 23 | } 24 | zapret_custom_firewall_nft() 25 | { 26 | # stop logic is not required 27 | 28 | local f="udp length 156 @th,64,32 0x01000000" 29 | nft_fw_nfqws_post "$f" "$f" $QNUM_WG4ALL 30 | } 31 | -------------------------------------------------------------------------------- /init.d/macos/custom.d.examples/50-extra-tpws: -------------------------------------------------------------------------------- 1 | # this script is an example describing how to run tpws on a custom port 2 | 3 | TPWS_OPT_EXTRA=${TPWS_OPT_EXTRA:---split-pos=2} 4 | DPORTS_EXTRA=${DPORTS_EXTRA:-20443,20444,30000-30009} 5 | 6 | alloc_dnum DNUM_EXTRA_TPWS 7 | alloc_tpws_port TPPORT_EXTRA_TPWS 8 | 9 | zapret_custom_daemons() 10 | { 11 | # $1 - 1 - run, 0 - stop 12 | local opt="--user=root --port=$TPPORT_EXTRA_TPWS" 13 | tpws_apply_binds opt 14 | opt="$opt $TPWS_OPT_EXTRA" 15 | filter_apply_hostlist_target opt 16 | do_daemon $1 $DNUM_EXTRA_TPWS "$TPWS" "$opt" 17 | } 18 | 19 | # custom firewall functions echo rules for zapret-v4 and zapret-v6 anchors 20 | # they come after automated table definitions. so you can use ... 21 | 22 | zapret_custom_firewall_v4() 23 | { 24 | pf_anchor_zapret_v4_tpws $TPPORT_EXTRA_TPWS $(replace_char - : $DPORTS_EXTRA) 25 | } 26 | zapret_custom_firewall_v6() 27 | { 28 | pf_anchor_zapret_v6_tpws $TPPORT_EXTRA_TPWS $(replace_char - : $DPORTS_EXTRA) 29 | } 30 | -------------------------------------------------------------------------------- /init.d/macos/custom.d/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bol-van/zapret/30a947b42bad60a8807831160ef6d45b34e426e2/init.d/macos/custom.d/.keep -------------------------------------------------------------------------------- /init.d/macos/functions: -------------------------------------------------------------------------------- 1 | # init script functions library for macos 2 | 3 | ZAPRET_BASE=${ZAPRET_BASE:-/opt/zapret} 4 | ZAPRET_RW=${ZAPRET_RW:-"$ZAPRET_BASE"} 5 | ZAPRET_CONFIG=${ZAPRET_CONFIG:-"$ZAPRET_RW/config"} 6 | . "$ZAPRET_CONFIG" 7 | . "$ZAPRET_BASE/common/base.sh" 8 | . "$ZAPRET_BASE/common/pf.sh" 9 | . "$ZAPRET_BASE/common/list.sh" 10 | . "$ZAPRET_BASE/common/custom.sh" 11 | CUSTOM_DIR="$ZAPRET_RW/init.d/macos" 12 | 13 | IPSET_DIR=$ZAPRET_BASE/ipset 14 | . "$IPSET_DIR/def.sh" 15 | 16 | PIDDIR=/var/run 17 | [ -n "$TPPORT" ] || TPPORT=988 18 | [ -n "$TPPORT_SOCKS" ] || TPPORT=987 19 | [ -n "$WS_USER" ] || WS_USER=daemon 20 | TPWS_WAIT="--bind-wait-ifup=30 --bind-wait-ip=30" 21 | TPWS_WAIT_SOCKS6="$TPWS_WAIT --bind-wait-ip-linklocal=30" 22 | [ -n "$TPWS" ] || TPWS="$ZAPRET_BASE/tpws/tpws" 23 | 24 | CUSTOM_SCRIPT="$ZAPRET_BASE/init.d/macos/custom" 25 | [ -f "$CUSTOM_SCRIPT" ] && . "$CUSTOM_SCRIPT" 26 | 27 | run_daemon() 28 | { 29 | # $1 - daemon number : 1,2,3,... 30 | # $2 - daemon 31 | # $3 - daemon args 32 | # use $PIDDIR/$DAEMONBASE$1.pid as pidfile 33 | local DAEMONBASE="$(basename "$2")" 34 | local PIDFILE="$PIDDIR/$DAEMONBASE$1.pid" 35 | local ARGS="--daemon --pidfile=$PIDFILE $3" 36 | [ -f "$PIDFILE" ] && pgrep -qF "$PIDFILE" && { 37 | echo Already running $1: $2 38 | return 0 39 | } 40 | echo "Starting daemon $1: $2 $ARGS" 41 | "$2" $ARGS 42 | } 43 | stop_daemon() 44 | { 45 | # $1 - daemon number : 1,2,3,... 46 | # $2 - daemon 47 | # use $PIDDIR/$DAEMONBASE$1.pid as pidfile 48 | 49 | local PID 50 | local DAEMONBASE="$(basename "$2")" 51 | local PIDFILE="$PIDDIR/$DAEMONBASE$1.pid" 52 | [ -f "$PIDFILE" ] && read PID <"$PIDFILE" 53 | [ -n "$PID" ] && { 54 | echo "Stopping daemon $1: $2 (PID=$PID)" 55 | kill $PID 56 | rm -f "$PIDFILE" 57 | } 58 | return 0 59 | } 60 | do_daemon() 61 | { 62 | # $1 - 1 - run, 0 - stop 63 | on_off_function run_daemon stop_daemon "$@" 64 | } 65 | 66 | tpws_apply_binds() 67 | { 68 | local o 69 | [ "$DISABLE_IPV4" = "1" ] || o="--bind-addr=127.0.0.1" 70 | [ "$DISABLE_IPV6" = "1" ] || { 71 | for i in lo0 $IFACE_LAN; do 72 | o="$o --bind-iface6=$i --bind-linklocal=force $TPWS_WAIT" 73 | done 74 | } 75 | eval $1="\"\$$1 $o\"" 76 | } 77 | tpws_apply_socks_binds() 78 | { 79 | local o 80 | 81 | [ "$DISABLE_IPV4" = "1" ] || o="--bind-addr=127.0.0.1" 82 | [ "$DISABLE_IPV6" = "1" ] || o="$o --bind-addr=::1" 83 | 84 | for lan in $IFACE_LAN; do 85 | [ "$DISABLE_IPV4" = "1" ] || o="$o --bind-iface4=$lan $TPWS_WAIT" 86 | [ "$DISABLE_IPV6" = "1" ] || o="$o --bind-iface6=$lan --bind-linklocal=unwanted $TPWS_WAIT_SOCKS6" 87 | done 88 | eval $1="\"\$$1 $o\"" 89 | } 90 | 91 | wait_interface_ll() 92 | { 93 | echo waiting for an ipv6 link local address on $1 ... 94 | "$TPWS" --bind-wait-only --bind-iface6=$1 --bind-linklocal=force $TPWS_WAIT 95 | } 96 | wait_lan_ll() 97 | { 98 | [ "$DISABLE_IPV6" != "1" ] && { 99 | for lan in $IFACE_LAN; do 100 | wait_interface_ll $lan >&2 || { 101 | echo "wait interface failed on $lan" 102 | return 1 103 | } 104 | done 105 | } 106 | return 0 107 | } 108 | get_ipv6_linklocal() 109 | { 110 | ifconfig $1 | sed -nEe 's/^.*inet6 (fe80:[a-f0-9:]+).*/\1/p' 111 | } 112 | 113 | 114 | zapret_do_firewall() 115 | { 116 | # $1 - 1 - add, 0 - del 117 | 118 | [ "$1" = 1 -a -n "$INIT_FW_PRE_UP_HOOK" ] && $INIT_FW_PRE_UP_HOOK 119 | [ "$1" = 0 -a -n "$INIT_FW_PRE_DOWN_HOOK" ] && $INIT_FW_PRE_DOWN_HOOK 120 | 121 | if [ "$1" = "1" ] ; then 122 | pf_anchor_root || return 1 123 | pf_anchors_create 124 | pf_anchors_load || return 1 125 | pf_enable 126 | else 127 | pf_anchors_clear 128 | fi 129 | 130 | [ "$1" = 1 -a -n "$INIT_FW_POST_UP_HOOK" ] && $INIT_FW_POST_UP_HOOK 131 | [ "$1" = 0 -a -n "$INIT_FW_POST_DOWN_HOOK" ] && $INIT_FW_POST_DOWN_HOOK 132 | 133 | return 0 134 | } 135 | zapret_apply_firewall() 136 | { 137 | zapret_do_firewall 1 "$@" 138 | } 139 | zapret_unapply_firewall() 140 | { 141 | zapret_do_firewall 0 "$@" 142 | } 143 | zapret_restart_firewall() 144 | { 145 | zapret_unapply_firewall "$@" 146 | zapret_apply_firewall "$@" 147 | } 148 | 149 | 150 | standard_mode_daemons() 151 | { 152 | local opt 153 | 154 | if [ "$1" = "1" ] && [ "$DISABLE_IPV4" = "1" ] && [ "$DISABLE_IPV6" = "1" ] ; then 155 | echo "both ipv4 and ipv6 are disabled. nothing to do" 156 | else 157 | [ "$TPWS_ENABLE" = 1 ] && check_bad_ws_options $1 "$TPWS_OPT" && { 158 | opt="--user=root --port=$TPPORT" 159 | tpws_apply_binds opt 160 | opt="$opt $TPWS_OPT" 161 | filter_apply_hostlist_target opt 162 | do_daemon $1 1 "$TPWS" "$opt" 163 | } 164 | [ "$TPWS_SOCKS_ENABLE" = 1 ] && { 165 | opt="--socks --user=$WS_USER --port=$TPPORT_SOCKS" 166 | tpws_apply_socks_binds opt 167 | opt="$opt $TPWS_SOCKS_OPT" 168 | filter_apply_hostlist_target opt 169 | do_daemon $1 2 "$TPWS" "$opt" 170 | } 171 | fi 172 | } 173 | 174 | zapret_do_daemons() 175 | { 176 | # $1 - 1 - run, 0 - stop 177 | 178 | standard_mode_daemons $1 179 | custom_runner zapret_custom_daemons $1 180 | 181 | return 0 182 | } 183 | zapret_run_daemons() 184 | { 185 | zapret_do_daemons 1 "$@" 186 | } 187 | zapret_stop_daemons() 188 | { 189 | zapret_do_daemons 0 "$@" 190 | } 191 | zapret_restart_daemons() 192 | { 193 | zapret_stop_daemons "$@" 194 | zapret_run_daemons "$@" 195 | } 196 | -------------------------------------------------------------------------------- /init.d/macos/zapret: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | EXEDIR="$(dirname "$0")" 4 | ZAPRET_BASE="$EXEDIR/../.." 5 | ZAPRET_BASE="$(cd "$ZAPRET_BASE"; pwd)" 6 | 7 | . "$EXEDIR/functions" 8 | 9 | case "$1" in 10 | start) 11 | zapret_run_daemons 12 | [ "$INIT_APPLY_FW" != "1" ] || zapret_apply_firewall 13 | ;; 14 | stop) 15 | [ "$INIT_APPLY_FW" != "1" ] || zapret_unapply_firewall 16 | zapret_stop_daemons 17 | ;; 18 | restart) 19 | "$0" stop 20 | "$0" start 21 | ;; 22 | 23 | start-fw|start_fw) 24 | zapret_apply_firewall 25 | ;; 26 | stop-fw|stop_fw) 27 | zapret_unapply_firewall 28 | ;; 29 | restart-fw|stop_fw) 30 | zapret_restart_firewall 31 | ;; 32 | reload-fw-tables|reload_fw_tables) 33 | pf_table_reload 34 | ;; 35 | 36 | start-daemons|start_daemons) 37 | zapret_run_daemons 38 | ;; 39 | stop-daemons|stop_daemons) 40 | zapret_stop_daemons 41 | ;; 42 | restart-daemons|restart_daemons) 43 | zapret_restart_daemons 44 | ;; 45 | 46 | *) 47 | N="$SCRIPT/$NAME" 48 | echo "Usage: $N {start|stop|start-fw|stop-fw|restart-fw|reload-fw-tables|start-daemons|stop-daemons|restart-daemons}" >&2 49 | exit 1 50 | ;; 51 | esac 52 | -------------------------------------------------------------------------------- /init.d/macos/zapret.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Label 6 | zapret 7 | LaunchOnlyOnce 8 | 9 | ProgramArguments 10 | 11 | /opt/zapret/init.d/macos/zapret 12 | start 13 | 14 | RunAtLoad 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /init.d/openrc/zapret: -------------------------------------------------------------------------------- 1 | #!/sbin/openrc-run 2 | 3 | # zapret openrc to sysv adapter 4 | # on some systems (alpine) for unknown reason non-openrc-run scripts are not started from /etc/init.d 5 | 6 | EXEDIR=$(dirname "$RC_SERVICE") 7 | EXEDIR="$(cd "$EXEDIR"; pwd)" 8 | ZAPRET_BASE="$EXEDIR/../.." 9 | ZAPRET_INIT="$ZAPRET_BASE/init.d/sysv/zapret" 10 | 11 | extra_commands="start_fw stop_fw restart_fw start_daemons stop_daemons restart_daemons reload_ifsets list_ifsets list_table" 12 | description="extra commands :" 13 | description_stop_fw="Stop zapret firewall" 14 | description_start_fw="Start zapret firewall" 15 | description_restart_fw="Restart zapret firewall" 16 | description_reload_ifsets="Reload interface lists (nftables only)" 17 | description_list_ifsets="Display interface lists (nftables only)" 18 | description_list_table="Display zapret nftable (nftables only)" 19 | description_stop_daemons="Stop zapret daemons only" 20 | description_start_daemons="Start zapret daemons only" 21 | description_restart_daemons="Restart zapret firewall only" 22 | 23 | depend() { 24 | rc-service -e networking && need networking 25 | } 26 | start() 27 | { 28 | "$ZAPRET_INIT" start 29 | } 30 | stop() 31 | { 32 | "$ZAPRET_INIT" stop 33 | } 34 | start_fw() 35 | { 36 | "$ZAPRET_INIT" start_fw 37 | } 38 | stop_fw() 39 | { 40 | "$ZAPRET_INIT" stop_fw 41 | } 42 | restart_fw() 43 | { 44 | "$ZAPRET_INIT" restart_fw 45 | } 46 | start_daemons() 47 | { 48 | "$ZAPRET_INIT" start_daemons 49 | } 50 | stop_daemons() 51 | { 52 | "$ZAPRET_INIT" stop_daemons 53 | } 54 | restart_daemons() 55 | { 56 | "$ZAPRET_INIT" restart_daemons 57 | } 58 | reload_ifsets() 59 | { 60 | "$ZAPRET_INIT" reload_ifsets 61 | } 62 | list_ifsets() 63 | { 64 | "$ZAPRET_INIT" list_ifsets 65 | } 66 | list_table() 67 | { 68 | "$ZAPRET_INIT" list_table 69 | } 70 | -------------------------------------------------------------------------------- /init.d/openwrt-minimal/readme.txt: -------------------------------------------------------------------------------- 1 | Minimal tpws startup script for low storage openwrt. 2 | 3 | --- openwrt with NFTABLES (22+) 4 | 5 | Make sure you are running openwrt with nftables, not iptables. 6 | No opkg dependencies required ! 7 | 8 | * install : 9 | 10 | Copy everything from tpws directory to the root of the router. 11 | Copy tpws binary for your architecture to /usr/bin/tpws 12 | Set proper access rights : chmod 755 /etc/init.d/tpws /usr/bin/tpws 13 | EDIT /etc/config/tpws 14 | If you don't want ipv6 : edit /etc/nftables.d and comment lines with ipv6 redirect 15 | /etc/init.d/tpws enable 16 | /etc/init.d/tpws start 17 | fw4 restart 18 | 19 | * full uninstall : 20 | 21 | /etc/init.d/tpws disable 22 | /etc/init.d/tpws stop 23 | rm -f /etc/nftables.d/90-tpws.nft /etc/firewall.user /etc/init.d/tpws 24 | fw4 restart 25 | 26 | --- openwrt with IPTABLES (21-) 27 | 28 | Make sure you are running openwrt with iptables, not nftables. 29 | Make sure you do not have anything valuable in /etc/firewall.user. 30 | If you have - do not blindly follow instruction in firewall.user part. 31 | Merge the code instead or setup your own firewall include in /etc/config/firewall. 32 | 33 | opkg update 34 | opkg install iptables-mod-extra 35 | IPV6 ONLY : opkg install ip6tables-mod-nat 36 | 37 | * install : 38 | 39 | Copy everything from tpws directory to the root of the router. 40 | Copy tpws binary for your architecture to /usr/bin/tpws 41 | Set proper access rights : chmod 755 /etc/init.d/tpws /usr/bin/tpws 42 | EDIT /etc/config/tpws 43 | If you don't want ipv6 : edit /etc/firewall.user and set DISABLE_IPV6=1 44 | /etc/init.d/tpws enable 45 | /etc/init.d/tpws start 46 | fw3 restart 47 | 48 | * full uninstall : 49 | 50 | /etc/init.d/tpws disable 51 | /etc/init.d/tpws stop 52 | rm -f /etc/nftables.d/90-tpws.nft /etc/firewall.user /etc/init.d/tpws 53 | touch /etc/firewall.user 54 | fw3 restart 55 | -------------------------------------------------------------------------------- /init.d/openwrt-minimal/tpws/etc/config/tpws: -------------------------------------------------------------------------------- 1 | config global defaults 2 | option user daemon 3 | option tpws /usr/bin/tpws 4 | 5 | config tpws 6 | option port 900 7 | option opt '--split-pos=2 --oob' 8 | option enabled 1 9 | config tpws 10 | option port 901 11 | option opt '--split-tls=sni --disorder' 12 | option enabled 0 13 | -------------------------------------------------------------------------------- /init.d/openwrt-minimal/tpws/etc/firewall.user: -------------------------------------------------------------------------------- 1 | DISABLE_IPV6=0 2 | TP_PORT=900 3 | TP_USER=daemon 4 | 5 | EXCLUDE4="10.0.0.0/8 172.16.0.0/12 192.168.0.0/16 169.254.0.0/16 127.0.0.0/8" 6 | EXCLUDE6="fc00::/7 fe80::/10 ::1" 7 | IPTS="iptables ip6tables" 8 | [ "$DISABLE_IPV6" = 1 ] && IPTS=iptables 9 | 10 | exists() 11 | { 12 | which "$1" >/dev/null 2>/dev/null 13 | } 14 | 15 | ipt() 16 | { 17 | $IPTABLES -C "$@" >/dev/null 2>/dev/null || $IPTABLES -I "$@" 18 | } 19 | 20 | redirect_port() 21 | { 22 | ipt tpws -t nat -p tcp --dport $1 -j REDIRECT --to-port $2 23 | } 24 | 25 | redirect() 26 | { 27 | redirect_port 80 $TP_PORT 28 | redirect_port 443 $TP_PORT 29 | } 30 | 31 | for IPTABLES in $IPTS; do 32 | $IPTABLES -t nat -N tpws 2>/dev/null 33 | $IPTABLES -t nat -F tpws 34 | redirect 35 | done 36 | 37 | for net in $EXCLUDE4; do 38 | iptables -t nat -I tpws -d $net -j RETURN 39 | done 40 | [ "$DISABLE_IPV6" = 1 ] || { 41 | for net in $EXCLUDE6; do 42 | ip6tables -t nat -I tpws -d $net -j RETURN 43 | done 44 | } 45 | 46 | for IPTABLES in $IPTS; do 47 | ipt PREROUTING -t nat -j tpws 48 | ipt OUTPUT -t nat -m owner ! --uid-owner $TP_USER -j tpws 49 | done 50 | -------------------------------------------------------------------------------- /init.d/openwrt-minimal/tpws/etc/init.d/tpws: -------------------------------------------------------------------------------- 1 | #!/bin/sh /etc/rc.common 2 | 3 | TPWS_DEFAULT=/usr/bin/tpws 4 | TPWS_USER_DEFAULT=daemon 5 | 6 | START=99 7 | STOP=01 8 | USE_PROCD=1 9 | 10 | tpws_instance() 11 | { 12 | config_get "$@" 13 | 14 | local enabled port opt 15 | 16 | config_get_bool enabled "$1" enabled 0 17 | [ "$enabled" -eq 1 ] || return 1 18 | 19 | config_get port "$1" port 20 | config_get opt "$1" opt 21 | 22 | local COMMAND="$TPWS --user=$TPWS_USER --port=$port $opt" 23 | procd_open_instance 24 | procd_set_param command $COMMAND 25 | procd_close_instance 26 | } 27 | 28 | start_service() 29 | { 30 | config_load tpws 31 | config_get TPWS_USER defaults user $TPWS_USER_DEFAULT 32 | config_get TPWS defaults tpws $TPWS_DEFAULT 33 | config_foreach tpws_instance tpws 34 | } 35 | -------------------------------------------------------------------------------- /init.d/openwrt-minimal/tpws/etc/nftables.d/90-tpws.nft: -------------------------------------------------------------------------------- 1 | set tpws_exclude4 { 2 | type ipv4_addr; flags interval; auto-merge; 3 | elements = { 10.0.0.0/8,172.16.0.0/12,192.168.0.0/16,169.254.0.0/16,127.0.0.0/8 } 4 | } 5 | set tpws_exclude6 { 6 | type ipv6_addr; flags interval; auto-merge; 7 | elements = { fc00::/7, fe80::/10, ::1 } 8 | } 9 | chain tpws_pre { 10 | type nat hook prerouting priority dstnat; policy accept; 11 | tcp dport {80,443} ip daddr != @tpws_exclude4 redirect to :900 12 | tcp dport {80,443} ip6 daddr != @tpws_exclude6 redirect to :900 13 | } 14 | chain tpws_out { 15 | type nat hook output priority -100; policy accept; 16 | tcp dport {80,443} skuid != daemon ip daddr != @tpws_exclude4 redirect to :900 17 | tcp dport {80,443} skuid != daemon ip6 daddr != @tpws_exclude6 redirect to :900 18 | } 19 | -------------------------------------------------------------------------------- /init.d/openwrt/90-zapret: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | ZAPRET=/etc/init.d/zapret 4 | 5 | check_lan() 6 | { 7 | IS_LAN= 8 | [ -n "$OPENWRT_LAN" ] || OPENWRT_LAN=lan 9 | for lan in $OPENWRT_LAN; do 10 | [ "$INTERFACE" = "$lan" ] && { 11 | IS_LAN=1 12 | break 13 | } 14 | done 15 | } 16 | check_need_to_reload_tpws6() 17 | { 18 | # tpws6 dnat target nft map can only be reloaded within firewall apply procedure 19 | # interface ifsets (wanif, wanif6, lanif) can be reloaded independently 20 | check_lan 21 | RELOAD_TPWS6= 22 | [ "$ACTION" = "ifup" -a "$DISABLE_IPV6" != 1 -a -n "$IS_LAN" ] && \ 23 | if [ "$TPWS_ENABLE" = 1 ] || dir_is_not_empty "$CUSTOM_DIR/custom.d"; then RELOAD_TPWS6=1; fi 24 | } 25 | 26 | 27 | [ -n "$INTERFACE" ] && [ "$ACTION" = ifup -o "$ACTION" = ifdown ] && [ -x "$ZAPRET" ] && "$ZAPRET" enabled && { 28 | SCRIPT=$(readlink "$ZAPRET") 29 | if [ -n "$SCRIPT" ]; then 30 | EXEDIR=$(dirname "$SCRIPT") 31 | ZAPRET_BASE=$(readlink -f "$EXEDIR/../..") 32 | else 33 | ZAPRET_BASE=/opt/zapret 34 | fi 35 | ZAPRET_RW=${ZAPRET_RW:-"$ZAPRET_BASE"} 36 | ZAPRET_CONFIG=${ZAPRET_CONFIG:-"$ZAPRET_RW/config"} 37 | CUSTOM_DIR="$ZAPRET_RW/init.d/openwrt" 38 | . "$ZAPRET_CONFIG" 39 | . "$ZAPRET_BASE/common/base.sh" 40 | . "$ZAPRET_BASE/common/fwtype.sh" 41 | 42 | check_need_to_reload_tpws6 43 | [ -n "$RELOAD_TPWS6" ] && { 44 | logger -t zapret restarting daemons due to $ACTION of $INTERFACE to update tpws6 dnat target 45 | "$ZAPRET" restart_daemons 46 | } 47 | linux_fwtype 48 | case "$FWTYPE" in 49 | nftables) 50 | if [ -n "$RELOAD_TPWS6" ] ; then 51 | logger -t zapret reloading nftables due to $ACTION of $INTERFACE to update tpws6 dnat target 52 | "$ZAPRET" restart_fw 53 | else 54 | logger -t zapret reloading nftables ifsets due to $ACTION of $INTERFACE 55 | "$ZAPRET" reload_ifsets 56 | fi 57 | ;; 58 | iptables) 59 | openwrt_fw3 || { 60 | logger -t zapret reloading iptables due to $ACTION of $INTERFACE 61 | "$ZAPRET" restart_fw 62 | } 63 | ;; 64 | esac 65 | } 66 | -------------------------------------------------------------------------------- /init.d/openwrt/custom.d/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bol-van/zapret/30a947b42bad60a8807831160ef6d45b34e426e2/init.d/openwrt/custom.d/.keep -------------------------------------------------------------------------------- /init.d/openwrt/firewall.zapret: -------------------------------------------------------------------------------- 1 | SCRIPT=$(readlink /etc/init.d/zapret) 2 | if [ -n "$SCRIPT" ]; then 3 | EXEDIR=$(dirname "$SCRIPT") 4 | ZAPRET_BASE=$(readlink -f "$EXEDIR/../..") 5 | else 6 | ZAPRET_BASE=/opt/zapret 7 | fi 8 | 9 | . "$ZAPRET_BASE/init.d/openwrt/functions" 10 | 11 | zapret_apply_firewall 12 | -------------------------------------------------------------------------------- /init.d/openwrt/zapret: -------------------------------------------------------------------------------- 1 | #!/bin/sh /etc/rc.common 2 | 3 | USE_PROCD=1 4 | # after network 5 | START=21 6 | 7 | my_extra_command() { 8 | local cmd="$1" 9 | local help="$2" 10 | 11 | local extra="$(printf "%-16s%s" "${cmd}" "${help}")" 12 | EXTRA_HELP="${EXTRA_HELP} ${extra} 13 | " 14 | EXTRA_COMMANDS="${EXTRA_COMMANDS} ${cmd}" 15 | } 16 | my_extra_command stop_fw "Stop zapret firewall (noop in iptables+fw3 case)" 17 | my_extra_command start_fw "Start zapret firewall (noop in iptables+fw3 case)" 18 | my_extra_command restart_fw "Restart zapret firewall (noop in iptables+fw3 case)" 19 | my_extra_command reload_ifsets "Reload interface lists (nftables only)" 20 | my_extra_command list_ifsets "Display interface lists (nftables only)" 21 | my_extra_command list_table "Display zapret nftable (nftables only)" 22 | my_extra_command stop_daemons "Stop zapret daemons only (=stop in iptables+fw3 case)" 23 | my_extra_command start_daemons "Start zapret daemons only (=start in iptables+fw3 case)" 24 | my_extra_command restart_daemons "Restart zapret firewall only (=restart in iptables+fw3 case)" 25 | 26 | SCRIPT=$(readlink /etc/init.d/zapret) 27 | if [ -n "$SCRIPT" ]; then 28 | EXEDIR=$(dirname "$SCRIPT") 29 | ZAPRET_BASE=$(readlink -f "$EXEDIR/../..") 30 | else 31 | ZAPRET_BASE=/opt/zapret 32 | fi 33 | 34 | . "$ZAPRET_BASE/init.d/openwrt/functions" 35 | 36 | 37 | # !!!!! in old openwrt 21.x- with iptables firewall rules are configured separately 38 | # !!!!! in new openwrt >21.x with nftables firewall is configured here 39 | 40 | PIDDIR=/var/run 41 | 42 | [ -n "$NFQWS" ] || NFQWS="$ZAPRET_BASE/nfq/nfqws" 43 | NFQWS_OPT_BASE="--user=$WS_USER --dpi-desync-fwmark=$DESYNC_MARK" 44 | 45 | [ -n "$TPWS" ] || TPWS="$ZAPRET_BASE/tpws/tpws" 46 | TPWS_OPT_BASE="--user=$WS_USER" 47 | TPWS_OPT_BASE4="--bind-addr=$TPWS_LOCALHOST4" 48 | TPWS_OPT_BASE6="--bind-addr=::1" 49 | TPWS_WAIT="--bind-wait-ifup=30 --bind-wait-ip=30" 50 | TPWS_WAIT_SOCKS6="$TPWS_WAIT --bind-wait-ip-linklocal=30" 51 | TPWS_OPT_BASE6_PRE="--bind-linklocal=prefer $TPWS_WAIT --bind-wait-ip-linklocal=3" 52 | 53 | run_daemon() 54 | { 55 | # $1 - daemon string id or number. can use 1,2,3,... 56 | # $2 - daemon 57 | # $3 - daemon args 58 | # use $PIDDIR/$DAEMONBASE$1.pid as pidfile 59 | local DAEMONBASE="$(basename "$2")" 60 | echo "Starting daemon $1: $2 $3" 61 | procd_open_instance 62 | procd_set_param command $2 $3 63 | procd_set_param pidfile $PIDDIR/$DAEMONBASE$1.pid 64 | procd_close_instance 65 | } 66 | 67 | run_tpws() 68 | { 69 | [ "$DISABLE_IPV4" = "1" ] && [ "$DISABLE_IPV6" = "1" ] && return 0 70 | 71 | local OPT="$TPWS_OPT_BASE" 72 | local DEVICE 73 | 74 | [ "$DISABLE_IPV4" = "1" ] || OPT="$OPT $TPWS_OPT_BASE4" 75 | [ "$DISABLE_IPV6" = "1" ] || { 76 | OPT="$OPT $TPWS_OPT_BASE6" 77 | for lan in $OPENWRT_LAN; do 78 | network_get_device DEVICE $lan 79 | [ -n "$DEVICE" ] && OPT="$OPT --bind-iface6=$DEVICE $TPWS_OPT_BASE6_PRE" 80 | done 81 | } 82 | run_daemon $1 "$TPWS" "$OPT $2" 83 | } 84 | do_tpws() 85 | { 86 | [ "$1" = 0 ] || { shift; run_tpws "$@"; } 87 | } 88 | run_tpws_socks() 89 | { 90 | [ "$DISABLE_IPV4" = "1" ] && [ "$DISABLE_IPV6" = "1" ] && return 0 91 | 92 | local opt="$TPWS_OPT_BASE --socks" 93 | 94 | tpws_apply_socks_binds opt 95 | run_daemon $1 "$TPWS" "$opt $2" 96 | } 97 | do_tpws_socks() 98 | { 99 | [ "$1" = 0 ] || { shift; run_tpws_socks "$@"; } 100 | } 101 | tpws_apply_socks_binds() 102 | { 103 | local o 104 | 105 | [ "$DISABLE_IPV4" = "1" ] || o="--bind-addr=127.0.0.1" 106 | [ "$DISABLE_IPV6" = "1" ] || o="$o --bind-addr=::1" 107 | 108 | for lan in $OPENWRT_LAN; do 109 | network_get_device DEVICE $lan 110 | [ -n "$DEVICE" ] || continue 111 | [ "$DISABLE_IPV4" = "1" ] || o="$o --bind-iface4=$DEVICE $TPWS_WAIT" 112 | [ "$DISABLE_IPV6" = "1" ] || o="$o --bind-iface6=$DEVICE --bind-linklocal=unwanted $TPWS_WAIT_SOCKS6" 113 | done 114 | eval $1="\"\$$1 $o\"" 115 | } 116 | 117 | run_nfqws() 118 | { 119 | run_daemon $1 "$NFQWS" "$NFQWS_OPT_BASE $2" 120 | } 121 | do_nfqws() 122 | { 123 | [ "$1" = 0 ] || { shift; run_nfqws "$@"; } 124 | } 125 | 126 | start_daemons_procd() 127 | { 128 | standard_mode_daemons 1 129 | custom_runner zapret_custom_daemons 1 130 | 131 | return 0 132 | } 133 | start_daemons() 134 | { 135 | rc_procd start_daemons_procd "$@" 136 | } 137 | stop_daemons() 138 | { 139 | local svc="$(basename ${basescript:-$initscript})" 140 | procd_running "$svc" "$1" && procd_kill "$svc" "$1" 141 | } 142 | restart_daemons() 143 | { 144 | stop_daemons 145 | start_daemons 146 | } 147 | 148 | start_fw() 149 | { 150 | zapret_apply_firewall 151 | } 152 | stop_fw() 153 | { 154 | zapret_unapply_firewall 155 | } 156 | restart_fw() 157 | { 158 | stop_fw 159 | start_fw 160 | } 161 | reload_ifsets() 162 | { 163 | zapret_reload_ifsets 164 | } 165 | list_ifsets() 166 | { 167 | zapret_list_ifsets 168 | } 169 | list_table() 170 | { 171 | zapret_list_table 172 | } 173 | 174 | start_service() 175 | { 176 | start_daemons_procd 177 | [ "$INIT_APPLY_FW" != "1" ] || { 178 | linux_fwtype 179 | openwrt_fw3_integration || start_fw 180 | } 181 | } 182 | 183 | stop_service() 184 | { 185 | # this procedure is called from stop() 186 | # stop() already stop daemons 187 | [ "$INIT_APPLY_FW" != "1" ] || { 188 | linux_fwtype 189 | openwrt_fw3_integration || stop_fw 190 | } 191 | } 192 | -------------------------------------------------------------------------------- /init.d/pfsense/zapret.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # this file should be placed to /usr/local/etc/rc.d and chmod 755 4 | 5 | # prepare system 6 | 7 | kldload ipfw 8 | kldload ipdivert 9 | 10 | # for older pfsense versions. newer do not have these sysctls 11 | sysctl net.inet.ip.pfil.outbound=ipfw,pf 12 | sysctl net.inet.ip.pfil.inbound=ipfw,pf 13 | sysctl net.inet6.ip6.pfil.outbound=ipfw,pf 14 | sysctl net.inet6.ip6.pfil.inbound=ipfw,pf 15 | 16 | # required for newer pfsense versions (2.6.0 tested) to return ipfw to functional state 17 | pfctl -d ; pfctl -e 18 | 19 | # add ipfw rules and start daemon 20 | 21 | ipfw delete 100 22 | ipfw add 100 divert 989 tcp from any to any 80,443 out not diverted not sockarg 23 | pkill ^dvtws$ 24 | dvtws --daemon --port 989 --dpi-desync=multisplit 25 | -------------------------------------------------------------------------------- /init.d/runit/zapret/finish: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | /opt/zapret/init.d/sysv/zapret stop 3 | -------------------------------------------------------------------------------- /init.d/runit/zapret/run: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | /opt/zapret/init.d/sysv/zapret start 3 | exec chpst -b zapret sleep infinity 4 | -------------------------------------------------------------------------------- /init.d/s6/zapret/down: -------------------------------------------------------------------------------- 1 | #!/bin/execlineb -P 2 | exec /opt/zapret/init.d/sysv/zapret stop 3 | -------------------------------------------------------------------------------- /init.d/s6/zapret/type: -------------------------------------------------------------------------------- 1 | oneshot 2 | -------------------------------------------------------------------------------- /init.d/s6/zapret/up: -------------------------------------------------------------------------------- 1 | #!/bin/execlineb -P 2 | exec /opt/zapret/init.d/sysv/zapret start 3 | -------------------------------------------------------------------------------- /init.d/systemd/nfqws@.service: -------------------------------------------------------------------------------- 1 | # Example systemd service unit for nfqws. Adjust for your installation. 2 | 3 | # WARNING ! This unit requires to compile nfqws using `make systemd` 4 | # WARNING ! This makefile target enables special systemd notify support. 5 | 6 | # PREPARE 7 | # install build depends 8 | # make -C /opt/zapret systemd 9 | # cp nfqws@service /lib/systemd/system 10 | # systemctl daemon-reload 11 | 12 | # MANAGE INSTANCE 13 | # prepare /etc/zapret/nfqws1.conf with nfqws parameters 14 | # systemctl start nfqws@nfqws1 15 | # systemctl status nfqws@nfqws1 16 | # systemctl restart nfqws@nfqws1 17 | # systemctl enable nfqws@nfqws1 18 | # systemctl disable nfqws@nfqws1 19 | # systemctl stop nfqws@nfqws1 20 | 21 | # DELETE 22 | # rm /lib/systemd/system/nfqws@.service 23 | # systemctl daemon-reload 24 | 25 | 26 | [Unit] 27 | After=network.target 28 | 29 | [Service] 30 | Type=notify 31 | Restart=on-failure 32 | 33 | ExecSearchPath=/opt/zapret/binaries/my 34 | ExecStart=nfqws @${CONFIG_DIR}/${INSTANCE}.conf 35 | Environment=CONFIG_DIR=/etc/zapret 36 | Environment=INSTANCE=%i 37 | 38 | RestrictAddressFamilies=AF_NETLINK AF_UNIX AF_INET6 AF_INET 39 | 40 | LockPersonality=true 41 | MemoryDenyWriteExecute=true 42 | PrivateDevices=true 43 | PrivateMounts=true 44 | PrivateTmp=true 45 | ProcSubset=pid 46 | ProtectClock=true 47 | ProtectControlGroups=true 48 | ProtectHome=true 49 | ProtectHostname=true 50 | ProtectKernelLogs=true 51 | ProtectKernelModules=true 52 | ProtectKernelTunables=true 53 | ProtectProc=invisible 54 | ProtectSystem=full 55 | RemoveIPC=true 56 | RestrictNamespaces=true 57 | RestrictRealtime=true 58 | RestrictSUIDSGID=true 59 | UMask=0077 60 | 61 | [Install] 62 | WantedBy=multi-user.target 63 | -------------------------------------------------------------------------------- /init.d/systemd/tpws@.service: -------------------------------------------------------------------------------- 1 | # Example systemd service unit for tpws. Adjust for your installation. 2 | 3 | # WARNING ! This unit requires to compile tpws using `make systemd` 4 | # WARNING ! This makefile target enables special systemd notify support. 5 | 6 | # PREPARE 7 | # install build depends 8 | # make -C /opt/zapret systemd 9 | # cp tpws@service /lib/systemd/system 10 | # systemctl daemon-reload 11 | 12 | # MANAGE INSTANCE 13 | # prepare /etc/zapret/tpws1.conf with tpws parameters 14 | # systemctl start tpws@tpws1 15 | # systemctl status tpws@tpws1 16 | # systemctl restart tpws@tpws1 17 | # systemctl enable tpws@tpws1 18 | # systemctl disable tpws@tpws1 19 | # systemctl stop tpws@tpws1 20 | 21 | # DELETE 22 | # rm /lib/systemd/system/tpws@.service 23 | # systemctl daemon-reload 24 | 25 | 26 | [Unit] 27 | After=network.target 28 | 29 | [Service] 30 | Type=notify 31 | Restart=on-failure 32 | 33 | ExecSearchPath=/opt/zapret/binaries/my 34 | ExecStart=tpws @${CONFIG_DIR}/${INSTANCE}.conf 35 | Environment=CONFIG_DIR=/etc/zapret 36 | Environment=INSTANCE=%i 37 | 38 | RestrictAddressFamilies=AF_NETLINK AF_UNIX AF_INET6 AF_INET 39 | 40 | LockPersonality=true 41 | MemoryDenyWriteExecute=true 42 | PrivateDevices=true 43 | PrivateMounts=true 44 | PrivateTmp=true 45 | ProcSubset=pid 46 | ProtectClock=true 47 | ProtectControlGroups=true 48 | ProtectHome=true 49 | ProtectHostname=true 50 | ProtectKernelLogs=true 51 | ProtectKernelModules=true 52 | ProtectProc=invisible 53 | ProtectSystem=full 54 | RemoveIPC=true 55 | RestrictNamespaces=true 56 | RestrictRealtime=true 57 | RestrictSUIDSGID=true 58 | UMask=0077 59 | 60 | [Install] 61 | WantedBy=multi-user.target 62 | -------------------------------------------------------------------------------- /init.d/systemd/zapret-list-update.service: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=zapret ip/host list update 3 | 4 | [Service] 5 | Restart=no 6 | IgnoreSIGPIPE=no 7 | KillMode=control-group 8 | GuessMainPID=no 9 | RemainAfterExit=no 10 | ExecStart=/opt/zapret/ipset/get_config.sh 11 | 12 | [Install] 13 | WantedBy=multi-user.target 14 | -------------------------------------------------------------------------------- /init.d/systemd/zapret-list-update.timer: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=zapret ip/host list update timer 3 | 4 | [Timer] 5 | OnCalendar=*-*-2,4,6,8,10,12,14,16,18,20,22,24,26,28,30 00:00:00 6 | RandomizedDelaySec=86400 7 | Persistent=true 8 | Unit=zapret-list-update.service 9 | 10 | [Install] 11 | WantedBy=timers.target 12 | -------------------------------------------------------------------------------- /init.d/systemd/zapret.service: -------------------------------------------------------------------------------- 1 | [Unit] 2 | After=network-online.target 3 | Wants=network-online.target 4 | 5 | [Service] 6 | Type=forking 7 | Restart=no 8 | TimeoutSec=30sec 9 | IgnoreSIGPIPE=no 10 | KillMode=none 11 | GuessMainPID=no 12 | RemainAfterExit=no 13 | ExecStart=/opt/zapret/init.d/sysv/zapret start 14 | ExecStop=/opt/zapret/init.d/sysv/zapret stop 15 | 16 | [Install] 17 | WantedBy=multi-user.target 18 | -------------------------------------------------------------------------------- /init.d/sysv/custom.d/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bol-van/zapret/30a947b42bad60a8807831160ef6d45b34e426e2/init.d/sysv/custom.d/.keep -------------------------------------------------------------------------------- /init.d/sysv/zapret: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | ### BEGIN INIT INFO 3 | # Provides: zapret 4 | # Required-Start: $local_fs $network 5 | # Required-Stop: $local_fs $network 6 | # Default-Start: 2 3 4 5 7 | # Default-Stop: 0 1 6 8 | ### END INIT INFO 9 | 10 | SCRIPT=$(readlink -f "$0") 11 | EXEDIR=$(dirname "$SCRIPT") 12 | ZAPRET_BASE=$(readlink -f "$EXEDIR/../..") 13 | . "$EXEDIR/functions" 14 | 15 | NAME=zapret 16 | DESC=anti-zapret 17 | 18 | do_start() 19 | { 20 | zapret_run_daemons 21 | [ "$INIT_APPLY_FW" != "1" ] || { zapret_apply_firewall; } 22 | } 23 | do_stop() 24 | { 25 | zapret_stop_daemons 26 | [ "$INIT_APPLY_FW" != "1" ] || zapret_unapply_firewall 27 | } 28 | 29 | case "$1" in 30 | start) 31 | do_start 32 | ;; 33 | 34 | stop) 35 | do_stop 36 | ;; 37 | 38 | restart) 39 | do_stop 40 | do_start 41 | ;; 42 | 43 | start-fw|start_fw) 44 | zapret_apply_firewall 45 | ;; 46 | stop-fw|stop_fw) 47 | zapret_unapply_firewall 48 | ;; 49 | 50 | restart-fw|restart_fw) 51 | zapret_unapply_firewall 52 | zapret_apply_firewall 53 | ;; 54 | 55 | start-daemons|start_daemons) 56 | zapret_run_daemons 57 | ;; 58 | stop-daemons|stop_daemons) 59 | zapret_stop_daemons 60 | ;; 61 | restart-daemons|restart_daemons) 62 | zapret_stop_daemons 63 | zapret_run_daemons 64 | ;; 65 | 66 | reload-ifsets|reload_ifsets) 67 | zapret_reload_ifsets 68 | ;; 69 | list-ifsets|list_ifsets) 70 | zapret_list_ifsets 71 | ;; 72 | list-table|list_table) 73 | zapret_list_table 74 | ;; 75 | 76 | *) 77 | echo "Usage: $SCRIPT {start|stop|restart|start-fw|stop-fw|restart-fw|start-daemons|stop-daemons|restart-daemons|reload-ifsets|list-ifsets|list-table}" >&2 78 | exit 1 79 | ;; 80 | esac 81 | 82 | exit 0 83 | -------------------------------------------------------------------------------- /install_bin.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | EXEDIR="$(dirname "$0")" 4 | EXEDIR="$(cd "$EXEDIR"; pwd)" 5 | BINS=binaries 6 | BINDIR="$EXEDIR/$BINS" 7 | 8 | ZAPRET_BASE=${ZAPRET_BASE:-"$EXEDIR"} 9 | . "$ZAPRET_BASE/common/base.sh" 10 | 11 | 12 | read_elf_arch() 13 | { 14 | # $1 - elf file 15 | 16 | local arch=$(dd if="$1" count=2 bs=1 skip=18 2>/dev/null | hexdump -e '2/1 "%02x"') 17 | local bit=$(dd if="$1" count=1 bs=1 skip=4 2>/dev/null | hexdump -e '1/1 "%02x"') 18 | echo $bit$arch 19 | } 20 | 21 | select_test_method() 22 | { 23 | local f ELF 24 | 25 | TEST=run 26 | 27 | # ash and dash try to execute invalid executables as a script. they interpret binary garbage with possible negative consequences 28 | # bash and zsh do not do this 29 | if exists bash; then 30 | TEST=bash 31 | elif exists zsh && [ "$UNAME" != CYGWIN ] ; then 32 | TEST=zsh 33 | elif [ "$UNAME" != Darwin -a "$UNAME" != CYGWIN ]; then 34 | if exists hexdump and exists dd; then 35 | # macos does not use ELF 36 | TEST=elf 37 | ELF= 38 | ELF_ARCH= 39 | for f in /bin/sh /system/bin/sh; do 40 | [ -x "$f" ] && { 41 | ELF=$f 42 | break 43 | } 44 | done 45 | [ -n "$ELF" ] && ELF_ARCH=$(read_elf_arch "$ELF") 46 | [ -n "$ELF_ARCH" ] && return 47 | fi 48 | 49 | # find does not use its own shell exec 50 | # it uses execvp(). in musl libc it does not call shell, in glibc it DOES call /bin/sh 51 | # that's why prefer bash or zsh if present. otherwise it's our last chance 52 | if exists find; then 53 | TEST=find 54 | FIND=find 55 | elif exists busybox; then 56 | busybox find /jGHUa3fh1A 2>/dev/null 57 | # 127 - command not found 58 | [ "$?" = 127 ] || { 59 | TEST=find 60 | FIND="busybox find" 61 | } 62 | fi 63 | fi 64 | 65 | } 66 | 67 | disable_antivirus() 68 | { 69 | # $1 - dir 70 | [ "$UNAME" = Darwin ] && find "$1" -maxdepth 1 -type f -perm +111 -exec xattr -d com.apple.quarantine {} \; 2>/dev/null 71 | } 72 | 73 | check_dir() 74 | { 75 | local dir="$BINDIR/$1" 76 | local exe="$dir/ip2net" 77 | local out 78 | if [ -f "$exe" ]; then 79 | if [ -x "$exe" ]; then 80 | disable_antivirus "$dir" 81 | case $TEST in 82 | bash) 83 | out=$(echo 0.0.0.0 | bash -c "\"$exe"\" 2>/dev/null) 84 | [ -n "$out" ] 85 | ;; 86 | zsh) 87 | out=$(echo 0.0.0.0 | zsh -c "\"$exe\"" 2>/dev/null) 88 | [ -n "$out" ] 89 | ;; 90 | elf) 91 | out=$(read_elf_arch "$exe") 92 | [ "$ELF_ARCH" = "$out" ] && { 93 | # exec test to verify it actually works. no illegal instruction or crash. 94 | out=$(echo 0.0.0.0 | "$exe" 2>/dev/null) 95 | [ -n "$out" ] 96 | } 97 | ;; 98 | find) 99 | out=$(echo 0.0.0.0 | $FIND "$dir" -maxdepth 1 -name ip2net -exec {} \; 2>/dev/null) 100 | [ -n "$out" ] 101 | ;; 102 | run) 103 | out=$(echo 0.0.0.0 | "$exe" 2>/dev/null) 104 | [ -n "$out" ] 105 | ;; 106 | *) 107 | false 108 | ;; 109 | esac 110 | else 111 | echo >&2 "$exe is not executable. set proper chmod." 112 | return 1 113 | fi 114 | else 115 | echo >&2 "$exe is absent" 116 | return 2 117 | fi 118 | } 119 | 120 | # link or copy executables. uncomment either ln or cp, comment other 121 | ccp() 122 | { 123 | local F="$(basename "$1")" 124 | [ -d "$ZAPRET_BASE/$2" ] || mkdir "$ZAPRET_BASE/$2" 125 | [ -f "$ZAPRET_BASE/$2/$F" ] && rm -f "$ZAPRET_BASE/$2/$F" 126 | ln -fs "../$BINS/$1" "$ZAPRET_BASE/$2" && echo linking : "../$BINS/$1" =\> "$ZAPRET_BASE/$2" 127 | #cp -f "../$BINS/$1" "$ZAPRET_BASE/$2" && echo copying : "../$BINS/$1" =\> "$ZAPRET_BASE/$2" 128 | } 129 | 130 | UNAME=$(uname) 131 | 132 | unset PKTWS 133 | case $UNAME in 134 | Linux) 135 | ARCHLIST="my x86_64 x86 aarch64 arm mips64r2-msb mips32r1-lsb mips32r1-msb lexra ppc" 136 | PKTWS=nfqws 137 | ;; 138 | Darwin) 139 | ARCHLIST="my mac64" 140 | ;; 141 | FreeBSD) 142 | ARCHLIST="my freebsd-x64" 143 | PKTWS=dvtws 144 | ;; 145 | CYGWIN*) 146 | UNAME=CYGWIN 147 | ARCHLIST="win64 win32" 148 | PKTWS=winws 149 | ;; 150 | *) 151 | ARCHLIST="my" 152 | esac 153 | 154 | select_test_method 155 | 156 | if [ "$1" = "getarch" ]; then 157 | for arch in $ARCHLIST 158 | do 159 | [ -d "$BINDIR/$arch" ] || continue 160 | if check_dir $arch; then 161 | echo $arch 162 | exit 0 163 | fi 164 | done 165 | else 166 | echo "using arch detect method : $TEST${ELF_ARCH:+ $ELF_ARCH}" 167 | 168 | for arch in $ARCHLIST 169 | do 170 | [ -d "$BINDIR/$arch" ] || continue 171 | if check_dir $arch; then 172 | echo $arch is OK 173 | echo installing binaries ... 174 | ccp $arch/ip2net ip2net 175 | ccp $arch/mdig mdig 176 | [ -n "$PKTWS" ] && ccp $arch/$PKTWS nfq 177 | [ "$UNAME" = CYGWIN ] || ccp $arch/tpws tpws 178 | exit 0 179 | else 180 | echo $arch is NOT OK 181 | fi 182 | done 183 | echo no compatible binaries found 184 | fi 185 | 186 | exit 1 187 | -------------------------------------------------------------------------------- /install_prereq.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # install prerequisites 4 | 5 | EXEDIR="$(dirname "$0")" 6 | EXEDIR="$(cd "$EXEDIR"; pwd)" 7 | ZAPRET_BASE=${ZAPRET_BASE:-"$EXEDIR"} 8 | ZAPRET_RW=${ZAPRET_RW:-"$ZAPRET_BASE"} 9 | ZAPRET_CONFIG=${ZAPRET_CONFIG:-"$ZAPRET_RW/config"} 10 | ZAPRET_CONFIG_DEFAULT="$ZAPRET_BASE/config.default" 11 | 12 | [ -f "$ZAPRET_CONFIG" ] || { 13 | ZAPRET_CONFIG_DIR="$(dirname "$ZAPRET_CONFIG")" 14 | [ -d "$ZAPRET_CONFIG_DIR" ] || mkdir -p "$ZAPRET_CONFIG_DIR" 15 | cp "$ZAPRET_CONFIG_DEFAULT" "$ZAPRET_CONFIG" 16 | } 17 | 18 | . "$ZAPRET_CONFIG" 19 | . "$ZAPRET_BASE/common/base.sh" 20 | . "$ZAPRET_BASE/common/elevate.sh" 21 | . "$ZAPRET_BASE/common/fwtype.sh" 22 | . "$ZAPRET_BASE/common/dialog.sh" 23 | . "$ZAPRET_BASE/common/installer.sh" 24 | . "$ZAPRET_BASE/common/ipt.sh" 25 | 26 | umask 0022 27 | fix_sbin_path 28 | fsleep_setup 29 | check_system accept_unknown_rc 30 | [ $UNAME = "Linux" ] || { 31 | echo no prerequisites required for $UNAME 32 | exitp 0 33 | } 34 | require_root 35 | 36 | case $UNAME in 37 | Linux) 38 | select_fwtype 39 | case $SYSTEM in 40 | openwrt) 41 | select_ipv6 42 | check_prerequisites_openwrt 43 | ;; 44 | *) 45 | check_prerequisites_linux 46 | ;; 47 | esac 48 | ;; 49 | esac 50 | 51 | exitp 0 52 | -------------------------------------------------------------------------------- /ip2net/Makefile: -------------------------------------------------------------------------------- 1 | CC ?= gcc 2 | CFLAGS += -std=gnu99 -Os -flto=auto 3 | CFLAGS_BSD = -Wno-address-of-packed-member 4 | CFLAGS_WIN = -static 5 | LIBS = 6 | LIBS_WIN = -lws2_32 7 | SRC_FILES = ip2net.c qsort.c 8 | 9 | all: ip2net 10 | 11 | ip2net: $(SRC_FILES) 12 | $(CC) -s $(CFLAGS) -o ip2net $(SRC_FILES) $(LIBS) $(LDFLAGS) 13 | 14 | systemd: ip2net 15 | 16 | android: ip2net 17 | 18 | bsd: $(SRC_FILES) 19 | $(CC) -s $(CFLAGS) $(CFLAGS_BSD) -o ip2net $(SRC_FILES) $(LIBS) $(LDFLAGS) 20 | 21 | mac: $(SRC_FILES) 22 | $(CC) $(CFLAGS) $(CFLAGS_BSD) -o ip2neta $(SRC_FILES) -target arm64-apple-macos10.8 $(LIBS) $(LDFLAGS) 23 | $(CC) $(CFLAGS) $(CFLAGS_BSD) -o ip2netx $(SRC_FILES) -target x86_64-apple-macos10.8 $(LIBS) $(LDFLAGS) 24 | strip ip2neta ip2netx 25 | lipo -create -output ip2net ip2netx ip2neta 26 | rm -f ip2netx ip2neta 27 | 28 | win: $(SRC_FILES) 29 | $(CC) -s $(CFLAGS) $(CFLAGS_WIN) -o ip2net $(SRC_FILES) $(LIBS_WIN) $(LDFLAGS) 30 | 31 | clean: 32 | rm -f ip2net *.o 33 | -------------------------------------------------------------------------------- /ip2net/qsort.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | // GNU qsort is 2x faster than musl 4 | 5 | typedef int (*__gnu_compar_d_fn_t) (const void *, const void *, void *); 6 | void gnu_quicksort (void *const pbase, size_t total_elems, size_t size, __gnu_compar_d_fn_t cmp, void *arg); 7 | -------------------------------------------------------------------------------- /ipset/antifilter.helper: -------------------------------------------------------------------------------- 1 | get_antifilter() 2 | { 3 | # $1 - list url 4 | # $2 - target file 5 | local ZIPLISTTMP="$TMPDIR/zapret-ip.txt" 6 | 7 | [ "$DISABLE_IPV4" != "1" ] && { 8 | curl --fail --max-time 150 --connect-timeout 20 --max-filesize 41943040 -k -L "$1" | cut_local >"$ZIPLISTTMP" && 9 | { 10 | dlsize=$(LC_ALL=C LANG=C wc -c "$ZIPLISTTMP" | xargs | cut -f 1 -d ' ') 11 | if [ $dlsize -lt 102400 ]; then 12 | echo list file is too small. can be bad. 13 | exit 2 14 | fi 15 | ip2net4 <"$ZIPLISTTMP" | zz "$2" 16 | rm -f "$ZIPLISTTMP" 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /ipset/clear_lists.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | IPSET_DIR="$(dirname "$0")" 4 | IPSET_DIR="$(cd "$IPSET_DIR"; pwd)" 5 | 6 | . "$IPSET_DIR/def.sh" 7 | 8 | rm -f "$ZIPLIST"* "$ZIPLIST6"* "$ZIPLIST_USER" "$ZIPLIST_USER6" "$ZIPLIST_IPBAN"* "$ZIPLIST_IPBAN6"* "$ZIPLIST_USER_IPBAN" "$ZIPLIST_USER_IPBAN6" "$ZIPLIST_EXCLUDE" "$ZIPLIST_EXCLUDE6" "$ZHOSTLIST"* 9 | -------------------------------------------------------------------------------- /ipset/get_antifilter_allyouneed.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | IPSET_DIR="$(dirname "$0")" 4 | IPSET_DIR="$(cd "$IPSET_DIR"; pwd)" 5 | 6 | . "$IPSET_DIR/def.sh" 7 | 8 | getuser && { 9 | . "$IPSET_DIR/antifilter.helper" 10 | get_antifilter https://antifilter.download/list/allyouneed.lst "$ZIPLIST" 11 | } 12 | 13 | "$IPSET_DIR/create_ipset.sh" 14 | -------------------------------------------------------------------------------- /ipset/get_antifilter_ip.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | IPSET_DIR="$(dirname "$0")" 4 | IPSET_DIR="$(cd "$IPSET_DIR"; pwd)" 5 | 6 | . "$IPSET_DIR/def.sh" 7 | 8 | getuser && { 9 | . "$IPSET_DIR/antifilter.helper" 10 | get_antifilter https://antifilter.download/list/ip.lst "$ZIPLIST" 11 | } 12 | 13 | "$IPSET_DIR/create_ipset.sh" 14 | -------------------------------------------------------------------------------- /ipset/get_antifilter_ipresolve.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | IPSET_DIR="$(dirname "$0")" 4 | IPSET_DIR="$(cd "$IPSET_DIR"; pwd)" 5 | 6 | . "$IPSET_DIR/def.sh" 7 | 8 | getuser && { 9 | . "$IPSET_DIR/antifilter.helper" 10 | get_antifilter https://antifilter.download/list/ipresolve.lst "$ZIPLIST" 11 | } 12 | 13 | "$IPSET_DIR/create_ipset.sh" 14 | -------------------------------------------------------------------------------- /ipset/get_antifilter_ipsmart.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | IPSET_DIR="$(dirname "$0")" 4 | IPSET_DIR="$(cd "$IPSET_DIR"; pwd)" 5 | 6 | . "$IPSET_DIR/def.sh" 7 | 8 | getuser && { 9 | . "$IPSET_DIR/antifilter.helper" 10 | get_antifilter https://antifilter.network/download/ipsmart.lst "$ZIPLIST" 11 | } 12 | 13 | "$IPSET_DIR/create_ipset.sh" 14 | -------------------------------------------------------------------------------- /ipset/get_antifilter_ipsum.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | IPSET_DIR="$(dirname "$0")" 4 | IPSET_DIR="$(cd "$IPSET_DIR"; pwd)" 5 | 6 | . "$IPSET_DIR/def.sh" 7 | 8 | getuser && { 9 | . "$IPSET_DIR/antifilter.helper" 10 | get_antifilter https://antifilter.download/list/ipsum.lst "$ZIPLIST" 11 | } 12 | 13 | "$IPSET_DIR/create_ipset.sh" 14 | -------------------------------------------------------------------------------- /ipset/get_antizapret_domains.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | IPSET_DIR="$(dirname "$0")" 4 | IPSET_DIR="$(cd "$IPSET_DIR"; pwd)" 5 | 6 | . "$IPSET_DIR/def.sh" 7 | 8 | # useful in case ipban set is used in custom scripts 9 | FAIL= 10 | getipban || FAIL=1 11 | "$IPSET_DIR/create_ipset.sh" 12 | [ -n "$FAIL" ] && exit 13 | 14 | ZURL=https://antizapret.prostovpn.org:8443/domains-export.txt 15 | ZDOM="$TMPDIR/zapret.txt" 16 | 17 | 18 | curl -H "Accept-Encoding: gzip" -k --fail --max-time 600 --connect-timeout 5 --retry 3 --max-filesize 251658240 "$ZURL" | gunzip - >"$ZDOM" || 19 | { 20 | echo domain list download failed 21 | exit 2 22 | } 23 | 24 | dlsize=$(LC_ALL=C LANG=C wc -c "$ZDOM" | xargs | cut -f 1 -d ' ') 25 | if test $dlsize -lt 102400; then 26 | echo list file is too small. can be bad. 27 | exit 2 28 | fi 29 | 30 | sort -u "$ZDOM" | zz "$ZHOSTLIST" 31 | 32 | rm -f "$ZDOM" 33 | 34 | hup_zapret_daemons 35 | 36 | exit 0 37 | -------------------------------------------------------------------------------- /ipset/get_config.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # run script specified in config 3 | 4 | IPSET_DIR="$(dirname "$0")" 5 | IPSET_DIR="$(cd "$IPSET_DIR"; pwd)" 6 | 7 | [ -f "$IPSET_DIR/../config" ] && . "$IPSET_DIR/../config" 8 | 9 | [ -z "$GETLIST" ] && GETLIST=get_ipban.sh 10 | [ -x "$IPSET_DIR/$GETLIST" ] && exec "$IPSET_DIR/$GETLIST" 11 | -------------------------------------------------------------------------------- /ipset/get_exclude.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # resolve user host list 3 | 4 | IPSET_DIR="$(dirname "$0")" 5 | IPSET_DIR="$(cd "$IPSET_DIR"; pwd)" 6 | 7 | . "$IPSET_DIR/def.sh" 8 | 9 | getexclude 10 | 11 | "$IPSET_DIR/create_ipset.sh" 12 | -------------------------------------------------------------------------------- /ipset/get_ipban.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # resolve only ipban user host list 3 | 4 | IPSET_DIR="$(dirname "$0")" 5 | IPSET_DIR="$(cd "$IPSET_DIR"; pwd)" 6 | 7 | . "$IPSET_DIR/def.sh" 8 | 9 | getipban 10 | 11 | "$IPSET_DIR/create_ipset.sh" 12 | -------------------------------------------------------------------------------- /ipset/get_reestr_hostlist.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | IPSET_DIR="$(dirname "$0")" 4 | IPSET_DIR="$(cd "$IPSET_DIR"; pwd)" 5 | 6 | . "$IPSET_DIR/def.sh" 7 | 8 | ZREESTR="$TMPDIR/zapret.txt.gz" 9 | IPB="$TMPDIR/ipb.txt" 10 | ZURL_REESTR=https://raw.githubusercontent.com/zapret-info/z-i/master/dump.csv.gz 11 | 12 | dl_checked() 13 | { 14 | # $1 - url 15 | # $2 - file 16 | # $3 - minsize 17 | # $4 - maxsize 18 | # $5 - maxtime 19 | curl -k --fail --max-time $5 --connect-timeout 10 --retry 4 --max-filesize $4 -o "$2" "$1" || 20 | { 21 | echo list download failed : $1 22 | return 2 23 | } 24 | dlsize=$(LC_ALL=C LANG=C wc -c "$2" | xargs | cut -f 1 -d ' ') 25 | if test $dlsize -lt $3; then 26 | echo list is too small : $dlsize bytes. can be bad. 27 | return 2 28 | fi 29 | return 0 30 | } 31 | 32 | reestr_list() 33 | { 34 | LC_ALL=C LANG=C gunzip -c "$ZREESTR" | cut -s -f2 -d';' | LC_ALL=C LANG=C nice -n 5 sed -Ee 's/^\*\.(.+)$/\1/' -ne 's/^[a-z0-9A-Z._-]+$/&/p' | $AWK '{ print tolower($0) }' 35 | } 36 | reestr_extract_ip() 37 | { 38 | LC_ALL=C LANG=C gunzip -c | nice -n 5 $AWK -F ';' '($1 ~ /^([0-9]{1,3}\.){3}[0-9]{1,3}/) && (($2 == "" && $3 == "") || ($1 == $2)) {gsub(/ \| /, RS); print $1}' | LC_ALL=C LANG=C $AWK '{split($1, a, /\|/); for (i in a) {print a[i]}}' 39 | } 40 | 41 | ipban_fin() 42 | { 43 | getipban 44 | "$IPSET_DIR/create_ipset.sh" 45 | } 46 | 47 | dl_checked "$ZURL_REESTR" "$ZREESTR" 204800 251658240 600 || { 48 | ipban_fin 49 | exit 2 50 | } 51 | 52 | reestr_list | sort -u | zz "$ZHOSTLIST" 53 | 54 | reestr_extract_ip <"$ZREESTR" >"$IPB" 55 | 56 | rm -f "$ZREESTR" 57 | [ "$DISABLE_IPV4" != "1" ] && $AWK '/^([0-9]{1,3}\.){3}[0-9]{1,3}($|(\/[0-9]{2}$))/' "$IPB" | cut_local | ip2net4 | zz "$ZIPLIST_IPBAN" 58 | [ "$DISABLE_IPV6" != "1" ] && $AWK '/^([0-9a-fA-F]{0,4}:){1,7}[0-9a-fA-F]{0,4}($|(\/[0-9]{2,3}$))/' "$IPB" | cut_local6 | ip2net6 | zz "$ZIPLIST_IPBAN6" 59 | rm -f "$IPB" 60 | 61 | hup_zapret_daemons 62 | 63 | ipban_fin 64 | 65 | exit 0 66 | -------------------------------------------------------------------------------- /ipset/get_reestr_preresolved.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | IPSET_DIR="$(dirname "$0")" 4 | IPSET_DIR="$(cd "$IPSET_DIR"; pwd)" 5 | 6 | . "$IPSET_DIR/def.sh" 7 | 8 | TMPLIST="$TMPDIR/list.txt" 9 | 10 | BASEURL="https://raw.githubusercontent.com/bol-van/rulist/main" 11 | URL4="$BASEURL/reestr_resolved4.txt" 12 | URL6="$BASEURL/reestr_resolved6.txt" 13 | IPB4="$BASEURL/reestr_ipban4.txt" 14 | IPB6="$BASEURL/reestr_ipban6.txt" 15 | 16 | dl() 17 | { 18 | # $1 - url 19 | # $2 - file 20 | # $3 - minsize 21 | # $4 - maxsize 22 | curl -H "Accept-Encoding: gzip" -k --fail --max-time 120 --connect-timeout 10 --retry 4 --max-filesize $4 -o "$TMPLIST" "$1" || 23 | { 24 | echo list download failed : $1 25 | exit 2 26 | } 27 | dlsize=$(LC_ALL=C LANG=C wc -c "$TMPLIST" | xargs | cut -f 1 -d ' ') 28 | if test $dlsize -lt $3; then 29 | echo list is too small : $dlsize bytes. can be bad. 30 | exit 2 31 | fi 32 | zzcopy "$TMPLIST" "$2" 33 | rm -f "$TMPLIST" 34 | } 35 | 36 | getuser && { 37 | [ "$DISABLE_IPV4" != "1" ] && { 38 | dl "$URL4" "$ZIPLIST" 32768 4194304 39 | dl "$IPB4" "$ZIPLIST_IPBAN" 8192 1048576 40 | } 41 | [ "$DISABLE_IPV6" != "1" ] && { 42 | dl "$URL6" "$ZIPLIST6" 8192 4194304 43 | dl "$IPB6" "$ZIPLIST_IPBAN6" 128 1048576 44 | } 45 | } 46 | 47 | "$IPSET_DIR/create_ipset.sh" 48 | -------------------------------------------------------------------------------- /ipset/get_reestr_preresolved_smart.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | IPSET_DIR="$(dirname "$0")" 4 | IPSET_DIR="$(cd "$IPSET_DIR"; pwd)" 5 | 6 | . "$IPSET_DIR/def.sh" 7 | 8 | TMPLIST="$TMPDIR/list.txt" 9 | 10 | BASEURL="https://raw.githubusercontent.com/bol-van/rulist/main" 11 | URL4="$BASEURL/reestr_smart4.txt" 12 | URL6="$BASEURL/reestr_smart6.txt" 13 | IPB4="$BASEURL/reestr_ipban4.txt" 14 | IPB6="$BASEURL/reestr_ipban6.txt" 15 | 16 | dl() 17 | { 18 | # $1 - url 19 | # $2 - file 20 | # $3 - minsize 21 | # $4 - maxsize 22 | curl -H "Accept-Encoding: gzip" -k --fail --max-time 120 --connect-timeout 10 --retry 4 --max-filesize $4 -o "$TMPLIST" "$1" || 23 | { 24 | echo list download failed : $1 25 | exit 2 26 | } 27 | dlsize=$(LC_ALL=C LANG=C wc -c "$TMPLIST" | xargs | cut -f 1 -d ' ') 28 | if test $dlsize -lt $3; then 29 | echo list is too small : $dlsize bytes. can be bad. 30 | exit 2 31 | fi 32 | zzcopy "$TMPLIST" "$2" 33 | rm -f "$TMPLIST" 34 | } 35 | 36 | getuser && { 37 | [ "$DISABLE_IPV4" != "1" ] && { 38 | dl "$URL4" "$ZIPLIST" 32768 4194304 39 | dl "$IPB4" "$ZIPLIST_IPBAN" 8192 1048576 40 | } 41 | [ "$DISABLE_IPV6" != "1" ] && { 42 | dl "$URL6" "$ZIPLIST6" 8192 4194304 43 | dl "$IPB6" "$ZIPLIST_IPBAN6" 128 1048576 44 | } 45 | } 46 | 47 | "$IPSET_DIR/create_ipset.sh" 48 | -------------------------------------------------------------------------------- /ipset/get_reestr_resolvable_domains.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | IPSET_DIR="$(dirname "$0")" 4 | IPSET_DIR="$(cd "$IPSET_DIR"; pwd)" 5 | 6 | . "$IPSET_DIR/def.sh" 7 | 8 | TMPLIST="$TMPDIR/list_nethub.txt" 9 | 10 | BASEURL="https://raw.githubusercontent.com/bol-van/rulist/main" 11 | URL="$BASEURL/reestr_hostname_resolvable.txt" 12 | IPB4="$BASEURL/reestr_ipban4.txt" 13 | IPB6="$BASEURL/reestr_ipban6.txt" 14 | 15 | dl() 16 | { 17 | # $1 - url 18 | # $2 - file 19 | # $3 - minsize 20 | # $4 - maxsize 21 | curl -H "Accept-Encoding: gzip" -k --fail --max-time 120 --connect-timeout 10 --retry 4 --max-filesize $4 -o "$TMPLIST" "$1" || 22 | { 23 | echo list download failed : $1 24 | exit 2 25 | } 26 | dlsize=$(LC_ALL=C LANG=C wc -c "$TMPLIST" | xargs | cut -f 1 -d ' ') 27 | if test $dlsize -lt $3; then 28 | echo list is too small : $dlsize bytes. can be bad. 29 | exit 2 30 | fi 31 | zzcopy "$TMPLIST" "$2" 32 | rm -f "$TMPLIST" 33 | } 34 | 35 | dl "$URL" "$ZHOSTLIST" 65536 67108864 36 | 37 | hup_zapret_daemons 38 | 39 | [ "$DISABLE_IPV4" != "1" ] && dl "$IPB4" "$ZIPLIST_IPBAN" 8192 1048576 40 | [ "$DISABLE_IPV6" != "1" ] && dl "$IPB6" "$ZIPLIST_IPBAN6" 128 1048576 41 | 42 | getipban 43 | "$IPSET_DIR/create_ipset.sh" 44 | 45 | exit 0 46 | -------------------------------------------------------------------------------- /ipset/get_reestr_resolve.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | IPSET_DIR="$(dirname "$0")" 4 | IPSET_DIR="$(cd "$IPSET_DIR"; pwd)" 5 | 6 | . "$IPSET_DIR/def.sh" 7 | 8 | ZREESTR="$TMPDIR/zapret.txt.gz" 9 | ZDIG="$TMPDIR/zapret-dig.txt" 10 | IPB="$TMPDIR/ipb.txt" 11 | ZIPLISTTMP="$TMPDIR/zapret-ip.txt" 12 | #ZURL=https://reestr.rublacklist.net/api/current 13 | ZURL_REESTR=https://raw.githubusercontent.com/zapret-info/z-i/master/dump.csv.gz 14 | 15 | dl_checked() 16 | { 17 | # $1 - url 18 | # $2 - file 19 | # $3 - minsize 20 | # $4 - maxsize 21 | # $5 - maxtime 22 | curl -k --fail --max-time $5 --connect-timeout 10 --retry 4 --max-filesize $4 -o "$2" "$1" || 23 | { 24 | echo list download failed : $1 25 | return 2 26 | } 27 | dlsize=$(LC_ALL=C LANG=C wc -c "$2" | xargs | cut -f 1 -d ' ') 28 | if test $dlsize -lt $3; then 29 | echo list is too small : $dlsize bytes. can be bad. 30 | return 2 31 | fi 32 | return 0 33 | } 34 | 35 | reestr_list() 36 | { 37 | LC_ALL=C LANG=C gunzip -c "$ZREESTR" | cut -s -f2 -d';' | LC_ALL=C LANG=C nice -n 5 sed -Ee 's/^\*\.(.+)$/\1/' -ne 's/^[a-z0-9A-Z._-]+$/&/p' | $AWK '{ print tolower($0) }' 38 | } 39 | reestr_extract_ip() 40 | { 41 | LC_ALL=C LANG=C gunzip -c | nice -n 5 $AWK -F ';' '($1 ~ /^([0-9]{1,3}\.){3}[0-9]{1,3}/) && (($2 == "" && $3 == "") || ($1 == $2)) {gsub(/ \| /, RS); print $1}' | LC_ALL=C LANG=C $AWK '{split($1, a, /\|/); for (i in a) {print a[i]}}' 42 | } 43 | 44 | getuser && { 45 | # both disabled 46 | [ "$DISABLE_IPV4" = "1" ] && [ "$DISABLE_IPV6" = "1" ] && exit 0 47 | 48 | dl_checked "$ZURL_REESTR" "$ZREESTR" 204800 251658240 600 || exit 2 49 | 50 | echo preparing ipban list .. 51 | 52 | reestr_extract_ip <"$ZREESTR" >"$IPB" 53 | [ "$DISABLE_IPV4" != "1" ] && $AWK '/^([0-9]{1,3}\.){3}[0-9]{1,3}($|(\/[0-9]{2}$))/' "$IPB" | cut_local | ip2net4 | zz "$ZIPLIST_IPBAN" 54 | [ "$DISABLE_IPV6" != "1" ] && $AWK '/^([0-9a-fA-F]{0,4}:){1,7}[0-9a-fA-F]{0,4}($|(\/[0-9]{2,3}$))/' "$IPB" | cut_local6 | ip2net6 | zz "$ZIPLIST_IPBAN6" 55 | rm -f "$IPB" 56 | 57 | echo preparing dig list .. 58 | reestr_list | sort -u >"$ZDIG" 59 | 60 | rm -f "$ZREESTR" 61 | 62 | echo digging started. this can take long ... 63 | 64 | [ "$DISABLE_IPV4" != "1" ] && { 65 | filedigger "$ZDIG" 4 | cut_local >"$ZIPLISTTMP" || { 66 | rm -f "$ZDIG" 67 | exit 1 68 | } 69 | ip2net4 <"$ZIPLISTTMP" | zz "$ZIPLIST" 70 | rm -f "$ZIPLISTTMP" 71 | } 72 | [ "$DISABLE_IPV6" != "1" ] && { 73 | filedigger "$ZDIG" 6 | cut_local6 >"$ZIPLISTTMP" || { 74 | rm -f "$ZDIG" 75 | exit 1 76 | } 77 | ip2net6 <"$ZIPLISTTMP" | zz "$ZIPLIST6" 78 | rm -f "$ZIPLISTTMP" 79 | } 80 | rm -f "$ZDIG" 81 | } 82 | 83 | "$IPSET_DIR/create_ipset.sh" 84 | -------------------------------------------------------------------------------- /ipset/get_refilter_domains.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | IPSET_DIR="$(dirname "$0")" 4 | IPSET_DIR="$(cd "$IPSET_DIR"; pwd)" 5 | 6 | . "$IPSET_DIR/def.sh" 7 | 8 | TMPLIST="$TMPDIR/list.txt" 9 | 10 | URL="https://github.com/1andrevich/Re-filter-lists/releases/latest/download/domains_all.lst" 11 | 12 | dl() 13 | { 14 | # $1 - url 15 | # $2 - file 16 | # $3 - minsize 17 | # $4 - maxsize 18 | curl -L -H "Accept-Encoding: gzip" -k --fail --max-time 60 --connect-timeout 10 --retry 4 --max-filesize $4 -o "$TMPLIST" "$1" || 19 | { 20 | echo list download failed : $1 21 | exit 2 22 | } 23 | dlsize=$(LC_ALL=C LANG=C wc -c "$TMPLIST" | xargs | cut -f 1 -d ' ') 24 | if test $dlsize -lt $3; then 25 | echo list is too small : $dlsize bytes. can be bad. 26 | exit 2 27 | fi 28 | zzcopy "$TMPLIST" "$2" 29 | rm -f "$TMPLIST" 30 | } 31 | 32 | # useful in case ipban set is used in custom scripts 33 | FAIL= 34 | getipban || FAIL=1 35 | "$IPSET_DIR/create_ipset.sh" 36 | [ -n "$FAIL" ] && exit 37 | 38 | dl "$URL" "$ZHOSTLIST" 32768 4194304 39 | 40 | hup_zapret_daemons 41 | 42 | exit 0 43 | -------------------------------------------------------------------------------- /ipset/get_refilter_ipsum.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | IPSET_DIR="$(dirname "$0")" 4 | IPSET_DIR="$(cd "$IPSET_DIR"; pwd)" 5 | 6 | . "$IPSET_DIR/def.sh" 7 | 8 | TMPLIST="$TMPDIR/list.txt" 9 | 10 | URL="https://github.com/1andrevich/Re-filter-lists/releases/latest/download/ipsum.lst" 11 | 12 | dl() 13 | { 14 | # $1 - url 15 | # $2 - file 16 | # $3 - minsize 17 | # $4 - maxsize 18 | curl -L -H "Accept-Encoding: gzip" -k --fail --max-time 60 --connect-timeout 10 --retry 4 --max-filesize $4 -o "$TMPLIST" "$1" || 19 | { 20 | echo list download failed : $1 21 | exit 2 22 | } 23 | dlsize=$(LC_ALL=C LANG=C wc -c "$TMPLIST" | xargs | cut -f 1 -d ' ') 24 | if test $dlsize -lt $3; then 25 | echo list is too small : $dlsize bytes. can be bad. 26 | exit 2 27 | fi 28 | zzcopy "$TMPLIST" "$2" 29 | rm -f "$TMPLIST" 30 | } 31 | 32 | getuser && { 33 | [ "$DISABLE_IPV4" != "1" ] && { 34 | dl "$URL" "$ZIPLIST" 32768 4194304 35 | } 36 | } 37 | 38 | "$IPSET_DIR/create_ipset.sh" 39 | -------------------------------------------------------------------------------- /ipset/get_user.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # resolve user host list 3 | 4 | IPSET_DIR="$(dirname "$0")" 5 | IPSET_DIR="$(cd "$IPSET_DIR"; pwd)" 6 | 7 | . "$IPSET_DIR/def.sh" 8 | 9 | getuser 10 | 11 | "$IPSET_DIR/create_ipset.sh" 12 | -------------------------------------------------------------------------------- /ipset/zapret-hosts-user-exclude.txt.default: -------------------------------------------------------------------------------- 1 | 127.0.0.0/8 2 | 10.0.0.0/8 3 | 172.16.0.0/12 4 | 192.168.0.0/16 5 | 169.254.0.0/16 6 | ::1 7 | fc00::/7 8 | fe80::/10 9 | -------------------------------------------------------------------------------- /mdig/Makefile: -------------------------------------------------------------------------------- 1 | CC ?= gcc 2 | CFLAGS += -std=gnu99 -Os 3 | CFLAGS_BSD = -Wno-address-of-packed-member 4 | CFLAGS_WIN = -static 5 | LIBS = -lpthread 6 | LIBS_ANDROID = 7 | LIBS_WIN = -lws2_32 8 | SRC_FILES = *.c 9 | 10 | all: mdig 11 | 12 | mdig: $(SRC_FILES) 13 | $(CC) -s $(CFLAGS) -o mdig $(SRC_FILES) $(LIBS) $(LDFLAGS) 14 | 15 | systemd: mdig 16 | 17 | android: $(SRC_FILES) 18 | $(CC) -s $(CFLAGS) -o mdig $(SRC_FILES) $(LIBS_ANDROID) $(LDFLAGS) 19 | 20 | bsd: $(SRC_FILES) 21 | $(CC) -s $(CFLAGS) $(CFLAGS_BSD) -o mdig $(SRC_FILES) $(LIBS) $(LDFLAGS) 22 | 23 | mac: $(SRC_FILES) 24 | $(CC) $(CFLAGS) $(CFLAGS_BSD) -o mdiga $(SRC_FILES) -target arm64-apple-macos10.8 $(LIBS_BSD) $(LDFLAGS) 25 | $(CC) $(CFLAGS) $(CFLAGS_BSD) -o mdigx $(SRC_FILES) -target x86_64-apple-macos10.8 $(LIBS_BSD) $(LDFLAGS) 26 | strip mdiga mdigx 27 | lipo -create -output mdig mdigx mdiga 28 | rm -f mdigx mdiga 29 | 30 | win: $(SRC_FILES) 31 | $(CC) -s $(CFLAGS) $(CFLAGS_WIN) -o mdig $(SRC_FILES) $(LIBS_WIN) $(LDFLAGS) 32 | 33 | clean: 34 | rm -f mdig *.o 35 | -------------------------------------------------------------------------------- /nfq/BSDmakefile: -------------------------------------------------------------------------------- 1 | CC ?= cc 2 | CFLAGS += -std=gnu99 -s -Os -Wno-address-of-packed-member -flto=auto 3 | LIBS = -lz 4 | SRC_FILES = *.c crypto/*.c 5 | 6 | all: dvtws 7 | 8 | dvtws: $(SRC_FILES) 9 | $(CC) $(CFLAGS) -o dvtws $(SRC_FILES) $(LIBS) $(LDFLAGS) 10 | 11 | clean: 12 | rm -f dvtws 13 | -------------------------------------------------------------------------------- /nfq/Makefile: -------------------------------------------------------------------------------- 1 | CC ?= gcc 2 | CFLAGS += -std=gnu99 -Os -flto=auto 3 | CFLAGS_SYSTEMD = -DUSE_SYSTEMD 4 | CFLAGS_BSD = -Wno-address-of-packed-member 5 | CFLAGS_CYGWIN = -Wno-address-of-packed-member -static 6 | LDFLAGS_ANDROID = -llog 7 | LIBS_LINUX = -lnetfilter_queue -lnfnetlink -lz 8 | LIBS_SYSTEMD = -lsystemd 9 | LIBS_BSD = -lz 10 | LIBS_CYGWIN = -lz -Lwindows/windivert -Iwindows -lwlanapi -lole32 -loleaut32 11 | LIBS_CYGWIN32 = -lwindivert32 12 | LIBS_CYGWIN64 = -lwindivert64 13 | RES_CYGWIN32 = windows/res/32/winmanifest.o windows/res/32/winicon.o 14 | RES_CYGWIN64 = windows/res/64/winmanifest.o windows/res/64/winicon.o 15 | SRC_FILES = *.c crypto/*.c 16 | 17 | all: nfqws 18 | 19 | nfqws: $(SRC_FILES) 20 | $(CC) -s $(CFLAGS) -o nfqws $(SRC_FILES) $(LIBS_LINUX) $(LDFLAGS) 21 | 22 | systemd: $(SRC_FILES) 23 | $(CC) -s $(CFLAGS) $(CFLAGS_SYSTEMD) -o nfqws $(SRC_FILES) $(LIBS_LINUX) $(LIBS_SYSTEMD) $(LDFLAGS) 24 | 25 | android: $(SRC_FILES) 26 | $(CC) -s $(CFLAGS) -o nfqws $(SRC_FILES) $(LIBS_LINUX) $(LDFLAGS) $(LDFLAGS_ANDROID) 27 | 28 | bsd: $(SRC_FILES) 29 | $(CC) -s $(CFLAGS) $(CFLAGS_BSD) -o dvtws $(SRC_FILES) $(LIBS_BSD) $(LDFLAGS) 30 | 31 | mac: $(SRC_FILES) 32 | $(CC) $(CFLAGS) $(CFLAGS_BSD) -o dvtwsa $(SRC_FILES) -target arm64-apple-macos10.8 $(LIBS_BSD) $(LDFLAGS) 33 | $(CC) $(CFLAGS) $(CFLAGS_BSD) -o dvtwsx $(SRC_FILES) -target x86_64-apple-macos10.8 $(LIBS_BSD) $(LDFLAGS) 34 | strip dvtwsa dvtwsx 35 | lipo -create -output dvtws dvtwsx dvtwsa 36 | rm -f dvtwsx dvtwsa 37 | 38 | cygwin64: 39 | $(CC) -s $(CFLAGS) $(CFLAGS_CYGWIN) -o winws $(SRC_FILES) $(LIBS_CYGWIN) $(LIBS_CYGWIN64) $(RES_CYGWIN64) $(LDFLAGS) 40 | cygwin32: 41 | $(CC) -s $(CFLAGS) $(CFLAGS_CYGWIN) -o winws $(SRC_FILES) $(LIBS_CYGWIN) $(LIBS_CYGWIN32) $(RES_CYGWIN32) $(LDFLAGS) 42 | cygwin: cygwin64 43 | 44 | clean: 45 | rm -f nfqws dvtws winws.exe 46 | -------------------------------------------------------------------------------- /nfq/checksum.c: -------------------------------------------------------------------------------- 1 | #define _GNU_SOURCE 2 | #include "checksum.h" 3 | #include 4 | 5 | //#define htonll(x) ((1==htonl(1)) ? (x) : ((uint64_t)htonl((x) & 0xFFFFFFFF) << 32) | htonl((x) >> 32)) 6 | //#define ntohll(x) ((1==ntohl(1)) ? (x) : ((uint64_t)ntohl((x) & 0xFFFFFFFF) << 32) | ntohl((x) >> 32)) 7 | 8 | static uint16_t from64to16(uint64_t x) 9 | { 10 | uint32_t u = (uint32_t)(uint16_t)x + (uint16_t)(x>>16) + (uint16_t)(x>>32) + (uint16_t)(x>>48); 11 | return (uint16_t)u + (uint16_t)(u>>16); 12 | } 13 | 14 | // this function preserves data alignment requirements (otherwise it will be damn slow on mips arch) 15 | // and uses 64-bit arithmetics to improve speed 16 | // taken from linux source code 17 | static uint16_t do_csum(const uint8_t * buff, size_t len) 18 | { 19 | uint8_t odd; 20 | size_t count; 21 | uint64_t result,w,carry=0; 22 | uint16_t u16; 23 | 24 | if (!len) return 0; 25 | odd = (uint8_t)(1 & (size_t)buff); 26 | if (odd) 27 | { 28 | // any endian compatible 29 | u16 = 0; 30 | *((uint8_t*)&u16+1) = *buff; 31 | result = u16; 32 | len--; 33 | buff++; 34 | } 35 | else 36 | result = 0; 37 | count = len >> 1; /* nr of 16-bit words.. */ 38 | if (count) 39 | { 40 | if (2 & (size_t) buff) 41 | { 42 | result += *(uint16_t *) buff; 43 | count--; 44 | len -= 2; 45 | buff += 2; 46 | } 47 | count >>= 1; /* nr of 32-bit words.. */ 48 | if (count) 49 | { 50 | if (4 & (size_t) buff) 51 | { 52 | result += *(uint32_t *) buff; 53 | count--; 54 | len -= 4; 55 | buff += 4; 56 | } 57 | count >>= 1; /* nr of 64-bit words.. */ 58 | if (count) 59 | { 60 | do 61 | { 62 | w = *(uint64_t *) buff; 63 | count--; 64 | buff += 8; 65 | result += carry; 66 | result += w; 67 | carry = (w > result); 68 | } while (count); 69 | result += carry; 70 | result = (result & 0xffffffff) + (result >> 32); 71 | } 72 | if (len & 4) 73 | { 74 | result += *(uint32_t *) buff; 75 | buff += 4; 76 | } 77 | } 78 | if (len & 2) 79 | { 80 | result += *(uint16_t *) buff; 81 | buff += 2; 82 | } 83 | } 84 | if (len & 1) 85 | { 86 | // any endian compatible 87 | u16 = 0; 88 | *(uint8_t*)&u16 = *buff; 89 | result += u16; 90 | } 91 | u16 = from64to16(result); 92 | if (odd) u16 = ((u16 >> 8) & 0xff) | ((u16 & 0xff) << 8); 93 | return u16; 94 | } 95 | 96 | uint16_t csum_partial(const void *buff, size_t len) 97 | { 98 | return do_csum(buff,len); 99 | } 100 | 101 | uint16_t csum_tcpudp_magic(uint32_t saddr, uint32_t daddr, size_t len, uint8_t proto, uint16_t sum) 102 | { 103 | return ~from64to16((uint64_t)saddr + daddr + sum + htonl(len+proto)); 104 | } 105 | 106 | uint16_t ip4_compute_csum(const void *buff, size_t len) 107 | { 108 | return ~from64to16(do_csum(buff,len)); 109 | } 110 | void ip4_fix_checksum(struct ip *ip) 111 | { 112 | ip->ip_sum = 0; 113 | ip->ip_sum = ip4_compute_csum(ip, ip->ip_hl<<2); 114 | } 115 | 116 | uint16_t csum_ipv6_magic(const void *saddr, const void *daddr, size_t len, uint8_t proto, uint16_t sum) 117 | { 118 | uint64_t a = (uint64_t)sum + htonl(len+proto) + 119 | *(uint32_t*)saddr + *((uint32_t*)saddr+1) + *((uint32_t*)saddr+2) + *((uint32_t*)saddr+3) + 120 | *(uint32_t*)daddr + *((uint32_t*)daddr+1) + *((uint32_t*)daddr+2) + *((uint32_t*)daddr+3); 121 | return ~from64to16(a); 122 | } 123 | 124 | 125 | void tcp4_fix_checksum(struct tcphdr *tcp,size_t len, const struct in_addr *src_addr, const struct in_addr *dest_addr) 126 | { 127 | tcp->th_sum = 0; 128 | tcp->th_sum = csum_tcpudp_magic(src_addr->s_addr,dest_addr->s_addr,len,IPPROTO_TCP,csum_partial(tcp,len)); 129 | } 130 | void tcp6_fix_checksum(struct tcphdr *tcp,size_t len, const struct in6_addr *src_addr, const struct in6_addr *dest_addr) 131 | { 132 | tcp->th_sum = 0; 133 | tcp->th_sum = csum_ipv6_magic(src_addr,dest_addr,len,IPPROTO_TCP,csum_partial(tcp,len)); 134 | } 135 | void tcp_fix_checksum(struct tcphdr *tcp,size_t len,const struct ip *ip,const struct ip6_hdr *ip6hdr) 136 | { 137 | if (ip) 138 | tcp4_fix_checksum(tcp, len, &ip->ip_src, &ip->ip_dst); 139 | else if (ip6hdr) 140 | tcp6_fix_checksum(tcp, len, &ip6hdr->ip6_src, &ip6hdr->ip6_dst); 141 | } 142 | 143 | void udp4_fix_checksum(struct udphdr *udp,size_t len, const struct in_addr *src_addr, const struct in_addr *dest_addr) 144 | { 145 | udp->uh_sum = 0; 146 | udp->uh_sum = csum_tcpudp_magic(src_addr->s_addr,dest_addr->s_addr,len,IPPROTO_UDP,csum_partial(udp,len)); 147 | } 148 | void udp6_fix_checksum(struct udphdr *udp,size_t len, const struct in6_addr *src_addr, const struct in6_addr *dest_addr) 149 | { 150 | udp->uh_sum = 0; 151 | udp->uh_sum = csum_ipv6_magic(src_addr,dest_addr,len,IPPROTO_UDP,csum_partial(udp,len)); 152 | } 153 | void udp_fix_checksum(struct udphdr *udp,size_t len,const struct ip *ip,const struct ip6_hdr *ip6hdr) 154 | { 155 | if (ip) 156 | udp4_fix_checksum(udp, len, &ip->ip_src, &ip->ip_dst); 157 | else if (ip6hdr) 158 | udp6_fix_checksum(udp, len, &ip6hdr->ip6_src, &ip6hdr->ip6_dst); 159 | } 160 | -------------------------------------------------------------------------------- /nfq/checksum.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | #define __FAVOR_BSD 9 | #include 10 | #include 11 | #include 12 | #include 13 | 14 | uint16_t csum_partial(const void *buff, size_t len); 15 | uint16_t csum_tcpudp_magic(uint32_t saddr, uint32_t daddr, size_t len, uint8_t proto, uint16_t sum); 16 | uint16_t csum_ipv6_magic(const void *saddr, const void *daddr, size_t len, uint8_t proto, uint16_t sum); 17 | 18 | uint16_t ip4_compute_csum(const void *buff, size_t len); 19 | void ip4_fix_checksum(struct ip *ip); 20 | 21 | void tcp4_fix_checksum(struct tcphdr *tcp,size_t len, const struct in_addr *src_addr, const struct in_addr *dest_addr); 22 | void tcp6_fix_checksum(struct tcphdr *tcp,size_t len, const struct in6_addr *src_addr, const struct in6_addr *dest_addr); 23 | void tcp_fix_checksum(struct tcphdr *tcp,size_t len,const struct ip *ip,const struct ip6_hdr *ip6hdr); 24 | 25 | void udp4_fix_checksum(struct udphdr *udp,size_t len, const struct in_addr *src_addr, const struct in_addr *dest_addr); 26 | void udp6_fix_checksum(struct udphdr *udp,size_t len, const struct in6_addr *src_addr, const struct in6_addr *dest_addr); 27 | void udp_fix_checksum(struct udphdr *udp,size_t len,const struct ip *ip,const struct ip6_hdr *ip6hdr); 28 | -------------------------------------------------------------------------------- /nfq/crypto/aes-gcm.c: -------------------------------------------------------------------------------- 1 | #include "aes-gcm.h" 2 | 3 | int aes_gcm_crypt(int mode, uint8_t *output, const uint8_t *input, size_t input_length, const uint8_t *key, const size_t key_len, const uint8_t *iv, const size_t iv_len, const uint8_t *adata, size_t adata_len, uint8_t *atag, size_t atag_len) 4 | { 5 | int ret = 0; 6 | gcm_context ctx; 7 | 8 | gcm_setkey(&ctx, key, (const uint)key_len); 9 | ret = gcm_crypt_and_tag(&ctx, mode, iv, iv_len, adata, adata_len, input, output, input_length, atag, atag_len); 10 | gcm_zero_ctx(&ctx); 11 | 12 | return ret; 13 | } 14 | -------------------------------------------------------------------------------- /nfq/crypto/aes-gcm.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "gcm.h" 4 | 5 | // mode : AES_ENCRYPT, AES_DECRYPT 6 | int aes_gcm_crypt(int mode, uint8_t *output, const uint8_t *input, size_t input_length, const uint8_t *key, const size_t key_len, const uint8_t *iv, const size_t iv_len, const uint8_t *adata, size_t adata_len, uint8_t *atag, size_t atag_len); 7 | -------------------------------------------------------------------------------- /nfq/crypto/aes.h: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * 3 | * THIS SOURCE CODE IS HEREBY PLACED INTO THE PUBLIC DOMAIN FOR THE GOOD OF ALL 4 | * 5 | * This is a simple and straightforward implementation of the AES Rijndael 6 | * 128-bit block cipher designed by Vincent Rijmen and Joan Daemen. The focus 7 | * of this work was correctness & accuracy. It is written in 'C' without any 8 | * particular focus upon optimization or speed. It should be endian (memory 9 | * byte order) neutral since the few places that care are handled explicitly. 10 | * 11 | * This implementation of Rijndael was created by Steven M. Gibson of GRC.com. 12 | * 13 | * It is intended for general purpose use, but was written in support of GRC's 14 | * reference implementation of the SQRL (Secure Quick Reliable Login) client. 15 | * 16 | * See: http://csrc.nist.gov/archive/aes/rijndael/wsdindex.html 17 | * 18 | * NO COPYRIGHT IS CLAIMED IN THIS WORK, HOWEVER, NEITHER IS ANY WARRANTY MADE 19 | * REGARDING ITS FITNESS FOR ANY PARTICULAR PURPOSE. USE IT AT YOUR OWN RISK. 20 | * 21 | *******************************************************************************/ 22 | 23 | #pragma once 24 | 25 | /******************************************************************************/ 26 | #define AES_DECRYPTION 0 // whether AES decryption is supported 27 | /******************************************************************************/ 28 | 29 | #include 30 | 31 | #define AES_ENCRYPT 1 // specify whether we're encrypting 32 | #define AES_DECRYPT 0 // or decrypting 33 | 34 | #if defined(_MSC_VER) 35 | #include 36 | typedef UINT32 uint32_t; 37 | #else 38 | #include 39 | #endif 40 | 41 | typedef unsigned char uchar; // add some convienent shorter types 42 | typedef unsigned int uint; 43 | 44 | 45 | /****************************************************************************** 46 | * AES_INIT_KEYGEN_TABLES : MUST be called once before any AES use 47 | ******************************************************************************/ 48 | void aes_init_keygen_tables(void); 49 | 50 | 51 | /****************************************************************************** 52 | * AES_CONTEXT : cipher context / holds inter-call data 53 | ******************************************************************************/ 54 | typedef struct { 55 | int mode; // 1 for Encryption, 0 for Decryption 56 | int rounds; // keysize-based rounds count 57 | uint32_t *rk; // pointer to current round key 58 | uint32_t buf[68]; // key expansion buffer 59 | } aes_context; 60 | 61 | 62 | /****************************************************************************** 63 | * AES_SETKEY : called to expand the key for encryption or decryption 64 | ******************************************************************************/ 65 | int aes_setkey(aes_context *ctx, // pointer to context 66 | int mode, // 1 or 0 for Encrypt/Decrypt 67 | const uchar *key, // AES input key 68 | uint keysize); // size in bytes (must be 16, 24, 32 for 69 | // 128, 192 or 256-bit keys respectively) 70 | // returns 0 for success 71 | 72 | /****************************************************************************** 73 | * AES_CIPHER : called to encrypt or decrypt ONE 128-bit block of data 74 | ******************************************************************************/ 75 | int aes_cipher(aes_context *ctx, // pointer to context 76 | const uchar input[16], // 128-bit block to en/decipher 77 | uchar output[16]); // 128-bit output result block 78 | // returns 0 for success 79 | -------------------------------------------------------------------------------- /nfq/crypto/sha-private.h: -------------------------------------------------------------------------------- 1 | /************************ sha-private.h ************************/ 2 | /***************** See RFC 6234 for details. *******************/ 3 | #pragma once 4 | /* 5 | * These definitions are defined in FIPS 180-3, section 4.1. 6 | * Ch() and Maj() are defined identically in sections 4.1.1, 7 | * 4.1.2, and 4.1.3. 8 | * 9 | * The definitions used in FIPS 180-3 are as follows: 10 | */ 11 | 12 | #ifndef USE_MODIFIED_MACROS 13 | #define SHA_Ch(x,y,z) (((x) & (y)) ^ ((~(x)) & (z))) 14 | #define SHA_Maj(x,y,z) (((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z))) 15 | #else /* USE_MODIFIED_MACROS */ 16 | /* 17 | * The following definitions are equivalent and potentially faster. 18 | */ 19 | 20 | #define SHA_Ch(x, y, z) (((x) & ((y) ^ (z))) ^ (z)) 21 | #define SHA_Maj(x, y, z) (((x) & ((y) | (z))) | ((y) & (z))) 22 | 23 | #endif /* USE_MODIFIED_MACROS */ 24 | 25 | #define SHA_Parity(x, y, z) ((x) ^ (y) ^ (z)) 26 | -------------------------------------------------------------------------------- /nfq/desync.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "darkmagic.h" 4 | 5 | #include 6 | #include 7 | 8 | #define __FAVOR_BSD 9 | #include 10 | #include 11 | #include 12 | #include 13 | 14 | #ifdef __linux__ 15 | #define DPI_DESYNC_FWMARK_DEFAULT 0x40000000 16 | #else 17 | #define DPI_DESYNC_FWMARK_DEFAULT 512 18 | #endif 19 | 20 | #define DPI_DESYNC_MAX_FAKE_LEN 9216 21 | 22 | enum dpi_desync_mode { 23 | DESYNC_NONE=0, 24 | DESYNC_INVALID, 25 | DESYNC_FAKE, 26 | DESYNC_FAKE_KNOWN, 27 | DESYNC_RST, 28 | DESYNC_RSTACK, 29 | DESYNC_SYNACK, 30 | DESYNC_SYNDATA, 31 | DESYNC_FAKEDSPLIT, 32 | DESYNC_FAKEDDISORDER, 33 | DESYNC_MULTISPLIT, 34 | DESYNC_MULTIDISORDER, 35 | DESYNC_IPFRAG2, 36 | DESYNC_HOPBYHOP, 37 | DESYNC_DESTOPT, 38 | DESYNC_IPFRAG1, 39 | DESYNC_UDPLEN, 40 | DESYNC_TAMPER 41 | }; 42 | 43 | extern const char *fake_http_request_default; 44 | extern const uint8_t fake_tls_clienthello_default[680]; 45 | void randomize_default_tls_payload(uint8_t *p); 46 | 47 | enum dpi_desync_mode desync_mode_from_string(const char *s); 48 | bool desync_valid_zero_stage(enum dpi_desync_mode mode); 49 | bool desync_valid_first_stage(enum dpi_desync_mode mode); 50 | bool desync_only_first_stage(enum dpi_desync_mode mode); 51 | bool desync_valid_second_stage(enum dpi_desync_mode mode); 52 | bool desync_valid_second_stage_tcp(enum dpi_desync_mode mode); 53 | bool desync_valid_second_stage_udp(enum dpi_desync_mode mode); 54 | 55 | uint8_t dpi_desync_packet(uint32_t fwmark, const char *ifin, const char *ifout, uint8_t *data_pkt, size_t *len_pkt); 56 | -------------------------------------------------------------------------------- /nfq/gzip.c: -------------------------------------------------------------------------------- 1 | #include "gzip.h" 2 | #include 3 | #include 4 | #include 5 | 6 | #define ZCHUNK 16384 7 | #define BUFMIN 128 8 | #define BUFCHUNK (1024*128) 9 | 10 | int z_readfile(FILE *F, char **buf, size_t *size) 11 | { 12 | z_stream zs; 13 | int r; 14 | unsigned char in[ZCHUNK]; 15 | size_t bufsize; 16 | void *newbuf; 17 | 18 | memset(&zs, 0, sizeof(zs)); 19 | 20 | *buf = NULL; 21 | bufsize = *size = 0; 22 | 23 | r = inflateInit2(&zs, 47); 24 | if (r != Z_OK) return r; 25 | 26 | do 27 | { 28 | zs.avail_in = fread(in, 1, sizeof(in), F); 29 | if (ferror(F)) 30 | { 31 | r = Z_ERRNO; 32 | goto zerr; 33 | } 34 | if (!zs.avail_in) break; 35 | zs.next_in = in; 36 | do 37 | { 38 | if ((bufsize - *size) < BUFMIN) 39 | { 40 | bufsize += BUFCHUNK; 41 | newbuf = *buf ? realloc(*buf, bufsize) : malloc(bufsize); 42 | if (!newbuf) 43 | { 44 | r = Z_MEM_ERROR; 45 | goto zerr; 46 | } 47 | *buf = newbuf; 48 | } 49 | zs.avail_out = bufsize - *size; 50 | zs.next_out = (unsigned char*)(*buf + *size); 51 | r = inflate(&zs, Z_NO_FLUSH); 52 | if (r != Z_OK && r != Z_STREAM_END) goto zerr; 53 | *size = bufsize - zs.avail_out; 54 | } while (r == Z_OK && zs.avail_in); 55 | } while (r == Z_OK); 56 | 57 | if (*size < bufsize) 58 | { 59 | // free extra space 60 | if ((newbuf = realloc(*buf, *size))) *buf = newbuf; 61 | } 62 | 63 | inflateEnd(&zs); 64 | return Z_OK; 65 | 66 | zerr: 67 | inflateEnd(&zs); 68 | free(*buf); 69 | *buf = NULL; 70 | return r; 71 | } 72 | 73 | bool is_gzip(FILE* F) 74 | { 75 | unsigned char magic[2]; 76 | bool b = !fseek(F, 0, SEEK_SET) && fread(magic, 1, 2, F) == 2 && magic[0] == 0x1F && magic[1] == 0x8B; 77 | fseek(F, 0, SEEK_SET); 78 | return b; 79 | } 80 | -------------------------------------------------------------------------------- /nfq/gzip.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | int z_readfile(FILE *F,char **buf,size_t *size); 8 | bool is_gzip(FILE* F); 9 | -------------------------------------------------------------------------------- /nfq/helpers.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | #define UNARY_PLUS(v) (v>0 ? "+" : "") 13 | 14 | // this saves memory. sockaddr_storage is larger than required. it can be 128 bytes. sockaddr_in6 is 28 bytes. 15 | typedef union 16 | { 17 | struct sockaddr_in sa4; // size 16 18 | struct sockaddr_in6 sa6; // size 28 19 | char _align[32]; // force 16-byte alignment for ip6_and int128 ops 20 | } sockaddr_in46; 21 | 22 | int unique_size_t(size_t *pu, int ct); 23 | void qsort_size_t(size_t *array,size_t ct); 24 | 25 | void rtrim(char *s); 26 | void replace_char(char *s, char from, char to); 27 | char *strncasestr(const char *s,const char *find, size_t slen); 28 | 29 | bool load_file(const char *filename,void *buffer,size_t *buffer_size); 30 | bool load_file_nonempty(const char *filename,void *buffer,size_t *buffer_size); 31 | bool save_file(const char *filename, const void *buffer, size_t buffer_size); 32 | bool append_to_list_file(const char *filename, const char *s); 33 | 34 | void expand_bits(void *target, const void *source, unsigned int source_bitlen, unsigned int target_bytelen); 35 | 36 | void print_sockaddr(const struct sockaddr *sa); 37 | void ntop46(const struct sockaddr *sa, char *str, size_t len); 38 | void ntop46_port(const struct sockaddr *sa, char *str, size_t len); 39 | bool pton4_port(const char *s, struct sockaddr_in *sa); 40 | bool pton6_port(const char *s, struct sockaddr_in6 *sa); 41 | 42 | uint16_t saport(const struct sockaddr *sa); 43 | 44 | bool seq_within(uint32_t s, uint32_t s1, uint32_t s2); 45 | 46 | uint64_t pntoh64(const void *p); 47 | void phton64(uint8_t *p, uint64_t v); 48 | 49 | bool ipv6_addr_is_zero(const struct in6_addr *a); 50 | 51 | static inline uint16_t pntoh16(const uint8_t *p) { 52 | return ((uint16_t)p[0] << 8) | (uint16_t)p[1]; 53 | } 54 | static inline void phton16(uint8_t *p, uint16_t v) { 55 | p[0] = (uint8_t)(v >> 8); 56 | p[1] = v & 0xFF; 57 | } 58 | static inline uint32_t pntoh24(const uint8_t *p) { 59 | return ((uint32_t)p[0] << 16) | ((uint32_t)p[1] << 8) | (uint32_t)p[2]; 60 | } 61 | static inline void phton24(uint8_t *p, uint32_t v) { 62 | p[0] = (uint8_t)(v>>16); 63 | p[1] = (uint8_t)(v>>8); 64 | p[2] = (uint8_t)v; 65 | } 66 | static inline uint32_t pntoh32(const uint8_t *p) { 67 | return ((uint32_t)p[0] << 24) | ((uint32_t)p[1] << 16) | ((uint32_t)p[2] << 8) | (uint32_t)p[3]; 68 | } 69 | 70 | bool parse_hex_str(const char *s, uint8_t *pbuf, size_t *size); 71 | void fill_pattern(uint8_t *buf,size_t bufsize,const void *pattern,size_t patsize); 72 | 73 | int fprint_localtime(FILE *F); 74 | 75 | typedef struct 76 | { 77 | time_t mod_time; 78 | off_t size; 79 | } file_mod_sig; 80 | #define FILE_MOD_COMPARE(ms1,ms2) (((ms1)->mod_time==(ms2)->mod_time) && ((ms1)->size==(ms2)->size)) 81 | #define FILE_MOD_RESET(ms) memset(ms,0,sizeof(file_mod_sig)) 82 | bool file_mod_signature(const char *filename, file_mod_sig *ms); 83 | time_t file_mod_time(const char *filename); 84 | bool file_open_test(const char *filename, int flags); 85 | 86 | typedef struct 87 | { 88 | uint16_t from,to; 89 | bool neg; 90 | } port_filter; 91 | bool pf_in_range(uint16_t port, const port_filter *pf); 92 | bool pf_parse(const char *s, port_filter *pf); 93 | bool pf_is_empty(const port_filter *pf); 94 | 95 | void fill_random_bytes(uint8_t *p,size_t sz); 96 | void fill_random_az(uint8_t *p,size_t sz); 97 | void fill_random_az09(uint8_t *p,size_t sz); 98 | 99 | void set_console_io_buffering(void); 100 | bool set_env_exedir(const char *argv0); 101 | 102 | 103 | struct cidr4 104 | { 105 | struct in_addr addr; 106 | uint8_t preflen; 107 | }; 108 | struct cidr6 109 | { 110 | struct in6_addr addr; 111 | uint8_t preflen; 112 | }; 113 | void str_cidr4(char *s, size_t s_len, const struct cidr4 *cidr); 114 | void print_cidr4(const struct cidr4 *cidr); 115 | void str_cidr6(char *s, size_t s_len, const struct cidr6 *cidr); 116 | void print_cidr6(const struct cidr6 *cidr); 117 | bool parse_cidr4(char *s, struct cidr4 *cidr); 118 | bool parse_cidr6(char *s, struct cidr6 *cidr); 119 | 120 | static inline uint32_t mask_from_preflen(uint32_t preflen) 121 | { 122 | return preflen ? preflen<32 ? ~((1 << (32-preflen)) - 1) : 0xFFFFFFFF : 0; 123 | } 124 | void ip6_and(const struct in6_addr * restrict a, const struct in6_addr * restrict b, struct in6_addr * restrict result); 125 | extern struct in6_addr ip6_mask[129]; 126 | void mask_from_preflen6_prepare(void); 127 | static inline const struct in6_addr *mask_from_preflen6(uint8_t preflen) 128 | { 129 | return ip6_mask+preflen; 130 | } 131 | -------------------------------------------------------------------------------- /nfq/hostlist.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include "pools.h" 5 | #include "params.h" 6 | 7 | bool AppendHostlistItem(hostlist_pool **hostlist, char *s); 8 | bool AppendHostList(hostlist_pool **hostlist, const char *filename); 9 | bool LoadAllHostLists(); 10 | bool NonEmptyHostlist(hostlist_pool **hostlist); 11 | // return : true = apply fooling, false = do not apply 12 | bool HostlistCheck(const struct desync_profile *dp,const char *host, bool *excluded, bool bSkipReloadCheck); 13 | struct hostlist_file *RegisterHostlist(struct desync_profile *dp, bool bExclude, const char *filename); 14 | bool HostlistsReloadCheckForProfile(const struct desync_profile *dp); 15 | void HostlistsDebug(); 16 | 17 | #define ResetAllHostlistsModTime() hostlist_files_reset_modtime(¶ms.hostlists) 18 | -------------------------------------------------------------------------------- /nfq/ipset.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include "params.h" 6 | #include "pools.h" 7 | 8 | bool LoadAllIpsets(); 9 | bool IpsetCheck(const struct desync_profile *dp, const struct in_addr *ipv4, const struct in6_addr *ipv6); 10 | struct ipset_file *RegisterIpset(struct desync_profile *dp, bool bExclude, const char *filename); 11 | void IpsetsDebug(); 12 | bool AppendIpsetItem(ipset *ips, char *ip); 13 | 14 | #define ResetAllIpsetModTime() ipset_files_reset_modtime(¶ms.ipsets) 15 | -------------------------------------------------------------------------------- /nfq/nfqws.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | #ifdef __CYGWIN__ 6 | extern bool bQuit; 7 | #endif 8 | int main(int argc, char *argv[]); 9 | -------------------------------------------------------------------------------- /nfq/packet_queue.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #include "packet_queue.h" 6 | 7 | void rawpacket_queue_init(struct rawpacket_tailhead *q) 8 | { 9 | TAILQ_INIT(q); 10 | } 11 | void rawpacket_free(struct rawpacket *rp) 12 | { 13 | if (rp) free(rp->packet); 14 | free(rp); 15 | } 16 | struct rawpacket *rawpacket_dequeue(struct rawpacket_tailhead *q) 17 | { 18 | struct rawpacket *rp; 19 | rp = TAILQ_FIRST(q); 20 | if (rp) TAILQ_REMOVE(q, rp, next); 21 | return rp; 22 | } 23 | void rawpacket_queue_destroy(struct rawpacket_tailhead *q) 24 | { 25 | struct rawpacket *rp; 26 | while((rp = rawpacket_dequeue(q))) rawpacket_free(rp); 27 | } 28 | 29 | struct rawpacket *rawpacket_queue(struct rawpacket_tailhead *q,const struct sockaddr_storage* dst,uint32_t fwmark,const char *ifin,const char *ifout,const void *data,size_t len,size_t len_payload) 30 | { 31 | struct rawpacket *rp = malloc(sizeof(struct rawpacket)); 32 | if (!rp) return NULL; 33 | 34 | rp->packet = malloc(len); 35 | if (!rp->packet) 36 | { 37 | free(rp); 38 | return NULL; 39 | } 40 | 41 | rp->dst = *dst; 42 | rp->fwmark = fwmark; 43 | if (ifin) 44 | snprintf(rp->ifin,sizeof(rp->ifin),"%s",ifin); 45 | else 46 | *rp->ifin = 0; 47 | if (ifout) 48 | snprintf(rp->ifout,sizeof(rp->ifout),"%s",ifout); 49 | else 50 | *rp->ifout = 0; 51 | memcpy(rp->packet,data,len); 52 | rp->len=len; 53 | rp->len_payload=len_payload; 54 | 55 | TAILQ_INSERT_TAIL(q, rp, next); 56 | 57 | return rp; 58 | } 59 | 60 | unsigned int rawpacket_queue_count(const struct rawpacket_tailhead *q) 61 | { 62 | const struct rawpacket *rp; 63 | unsigned int ct=0; 64 | TAILQ_FOREACH(rp, q, next) ct++; 65 | return ct; 66 | } 67 | bool rawpacket_queue_empty(const struct rawpacket_tailhead *q) 68 | { 69 | return !TAILQ_FIRST(q); 70 | } 71 | -------------------------------------------------------------------------------- /nfq/packet_queue.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | struct rawpacket 10 | { 11 | struct sockaddr_storage dst; 12 | char ifin[IFNAMSIZ], ifout[IFNAMSIZ]; 13 | uint32_t fwmark; 14 | size_t len, len_payload; 15 | uint8_t *packet; 16 | TAILQ_ENTRY(rawpacket) next; 17 | }; 18 | TAILQ_HEAD(rawpacket_tailhead, rawpacket); 19 | 20 | void rawpacket_queue_init(struct rawpacket_tailhead *q); 21 | void rawpacket_queue_destroy(struct rawpacket_tailhead *q); 22 | bool rawpacket_queue_empty(const struct rawpacket_tailhead *q); 23 | unsigned int rawpacket_queue_count(const struct rawpacket_tailhead *q); 24 | struct rawpacket *rawpacket_queue(struct rawpacket_tailhead *q,const struct sockaddr_storage* dst,uint32_t fwmark,const char *ifin,const char *ifout,const void *data,size_t len,size_t len_payload); 25 | struct rawpacket *rawpacket_dequeue(struct rawpacket_tailhead *q); 26 | void rawpacket_free(struct rawpacket *rp); 27 | -------------------------------------------------------------------------------- /nfq/protocol.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include "crypto/sha.h" 7 | #include "crypto/aes-gcm.h" 8 | #include "helpers.h" 9 | 10 | typedef enum {UNKNOWN=0, HTTP, TLS, QUIC, WIREGUARD, DHT, DISCORD, STUN} t_l7proto; 11 | #define L7_PROTO_HTTP 0x00000001 12 | #define L7_PROTO_TLS 0x00000002 13 | #define L7_PROTO_QUIC 0x00000004 14 | #define L7_PROTO_WIREGUARD 0x00000008 15 | #define L7_PROTO_DHT 0x00000010 16 | #define L7_PROTO_DISCORD 0x00000020 17 | #define L7_PROTO_STUN 0x00000040 18 | #define L7_PROTO_UNKNOWN 0x80000000 19 | const char *l7proto_str(t_l7proto l7); 20 | bool l7_proto_match(t_l7proto l7proto, uint32_t filter_l7); 21 | 22 | // pos markers 23 | #define PM_ABS 0 24 | #define PM_HOST 1 25 | #define PM_HOST_END 2 26 | #define PM_HOST_SLD 3 27 | #define PM_HOST_MIDSLD 4 28 | #define PM_HOST_ENDSLD 5 29 | #define PM_HTTP_METHOD 6 30 | #define PM_SNI_EXT 7 31 | struct proto_pos 32 | { 33 | int16_t pos; 34 | uint8_t marker; 35 | }; 36 | #define PROTO_POS_EMPTY(sp) ((sp)->marker==PM_ABS && (sp)->pos==0) 37 | bool IsHostMarker(uint8_t posmarker); 38 | const char *posmarker_name(uint8_t posmarker); 39 | size_t AnyProtoPos(uint8_t posmarker, int16_t pos, const uint8_t *data, size_t sz); 40 | size_t HttpPos(uint8_t posmarker, int16_t pos, const uint8_t *data, size_t sz); 41 | size_t TLSPos(uint8_t posmarker, int16_t pos, const uint8_t *data, size_t sz); 42 | size_t ResolvePos(const uint8_t *data, size_t sz, t_l7proto l7proto, const struct proto_pos *sp); 43 | void ResolveMultiPos(const uint8_t *data, size_t sz, t_l7proto l7proto, const struct proto_pos *splits, int split_count, size_t *pos, int *pos_count); 44 | 45 | extern const char *http_methods[9]; 46 | const char *HttpMethod(const uint8_t *data, size_t len); 47 | bool IsHttp(const uint8_t *data, size_t len); 48 | bool HttpFindHost(uint8_t **pHost,uint8_t *buf,size_t bs); 49 | bool HttpFindHostConst(const uint8_t **pHost,const uint8_t *buf,size_t bs); 50 | // header must be passed like this : "\nHost:" 51 | bool HttpExtractHeader(const uint8_t *data, size_t len, const char *header, char *buf, size_t len_buf); 52 | bool HttpExtractHost(const uint8_t *data, size_t len, char *host, size_t len_host); 53 | bool IsHttpReply(const uint8_t *data, size_t len); 54 | const char *HttpFind2ndLevelDomain(const char *host); 55 | // must be pre-checked by IsHttpReply 56 | int HttpReplyCode(const uint8_t *data, size_t len); 57 | // must be pre-checked by IsHttpReply 58 | bool HttpReplyLooksLikeDPIRedirect(const uint8_t *data, size_t len, const char *host); 59 | 60 | const char *TLSVersionStr(uint16_t tlsver); 61 | uint16_t TLSRecordDataLen(const uint8_t *data); 62 | size_t TLSRecordLen(const uint8_t *data); 63 | bool IsTLSRecordFull(const uint8_t *data, size_t len); 64 | bool IsTLSClientHello(const uint8_t *data, size_t len, bool bPartialIsOK); 65 | size_t TLSHandshakeLen(const uint8_t *data); 66 | bool IsTLSHandshakeClientHello(const uint8_t *data, size_t len); 67 | bool IsTLSHandshakeFull(const uint8_t *data, size_t len); 68 | bool TLSAdvanceToHostInSNI(const uint8_t **ext, size_t *elen, size_t *slen); 69 | bool TLSFindExtLen(const uint8_t *data, size_t len, size_t *off); 70 | bool TLSFindExtLenOffsetInHandshake(const uint8_t *data, size_t len, size_t *off); 71 | bool TLSFindExt(const uint8_t *data, size_t len, uint16_t type, const uint8_t **ext, size_t *len_ext, bool bPartialIsOK); 72 | bool TLSFindExtInHandshake(const uint8_t *data, size_t len, uint16_t type, const uint8_t **ext, size_t *len_ext, bool bPartialIsOK); 73 | bool TLSHelloExtractHost(const uint8_t *data, size_t len, char *host, size_t len_host, bool bPartialIsOK); 74 | bool TLSHelloExtractHostFromHandshake(const uint8_t *data, size_t len, char *host, size_t len_host, bool bPartialIsOK); 75 | 76 | bool IsWireguardHandshakeInitiation(const uint8_t *data, size_t len); 77 | bool IsDhtD1(const uint8_t *data, size_t len); 78 | bool IsDiscordIpDiscoveryRequest(const uint8_t *data, size_t len); 79 | bool IsStunMessage(const uint8_t *data, size_t len); 80 | 81 | #define QUIC_MAX_CID_LENGTH 20 82 | typedef struct quic_cid { 83 | uint8_t len; 84 | uint8_t cid[QUIC_MAX_CID_LENGTH]; 85 | } quic_cid_t; 86 | 87 | bool IsQUICInitial(const uint8_t *data, size_t len); 88 | bool IsQUICCryptoHello(const uint8_t *data, size_t len, size_t *hello_offset, size_t *hello_len); 89 | bool QUICIsLongHeader(const uint8_t *data, size_t len); 90 | uint32_t QUICExtractVersion(const uint8_t *data, size_t len); 91 | uint8_t QUICDraftVersion(uint32_t version); 92 | bool QUICExtractDCID(const uint8_t *data, size_t len, quic_cid_t *cid); 93 | 94 | bool QUICDecryptInitial(const uint8_t *data, size_t data_len, uint8_t *clean, size_t *clean_len); 95 | // returns true if crypto frames were found . bFull = true if crypto frame fragments have full coverage 96 | bool QUICDefragCrypto(const uint8_t *clean,size_t clean_len, uint8_t *defrag,size_t *defrag_len, bool *bFull); 97 | //bool QUICExtractHostFromInitial(const uint8_t *data, size_t data_len, char *host, size_t len_host, bool *bDecryptOK, bool *bIsCryptoHello); 98 | -------------------------------------------------------------------------------- /nfq/sec.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | 6 | #ifdef __linux__ 7 | 8 | #include 9 | #include 10 | #include 11 | 12 | bool checkpcap(uint64_t caps); 13 | bool setpcap(uint64_t caps); 14 | int getmaxcap(void); 15 | bool dropcaps(void); 16 | 17 | #define syscall_nr (offsetof(struct seccomp_data, nr)) 18 | #define arch_nr (offsetof(struct seccomp_data, arch)) 19 | #define syscall_arg(x) (offsetof(struct seccomp_data, args[x])) 20 | 21 | #if defined(__aarch64__) 22 | 23 | # define ARCH_NR AUDIT_ARCH_AARCH64 24 | 25 | #elif defined(__amd64__) 26 | 27 | # define ARCH_NR AUDIT_ARCH_X86_64 28 | 29 | #elif defined(__arm__) && (defined(__ARM_EABI__) || defined(__thumb__)) 30 | 31 | # if __BYTE_ORDER == __LITTLE_ENDIAN 32 | # define ARCH_NR AUDIT_ARCH_ARM 33 | # else 34 | # define ARCH_NR AUDIT_ARCH_ARMEB 35 | # endif 36 | 37 | #elif defined(__i386__) 38 | 39 | # define ARCH_NR AUDIT_ARCH_I386 40 | 41 | #elif defined(__mips__) 42 | 43 | #if _MIPS_SIM == _MIPS_SIM_ABI32 44 | # if __BYTE_ORDER == __LITTLE_ENDIAN 45 | # define ARCH_NR AUDIT_ARCH_MIPSEL 46 | # else 47 | # define ARCH_NR AUDIT_ARCH_MIPS 48 | # endif 49 | #elif _MIPS_SIM == _MIPS_SIM_ABI64 50 | # if __BYTE_ORDER == __LITTLE_ENDIAN 51 | # define ARCH_NR AUDIT_ARCH_MIPSEL64 52 | # else 53 | # define ARCH_NR AUDIT_ARCH_MIPS64 54 | # endif 55 | #else 56 | # error "Unsupported mips abi" 57 | #endif 58 | 59 | #elif defined(__PPC64__) 60 | 61 | # if __BYTE_ORDER == __LITTLE_ENDIAN 62 | # define ARCH_NR AUDIT_ARCH_PPC64LE 63 | # else 64 | # define ARCH_NR AUDIT_ARCH_PPC64 65 | # endif 66 | 67 | #elif defined(__PPC__) 68 | 69 | # define ARCH_NR AUDIT_ARCH_PPC 70 | 71 | #elif __riscv && __riscv_xlen == 64 72 | 73 | # define ARCH_NR AUDIT_ARCH_RISCV64 74 | 75 | #else 76 | 77 | # error "Platform does not support seccomp filter yet" 78 | 79 | #endif 80 | 81 | #endif 82 | 83 | 84 | #ifndef __CYGWIN__ 85 | bool sec_harden(void); 86 | bool can_drop_root(void); 87 | bool droproot(uid_t uid, gid_t *gid, int gid_count); 88 | void print_id(void); 89 | #endif 90 | 91 | void daemonize(void); 92 | bool writepid(const char *filename); 93 | -------------------------------------------------------------------------------- /nfq/win.c: -------------------------------------------------------------------------------- 1 | #ifdef __CYGWIN__ 2 | 3 | #include 4 | 5 | #include "win.h" 6 | #include "nfqws.h" 7 | 8 | #define SERVICE_NAME "winws" 9 | 10 | static SERVICE_STATUS ServiceStatus; 11 | static SERVICE_STATUS_HANDLE hStatus = NULL; 12 | static int service_argc = 0; 13 | static char **service_argv = NULL; 14 | 15 | void service_main(int argc __attribute__((unused)), char *argv[] __attribute__((unused))); 16 | 17 | bool service_run(int argc, char *argv[]) 18 | { 19 | SERVICE_TABLE_ENTRY ServiceTable[] = { 20 | {SERVICE_NAME, (LPSERVICE_MAIN_FUNCTION)service_main}, 21 | {NULL, NULL} 22 | }; 23 | 24 | service_argc = argc; 25 | service_argv = argv; 26 | 27 | return StartServiceCtrlDispatcherA(ServiceTable); 28 | } 29 | 30 | static void service_set_status(DWORD state) 31 | { 32 | ServiceStatus.dwCurrentState = state; 33 | SetServiceStatus(hStatus, &ServiceStatus); 34 | } 35 | 36 | // Control handler function 37 | void service_controlhandler(DWORD request) 38 | { 39 | switch (request) 40 | { 41 | case SERVICE_CONTROL_STOP: 42 | case SERVICE_CONTROL_SHUTDOWN: 43 | bQuit = true; 44 | ServiceStatus.dwCurrentState = SERVICE_STOP_PENDING; 45 | break; 46 | } 47 | SetServiceStatus(hStatus, &ServiceStatus); 48 | } 49 | 50 | void service_main(int argc __attribute__((unused)), char *argv[] __attribute__((unused))) 51 | { 52 | ServiceStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS; 53 | ServiceStatus.dwCurrentState = SERVICE_RUNNING; 54 | ServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN; 55 | ServiceStatus.dwWin32ExitCode = 0; 56 | ServiceStatus.dwServiceSpecificExitCode = 0; 57 | ServiceStatus.dwCheckPoint = 1; 58 | ServiceStatus.dwWaitHint = 0; 59 | 60 | hStatus = RegisterServiceCtrlHandlerA( 61 | SERVICE_NAME, 62 | (LPHANDLER_FUNCTION)service_controlhandler); 63 | if (hStatus == (SERVICE_STATUS_HANDLE)0) 64 | { 65 | // Registering Control Handler failed 66 | return; 67 | } 68 | 69 | SetServiceStatus(hStatus, &ServiceStatus); 70 | 71 | // Calling main with saved argc & argv 72 | ServiceStatus.dwWin32ExitCode = (DWORD)main(service_argc, service_argv); 73 | 74 | ServiceStatus.dwCurrentState = SERVICE_STOPPED; 75 | SetServiceStatus(hStatus, &ServiceStatus); 76 | return; 77 | } 78 | 79 | 80 | #endif 81 | -------------------------------------------------------------------------------- /nfq/win.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #ifdef __CYGWIN__ 4 | 5 | #include 6 | 7 | bool service_run(); 8 | 9 | #endif 10 | 11 | -------------------------------------------------------------------------------- /nfq/windows/res/32/winicon.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bol-van/zapret/30a947b42bad60a8807831160ef6d45b34e426e2/nfq/windows/res/32/winicon.o -------------------------------------------------------------------------------- /nfq/windows/res/32/winmanifest.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bol-van/zapret/30a947b42bad60a8807831160ef6d45b34e426e2/nfq/windows/res/32/winmanifest.o -------------------------------------------------------------------------------- /nfq/windows/res/64/winicon.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bol-van/zapret/30a947b42bad60a8807831160ef6d45b34e426e2/nfq/windows/res/64/winicon.o -------------------------------------------------------------------------------- /nfq/windows/res/64/winmanifest.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bol-van/zapret/30a947b42bad60a8807831160ef6d45b34e426e2/nfq/windows/res/64/winmanifest.o -------------------------------------------------------------------------------- /nfq/windows/windivert/libwindivert32.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bol-van/zapret/30a947b42bad60a8807831160ef6d45b34e426e2/nfq/windows/windivert/libwindivert32.a -------------------------------------------------------------------------------- /nfq/windows/windivert/libwindivert64.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bol-van/zapret/30a947b42bad60a8807831160ef6d45b34e426e2/nfq/windows/windivert/libwindivert64.a -------------------------------------------------------------------------------- /tmp/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bol-van/zapret/30a947b42bad60a8807831160ef6d45b34e426e2/tmp/.keep -------------------------------------------------------------------------------- /tpws/BSDmakefile: -------------------------------------------------------------------------------- 1 | CC ?= cc 2 | CFLAGS += -std=gnu99 -s -Os -flto=auto 3 | LIBS = -lz -lpthread 4 | SRC_FILES = *.c 5 | 6 | all: tpws 7 | 8 | tpws: $(SRC_FILES) 9 | $(CC) $(CFLAGS) -Iepoll-shim/include -o tpws $(SRC_FILES) epoll-shim/src/*.c $(LIBS) $(LDFLAGS) 10 | 11 | clean: 12 | rm -f tpws *.o 13 | -------------------------------------------------------------------------------- /tpws/Makefile: -------------------------------------------------------------------------------- 1 | CC ?= gcc 2 | CFLAGS += -std=gnu99 -Os -flto=auto 3 | CFLAGS_SYSTEMD = -DUSE_SYSTEMD 4 | CFLAGS_BSD = -Wno-address-of-packed-member 5 | LDFLAGS_ANDROID = -llog 6 | LIBS = -lz -lpthread 7 | LIBS_SYSTEMD = -lsystemd 8 | LIBS_ANDROID = -lz 9 | SRC_FILES = *.c 10 | SRC_FILES_ANDROID = $(SRC_FILES) andr/*.c 11 | 12 | all: tpws 13 | 14 | tpws: $(SRC_FILES) 15 | $(CC) -s $(CFLAGS) -o tpws $(SRC_FILES) $(LIBS) $(LDFLAGS) 16 | 17 | systemd: $(SRC_FILES) 18 | $(CC) -s $(CFLAGS) $(CFLAGS_SYSTEMD) -o tpws $(SRC_FILES) $(LIBS) $(LIBS_SYSTEMD) $(LDFLAGS) 19 | 20 | android: $(SRC_FILES) 21 | $(CC) -s $(CFLAGS) -o tpws $(SRC_FILES_ANDROID) $(LIBS_ANDROID) $(LDFLAGS) $(LDFLAGS_ANDROID) 22 | 23 | bsd: $(SRC_FILES) 24 | $(CC) -s $(CFLAGS) $(CFLAGS_BSD) -Iepoll-shim/include -o tpws $(SRC_FILES) epoll-shim/src/*.c $(LIBS) $(LDFLAGS) 25 | 26 | mac: $(SRC_FILES) 27 | $(CC) $(CFLAGS) $(CFLAGS_BSD) -Iepoll-shim/include -Imacos -o tpwsa -target arm64-apple-macos10.8 $(SRC_FILES) epoll-shim/src/*.c $(LIBS) $(LDFLAGS) 28 | $(CC) $(CFLAGS) $(CFLAGS_BSD) -Iepoll-shim/include -Imacos -o tpwsx -target x86_64-apple-macos10.8 $(SRC_FILES) epoll-shim/src/*.c $(LIBS) $(LDFLAGS) 29 | strip tpwsa tpwsx 30 | lipo -create -output tpws tpwsx tpwsa 31 | rm -f tpwsx tpwsa 32 | 33 | clean: 34 | rm -f tpws *.o 35 | -------------------------------------------------------------------------------- /tpws/andr/_musl_license.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bol-van/zapret/30a947b42bad60a8807831160ef6d45b34e426e2/tpws/andr/_musl_license.txt -------------------------------------------------------------------------------- /tpws/andr/ifaddrs.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | #if __ANDROID_API__ < 24 6 | void freeifaddrs(struct ifaddrs *); 7 | int getifaddrs(struct ifaddrs **); 8 | #endif 9 | -------------------------------------------------------------------------------- /tpws/andr/netlink.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | #include "netlink.h" 8 | 9 | static int __netlink_enumerate(int fd, unsigned int seq, int type, int af, 10 | int (*cb)(void *ctx, struct nlmsghdr *h), void *ctx) 11 | { 12 | struct nlmsghdr *h; 13 | union { 14 | uint8_t buf[8192]; 15 | struct { 16 | struct nlmsghdr nlh; 17 | struct rtgenmsg g; 18 | } req; 19 | struct nlmsghdr reply; 20 | } u; 21 | int r, ret; 22 | 23 | memset(&u.req, 0, sizeof(u.req)); 24 | u.req.nlh.nlmsg_len = sizeof(u.req); 25 | u.req.nlh.nlmsg_type = type; 26 | u.req.nlh.nlmsg_flags = NLM_F_DUMP | NLM_F_REQUEST; 27 | u.req.nlh.nlmsg_seq = seq; 28 | u.req.g.rtgen_family = af; 29 | r = send(fd, &u.req, sizeof(u.req), 0); 30 | if (r < 0) return r; 31 | 32 | while (1) { 33 | r = recv(fd, u.buf, sizeof(u.buf), MSG_DONTWAIT); 34 | if (r <= 0) return -1; 35 | for (h = &u.reply; NLMSG_OK(h, (void*)&u.buf[r]); h = NLMSG_NEXT(h)) { 36 | if (h->nlmsg_type == NLMSG_DONE) return 0; 37 | if (h->nlmsg_type == NLMSG_ERROR) return -1; 38 | ret = cb(ctx, h); 39 | if (ret) return ret; 40 | } 41 | } 42 | } 43 | 44 | int __rtnetlink_enumerate(int link_af, int addr_af, int (*cb)(void *ctx, struct nlmsghdr *h), void *ctx) 45 | { 46 | int fd, r; 47 | 48 | fd = socket(PF_NETLINK, SOCK_RAW|SOCK_CLOEXEC, NETLINK_ROUTE); 49 | if (fd < 0) return -1; 50 | r = __netlink_enumerate(fd, 1, RTM_GETLINK, link_af, cb, ctx); 51 | if (!r) r = __netlink_enumerate(fd, 2, RTM_GETADDR, addr_af, cb, ctx); 52 | close(fd); 53 | return r; 54 | } 55 | -------------------------------------------------------------------------------- /tpws/andr/netlink.h: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | /* linux/netlink.h */ 4 | 5 | #define NETLINK_ROUTE 0 6 | 7 | struct nlmsghdr { 8 | uint32_t nlmsg_len; 9 | uint16_t nlmsg_type; 10 | uint16_t nlmsg_flags; 11 | uint32_t nlmsg_seq; 12 | uint32_t nlmsg_pid; 13 | }; 14 | 15 | #define NLM_F_REQUEST 1 16 | #define NLM_F_MULTI 2 17 | #define NLM_F_ACK 4 18 | 19 | #define NLM_F_ROOT 0x100 20 | #define NLM_F_MATCH 0x200 21 | #define NLM_F_ATOMIC 0x400 22 | #define NLM_F_DUMP (NLM_F_ROOT|NLM_F_MATCH) 23 | 24 | #define NLMSG_NOOP 0x1 25 | #define NLMSG_ERROR 0x2 26 | #define NLMSG_DONE 0x3 27 | #define NLMSG_OVERRUN 0x4 28 | 29 | /* linux/rtnetlink.h */ 30 | 31 | #define RTM_NEWLINK 16 32 | #define RTM_GETLINK 18 33 | #define RTM_NEWADDR 20 34 | #define RTM_GETADDR 22 35 | 36 | struct rtattr { 37 | unsigned short rta_len; 38 | unsigned short rta_type; 39 | }; 40 | 41 | struct rtgenmsg { 42 | unsigned char rtgen_family; 43 | }; 44 | 45 | struct ifinfomsg { 46 | unsigned char ifi_family; 47 | unsigned char __ifi_pad; 48 | unsigned short ifi_type; 49 | int ifi_index; 50 | unsigned ifi_flags; 51 | unsigned ifi_change; 52 | }; 53 | 54 | /* linux/if_link.h */ 55 | 56 | #define IFLA_ADDRESS 1 57 | #define IFLA_BROADCAST 2 58 | #define IFLA_IFNAME 3 59 | #define IFLA_STATS 7 60 | 61 | /* linux/if_addr.h */ 62 | 63 | struct ifaddrmsg { 64 | uint8_t ifa_family; 65 | uint8_t ifa_prefixlen; 66 | uint8_t ifa_flags; 67 | uint8_t ifa_scope; 68 | uint32_t ifa_index; 69 | }; 70 | 71 | #define IFA_ADDRESS 1 72 | #define IFA_LOCAL 2 73 | #define IFA_LABEL 3 74 | #define IFA_BROADCAST 4 75 | 76 | /* musl */ 77 | 78 | #define NETLINK_ALIGN(len) (((len)+3) & ~3) 79 | #define NLMSG_DATA(nlh) ((void*)((char*)(nlh)+sizeof(struct nlmsghdr))) 80 | #define NLMSG_DATALEN(nlh) ((nlh)->nlmsg_len-sizeof(struct nlmsghdr)) 81 | #define NLMSG_DATAEND(nlh) ((char*)(nlh)+(nlh)->nlmsg_len) 82 | #define NLMSG_NEXT(nlh) (struct nlmsghdr*)((char*)(nlh)+NETLINK_ALIGN((nlh)->nlmsg_len)) 83 | #define NLMSG_OK(nlh,end) ((char*)(end)-(char*)(nlh) >= sizeof(struct nlmsghdr)) 84 | 85 | #define RTA_DATA(rta) ((void*)((char*)(rta)+sizeof(struct rtattr))) 86 | #define RTA_DATALEN(rta) ((rta)->rta_len-sizeof(struct rtattr)) 87 | #define RTA_DATAEND(rta) ((char*)(rta)+(rta)->rta_len) 88 | #define RTA_NEXT(rta) (struct rtattr*)((char*)(rta)+NETLINK_ALIGN((rta)->rta_len)) 89 | #define RTA_OK(rta,end) ((char*)(end)-(char*)(rta) >= sizeof(struct rtattr)) 90 | 91 | #define NLMSG_RTA(nlh,len) ((void*)((char*)(nlh)+sizeof(struct nlmsghdr)+NETLINK_ALIGN(len))) 92 | #define NLMSG_RTAOK(rta,nlh) RTA_OK(rta,NLMSG_DATAEND(nlh)) 93 | 94 | int __rtnetlink_enumerate(int link_af, int addr_af, int (*cb)(void *ctx, struct nlmsghdr *h), void *ctx); 95 | -------------------------------------------------------------------------------- /tpws/epoll-shim/include/sys/epoll.h: -------------------------------------------------------------------------------- 1 | #ifndef SHIM_SYS_EPOLL_H 2 | #define SHIM_SYS_EPOLL_H 3 | 4 | #ifdef __cplusplus 5 | extern "C" { 6 | #endif 7 | 8 | #include 9 | #include 10 | #include 11 | 12 | #if defined(__NetBSD__) 13 | #include 14 | #elif defined(__OpenBSD__) || defined(__DragonFly__) || defined(__FreeBSD__) || defined(__APPLE__) 15 | #include 16 | #endif 17 | 18 | #define EPOLL_CLOEXEC O_CLOEXEC 19 | #define EPOLL_NONBLOCK O_NONBLOCK 20 | 21 | enum EPOLL_EVENTS { __EPOLL_DUMMY }; 22 | #define EPOLLIN 0x001 23 | #define EPOLLPRI 0x002 24 | #define EPOLLOUT 0x004 25 | #define EPOLLRDNORM 0x040 26 | #define EPOLLNVAL 0x020 27 | #define EPOLLRDBAND 0x080 28 | #define EPOLLWRNORM 0x100 29 | #define EPOLLWRBAND 0x200 30 | #define EPOLLMSG 0x400 31 | #define EPOLLERR 0x008 32 | #define EPOLLHUP 0x010 33 | #define EPOLLRDHUP 0x2000 34 | #define EPOLLEXCLUSIVE (1U<<28) 35 | #define EPOLLWAKEUP (1U<<29) 36 | #define EPOLLONESHOT (1U<<30) 37 | #define EPOLLET (1U<<31) 38 | 39 | #define EPOLL_CTL_ADD 1 40 | #define EPOLL_CTL_DEL 2 41 | #define EPOLL_CTL_MOD 3 42 | 43 | typedef union epoll_data { 44 | void *ptr; 45 | int fd; 46 | uint32_t u32; 47 | uint64_t u64; 48 | } epoll_data_t; 49 | 50 | struct epoll_event { 51 | uint32_t events; 52 | epoll_data_t data; 53 | } 54 | #ifdef __x86_64__ 55 | __attribute__ ((__packed__)) 56 | #endif 57 | ; 58 | 59 | 60 | int epoll_create(int); 61 | int epoll_create1(int); 62 | int epoll_ctl(int, int, int, struct epoll_event *); 63 | int epoll_wait(int, struct epoll_event *, int, int); 64 | int epoll_pwait(int, struct epoll_event *, int, int, const sigset_t *); 65 | 66 | 67 | #ifndef SHIM_SYS_SHIM_HELPERS 68 | #define SHIM_SYS_SHIM_HELPERS 69 | #include /* IWYU pragma: keep */ 70 | 71 | extern int epoll_shim_close(int); 72 | #define close epoll_shim_close 73 | #endif 74 | 75 | 76 | #ifdef __cplusplus 77 | } 78 | #endif 79 | 80 | #endif /* sys/epoll.h */ 81 | -------------------------------------------------------------------------------- /tpws/epoll-shim/src/epoll_shim_ctx.h: -------------------------------------------------------------------------------- 1 | #ifndef EPOLL_SHIM_CTX_H_ 2 | #define EPOLL_SHIM_CTX_H_ 3 | 4 | #include "fix.h" 5 | 6 | #include 7 | 8 | #include 9 | 10 | #include "epollfd_ctx.h" 11 | #include "eventfd_ctx.h" 12 | #include "signalfd_ctx.h" 13 | #include "timerfd_ctx.h" 14 | 15 | struct fd_context_map_node_; 16 | typedef struct fd_context_map_node_ FDContextMapNode; 17 | 18 | typedef errno_t (*fd_context_read_fun)(FDContextMapNode *node, /**/ 19 | void *buf, size_t nbytes, size_t *bytes_transferred); 20 | typedef errno_t (*fd_context_write_fun)(FDContextMapNode *node, /**/ 21 | const void *buf, size_t nbytes, size_t *bytes_transferred); 22 | typedef errno_t (*fd_context_close_fun)(FDContextMapNode *node); 23 | 24 | typedef struct { 25 | fd_context_read_fun read_fun; 26 | fd_context_write_fun write_fun; 27 | fd_context_close_fun close_fun; 28 | } FDContextVTable; 29 | 30 | errno_t fd_context_default_read(FDContextMapNode *node, /**/ 31 | void *buf, size_t nbytes, size_t *bytes_transferred); 32 | errno_t fd_context_default_write(FDContextMapNode *node, /**/ 33 | void const *buf, size_t nbytes, size_t *bytes_transferred); 34 | 35 | struct fd_context_map_node_ { 36 | RB_ENTRY(fd_context_map_node_) entry; 37 | int fd; 38 | int flags; 39 | union { 40 | EpollFDCtx epollfd; 41 | EventFDCtx eventfd; 42 | TimerFDCtx timerfd; 43 | SignalFDCtx signalfd; 44 | } ctx; 45 | FDContextVTable const *vtable; 46 | }; 47 | 48 | errno_t fd_context_map_node_destroy(FDContextMapNode *node); 49 | 50 | /**/ 51 | 52 | typedef RB_HEAD(fd_context_map_, fd_context_map_node_) FDContextMap; 53 | 54 | typedef struct { 55 | FDContextMap fd_context_map; 56 | pthread_mutex_t mutex; 57 | } EpollShimCtx; 58 | 59 | extern EpollShimCtx epoll_shim_ctx; 60 | 61 | FDContextMapNode *epoll_shim_ctx_create_node(EpollShimCtx *epoll_shim_ctx, 62 | errno_t *ec); 63 | FDContextMapNode *epoll_shim_ctx_find_node(EpollShimCtx *epoll_shim_ctx, 64 | int fd); 65 | FDContextMapNode *epoll_shim_ctx_remove_node(EpollShimCtx *epoll_shim_ctx, 66 | int fd); 67 | void epoll_shim_ctx_remove_node_explicit(EpollShimCtx *epoll_shim_ctx, 68 | FDContextMapNode *node); 69 | 70 | /**/ 71 | 72 | int epoll_shim_close(int fd); 73 | ssize_t epoll_shim_read(int fd, void *buf, size_t nbytes); 74 | ssize_t epoll_shim_write(int fd, void const *buf, size_t nbytes); 75 | 76 | #endif 77 | -------------------------------------------------------------------------------- /tpws/epoll-shim/src/epollfd_ctx.h: -------------------------------------------------------------------------------- 1 | #ifndef EPOLLFD_CTX_H_ 2 | #define EPOLLFD_CTX_H_ 3 | 4 | #include "fix.h" 5 | 6 | #define SHIM_SYS_SHIM_HELPERS 7 | #include 8 | 9 | #include 10 | #include 11 | 12 | #include 13 | #include 14 | #include 15 | 16 | #include 17 | #include 18 | 19 | struct registered_fds_node_; 20 | typedef struct registered_fds_node_ RegisteredFDsNode; 21 | 22 | typedef enum { 23 | EOF_STATE_READ_EOF = 0x01, 24 | EOF_STATE_WRITE_EOF = 0x02, 25 | } EOFState; 26 | 27 | typedef enum { 28 | NODE_TYPE_FIFO = 1, 29 | NODE_TYPE_SOCKET = 2, 30 | NODE_TYPE_KQUEUE = 3, 31 | NODE_TYPE_OTHER = 4, 32 | NODE_TYPE_POLL = 5, 33 | } NodeType; 34 | 35 | struct registered_fds_node_ { 36 | RB_ENTRY(registered_fds_node_) entry; 37 | TAILQ_ENTRY(registered_fds_node_) pollfd_list_entry; 38 | 39 | int fd; 40 | epoll_data_t data; 41 | 42 | bool is_registered; 43 | 44 | bool has_evfilt_read; 45 | bool has_evfilt_write; 46 | bool has_evfilt_except; 47 | 48 | bool got_evfilt_read; 49 | bool got_evfilt_write; 50 | bool got_evfilt_except; 51 | 52 | NodeType node_type; 53 | union { 54 | struct { 55 | bool readable; 56 | bool writable; 57 | } fifo; 58 | } node_data; 59 | int eof_state; 60 | bool pollpri_active; 61 | 62 | uint16_t events; 63 | uint32_t revents; 64 | 65 | bool is_edge_triggered; 66 | bool is_oneshot; 67 | 68 | bool is_on_pollfd_list; 69 | int self_pipe[2]; 70 | }; 71 | 72 | typedef TAILQ_HEAD(pollfds_list_, registered_fds_node_) PollFDList; 73 | typedef RB_HEAD(registered_fds_set_, registered_fds_node_) RegisteredFDsSet; 74 | 75 | typedef struct { 76 | int kq; // non owning 77 | pthread_mutex_t mutex; 78 | 79 | PollFDList poll_fds; 80 | size_t poll_fds_size; 81 | 82 | RegisteredFDsSet registered_fds; 83 | size_t registered_fds_size; 84 | 85 | struct kevent *kevs; 86 | size_t kevs_length; 87 | 88 | struct pollfd *pfds; 89 | size_t pfds_length; 90 | 91 | pthread_mutex_t nr_polling_threads_mutex; 92 | pthread_cond_t nr_polling_threads_cond; 93 | unsigned long nr_polling_threads; 94 | 95 | int self_pipe[2]; 96 | } EpollFDCtx; 97 | 98 | errno_t epollfd_ctx_init(EpollFDCtx *epollfd, int kq); 99 | errno_t epollfd_ctx_terminate(EpollFDCtx *epollfd); 100 | 101 | void epollfd_ctx_fill_pollfds(EpollFDCtx *epollfd, struct pollfd *pfds); 102 | 103 | errno_t epollfd_ctx_ctl(EpollFDCtx *epollfd, int op, int fd2, 104 | struct epoll_event *ev); 105 | errno_t epollfd_ctx_wait(EpollFDCtx *epollfd, struct epoll_event *ev, int cnt, 106 | int *actual_cnt); 107 | 108 | #endif 109 | -------------------------------------------------------------------------------- /tpws/epoll-shim/src/eventfd_ctx.h: -------------------------------------------------------------------------------- 1 | #ifndef EVENTFD_CTX_H_ 2 | #define EVENTFD_CTX_H_ 3 | 4 | #include "fix.h" 5 | 6 | #include 7 | #include 8 | #include 9 | 10 | #include 11 | 12 | #define EVENTFD_CTX_FLAG_SEMAPHORE (1 << 0) 13 | 14 | typedef struct { 15 | int kq_; // non owning 16 | int flags_; 17 | pthread_mutex_t mutex_; 18 | 19 | bool is_signalled_; 20 | int self_pipe_[2]; // only used if EVFILT_USER is not available 21 | uint_least64_t counter_; 22 | } EventFDCtx; 23 | 24 | errno_t eventfd_ctx_init(EventFDCtx *eventfd, int kq, unsigned int counter, 25 | int flags); 26 | errno_t eventfd_ctx_terminate(EventFDCtx *eventfd); 27 | 28 | errno_t eventfd_ctx_write(EventFDCtx *eventfd, uint64_t value); 29 | errno_t eventfd_ctx_read(EventFDCtx *eventfd, uint64_t *value); 30 | 31 | #endif 32 | -------------------------------------------------------------------------------- /tpws/epoll-shim/src/fix.c: -------------------------------------------------------------------------------- 1 | #include "fix.h" 2 | 3 | #ifdef __APPLE__ 4 | 5 | #include 6 | 7 | int ppoll(struct pollfd *fds, nfds_t nfds,const struct timespec *tmo_p, const sigset_t *sigmask) 8 | { 9 | // macos does not implement ppoll 10 | // this is a hacky ppoll shim. only for tpws which does not require sigmask 11 | if (sigmask) 12 | { 13 | errno = EINVAL; 14 | return -1; 15 | } 16 | return poll(fds,nfds,tmo_p ? tmo_p->tv_sec*1000 + tmo_p->tv_nsec/1000000 : -1); 17 | } 18 | 19 | #endif 20 | -------------------------------------------------------------------------------- /tpws/epoll-shim/src/fix.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #ifndef _ERRNO_T_DEFINED 4 | #define _ERRNO_T_DEFINED 5 | typedef int errno_t; 6 | #endif 7 | 8 | #ifdef __APPLE__ 9 | 10 | #include 11 | #include 12 | #include 13 | 14 | struct itimerspec { 15 | struct timespec it_interval; 16 | struct timespec it_value; 17 | }; 18 | int ppoll(struct pollfd *fds, nfds_t nfds,const struct timespec *tmo_p, const sigset_t *sigmask); 19 | 20 | #endif 21 | -------------------------------------------------------------------------------- /tpws/epoll-shim/src/signalfd_ctx.h: -------------------------------------------------------------------------------- 1 | #ifndef SIGNALFD_CTX_H_ 2 | #define SIGNALFD_CTX_H_ 3 | 4 | #include "fix.h" 5 | 6 | #include 7 | #include 8 | #include 9 | 10 | typedef struct { 11 | int kq; // non owning 12 | } SignalFDCtx; 13 | 14 | errno_t signalfd_ctx_init(SignalFDCtx *signalfd, int kq, const sigset_t *sigs); 15 | errno_t signalfd_ctx_terminate(SignalFDCtx *signalfd); 16 | 17 | errno_t signalfd_ctx_read(SignalFDCtx *signalfd, uint32_t *ident); 18 | 19 | #endif 20 | -------------------------------------------------------------------------------- /tpws/epoll-shim/src/timerfd_ctx.h: -------------------------------------------------------------------------------- 1 | #ifndef TIMERFD_CTX_H_ 2 | #define TIMERFD_CTX_H_ 3 | 4 | #include "fix.h" 5 | 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | #include 12 | #include 13 | 14 | typedef struct { 15 | int kq; // non owning 16 | int flags; 17 | pthread_mutex_t mutex; 18 | 19 | int clockid; 20 | /* 21 | * Next expiration time, absolute (clock given by clockid). 22 | * If it_interval is != 0, it is a periodic timer. 23 | * If it_value is == 0, the timer is disarmed. 24 | */ 25 | struct itimerspec current_itimerspec; 26 | uint64_t nr_expirations; 27 | } TimerFDCtx; 28 | 29 | errno_t timerfd_ctx_init(TimerFDCtx *timerfd, int kq, int clockid); 30 | errno_t timerfd_ctx_terminate(TimerFDCtx *timerfd); 31 | 32 | errno_t timerfd_ctx_settime(TimerFDCtx *timerfd, int flags, 33 | struct itimerspec const *new, struct itimerspec *old); 34 | errno_t timerfd_ctx_gettime(TimerFDCtx *timerfd, struct itimerspec *cur); 35 | 36 | errno_t timerfd_ctx_read(TimerFDCtx *timerfd, uint64_t *value); 37 | 38 | #endif 39 | -------------------------------------------------------------------------------- /tpws/gzip.c: -------------------------------------------------------------------------------- 1 | #include "gzip.h" 2 | #include 3 | #include 4 | #include 5 | 6 | #define ZCHUNK 16384 7 | #define BUFMIN 128 8 | #define BUFCHUNK (1024*128) 9 | 10 | int z_readfile(FILE *F, char **buf, size_t *size) 11 | { 12 | z_stream zs; 13 | int r; 14 | unsigned char in[ZCHUNK]; 15 | size_t bufsize; 16 | void *newbuf; 17 | 18 | memset(&zs, 0, sizeof(zs)); 19 | 20 | *buf = NULL; 21 | bufsize = *size = 0; 22 | 23 | r = inflateInit2(&zs, 47); 24 | if (r != Z_OK) return r; 25 | 26 | do 27 | { 28 | zs.avail_in = fread(in, 1, sizeof(in), F); 29 | if (ferror(F)) 30 | { 31 | r = Z_ERRNO; 32 | goto zerr; 33 | } 34 | if (!zs.avail_in) break; 35 | zs.next_in = in; 36 | do 37 | { 38 | if ((bufsize - *size) < BUFMIN) 39 | { 40 | bufsize += BUFCHUNK; 41 | newbuf = *buf ? realloc(*buf, bufsize) : malloc(bufsize); 42 | if (!newbuf) 43 | { 44 | r = Z_MEM_ERROR; 45 | goto zerr; 46 | } 47 | *buf = newbuf; 48 | } 49 | zs.avail_out = bufsize - *size; 50 | zs.next_out = (unsigned char*)(*buf + *size); 51 | r = inflate(&zs, Z_NO_FLUSH); 52 | if (r != Z_OK && r != Z_STREAM_END) goto zerr; 53 | *size = bufsize - zs.avail_out; 54 | } while (r == Z_OK && zs.avail_in); 55 | } while (r == Z_OK); 56 | 57 | if (*size < bufsize) 58 | { 59 | // free extra space 60 | if ((newbuf = realloc(*buf, *size))) *buf = newbuf; 61 | } 62 | 63 | inflateEnd(&zs); 64 | return Z_OK; 65 | 66 | zerr: 67 | inflateEnd(&zs); 68 | free(*buf); 69 | *buf = NULL; 70 | return r; 71 | } 72 | 73 | bool is_gzip(FILE* F) 74 | { 75 | unsigned char magic[2]; 76 | bool b = !fseek(F, 0, SEEK_SET) && fread(magic, 1, 2, F) == 2 && magic[0] == 0x1F && magic[1] == 0x8B; 77 | fseek(F, 0, SEEK_SET); 78 | return b; 79 | } 80 | -------------------------------------------------------------------------------- /tpws/gzip.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | int z_readfile(FILE *F,char **buf,size_t *size); 8 | bool is_gzip(FILE* F); 9 | -------------------------------------------------------------------------------- /tpws/helpers.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | // this saves memory. sockaddr_storage is larger than required. it can be 128 bytes. sockaddr_in6 is 28 bytes. 13 | typedef union 14 | { 15 | sa_family_t sa_family; 16 | struct sockaddr_in sa4; // size 16 17 | struct sockaddr_in6 sa6; // size 28 18 | } sockaddr_in46; 19 | 20 | int unique_size_t(size_t *pu, int ct); 21 | void qsort_size_t(size_t *array,size_t ct); 22 | 23 | void rtrim(char *s); 24 | void replace_char(char *s, char from, char to); 25 | char *strncasestr(const char *s,const char *find, size_t slen); 26 | 27 | bool str_ends_with(const char *s, const char *suffix); 28 | 29 | bool load_file(const char *filename,void *buffer,size_t *buffer_size); 30 | bool append_to_list_file(const char *filename, const char *s); 31 | 32 | void expand_bits(void *target, const void *source, unsigned int source_bitlen, unsigned int target_bytelen); 33 | 34 | void ntop46(const struct sockaddr *sa, char *str, size_t len); 35 | void ntop46_port(const struct sockaddr *sa, char *str, size_t len); 36 | void print_sockaddr(const struct sockaddr *sa); 37 | void print_addrinfo(const struct addrinfo *ai); 38 | bool check_local_ip(const struct sockaddr *saddr); 39 | 40 | bool saismapped(const struct sockaddr_in6 *sa); 41 | bool samappedcmp(const struct sockaddr_in *sa1,const struct sockaddr_in6 *sa2); 42 | bool sacmp(const struct sockaddr *sa1,const struct sockaddr *sa2); 43 | uint16_t saport(const struct sockaddr *sa); 44 | // true = was converted 45 | bool saconvmapped(struct sockaddr_storage *a); 46 | 47 | void sacopy(struct sockaddr_storage *sa_dest, const struct sockaddr *sa); 48 | void sa46copy(sockaddr_in46 *sa_dest, const struct sockaddr *sa); 49 | 50 | bool is_localnet(const struct sockaddr *a); 51 | bool is_linklocal(const struct sockaddr_in6* a); 52 | bool is_private6(const struct sockaddr_in6* a); 53 | 54 | bool set_keepalive(int fd); 55 | bool set_ttl(int fd, int ttl); 56 | bool set_hl(int fd, int hl); 57 | bool set_ttl_hl(int fd, int ttl); 58 | int get_so_error(int fd); 59 | 60 | // alignment-safe functions 61 | static inline uint16_t pntoh16(const uint8_t *p) { 62 | return ((uint16_t)p[0] << 8) | (uint16_t)p[1]; 63 | } 64 | static inline void phton16(uint8_t *p, uint16_t v) { 65 | p[0] = (uint8_t)(v>>8); 66 | p[1] = (uint8_t)v; 67 | } 68 | 69 | int fprint_localtime(FILE *F); 70 | 71 | typedef struct 72 | { 73 | time_t mod_time; 74 | off_t size; 75 | } file_mod_sig; 76 | #define FILE_MOD_COMPARE(ms1,ms2) (((ms1)->mod_time==(ms2)->mod_time) && ((ms1)->size==(ms2)->size)) 77 | #define FILE_MOD_RESET(ms) memset(ms,0,sizeof(file_mod_sig)) 78 | bool file_mod_signature(const char *filename, file_mod_sig *ms); 79 | time_t file_mod_time(const char *filename); 80 | bool file_open_test(const char *filename, int flags); 81 | 82 | typedef struct 83 | { 84 | uint16_t from,to; 85 | bool neg; 86 | } port_filter; 87 | bool pf_in_range(uint16_t port, const port_filter *pf); 88 | bool pf_parse(const char *s, port_filter *pf); 89 | bool pf_is_empty(const port_filter *pf); 90 | 91 | void set_console_io_buffering(void); 92 | bool set_env_exedir(const char *argv0); 93 | 94 | #ifndef IN_LOOPBACK 95 | #define IN_LOOPBACK(a) ((((uint32_t) (a)) & 0xff000000) == 0x7f000000) 96 | #endif 97 | 98 | #ifdef __GNUC__ 99 | #define IN6_EXTRACT_MAP4(a) \ 100 | (__extension__ \ 101 | ({ const struct in6_addr *__a = (const struct in6_addr *) (a); \ 102 | (((const uint32_t *) (__a))[3]); })) 103 | #else 104 | #define IN6_EXTRACT_MAP4(a) (((const uint32_t *) (a))[3]) 105 | #endif 106 | 107 | 108 | struct cidr4 109 | { 110 | struct in_addr addr; 111 | uint8_t preflen; 112 | }; 113 | struct cidr6 114 | { 115 | struct in6_addr addr; 116 | uint8_t preflen; 117 | }; 118 | void str_cidr4(char *s, size_t s_len, const struct cidr4 *cidr); 119 | void print_cidr4(const struct cidr4 *cidr); 120 | void str_cidr6(char *s, size_t s_len, const struct cidr6 *cidr); 121 | void print_cidr6(const struct cidr6 *cidr); 122 | bool parse_cidr4(char *s, struct cidr4 *cidr); 123 | bool parse_cidr6(char *s, struct cidr6 *cidr); 124 | 125 | static inline uint32_t mask_from_preflen(uint32_t preflen) 126 | { 127 | return preflen ? preflen<32 ? ~((1 << (32-preflen)) - 1) : 0xFFFFFFFF : 0; 128 | } 129 | void ip6_and(const struct in6_addr * restrict a, const struct in6_addr * restrict b, struct in6_addr * restrict result); 130 | extern struct in6_addr ip6_mask[129]; 131 | void mask_from_preflen6_prepare(void); 132 | static inline const struct in6_addr *mask_from_preflen6(uint8_t preflen) 133 | { 134 | return ip6_mask+preflen; 135 | } 136 | 137 | void msleep(unsigned int ms); 138 | #ifdef __linux__ 139 | bool socket_supports_notsent(); 140 | bool socket_has_notsent(int sfd); 141 | bool socket_wait_notsent(int sfd, unsigned int delay_ms, unsigned int *wasted_ms); 142 | 143 | int is_wsl(); 144 | #endif 145 | -------------------------------------------------------------------------------- /tpws/hostlist.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include "pools.h" 5 | #include "params.h" 6 | 7 | bool AppendHostlistItem(hostlist_pool **hostlist, char *s); 8 | bool AppendHostList(hostlist_pool **hostlist, const char *filename); 9 | bool LoadAllHostLists(); 10 | bool NonEmptyHostlist(hostlist_pool **hostlist); 11 | // return : true = apply fooling, false = do not apply 12 | bool HostlistCheck(const struct desync_profile *dp,const char *host, bool *excluded, bool bSkipReloadCheck); 13 | struct hostlist_file *RegisterHostlist(struct desync_profile *dp, bool bExclude, const char *filename); 14 | bool HostlistsReloadCheckForProfile(const struct desync_profile *dp); 15 | void HostlistsDebug(); 16 | 17 | #define ResetAllHostlistsModTime() hostlist_files_reset_modtime(¶ms.hostlists) 18 | -------------------------------------------------------------------------------- /tpws/ipset.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include "params.h" 6 | #include "pools.h" 7 | 8 | bool LoadAllIpsets(); 9 | bool IpsetCheck(const struct desync_profile *dp, const struct in_addr *ipv4, const struct in6_addr *ipv6); 10 | struct ipset_file *RegisterIpset(struct desync_profile *dp, bool bExclude, const char *filename); 11 | void IpsetsDebug(); 12 | bool AppendIpsetItem(ipset *ips, char *ip); 13 | 14 | #define ResetAllIpsetModTime() ipset_files_reset_modtime(¶ms.ipsets) 15 | -------------------------------------------------------------------------------- /tpws/linux_compat.h: -------------------------------------------------------------------------------- 1 | #ifdef __linux__ 2 | 3 | #include 4 | 5 | #ifndef TCP_USER_TIMEOUT 6 | #define TCP_USER_TIMEOUT 18 7 | #endif 8 | 9 | #ifndef IP6T_SO_ORIGINAL_DST 10 | #define IP6T_SO_ORIGINAL_DST 80 11 | #endif 12 | 13 | #ifndef PR_SET_NO_NEW_PRIVS 14 | #define PR_SET_NO_NEW_PRIVS 38 15 | #endif 16 | 17 | // workaround for old headers 18 | 19 | struct tcp_info_new { 20 | __u8 tcpi_state; 21 | __u8 tcpi_ca_state; 22 | __u8 tcpi_retransmits; 23 | __u8 tcpi_probes; 24 | __u8 tcpi_backoff; 25 | __u8 tcpi_options; 26 | __u8 tcpi_snd_wscale : 4, tcpi_rcv_wscale : 4; 27 | __u8 tcpi_delivery_rate_app_limited : 1, tcpi_fastopen_client_fail : 2; 28 | 29 | __u32 tcpi_rto; 30 | __u32 tcpi_ato; 31 | __u32 tcpi_snd_mss; 32 | __u32 tcpi_rcv_mss; 33 | 34 | __u32 tcpi_unacked; 35 | __u32 tcpi_sacked; 36 | __u32 tcpi_lost; 37 | __u32 tcpi_retrans; 38 | __u32 tcpi_fackets; 39 | 40 | /* Times. */ 41 | __u32 tcpi_last_data_sent; 42 | __u32 tcpi_last_ack_sent; /* Not remembered, sorry. */ 43 | __u32 tcpi_last_data_recv; 44 | __u32 tcpi_last_ack_recv; 45 | 46 | /* Metrics. */ 47 | __u32 tcpi_pmtu; 48 | __u32 tcpi_rcv_ssthresh; 49 | __u32 tcpi_rtt; 50 | __u32 tcpi_rttvar; 51 | __u32 tcpi_snd_ssthresh; 52 | __u32 tcpi_snd_cwnd; 53 | __u32 tcpi_advmss; 54 | __u32 tcpi_reordering; 55 | 56 | __u32 tcpi_rcv_rtt; 57 | __u32 tcpi_rcv_space; 58 | 59 | __u32 tcpi_total_retrans; 60 | 61 | __u64 tcpi_pacing_rate; 62 | __u64 tcpi_max_pacing_rate; 63 | __u64 tcpi_bytes_acked; /* RFC4898 tcpEStatsAppHCThruOctetsAcked */ 64 | __u64 tcpi_bytes_received; /* RFC4898 tcpEStatsAppHCThruOctetsReceived */ 65 | __u32 tcpi_segs_out; /* RFC4898 tcpEStatsPerfSegsOut */ 66 | __u32 tcpi_segs_in; /* RFC4898 tcpEStatsPerfSegsIn */ 67 | 68 | __u32 tcpi_notsent_bytes; 69 | __u32 tcpi_min_rtt; 70 | __u32 tcpi_data_segs_in; /* RFC4898 tcpEStatsDataSegsIn */ 71 | __u32 tcpi_data_segs_out; /* RFC4898 tcpEStatsDataSegsOut */ 72 | 73 | __u64 tcpi_delivery_rate; 74 | 75 | __u64 tcpi_busy_time; /* Time (usec) busy sending data */ 76 | __u64 tcpi_rwnd_limited; /* Time (usec) limited by receive window */ 77 | __u64 tcpi_sndbuf_limited; /* Time (usec) limited by send buffer */ 78 | 79 | __u32 tcpi_delivered; 80 | __u32 tcpi_delivered_ce; 81 | 82 | __u64 tcpi_bytes_sent; /* RFC4898 tcpEStatsPerfHCDataOctetsOut */ 83 | __u64 tcpi_bytes_retrans; /* RFC4898 tcpEStatsPerfOctetsRetrans */ 84 | __u32 tcpi_dsack_dups; /* RFC4898 tcpEStatsStackDSACKDups */ 85 | __u32 tcpi_reord_seen; /* reordering events seen */ 86 | 87 | __u32 tcpi_rcv_ooopack; /* Out-of-order packets received */ 88 | 89 | __u32 tcpi_snd_wnd; /* peer's advertised receive window after 90 | * scaling (bytes) 91 | */ 92 | __u32 tcpi_rcv_wnd; /* local advertised receive window after 93 | * scaling (bytes) 94 | */ 95 | 96 | __u32 tcpi_rehash; /* PLB or timeout triggered rehash attempts */ 97 | 98 | __u16 tcpi_total_rto; /* Total number of RTO timeouts, including 99 | * SYN/SYN-ACK and recurring timeouts. 100 | */ 101 | __u16 tcpi_total_rto_recoveries; /* Total number of RTO 102 | * recoveries, including any 103 | * unfinished recovery. 104 | */ 105 | __u32 tcpi_total_rto_time; /* Total time spent in RTO recoveries 106 | * in milliseconds, including any 107 | * unfinished recovery. 108 | */ 109 | }; 110 | 111 | #endif 112 | -------------------------------------------------------------------------------- /tpws/macos/net/pfvar.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | 6 | // taken from an older apple SDK 7 | // some fields are different from BSDs 8 | 9 | #define DIOCNATLOOK _IOWR('D', 23, struct pfioc_natlook) 10 | 11 | enum { PF_INOUT, PF_IN, PF_OUT, PF_FWD }; 12 | 13 | struct pf_addr { 14 | union { 15 | struct in_addr v4; 16 | struct in6_addr v6; 17 | u_int8_t addr8[16]; 18 | u_int16_t addr16[8]; 19 | u_int32_t addr32[4]; 20 | } pfa; /* 128-bit address */ 21 | #define v4 pfa.v4 22 | #define v6 pfa.v6 23 | #define addr8 pfa.addr8 24 | #define addr16 pfa.addr16 25 | #define addr32 pfa.addr32 26 | }; 27 | 28 | union pf_state_xport { 29 | u_int16_t port; 30 | u_int16_t call_id; 31 | u_int32_t spi; 32 | }; 33 | 34 | struct pfioc_natlook { 35 | struct pf_addr saddr; 36 | struct pf_addr daddr; 37 | struct pf_addr rsaddr; 38 | struct pf_addr rdaddr; 39 | union pf_state_xport sxport; 40 | union pf_state_xport dxport; 41 | union pf_state_xport rsxport; 42 | union pf_state_xport rdxport; 43 | sa_family_t af; 44 | u_int8_t proto; 45 | u_int8_t proto_variant; 46 | u_int8_t direction; 47 | }; 48 | -------------------------------------------------------------------------------- /tpws/params.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #if !defined( __OpenBSD__) && !defined(__ANDROID__) 11 | #include 12 | #endif 13 | 14 | 15 | #include "tpws.h" 16 | #include "pools.h" 17 | #include "helpers.h" 18 | #include "protocol.h" 19 | 20 | #define HOSTLIST_AUTO_FAIL_THRESHOLD_DEFAULT 3 21 | #define HOSTLIST_AUTO_FAIL_TIME_DEFAULT 60 22 | 23 | #define FIX_SEG_DEFAULT_MAX_WAIT 50 24 | 25 | #define IPCACHE_LIFETIME 7200 26 | 27 | #define MAX_GIDS 64 28 | 29 | enum bindll { unwanted=0, no, prefer, force }; 30 | 31 | #define MAX_BINDS 32 32 | struct bind_s 33 | { 34 | char bindaddr[64],bindiface[IF_NAMESIZE]; 35 | bool bind_if6; 36 | enum bindll bindll; 37 | int bind_wait_ifup,bind_wait_ip,bind_wait_ip_ll; 38 | }; 39 | 40 | #define MAX_SPLITS 16 41 | 42 | enum log_target { LOG_TARGET_CONSOLE=0, LOG_TARGET_FILE, LOG_TARGET_SYSLOG, LOG_TARGET_ANDROID }; 43 | 44 | struct desync_profile 45 | { 46 | int n; // number of the profile 47 | 48 | bool hostcase, hostdot, hosttab, hostnospace, methodspace, methodeol, unixeol, domcase; 49 | int hostpad; 50 | char hostspell[4]; 51 | bool split_any_protocol; 52 | bool disorder, disorder_http, disorder_tls; 53 | bool oob, oob_http, oob_tls; 54 | uint8_t oob_byte; 55 | 56 | // multisplit 57 | struct proto_pos splits[MAX_SPLITS]; 58 | int split_count; 59 | struct proto_pos tlsrec; 60 | 61 | int mss; 62 | 63 | bool tamper_start_n,tamper_cutoff_n; 64 | unsigned int tamper_start,tamper_cutoff; 65 | 66 | bool filter_ipv4,filter_ipv6; 67 | struct port_filters_head pf_tcp; 68 | uint32_t filter_l7; // L7_PROTO_* bits 69 | 70 | // list of pointers to ipsets 71 | struct ipset_collection_head ips_collection, ips_collection_exclude; 72 | 73 | // list of pointers to hostlist files 74 | struct hostlist_collection_head hl_collection, hl_collection_exclude; 75 | // pointer to autohostlist. NULL if no autohostlist for the profile. 76 | struct hostlist_file *hostlist_auto; 77 | int hostlist_auto_fail_threshold, hostlist_auto_fail_time, hostlist_auto_retrans_threshold; 78 | 79 | hostfail_pool *hostlist_auto_fail_counters; 80 | }; 81 | 82 | #define PROFILE_IPSETS_ABSENT(dp) (!LIST_FIRST(&dp->ips_collection) && !LIST_FIRST(&dp->ips_collection_exclude)) 83 | #define PROFILE_IPSETS_EMPTY(dp) (ipset_collection_is_empty(&dp->ips_collection) && ipset_collection_is_empty(&dp->ips_collection_exclude)) 84 | #define PROFILE_HOSTLISTS_EMPTY(dp) (hostlist_collection_is_empty(&dp->hl_collection) && hostlist_collection_is_empty(&dp->hl_collection_exclude)) 85 | 86 | struct desync_profile_list { 87 | struct desync_profile dp; 88 | LIST_ENTRY(desync_profile_list) next; 89 | }; 90 | LIST_HEAD(desync_profile_list_head, desync_profile_list); 91 | struct desync_profile_list *dp_list_add(struct desync_profile_list_head *head); 92 | void dp_entry_destroy(struct desync_profile_list *entry); 93 | void dp_list_destroy(struct desync_profile_list_head *head); 94 | void dp_init(struct desync_profile *dp); 95 | void dp_clear(struct desync_profile *dp); 96 | 97 | struct params_s 98 | { 99 | #if !defined( __OpenBSD__) && !defined(__ANDROID__) 100 | wordexp_t wexp; // for file based config 101 | #endif 102 | 103 | int debug; 104 | enum log_target debug_target; 105 | char debug_logfile[PATH_MAX]; 106 | 107 | struct bind_s binds[MAX_BINDS]; 108 | int binds_last; 109 | bool bind_wait_only; 110 | uint16_t port; 111 | struct sockaddr_in connect_bind4; 112 | struct sockaddr_in6 connect_bind6; 113 | char connect_bind6_ifname[IF_NAMESIZE]; 114 | 115 | uint8_t proxy_type; 116 | unsigned int fix_seg; 117 | bool fix_seg_avail; 118 | bool no_resolve; 119 | bool skip_nodelay; 120 | bool droproot; 121 | bool daemon; 122 | uid_t uid; 123 | gid_t gid[MAX_GIDS]; 124 | int gid_count; 125 | char pidfile[PATH_MAX]; 126 | int maxconn,resolver_threads,maxfiles,max_orphan_time; 127 | int local_rcvbuf,local_sndbuf,remote_rcvbuf,remote_sndbuf; 128 | #if defined(__linux__) || defined(__APPLE__) 129 | int tcp_user_timeout_local,tcp_user_timeout_remote; 130 | #endif 131 | 132 | #if defined(BSD) 133 | bool pf_enable; 134 | #endif 135 | #ifdef SPLICE_PRESENT 136 | bool nosplice; 137 | #endif 138 | 139 | int ttl_default; 140 | char hostlist_auto_debuglog[PATH_MAX]; 141 | 142 | // hostlist files with data for all profiles 143 | struct hostlist_files_head hostlists; 144 | // ipset files with data for all profiles 145 | struct ipset_files_head ipsets; 146 | 147 | bool tamper; // any tamper option is set 148 | bool tamper_lim; // tamper-start or tamper-cutoff set in any profile 149 | struct desync_profile_list_head desync_profiles; 150 | 151 | unsigned int ipcache_lifetime; 152 | bool cache_hostname; 153 | ip_cache ipcache; 154 | }; 155 | 156 | extern struct params_s params; 157 | extern const char *progname; 158 | 159 | int DLOG(const char *format, int level, ...); 160 | int DLOG_CONDUP(const char *format, ...); 161 | int DLOG_ERR(const char *format, ...); 162 | int DLOG_PERROR(const char *s); 163 | int HOSTLIST_DEBUGLOG_APPEND(const char *format, ...); 164 | void hexdump_limited_dlog(const uint8_t *data, size_t size, size_t limit); 165 | 166 | #define VPRINT(format, ...) DLOG(format, 1, ##__VA_ARGS__) 167 | #define DBGPRINT(format, ...) DLOG(format, 2, ##__VA_ARGS__) 168 | -------------------------------------------------------------------------------- /tpws/protocol.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | typedef enum {UNKNOWN=0, HTTP, TLS, QUIC, WIREGUARD, DHT} t_l7proto; 8 | #define L7_PROTO_HTTP 0x00000001 9 | #define L7_PROTO_TLS 0x00000002 10 | #define L7_PROTO_QUIC 0x00000004 11 | #define L7_PROTO_WIREGUARD 0x00000008 12 | #define L7_PROTO_DHT 0x00000010 13 | #define L7_PROTO_UNKNOWN 0x80000000 14 | const char *l7proto_str(t_l7proto l7); 15 | bool l7_proto_match(t_l7proto l7proto, uint32_t filter_l7); 16 | 17 | // pos markers 18 | #define PM_ABS 0 19 | #define PM_HOST 1 20 | #define PM_HOST_END 2 21 | #define PM_HOST_SLD 3 22 | #define PM_HOST_MIDSLD 4 23 | #define PM_HOST_ENDSLD 5 24 | #define PM_HTTP_METHOD 6 25 | #define PM_SNI_EXT 7 26 | struct proto_pos 27 | { 28 | int16_t pos; 29 | uint8_t marker; 30 | }; 31 | #define PROTO_POS_EMPTY(sp) ((sp)->marker==PM_ABS && (sp)->pos==0) 32 | bool IsHostMarker(uint8_t posmarker); 33 | const char *posmarker_name(uint8_t posmarker); 34 | size_t AnyProtoPos(uint8_t posmarker, int16_t pos, const uint8_t *data, size_t sz); 35 | size_t HttpPos(uint8_t posmarker, int16_t pos, const uint8_t *data, size_t sz); 36 | size_t TLSPos(uint8_t posmarker, int16_t pos, const uint8_t *data, size_t sz); 37 | size_t ResolvePos(const uint8_t *data, size_t sz, t_l7proto l7proto, const struct proto_pos *sp); 38 | void ResolveMultiPos(const uint8_t *data, size_t sz, t_l7proto l7proto, const struct proto_pos *splits, int split_count, size_t *pos, int *pos_count); 39 | 40 | 41 | extern const char *http_methods[9]; 42 | const char *HttpMethod(const uint8_t *data, size_t len); 43 | bool IsHttp(const uint8_t *data, size_t len); 44 | bool HttpFindHost(uint8_t **pHost,uint8_t *buf,size_t bs); 45 | bool HttpFindHostConst(const uint8_t **pHost,const uint8_t *buf,size_t bs); 46 | // header must be passed like this : "\nHost:" 47 | bool HttpExtractHeader(const uint8_t *data, size_t len, const char *header, char *buf, size_t len_buf); 48 | bool HttpExtractHost(const uint8_t *data, size_t len, char *host, size_t len_host); 49 | bool IsHttpReply(const uint8_t *data, size_t len); 50 | const char *HttpFind2ndLevelDomain(const char *host); 51 | // must be pre-checked by IsHttpReply 52 | int HttpReplyCode(const uint8_t *data, size_t len); 53 | // must be pre-checked by IsHttpReply 54 | bool HttpReplyLooksLikeDPIRedirect(const uint8_t *data, size_t len, const char *host); 55 | 56 | const char *TLSVersionStr(uint16_t tlsver); 57 | uint16_t TLSRecordDataLen(const uint8_t *data); 58 | size_t TLSRecordLen(const uint8_t *data); 59 | bool IsTLSRecordFull(const uint8_t *data, size_t len); 60 | bool IsTLSClientHello(const uint8_t *data, size_t len, bool bPartialIsOK); 61 | bool TLSFindExt(const uint8_t *data, size_t len, uint16_t type, const uint8_t **ext, size_t *len_ext, bool bPartialIsOK); 62 | bool TLSFindExtInHandshake(const uint8_t *data, size_t len, uint16_t type, const uint8_t **ext, size_t *len_ext, bool bPartialIsOK); 63 | bool TLSHelloExtractHost(const uint8_t *data, size_t len, char *host, size_t len_host, bool bPartialIsOK); 64 | bool TLSHelloExtractHostFromHandshake(const uint8_t *data, size_t len, char *host, size_t len_host, bool bPartialIsOK); 65 | -------------------------------------------------------------------------------- /tpws/redirect.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | bool get_dest_addr(int sockfd, const struct sockaddr *accept_sa, struct sockaddr_storage *orig_dst); 8 | bool redir_init(void); 9 | void redir_close(void); 10 | -------------------------------------------------------------------------------- /tpws/resolver.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | #include "helpers.h" 10 | 11 | struct resolve_item 12 | { 13 | char dom[256]; // request dom 14 | sockaddr_in46 ss; // resolve result 15 | int ga_res; // getaddrinfo result code 16 | uint16_t port; // request port 17 | void *ptr; 18 | TAILQ_ENTRY(resolve_item) next; 19 | }; 20 | 21 | struct resolve_item *resolver_queue(const char *dom, uint16_t port, void *ptr); 22 | void resolver_deinit(void); 23 | bool resolver_init(int threads, int fd_signal_pipe); 24 | int resolver_thread_count(void); 25 | -------------------------------------------------------------------------------- /tpws/sec.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "params.h" 4 | 5 | #include 6 | #include 7 | 8 | #ifdef __linux__ 9 | 10 | #include 11 | #include 12 | #include 13 | 14 | bool checkpcap(uint64_t caps); 15 | bool setpcap(uint64_t caps); 16 | int getmaxcap(void); 17 | bool dropcaps(void); 18 | 19 | #define syscall_nr (offsetof(struct seccomp_data, nr)) 20 | #define arch_nr (offsetof(struct seccomp_data, arch)) 21 | #define syscall_arg(x) (offsetof(struct seccomp_data, args[x])) 22 | 23 | #if defined(__aarch64__) 24 | 25 | # define ARCH_NR AUDIT_ARCH_AARCH64 26 | 27 | #elif defined(__amd64__) 28 | 29 | # define ARCH_NR AUDIT_ARCH_X86_64 30 | 31 | #elif defined(__arm__) && (defined(__ARM_EABI__) || defined(__thumb__)) 32 | 33 | # if __BYTE_ORDER == __LITTLE_ENDIAN 34 | # define ARCH_NR AUDIT_ARCH_ARM 35 | # else 36 | # define ARCH_NR AUDIT_ARCH_ARMEB 37 | # endif 38 | 39 | #elif defined(__i386__) 40 | 41 | # define ARCH_NR AUDIT_ARCH_I386 42 | 43 | #elif defined(__mips__) 44 | 45 | #if _MIPS_SIM == _MIPS_SIM_ABI32 46 | # if __BYTE_ORDER == __LITTLE_ENDIAN 47 | # define ARCH_NR AUDIT_ARCH_MIPSEL 48 | # else 49 | # define ARCH_NR AUDIT_ARCH_MIPS 50 | # endif 51 | #elif _MIPS_SIM == _MIPS_SIM_ABI64 52 | # if __BYTE_ORDER == __LITTLE_ENDIAN 53 | # define ARCH_NR AUDIT_ARCH_MIPSEL64 54 | # else 55 | # define ARCH_NR AUDIT_ARCH_MIPS64 56 | # endif 57 | #else 58 | # error "Unsupported mips abi" 59 | #endif 60 | 61 | #elif defined(__PPC64__) 62 | 63 | # if __BYTE_ORDER == __LITTLE_ENDIAN 64 | # define ARCH_NR AUDIT_ARCH_PPC64LE 65 | # else 66 | # define ARCH_NR AUDIT_ARCH_PPC64 67 | # endif 68 | 69 | #elif defined(__PPC__) 70 | 71 | # define ARCH_NR AUDIT_ARCH_PPC 72 | 73 | #elif __riscv && __riscv_xlen == 64 74 | 75 | # define ARCH_NR AUDIT_ARCH_RISCV64 76 | 77 | #else 78 | 79 | # error "Platform does not support seccomp filter yet" 80 | 81 | #endif 82 | 83 | #endif 84 | 85 | bool sec_harden(void); 86 | bool can_drop_root(); 87 | bool droproot(uid_t uid, gid_t *gid, int gid_count); 88 | void print_id(void); 89 | void daemonize(void); 90 | bool writepid(const char *filename); 91 | -------------------------------------------------------------------------------- /tpws/socks.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | 6 | #pragma pack(push,1) 7 | 8 | #define S4_CMD_CONNECT 1 9 | #define S4_CMD_BIND 2 10 | typedef struct 11 | { 12 | uint8_t ver,cmd; 13 | uint16_t port; 14 | uint32_t ip; 15 | } s4_req; 16 | #define S4_REQ_HEADER_VALID(r,l) (l>=sizeof(s4_req) && r->ver==4) 17 | #define S4_REQ_CONNECT_VALID(r,l) (S4_REQ_HEADER_VALID(r,l) && r->cmd==S4_CMD_CONNECT) 18 | 19 | #define S4_REP_OK 90 20 | #define S4_REP_FAILED 91 21 | typedef struct 22 | { 23 | uint8_t zero,rep; 24 | uint16_t port; 25 | uint32_t ip; 26 | } s4_rep; 27 | 28 | 29 | 30 | #define S5_AUTH_NONE 0 31 | #define S5_AUTH_GSSAPI 1 32 | #define S5_AUTH_USERPASS 2 33 | #define S5_AUTH_UNACCEPTABLE 0xFF 34 | typedef struct 35 | { 36 | uint8_t ver,nmethods,methods[255]; 37 | } s5_handshake; 38 | #define S5_REQ_HANDHSHAKE_VALID(r,l) (l>=3 && r->ver==5 && r->nmethods && l>=(2+r->nmethods)) 39 | typedef struct 40 | { 41 | uint8_t ver,method; 42 | } s5_handshake_ack; 43 | 44 | #define S5_CMD_CONNECT 1 45 | #define S5_CMD_BIND 2 46 | #define S5_CMD_UDP_ASSOC 3 47 | #define S5_ATYP_IP4 1 48 | #define S5_ATYP_DOM 3 49 | #define S5_ATYP_IP6 4 50 | typedef struct 51 | { 52 | uint8_t ver,cmd,rsv,atyp; 53 | union { 54 | struct { 55 | struct in_addr addr; 56 | uint16_t port; 57 | } d4; 58 | struct { 59 | struct in6_addr addr; 60 | uint16_t port; 61 | } d6; 62 | struct { 63 | uint8_t len; 64 | char domport[255+2]; // max hostname + binary port 65 | } dd; 66 | }; 67 | } s5_req; 68 | #define S5_REQ_HEADER_VALID(r,l) (l>=4 && r->ver==5) 69 | #define S5_IP46_VALID(r,l) ((r->atyp==S5_ATYP_IP4 && l>=(4+sizeof(r->d4))) || (r->atyp==S5_ATYP_IP6 && l>=(4+sizeof(r->d6)))) 70 | #define S5_REQ_CONNECT_VALID(r,l) (S5_REQ_HEADER_VALID(r,l) && r->cmd==S5_CMD_CONNECT && (S5_IP46_VALID(r,l) || (r->atyp==S5_ATYP_DOM && l>=5 && l>=(5+r->dd.len)))) 71 | #define S5_PORT_FROM_DD(r,l) (l>=(4+r->dd.len+2) ? ntohs(*(uint16_t*)(r->dd.domport+r->dd.len)) : 0) 72 | 73 | #define S5_REP_OK 0 74 | #define S5_REP_GENERAL_FAILURE 1 75 | #define S5_REP_NOT_ALLOWED_BY_RULESET 2 76 | #define S5_REP_NETWORK_UNREACHABLE 3 77 | #define S5_REP_HOST_UNREACHABLE 4 78 | #define S5_REP_CONN_REFUSED 5 79 | #define S5_REP_TTL_EXPIRED 6 80 | #define S5_REP_COMMAND_NOT_SUPPORTED 7 81 | #define S5_REP_ADDR_TYPE_NOT_SUPPORTED 8 82 | typedef struct 83 | { 84 | uint8_t ver,rep,rsv,atyp; 85 | union { 86 | struct { 87 | struct in_addr addr; 88 | uint16_t port; 89 | } d4; 90 | }; 91 | } s5_rep; 92 | 93 | #pragma pack(pop) 94 | -------------------------------------------------------------------------------- /tpws/tamper.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | #include "params.h" 8 | 9 | #define SPLIT_FLAG_DISORDER 0x01 10 | #define SPLIT_FLAG_OOB 0x02 11 | 12 | typedef struct 13 | { 14 | // common state 15 | t_l7proto l7proto; 16 | bool bTamperInCutoff; 17 | bool b_host_checked,b_host_matches,b_ah_check; 18 | bool hostname_discovered; 19 | char *hostname; 20 | struct desync_profile *dp; // desync profile cache 21 | } t_ctrack; 22 | 23 | void apply_desync_profile(t_ctrack *ctrack, const struct sockaddr *dest); 24 | bool ipcache_put_hostname(const struct in_addr *a4, const struct in6_addr *a6, const char *hostname); 25 | 26 | void tamper_out(t_ctrack *ctrack, const struct sockaddr *dest, uint8_t *segment,size_t segment_buffer_size,size_t *size, size_t *multisplit_pos, int *multisplit_count, uint8_t *split_flags); 27 | void tamper_in(t_ctrack *ctrack, const struct sockaddr *client, uint8_t *segment,size_t segment_buffer_size,size_t *size); 28 | // connection reset by remote leg 29 | void rst_in(t_ctrack *ctrack, const struct sockaddr *client); 30 | // local leg closed connection (timeout waiting response ?) 31 | void hup_out(t_ctrack *ctrack, const struct sockaddr *client); 32 | 33 | void packet_debug(const uint8_t *data, size_t sz); 34 | -------------------------------------------------------------------------------- /tpws/tpws.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #ifdef __linux__ 4 | #define SPLICE_PRESENT 5 | #endif 6 | 7 | #include 8 | 9 | void ReloadCheck(); 10 | -------------------------------------------------------------------------------- /tpws/tpws_conn.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include "tamper.h" 8 | #include "params.h" 9 | #include "resolver.h" 10 | 11 | #define BACKLOG 10 12 | #define MAX_EPOLL_EVENTS 64 13 | #define IP_TRANSPARENT 19 //So that application compiles on OpenWRT 14 | #define SPLICE_LEN 65536 15 | #define DEFAULT_MAX_CONN 512 16 | #define DEFAULT_MAX_ORPHAN_TIME 5 17 | #define DEFAULT_TCP_USER_TIMEOUT_LOCAL 10 18 | #define DEFAULT_TCP_USER_TIMEOUT_REMOTE 20 19 | 20 | int event_loop(const int *listen_fd, size_t listen_fd_ct); 21 | 22 | //Three different states of a connection 23 | enum{ 24 | CONN_UNAVAILABLE=0, // connecting 25 | CONN_AVAILABLE, // operational 26 | CONN_RDHUP, // received RDHUP, only sending unsent buffers. more RDHUPs are blocked 27 | CONN_CLOSED // will be deleted soon 28 | }; 29 | typedef uint8_t conn_state_t; 30 | 31 | // data in a send_buffer can be sent in several stages 32 | // pos indicates size of already sent data 33 | // when pos==len its time to free buffer 34 | struct send_buffer 35 | { 36 | uint8_t *data; 37 | size_t len,pos; 38 | int ttl, flags; 39 | }; 40 | typedef struct send_buffer send_buffer_t; 41 | 42 | enum{ 43 | CONN_TYPE_TRANSPARENT=0, 44 | CONN_TYPE_SOCKS 45 | }; 46 | typedef uint8_t conn_type_t; 47 | 48 | struct tproxy_conn 49 | { 50 | bool listener; // true - listening socket. false = connecion socket 51 | bool remote; // false - accepted, true - connected 52 | int efd; // epoll fd 53 | int fd; 54 | int splice_pipe[2]; 55 | conn_state_t state; 56 | conn_type_t conn_type; 57 | sockaddr_in46 client, dest; // ip:port of client, ip:port of target 58 | 59 | struct tproxy_conn *partner; // other leg 60 | time_t orphan_since; 61 | 62 | // socks5 state machine 63 | enum { 64 | S_WAIT_HANDSHAKE=0, 65 | S_WAIT_REQUEST, 66 | S_WAIT_RESOLVE, 67 | S_WAIT_CONNECTION, 68 | S_TCP 69 | } socks_state; 70 | uint8_t socks_ver; 71 | struct resolve_item *socks_ri; 72 | 73 | // these value are used in flow control. we do not use ET (edge triggered) polling 74 | // if we dont disable notifications they will come endlessly until condition becomes false and will eat all cpu time 75 | bool bFlowIn,bFlowOut, bShutdown, bFlowInPrev,bFlowOutPrev, bPrevRdhup; 76 | 77 | // total read,write 78 | uint64_t trd,twr, tnrd; 79 | // number of epoll_wait events 80 | unsigned int event_count; 81 | 82 | // connection is either spliced or send/recv 83 | // spliced connection have pipe buffering but also can have send_buffer's 84 | // pipe buffer comes first, then send_buffer's from 0 to countof(wr_buf)-1 85 | // send/recv connection do not have pipe and wr_unsent is meaningless, always 0 86 | ssize_t wr_unsent; // unsent bytes in the pipe 87 | // buffer 0 : send before split_pos 88 | // buffer 1 : send after split_pos 89 | // buffer 2 : after RDHUP read all and buffer to the partner 90 | // buffer 3 : after HUP read all and buffer to the partner 91 | // (2 and 3 should not be filled simultaneously, but who knows what can happen. if we have to refill non-empty buffer its FATAL) 92 | // all buffers are sent strictly from 0 to countof(wr_buf)-1 93 | // buffer cannot be sent if there is unsent data in a lower buffer 94 | struct send_buffer wr_buf[4]; 95 | 96 | t_ctrack track; 97 | 98 | //Create the struct which contains ptrs to next/prev element 99 | TAILQ_ENTRY(tproxy_conn) conn_ptrs; 100 | }; 101 | typedef struct tproxy_conn tproxy_conn_t; 102 | 103 | //Define the struct tailhead (code in sys/queue.h is quite intuitive) 104 | //Use tail queue for efficient delete 105 | TAILQ_HEAD(tailhead, tproxy_conn); 106 | 107 | 108 | bool set_socket_buffers(int fd, int rcvbuf, int sndbuf); 109 | -------------------------------------------------------------------------------- /uninstall_easy.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # automated script for easy uninstalling zapret 4 | 5 | EXEDIR="$(dirname "$0")" 6 | EXEDIR="$(cd "$EXEDIR"; pwd)" 7 | ZAPRET_BASE=${ZAPRET_BASE:-"$EXEDIR"} 8 | ZAPRET_RW=${ZAPRET_RW:-"$ZAPRET_BASE"} 9 | ZAPRET_CONFIG=${ZAPRET_CONFIG:-"$ZAPRET_RW/config"} 10 | ZAPRET_CONFIG_DEFAULT="$ZAPRET_BASE/config.default" 11 | IPSET_DIR="$ZAPRET_BASE/ipset" 12 | 13 | [ -f "$ZAPRET_CONFIG" ] || { 14 | ZAPRET_CONFIG_DIR="$(dirname "$ZAPRET_CONFIG")" 15 | [ -d "$ZAPRET_CONFIG_DIR" ] || mkdir -p "$ZAPRET_CONFIG_DIR" 16 | cp "$ZAPRET_CONFIG_DEFAULT" "$ZAPRET_CONFIG" 17 | } 18 | 19 | . "$ZAPRET_CONFIG" 20 | . "$ZAPRET_BASE/common/base.sh" 21 | . "$ZAPRET_BASE/common/elevate.sh" 22 | . "$ZAPRET_BASE/common/fwtype.sh" 23 | . "$ZAPRET_BASE/common/dialog.sh" 24 | . "$ZAPRET_BASE/common/ipt.sh" 25 | . "$ZAPRET_BASE/common/nft.sh" 26 | . "$ZAPRET_BASE/common/pf.sh" 27 | . "$ZAPRET_BASE/common/installer.sh" 28 | 29 | remove_systemd() 30 | { 31 | clear_ipset 32 | service_stop_systemd 33 | service_remove_systemd 34 | timer_remove_systemd 35 | nft_del_table 36 | crontab_del 37 | } 38 | 39 | remove_openrc() 40 | { 41 | clear_ipset 42 | service_remove_openrc 43 | nft_del_table 44 | crontab_del 45 | } 46 | 47 | remove_linux() 48 | { 49 | INIT_SCRIPT_SRC="$EXEDIR/init.d/sysv/zapret" 50 | 51 | clear_ipset 52 | 53 | echo \* executing sysv init stop 54 | "$INIT_SCRIPT_SRC" stop 55 | 56 | nft_del_table 57 | crontab_del 58 | 59 | echo 60 | echo '!!! WARNING. YOUR UNINSTALL IS INCOMPLETE !!!' 61 | echo 'you must manually remove zapret auto start from your system' 62 | } 63 | 64 | remove_openwrt() 65 | { 66 | OPENWRT_FW_INCLUDE=/etc/firewall.zapret 67 | 68 | clear_ipset 69 | service_remove_sysv 70 | remove_openwrt_firewall 71 | remove_openwrt_iface_hook 72 | nft_del_table 73 | restart_openwrt_firewall 74 | crontab_del 75 | remove_extra_pkgs_openwrt 76 | echo 77 | echo to fully remove zapret : rm -r \"$ZAPRET_BASE\" 78 | } 79 | 80 | remove_macos() 81 | { 82 | remove_macos_firewall 83 | service_remove_macos 84 | crontab_del 85 | } 86 | 87 | 88 | fix_sbin_path 89 | check_system 90 | require_root 91 | 92 | [ "$SYSTEM" = "macos" ] && . "$EXEDIR/init.d/macos/functions" 93 | 94 | case $SYSTEM in 95 | systemd) 96 | remove_systemd 97 | ;; 98 | openrc) 99 | remove_openrc 100 | ;; 101 | linux) 102 | remove_linux 103 | ;; 104 | openwrt) 105 | remove_openwrt 106 | ;; 107 | macos) 108 | remove_macos 109 | ;; 110 | esac 111 | 112 | 113 | exitp 0 114 | --------------------------------------------------------------------------------