diff --git a/binaries/win64/zapret-winws/list-youtube.txt b/binaries/win64/zapret-winws/list-youtube.txt index e37b016..cfd4e85 100644 --- a/binaries/win64/zapret-winws/list-youtube.txt +++ b/binaries/win64/zapret-winws/list-youtube.txt @@ -1,3 +1,13 @@ googlevideo.com youtubei.googleapis.com -i.ytimg.com +ytimg.com +yt3.ggpht.com +yt4.ggpht.com +youtube.com +youtubeembeddedplayer.googleapis.com +ytimg.l.google.com +jnn-pa.googleapis.com +youtube-nocookie.com +youtube-ui.l.google.com +yt-video-upload.l.google.com +wide-youtube.l.google.com diff --git a/binaries/win64/zapret-winws/preset_russia.cmd b/binaries/win64/zapret-winws/preset_russia.cmd index 5dba037..f2d0b27 100644 --- a/binaries/win64/zapret-winws/preset_russia.cmd +++ b/binaries/win64/zapret-winws/preset_russia.cmd @@ -3,5 +3,5 @@ start "zapret: http,https,quic" /min "%~dp0winws.exe" ^ --filter-udp=443 --hostlist="%~dp0list-youtube.txt" --dpi-desync=fake --dpi-desync-repeats=11 --dpi-desync-fake-quic="%~dp0quic_initial_www_google_com.bin" --new ^ --filter-udp=443 --dpi-desync=fake --dpi-desync-repeats=11 --new ^ --filter-tcp=80 --dpi-desync=fake,split2 --dpi-desync-autottl=2 --dpi-desync-fooling=md5sig --new ^ ---filter-tcp=443 --hostlist="%~dp0list-youtube.txt" --dpi-desync=fake,split2 --dpi-desync-autottl=2 --dpi-desync-fooling=md5sig --dpi-desync-fake-tls="%~dp0tls_clienthello_www_google_com.bin" --new ^ +--filter-tcp=443 --hostlist="%~dp0list-youtube.txt" --dpi-desync=fake,split2 --dpi-desync-repeats=11 --dpi-desync-autottl=2 --dpi-desync-fooling=md5sig --dpi-desync-fake-tls="%~dp0tls_clienthello_www_google_com.bin" --new ^ --dpi-desync=fake,disorder2 --dpi-desync-autottl=2 --dpi-desync-fooling=md5sig diff --git a/binaries/win64/zapret-winws/preset_russia_autohostlist.cmd b/binaries/win64/zapret-winws/preset_russia_autohostlist.cmd index b6d3b74..fd693eb 100644 --- a/binaries/win64/zapret-winws/preset_russia_autohostlist.cmd +++ b/binaries/win64/zapret-winws/preset_russia_autohostlist.cmd @@ -3,5 +3,5 @@ start "zapret: http,https,quic" /min "%~dp0winws.exe" ^ --filter-udp=443 --hostlist="%~dp0list-youtube.txt" --dpi-desync=fake --dpi-desync-repeats=11 --dpi-desync-fake-quic="%~dp0quic_initial_www_google_com.bin" --new ^ --filter-udp=443 --dpi-desync=fake --dpi-desync-repeats=11 --new ^ --filter-tcp=80 --dpi-desync=fake,split2 --dpi-desync-autottl=2 --dpi-desync-fooling=md5sig --hostlist-auto="%~dp0autohostlist.txt" --new ^ ---filter-tcp=443 --hostlist="%~dp0list-youtube.txt" --dpi-desync=fake,split2 --dpi-desync-autottl=2 --dpi-desync-fooling=md5sig --dpi-desync-fake-tls="%~dp0tls_clienthello_www_google_com.bin" --new ^ +--filter-tcp=443 --hostlist="%~dp0list-youtube.txt" --dpi-desync=fake,split2 --dpi-desync-repeats=11 --dpi-desync-autottl=2 --dpi-desync-fooling=md5sig --dpi-desync-fake-tls="%~dp0tls_clienthello_www_google_com.bin" --new ^ --dpi-desync=fake,disorder2 --dpi-desync-autottl=2 --dpi-desync-fooling=md5sig --hostlist-auto="%~dp0autohostlist.txt" diff --git a/blockcheck.sh b/blockcheck.sh index 39d84c3..eb91336 100755 --- a/blockcheck.sh +++ b/blockcheck.sh @@ -964,6 +964,8 @@ report_strategy() # $3 - daemon echo if [ -n "$strategy" ]; then + # trim spaces at the end + strategy="$(echo "$strategy" | xargs)" echo "!!!!! $1: working strategy found for ipv${IPV} $2 : $3 $strategy !!!!!" echo report_append "ipv${IPV} $2 $1 : $3 ${WF:+$WF }$strategy" @@ -1171,6 +1173,7 @@ pktws_check_domain_http_bypass() local strategy pktws_check_domain_http_bypass_ "$@" + strategy="${strategy:+$strategy $PKTWS_EXTRA $PKTWS_EXTRA_1 $PKTWS_EXTRA_2 $PKTWS_EXTRA_3 $PKTWS_EXTRA_4 $PKTWS_EXTRA_5 $PKTWS_EXTRA_6 $PKTWS_EXTRA_7 $PKTWS_EXTRA_8 $PKTWS_EXTRA_9}" report_strategy $1 $3 $PKTWSD } @@ -1215,6 +1218,7 @@ pktws_check_domain_http3_bypass() local strategy pktws_check_domain_http3_bypass_ "$@" + strategy="${strategy:+$strategy $PKTWS_EXTRA $PKTWS_EXTRA_1 $PKTWS_EXTRA_2 $PKTWS_EXTRA_3 $PKTWS_EXTRA_4 $PKTWS_EXTRA_5 $PKTWS_EXTRA_6 $PKTWS_EXTRA_7 $PKTWS_EXTRA_8 $PKTWS_EXTRA_9}" report_strategy $1 $2 $PKTWSD } warn_mss() @@ -1284,6 +1288,7 @@ tpws_check_domain_http_bypass() local strategy tpws_check_domain_http_bypass_ "$@" + strategy="${strategy:+$strategy $TPWS_EXTRA $TPWS_EXTRA_1 $TPWS_EXTRA_2 $TPWS_EXTRA_3 $TPWS_EXTRA_4 $TPWS_EXTRA_5 $TPWS_EXTRA_6 $TPWS_EXTRA_7 $TPWS_EXTRA_8 $TPWS_EXTRA_9}" report_strategy $1 $3 tpws } diff --git a/common/base.sh b/common/base.sh index 7c772ef..39a3872 100644 --- a/common/base.sh +++ b/common/base.sh @@ -329,6 +329,25 @@ win_process_exists() tasklist /NH /FI "IMAGENAME eq ${1}.exe" | grep -q "^${1}.exe" } +alloc_num() +{ + # $1 - source var name + # $2 - target var name + # $3 - min + # $4 - max + + local v + eval v="\$$2" + # do not replace existing value + [ -n "$v" ] && return + eval v="\$$1" + [ -n "$v" ] || v=$3 + eval $2="$v" + v=$((v + 1)) + [ $v -gt $4 ] && v=$3 + eval $1="$v" +} + std_ports() { HTTP_PORTS=${HTTP_PORTS:-80} diff --git a/common/custom.sh b/common/custom.sh new file mode 100644 index 0000000..752f7f0 --- /dev/null +++ b/common/custom.sh @@ -0,0 +1,43 @@ +custom_runner() +{ + # $1 - function name + # $2+ - params + + local n script FUNC=$1 + + shift + + [ -f "$CUSTOM_DIR/custom" ] && { + unset -f $FUNC + . "$CUSTOM_DIR/custom" + existf $FUNC && $FUNC "$@" + } + [ -d "$CUSTOM_DIR/custom.d" ] && { + n=$(ls "$CUSTOM_DIR/custom.d" | wc -c | xargs) + [ "$n" = 0 ] || { + for script in "$CUSTOM_DIR/custom.d/"*; do + [ -f "$script" ] || continue + unset -f $FUNC + . "$script" + existf $FUNC && $FUNC "$@" + done + } + } +} + +alloc_tpws_port() +{ + # $1 - target var name + alloc_num NUMPOOL_TPWS_PORT $1 910 979 +} +alloc_qnum() +{ + # $1 - target var name + alloc_num NUMPOOL_QNUM $1 65400 65499 +} +alloc_dnum() +{ + # alloc daemon number + # $1 - target var name + alloc_num NUMPOOL_DNUM $1 1000 1999 +} diff --git a/common/ipt.sh b/common/ipt.sh index ec5af86..8e82c65 100644 --- a/common/ipt.sh +++ b/common/ipt.sh @@ -3,15 +3,15 @@ readonly ipt_connbytes="-m connbytes --connbytes-dir=original --connbytes-mode=p ipt() { - iptables -C "$@" >/dev/null 2>/dev/null || iptables -I "$@" + iptables $FW_EXTRA_PRE -C "$@" $FW_EXTRA_POST >/dev/null 2>/dev/null || iptables $FW_EXTRA_PRE -I "$@" $FW_EXTRA_POST } ipta() { - iptables -C "$@" >/dev/null 2>/dev/null || iptables -A "$@" + iptables $FW_EXTRA_PRE -C "$@" $FW_EXTRA_POST >/dev/null 2>/dev/null || iptables $FW_EXTRA_PRE -A "$@" $FW_EXTRA_POST } ipt_del() { - iptables -C "$@" >/dev/null 2>/dev/null && iptables -D "$@" + iptables $FW_EXTRA_PRE -C "$@" $FW_EXTRA_POST >/dev/null 2>/dev/null && iptables $FW_EXTRA_PRE -D "$@" $FW_EXTRA_POST } ipt_add_del() { @@ -134,7 +134,7 @@ unprepare_tpws_fw() ipt_print_op() { if [ "$1" = "1" ]; then - echo "Adding ip$4tables rule for $3 : $2" + echo "Inserting ip$4tables rule for $3 : $2" else echo "Deleting ip$4tables rule for $3 : $2" fi @@ -437,7 +437,7 @@ zapret_do_firewall_rules_ipt() fi ;; custom) - existf zapret_custom_firewall && zapret_custom_firewall $1 + custom_runner zapret_custom_firewall $1 ;; esac } diff --git a/common/nft.sh b/common/nft.sh index aed2512..0179f82 100644 --- a/common/nft.sh +++ b/common/nft.sh @@ -199,7 +199,15 @@ nft_add_rule() # $2,$3,... - rule(s) local chain="$1" shift - nft add rule inet $ZAPRET_NFT_TABLE $chain "$@" + nft add rule inet $ZAPRET_NFT_TABLE $chain $FW_EXTRA_PRE "$@" +} +nft_insert_rule() +{ + # $1 - chain + # $2,$3,... - rule(s) + local chain="$1" + shift + nft insert rule inet $ZAPRET_NFT_TABLE $chain $FW_EXTRA_PRE "$@" } nft_add_set_element() { @@ -227,6 +235,7 @@ nft_clean_nfqws_rule() nft_add_nfqws_flow_exempt_rule() { # $1 - rule (must be all filters in one var) + local FW_EXTRA_POST= FW_EXTRA_PRE= nft_add_rule flow_offload $(nft_clean_nfqws_rule $1) return comment \"direct flow offloading exemption\" # do not need this because of oifname @wanif/@wanif6 filter in forward chain #nft_add_rule flow_offload $(nft_reverse_nfqws_rule $1) return comment \"reverse flow offloading exemption\" @@ -236,6 +245,7 @@ nft_add_flow_offload_exemption() # "$1" - rule for ipv4 # "$2" - rule for ipv6 # "$3" - comment + local FW_EXTRA_POST= FW_EXTRA_PRE= [ "$DISABLE_IPV4" = "1" -o -z "$1" ] || nft_add_rule flow_offload oifname @wanif $1 ip daddr != @nozapret return comment \"$3\" [ "$DISABLE_IPV6" = "1" -o -z "$2" ] || nft_add_rule flow_offload oifname @wanif6 $2 ip6 daddr != @nozapret6 return comment \"$3\" } @@ -399,7 +409,7 @@ nft_only() nft_print_op() { - echo "Adding nftables ipv$3 rule for $2 : $1" + echo "Inserting nftables ipv$3 rule for $2 : $1" } _nft_fw_tpws4() { @@ -410,8 +420,8 @@ _nft_fw_tpws4() [ "$DISABLE_IPV4" = "1" -o -z "$1" ] || { local filter="$1" port="$2" nft_print_op "$filter" "tpws (port $2)" 4 - nft_add_rule dnat_output skuid != $WS_USER ${3:+oifname @wanif }$filter ip daddr != @nozapret dnat ip to $TPWS_LOCALHOST4:$port - nft_add_rule dnat_pre iifname @lanif $filter ip daddr != @nozapret dnat ip to $TPWS_LOCALHOST4:$port + nft_insert_rule dnat_output skuid != $WS_USER ${3:+oifname @wanif }$filter ip daddr != @nozapret $FW_EXTRA_POST dnat ip to $TPWS_LOCALHOST4:$port + nft_insert_rule dnat_pre iifname @lanif $filter ip daddr != @nozapret $FW_EXTRA_POST dnat ip to $TPWS_LOCALHOST4:$port prepare_route_localnet } } @@ -425,9 +435,9 @@ _nft_fw_tpws6() [ "$DISABLE_IPV6" = "1" -o -z "$1" ] || { local filter="$1" port="$2" DNAT6 i nft_print_op "$filter" "tpws (port $port)" 6 - nft_add_rule dnat_output skuid != $WS_USER ${4:+oifname @wanif6 }$filter ip6 daddr != @nozapret6 dnat ip6 to [::1]:$port + nft_insert_rule dnat_output skuid != $WS_USER ${4:+oifname @wanif6 }$filter ip6 daddr != @nozapret6 $FW_EXTRA_POST dnat ip6 to [::1]:$port [ -n "$3" ] && { - nft_add_rule dnat_pre $filter ip6 daddr != @nozapret6 dnat ip6 to iifname map @link_local:$port + nft_insert_rule dnat_pre $filter ip6 daddr != @nozapret6 $FW_EXTRA_POST dnat ip6 to iifname map @link_local:$port for i in $3; do _dnat6_target $i DNAT6 # can be multiple tpws processes on different ports @@ -476,7 +486,7 @@ _nft_fw_nfqws_post4() nft_print_op "$filter" "nfqws postrouting (qnum $port)" 4 rule="${3:+oifname @wanif }$filter ip daddr != @nozapret" is_postnat && setmark="meta mark set meta mark or $DESYNC_MARK_POSTNAT" - nft_add_rule $chain $rule $setmark queue num $port bypass + nft_insert_rule $chain $rule $setmark $FW_EXTRA_POST queue num $port bypass nft_add_nfqws_flow_exempt_rule "$rule" } } @@ -491,7 +501,7 @@ _nft_fw_nfqws_post6() nft_print_op "$filter" "nfqws postrouting (qnum $port)" 6 rule="${3:+oifname @wanif6 }$filter ip6 daddr != @nozapret6" is_postnat && setmark="meta mark set meta mark or $DESYNC_MARK_POSTNAT" - nft_add_rule $chain $rule $setmark queue num $port bypass + nft_insert_rule $chain $rule $setmark $FW_EXTRA_POST queue num $port bypass nft_add_nfqws_flow_exempt_rule "$rule" } } @@ -515,7 +525,7 @@ _nft_fw_nfqws_pre4() local filter="$1" port="$2" rule nft_print_op "$filter" "nfqws prerouting (qnum $port)" 4 rule="${3:+iifname @wanif }$filter ip saddr != @nozapret" - nft_add_rule $(get_prechain) $rule queue num $port bypass + nft_insert_rule $(get_prechain) $rule $FW_EXTRA_POST queue num $port bypass } } _nft_fw_nfqws_pre6() @@ -528,7 +538,7 @@ _nft_fw_nfqws_pre6() local filter="$1" port="$2" rule nft_print_op "$filter" "nfqws prerouting (qnum $port)" 6 rule="${3:+iifname @wanif6 }$filter ip6 saddr != @nozapret6" - nft_add_rule $(get_prechain) $rule queue num $port bypass + nft_insert_rule $(get_prechain) $rule $FW_EXTRA_POST queue num $port bypass } } nft_fw_nfqws_pre() @@ -705,7 +715,7 @@ zapret_apply_firewall_rules_nft() POSTNAT=$POSTNAT_SAVE ;; custom) - existf zapret_custom_firewall_nft && zapret_custom_firewall_nft + custom_runner zapret_custom_firewall_nft ;; esac } @@ -734,6 +744,7 @@ zapret_unapply_firewall_nft() unprepare_route_localnet nft_del_firewall + [ "$MODE" = custom ] && custom_runner zapret_custom_firewall_nft_flush return 0 } zapret_do_firewall_nft() diff --git a/common/pf.sh b/common/pf.sh index a6fa57c..ed3945f 100644 --- a/common/pf.sh +++ b/common/pf.sh @@ -106,6 +106,12 @@ pf_anchor_zapret_tables() eval $tblv="\"\$_tbl\"" } +pf_nat_reorder_rules() +{ + # this is dirty hack to move rdr above route-to + # use only first word as a key and preserve order within a single key + sort -srfk 1,1 +} pf_anchor_port_target() { if [ "$MODE_HTTP" = "1" ] && [ "$MODE_HTTPS" = "1" ]; then @@ -119,9 +125,17 @@ pf_anchor_port_target() pf_anchor_zapret_v4_tpws() { - # $1 - port + # $1 - tpws listen port + # $2 - rdr ports. defaults are used if empty + + local rule port + + if [ -n "$2" ]; then + port="{$2}" + else + port=$(pf_anchor_port_target) + fi - local rule port=$(pf_anchor_port_target) for lan in $IFACE_LAN; do for t in $tbl; do echo "rdr on $lan inet proto tcp from any to $t port $port -> 127.0.0.1 port $1" @@ -144,7 +158,7 @@ pf_anchor_zapret_v4() { local tbl port [ "$DISABLE_IPV4" = "1" ] || { - case $MODE in + case "${MODE_OVERRIDE:-$MODE}" in tpws) [ ! "$MODE_HTTP" = "1" ] && [ ! "$MODE_HTTPS" = "1" ] && return pf_anchor_zapret_tables tbl zapret-user "$ZIPLIST_USER" zapret "$ZIPLIST" @@ -152,16 +166,24 @@ pf_anchor_zapret_v4() ;; custom) pf_anchor_zapret_tables tbl zapret-user "$ZIPLIST_USER" zapret "$ZIPLIST" - existf zapret_custom_firewall_v4 && zapret_custom_firewall_v4 + custom_runner zapret_custom_firewall_v4 | pf_nat_reorder_rules ;; esac } } pf_anchor_zapret_v6_tpws() { - # $1 - port + # $1 - tpws listen port + # $2 - rdr ports. defaults are used if empty + + local rule LL_LAN port + + if [ -n "$2" ]; then + port="{$2}" + else + port=$(pf_anchor_port_target) + fi - local LL_LAN rule port=$(pf_anchor_port_target) # LAN link local is only for router for lan in $IFACE_LAN; do LL_LAN=$(get_ipv6_linklocal $lan) @@ -188,7 +210,7 @@ pf_anchor_zapret_v6() local tbl port [ "$DISABLE_IPV6" = "1" ] || { - case $MODE in + case "${MODE_OVERRIDE:-$MODE}" in tpws) [ ! "$MODE_HTTP" = "1" ] && [ ! "$MODE_HTTPS" = "1" ] && return pf_anchor_zapret_tables tbl zapret6-user "$ZIPLIST_USER6" zapret6 "$ZIPLIST6" @@ -196,7 +218,7 @@ pf_anchor_zapret_v6() ;; custom) pf_anchor_zapret_tables tbl zapret6-user "$ZIPLIST_USER6" zapret6 "$ZIPLIST6" - existf zapret_custom_firewall_v6 && zapret_custom_firewall_v6 + custom_runner zapret_custom_firewall_v6 | pf_nat_reorder_rules ;; esac } diff --git a/docs/changes.txt b/docs/changes.txt index 51bf952..f5edfbf 100644 --- a/docs/changes.txt +++ b/docs/changes.txt @@ -317,3 +317,15 @@ nfqws: multi-strategy v63: tpws: multi-strategy + +v64: + +blockcheck: warn if dpi bypass software is already running +blockcheck: TPWS_EXTRA, NFQWS_EXTRA +init.d: multiple custom scripts + +v65: + +init.d: dynamic number allocation for dnum,tpws_port,qnum +init.d: FW_EXTRA_PRE, FW_EXTRA_POST +init.d: zapret_custom_firewall_nft_flush diff --git a/docs/nftables.txt b/docs/nftables.txt index 4acbb59..ae76105 100644 --- a/docs/nftables.txt +++ b/docs/nftables.txt @@ -19,8 +19,8 @@ For dpi desync attack : nft delete table inet ztest nft create table inet ztest nft add chain inet ztest post "{type filter hook postrouting priority mangle;}" -nft add rule inet ztest post tcp dport "{80,443}" ct original packets 1-12 queue num 200 bypass -nft add rule inet ztest post udp dport 443 ct original packets 1-4 queue num 200 bypass +nft add rule inet ztest post meta mark and 0x40000000 == 0 tcp dport "{80,443}" ct original packets 1-12 queue num 200 bypass +nft add rule inet ztest post meta mark and 0x40000000 == 0 udp dport 443 ct original packets 1-4 queue num 200 bypass # auto hostlist with avoiding wrong ACK numbers in RST,ACK packets sent by russian DPI sysctl net.netfilter.nf_conntrack_tcp_be_liberal=1 diff --git a/docs/readme.eng.md b/docs/readme.eng.md index 40f298e..f998942 100644 --- a/docs/readme.eng.md +++ b/docs/readme.eng.md @@ -97,7 +97,8 @@ Then we can reduce CPU load, refusing to process unnecessary packets. `iptables -t mangle -I POSTROUTING -o -p tcp --dport 80 -m connbytes --connbytes-dir=original --connbytes-mode=packets --connbytes 1:6 -m mark ! --mark 0x40000000/0x40000000 -m set --match-set zapret dst -j NFQUEUE --queue-num 200 --queue-bypass` Mark filter does not allow nfqws-generated packets to enter the queue again. -Its necessary to use this filter when also using `connbytes 1:6`. Without it packet ordering can be changed breaking the whole idea. +Its necessary to use this filter when also using `connbytes`. Without it packet ordering can be changed breaking the whole idea. +Also if there's huge packet send from nfqws it may deadlock without mark filter. Some attacks require redirection of incoming packets : diff --git a/docs/readme.txt b/docs/readme.txt index 93a462e..6fbc17e 100644 --- a/docs/readme.txt +++ b/docs/readme.txt @@ -1,4 +1,4 @@ -zapret v.63 +zapret v.64 English ------- @@ -464,8 +464,8 @@ mark нужен, чтобы сгенерированный поддельный чтобы не допустить изменения порядка следования пакетов. Процессинг очереди - процесс отложенный. Если ядро имеет пакеты на отсылку вне очереди - оно их отправляет незамедлительно. Изменение правильного порядка следования пакетов при десинхронизации ломает всю идею. -При отсутствии ограничения на connbytes, атака будет работать и без фильтра по mark. -Но лучше его все же оставить для увеличения скорости. +Так же были замечены дедлоки при достаточно большой отсылке пакетов из nfqws и отсутствии mark фильтра. +Процесс может зависнуть. Поэтому наличие фильтра по mark в ip/nf tables можно считать обязательным. Почему --connbytes 1:6 : 1 - для работы методов десинхронизации 0-й фазы и wssize @@ -981,10 +981,13 @@ Cкрипты с названием get_antifilter_* оперируют спис 9) ipset/get_antifilter_allyouneed.sh. получает лист https://antifilter.download/list/allyouneed.lst. Суммарный список префиксов, созданный из ipsum.lst и subnet.lst. -Все варианты рассмотренных скриптов автоматически создают и заполняют ipset. -Варианты 2-9 дополнительно вызывают вариант 1. +10) ipset/get_refilter_ipsum.sh. +Список берется отсюда : https://github.com/1andrevich/Re-filter-lists -10) ipset/get_config.sh. этот скрипт вызывает то, что прописано в переменной GETLIST из файла config +Все варианты рассмотренных скриптов автоматически создают и заполняют ipset. +Варианты 2-10 дополнительно вызывают вариант 1. + +11) ipset/get_config.sh. этот скрипт вызывает то, что прописано в переменной GETLIST из файла config Если переменная не определена, то ресолвятся лишь листы для ipset nozapret/nozapret6. Листы РКН все время изменяются. Возникают новые тенденции. Требования к RAM могут меняться. @@ -1111,7 +1114,11 @@ ipset/zapret-hosts-users-exclude.txt.gz или ipset/zapret-hosts-users-exclude. Поддомены учитываются автоматически. Например, строчка "ru" вносит в список "*.ru". Строчка "*.ru" в списке не сработает. -Список доменов РКН может быть получен скриптами ipset/get_reestr_hostlist.sh или ipset/get_antizapret_domains.sh +Список доменов РКН может быть получен скриптами +ipset/get_reestr_hostlist.sh +ipset/get_antizapret_domains.sh +ipset/get_reestr_resolvable_domains.sh +ipset/get_refilter_domains.sh - кладется в ipset/zapret-hosts.txt.gz. Чтобы обновить списки, перезапускать nfqws или tpws не нужно. Обновляете файлы, затем даете сигнал HUP. @@ -1572,35 +1579,76 @@ nfset-ы принадлежат только одной таблице, след Вариант custom -------------- -custom код вынесен в отдельный shell include +custom код вынесен в отдельные shell includes. +Поддерживается старый вариант в /opt/zapret/init.d/sysv/custom -или /opt/zapret/init.d/openwrt/custom +/opt/zapret/init.d/macos/custom +Он считается устаревшим. Актуальный вариант - помещать отдельные скрипты там же, но в директорию "custom.d". +Она будет просканирована стандартным образом, т.е. в алфавитном порядке, и каждый скрипт будет применен. +Рядом имеется "custom.d.examples". Это готовые скрипты, которые можно копировать в "custom.d". +Особо стоит отметить "10-inherit-*". Они наследуют стандартные режимы nfqws/tpws/tpws-socks. +Полезно, чтобы не писать код заново. Достаточно лишь скопировать соответствующий файл. +Можно наследовать и более сложным образом. +"10-inherit-tpws4http-nfqws4https" наследует для http tpws, а для https и quic - nfqws. -Нужно свой код вписать в функции : +Для linux пишется код в функции zapret_custom_daemons zapret_custom_firewall zapret_custom_firewall_nft +zapret_custom_firewall_nft_flush -В файле custom пишите ваш код, пользуясь хелперами из "functions" или "zapret". -Смотрите как там сделано добавление iptables или запуск демонов. +Для macos +zapret_custom_daemons +zapret_custom_firewall_v4 +zapret_custom_firewall_v6 + +zapret_custom_daemons поднимает демоны nfqws/tpws в нужном вам количестве и с нужными вам параметрами. +Для систем традиционного linux (sysv) и MacOS в первом параметре передается код операции : 1 = запуск, 0 = останов. +Для openwrt логика останова отсутствует за ненадобностью. +Схема запуска демонов в openwrt отличается - используется procd. + +zapret_custom_firewall поднимает и убирает правила iptables. +В первом параметре передается код операции : 1 = запуск, 0 = останов. + +zapret_custom_firewall_nft поднимает правила nftables. +Логика останова отсутствует за ненадобностью. Стандартные цепочки zapret удаляются автоматически. +Однако, sets и правила из ваших собственных цепочек не удаляются. +Их нужно подчистить в zapret_custom_firewall_nft_flush. +Если set-ов и собственных цепочек у вас нет, функцию можно не определять или оставить пустой. + +Если вам не нужны iptables или nftables - можете не писать соответствующую функцию. + +В linux можно использовать локальные переменные FW_EXTRA_PRE и FW_EXTRA_POST. +FW_EXTRA_PRE добавляет код к правилам ip/nf tables до кода, генерируемого функциями-хелперами. +FW_EXTRA_POST добавляет код после. + +В linux функции-хелперы добавляют правило в начало цепочек, то есть перед уже имеющимися. +Поэтому специализации должны идти после более общих вариантов. +Поэтому наследования идут с префиксом 10, а остальные custom скрипты с префиксом 50. +Допустим, у вас есть особые правила для IP подсети youtube. Порты те же самые. +Включен и общий обход. Чтобы youtube пошел приоритетом, скрипт должен применяться после +общего обхода. +Для macos правило обратное. Там правила добавляются в конец. Поэтому inherit скрипты +имеют префикс 90. + +В macos firewall-функции ничего сами никуда не заносят. Их задача - лишь выдать текст в stdout, +содержащий правила для pf-якоря. Остальное сделает обертка. + +Особо обратите внимание на номер демона в функциях "run_daemon" и "do_daemon", номера портов tpws +и очередей nfqueue. +Они должны быть уникальными во всех скриптах. При накладке будет ошибка. +Поэтому используйте функции динамического получения этих значений из пула. + +custom скрипты могут использовать переменные из config. Можно помещать в config свои переменные +и задействовать их в скриптах. +Можно использовать функции-хелперы. Они являются частью общего пространства функций shell. +Полезные функции можно взять из примеров скриптов. Так же смотрите "common/*.sh". Используя хелпер функции, вы избавитесь от необходимости учитывать все возможные случаи типа наличия/отсутствия ipv6, является ли система роутером, имена интерфейсов, ... Хелперы это учитывают, вам нужно сосредоточиться лишь на фильтрах {ip,nf}tables и параметрах демонов. -Код для openwrt и sysv немного отличается. В sysv нужно обрабатывать и запуск, и остановку демонов. -Запуск это или остановка передается в параметре $1 (0 или 1). -В openwrt за остановку отвечает procd. - -Для фаервола кастом пишется отдельно для iptables и nftables. Все очень похоже, но отличается -написание фильтров и названия процедур хелперов. Если вам не нужны iptables или nftables - -можете не писать соответствующую функцию. - -Готовый custom скрипт custom-tpws4http-nfqws4https позволяет применить дурение -tpws к http и nfqws к https. При этом поддерживаются установки из config. -Его можно использовать как стартовую точку для написания своих скриптов. - Простая установка ----------------- diff --git a/init.d/macos/custom-tpws b/init.d/macos/custom-tpws deleted file mode 100644 index 1f99a0e..0000000 --- a/init.d/macos/custom-tpws +++ /dev/null @@ -1,26 +0,0 @@ -# this script is an example describing how to run tpws on a custom port - -TPPORT_MY=987 - -zapret_custom_daemons() -{ - # $1 - 1 - run, 0 - stop - local opt="--user=root --port=$TPPORT_MY" - tpws_apply_binds opt - opt="$opt $TPWS_OPT" - filter_apply_hostlist_target opt - filter_apply_suffix opt "$TPWS_OPT_SUFFIX" - do_daemon $1 1 "$TPWS" "$opt" -} - -# custom firewall functions echo rules for zapret-v4 and zapret-v6 anchors -# they come after automated table definitions. so you can use ... - -zapret_custom_firewall_v4() -{ - pf_anchor_zapret_v4_tpws $TPPORT_MY -} -zapret_custom_firewall_v6() -{ - pf_anchor_zapret_v6_tpws $TPPORT_MY -} diff --git a/init.d/macos/custom.d.examples/50-extra-tpws b/init.d/macos/custom.d.examples/50-extra-tpws new file mode 100644 index 0000000..f968ee0 --- /dev/null +++ b/init.d/macos/custom.d.examples/50-extra-tpws @@ -0,0 +1,31 @@ +# this script is an example describing how to run tpws on a custom port + +TPWS_OPT_EXTRA=${TPWS_OPT_EXTRA:---split-pos=2} +TPWS_OPT_SUFFIX_EXTRA="${TPWS_OPT_SUFFIX_EXTRA:-}" +DPORTS_EXTRA=${DPORTS_EXTRA:-20443,20444,30000-30009} + +alloc_dnum DNUM_EXTRA_TPWS +alloc_tpws_port TPPORT_EXTRA_TPWS + +zapret_custom_daemons() +{ + # $1 - 1 - run, 0 - stop + local opt="--user=root --port=$TPPORT_EXTRA_TPWS" + tpws_apply_binds opt + opt="$opt $TPWS_OPT_EXTRA" + filter_apply_hostlist_target opt + filter_apply_suffix opt "$TPWS_OPT_SUFFIX_EXTRA" + do_daemon $1 $DNUM_EXTRA_TPWS "$TPWS" "$opt" +} + +# custom firewall functions echo rules for zapret-v4 and zapret-v6 anchors +# they come after automated table definitions. so you can use ... + +zapret_custom_firewall_v4() +{ + pf_anchor_zapret_v4_tpws $TPPORT_EXTRA_TPWS $(replace_char - : $DPORTS_EXTRA) +} +zapret_custom_firewall_v6() +{ + pf_anchor_zapret_v6_tpws $TPPORT_EXTRA_TPWS $(replace_char - : $DPORTS_EXTRA) +} diff --git a/init.d/macos/custom.d.examples/90-inherit-tpws b/init.d/macos/custom.d.examples/90-inherit-tpws new file mode 100644 index 0000000..a4c08c5 --- /dev/null +++ b/init.d/macos/custom.d.examples/90-inherit-tpws @@ -0,0 +1,18 @@ +# this custom script applies tpws mode as it would be with MODE=tpws + +OVERRIDE=tpws + +zapret_custom_daemons() +{ + # $1 - 1 - run, 0 - stop + + MODE_OVERRIDE=$OVERRIDE zapret_do_daemons $1 +} +zapret_custom_firewall_v4() +{ + MODE_OVERRIDE=$OVERRIDE pf_anchor_zapret_v4 +} +zapret_custom_firewall_v6() +{ + MODE_OVERRIDE=$OVERRIDE pf_anchor_zapret_v6 +} diff --git a/init.d/macos/custom.d.examples/90-inherit-tpws-socks b/init.d/macos/custom.d.examples/90-inherit-tpws-socks new file mode 100644 index 0000000..bdcda12 --- /dev/null +++ b/init.d/macos/custom.d.examples/90-inherit-tpws-socks @@ -0,0 +1,18 @@ +# this custom script applies tpws-socks mode as it would be with MODE=tpws-socks + +OVERRIDE=tpws-socks + +zapret_custom_daemons() +{ + # $1 - 1 - run, 0 - stop + + MODE_OVERRIDE=$OVERRIDE zapret_do_daemons $1 +} +zapret_custom_firewall_v4() +{ + MODE_OVERRIDE=$OVERRIDE pf_anchor_zapret_v4 +} +zapret_custom_firewall_v6() +{ + MODE_OVERRIDE=$OVERRIDE pf_anchor_zapret_v6 +} diff --git a/init.d/macos/custom.d/.keep b/init.d/macos/custom.d/.keep new file mode 100644 index 0000000..e69de29 diff --git a/init.d/macos/custom.default b/init.d/macos/custom.default deleted file mode 100644 index e00e1c8..0000000 --- a/init.d/macos/custom.default +++ /dev/null @@ -1,21 +0,0 @@ -# this script contain your special code to launch daemons and configure firewall -# use helpers from "functions" file -# in case of upgrade keep this file only, do not modify others - -zapret_custom_daemons() -{ - # $1 - 1 - run, 0 - stop - : -} - -# custom firewall functions echo rules for zapret-v4 and zapret-v6 anchors -# they come after automated table definitions. so you can use ... - -zapret_custom_firewall_v4() -{ - : -} -zapret_custom_firewall_v6() -{ - : -} diff --git a/init.d/macos/functions b/init.d/macos/functions index 4fb826f..d004dc2 100644 --- a/init.d/macos/functions +++ b/init.d/macos/functions @@ -7,6 +7,8 @@ ZAPRET_CONFIG=${ZAPRET_CONFIG:-"$ZAPRET_RW/config"} . "$ZAPRET_BASE/common/base.sh" . "$ZAPRET_BASE/common/pf.sh" . "$ZAPRET_BASE/common/list.sh" +. "$ZAPRET_BASE/common/custom.sh" +CUSTOM_DIR="$ZAPRET_RW/init.d/macos" IPSET_DIR=$ZAPRET_BASE/ipset . "$IPSET_DIR/def.sh" @@ -184,7 +186,7 @@ zapret_do_daemons() filter) ;; custom) - existf zapret_custom_daemons && zapret_custom_daemons $1 + custom_runner zapret_custom_daemons $1 ;; *) echo "unsupported MODE=$MODE" diff --git a/init.d/openwrt/custom-reuse-builtin-mode b/init.d/openwrt/custom-reuse-builtin-mode deleted file mode 100644 index 39c16e8..0000000 --- a/init.d/openwrt/custom-reuse-builtin-mode +++ /dev/null @@ -1,47 +0,0 @@ -# this custom script demonstrates how to reuse built-in modes and add something from yourself - -MY_TPPORT=$(($TPPORT + 1)) -MY_TPWS_OPT="--methodeol --hostcase" -MY_DPORT=81 - -zapret_custom_daemons() -{ - # stop logic is managed by procd - - local MODE_OVERRIDE=tpws - local opt - - start_daemons_procd - - opt="--port=$MY_TPPORT $MY_TPWS_OPT" - filter_apply_hostlist_target opt - run_tpws 100 "$opt" -} -zapret_custom_firewall() -{ - # $1 - 1 - run, 0 - stop - - local MODE_OVERRIDE=tpws - local f4 f6 - - zapret_do_firewall_rules_ipt $1 - - f4="-p tcp --dport $MY_DPORT" - f6=$f4 - filter_apply_ipset_target f4 f6 - fw_tpws $1 "$f4" "$f6" $MY_TPPORT -} -zapret_custom_firewall_nft() -{ - # stop logic is not required - - local MODE_OVERRIDE=tpws - local f4 f6 - - zapret_apply_firewall_rules_nft - - f4="tcp dport $MY_DPORT" - f6=$f4 - nft_filter_apply_ipset_target f4 f6 - nft_fw_tpws "$f4" "$f6" $MY_TPPORT -} diff --git a/init.d/openwrt/custom-tpws4http-nfqws4https b/init.d/openwrt/custom-tpws4http-nfqws4https deleted file mode 100644 index d777aa8..0000000 --- a/init.d/openwrt/custom-tpws4http-nfqws4https +++ /dev/null @@ -1,69 +0,0 @@ -# this custom script demonstrates how to apply tpws to http and nfqws to https -# it preserves config settings : MODE_HTTP, MODE_HTTPS, MODE_FILTER, TPWS_OPT, NFQWS_OPT_DESYNC, NFQWS_OPT_DESYNC_HTTPS - -zapret_custom_daemons() -{ - # stop logic is managed by procd - - local opt - - [ "$MODE_HTTP" = "1" ] && { - opt="--port=$TPPORT $TPWS_OPT" - filter_apply_hostlist_target opt - filter_apply_suffix opt "$TPWS_OPT_SUFFIX" - run_tpws 1 "$opt" - } - - [ "$MODE_HTTPS" = "1" ] && { - opt="--qnum=$QNUM $NFQWS_OPT_BASE $NFQWS_OPT_DESYNC_HTTPS" - filter_apply_hostlist_target opt - filter_apply_suffix opt "$NFQWS_OPT_DESYNC_HTTPS_SUFFIX" - run_daemon 2 $NFQWS "$opt" - } -} -zapret_custom_firewall() -{ - # $1 - 1 - run, 0 - stop - - local f4 f6 - local first_packet_only="$ipt_connbytes 1:$(first_packets_for_mode)" - local desync="-m mark ! --mark $DESYNC_MARK/$DESYNC_MARK" - - [ "$MODE_HTTP" = "1" ] && { - f4="-p tcp -m multiport --dports $HTTP_PORTS_IPT" - f6=$f4 - filter_apply_ipset_target f4 f6 - fw_tpws $1 "$f4" "$f6" $TPPORT - } - - [ "$MODE_HTTPS" = "1" ] && { - f4="-p tcp -m multiport --dports $HTTPS_PORTS_IPT $first_packet_only" - f6=$f4 - filter_apply_ipset_target f4 f6 - fw_nfqws_post $1 "$f4 $desync" "$f6 $desync" $QNUM - } -} -zapret_custom_firewall_nft() -{ - # stop logic is not required - - local f4 f6 - local first_packet_only="$nft_connbytes 1-$(first_packets_for_mode)" - local desync="mark and $DESYNC_MARK == 0" - - [ "$MODE_HTTP" = "1" ] && { - f4="tcp dport {$HTTP_PORTS}" - f6=$f4 - nft_filter_apply_ipset_target f4 f6 - nft_fw_tpws "$f4" "$f6" $TPPORT - } - - [ "$MODE_HTTPS" = "1" ] && { - f4="tcp dport {$HTTPS_PORTS} $first_packet_only" - f6=$f4 - nft_filter_apply_ipset_target f4 f6 - nft_fw_nfqws_post "$f4 $desync" "$f6 $desync" $QNUM - # for modes that require incoming traffic - nft_fw_reverse_nfqws_rule "$f4" "$f6" $QNUM - } -} diff --git a/init.d/openwrt/custom.d.examples/10-inherit-nfqws b/init.d/openwrt/custom.d.examples/10-inherit-nfqws new file mode 100644 index 0000000..b156402 --- /dev/null +++ b/init.d/openwrt/custom.d.examples/10-inherit-nfqws @@ -0,0 +1,22 @@ +# this custom script applies nfqws mode as it would be with MODE=nfqws + +OVERRIDE=nfqws + +zapret_custom_daemons() +{ + # stop logic is managed by procd + + MODE_OVERRIDE=$OVERRIDE start_daemons_procd +} +zapret_custom_firewall() +{ + # $1 - 1 - run, 0 - stop + + MODE_OVERRIDE=$OVERRIDE zapret_do_firewall_rules_ipt $1 +} +zapret_custom_firewall_nft() +{ + # stop logic is not required + + MODE_OVERRIDE=$OVERRIDE zapret_apply_firewall_rules_nft +} diff --git a/init.d/openwrt/custom.d.examples/10-inherit-tpws b/init.d/openwrt/custom.d.examples/10-inherit-tpws new file mode 100644 index 0000000..e9c5f69 --- /dev/null +++ b/init.d/openwrt/custom.d.examples/10-inherit-tpws @@ -0,0 +1,22 @@ +# this custom script applies tpws mode as it would be with MODE=tpws + +OVERRIDE=tpws + +zapret_custom_daemons() +{ + # stop logic is managed by procd + + MODE_OVERRIDE=$OVERRIDE start_daemons_procd +} +zapret_custom_firewall() +{ + # $1 - 1 - run, 0 - stop + + MODE_OVERRIDE=$OVERRIDE zapret_do_firewall_rules_ipt $1 +} +zapret_custom_firewall_nft() +{ + # stop logic is not required + + MODE_OVERRIDE=$OVERRIDE zapret_apply_firewall_rules_nft +} diff --git a/init.d/openwrt/custom.d.examples/10-inherit-tpws-socks b/init.d/openwrt/custom.d.examples/10-inherit-tpws-socks new file mode 100644 index 0000000..b4e686a --- /dev/null +++ b/init.d/openwrt/custom.d.examples/10-inherit-tpws-socks @@ -0,0 +1,22 @@ +# this custom script applies tpws-socks mode as it would be with MODE=tpws-socks + +OVERRIDE=tpws-socks + +zapret_custom_daemons() +{ + # stop logic is managed by procd + + MODE_OVERRIDE=$OVERRIDE start_daemons_procd +} +zapret_custom_firewall() +{ + # $1 - 1 - run, 0 - stop + + MODE_OVERRIDE=$OVERRIDE zapret_do_firewall_rules_ipt $1 +} +zapret_custom_firewall_nft() +{ + # stop logic is not required + + MODE_OVERRIDE=$OVERRIDE zapret_apply_firewall_rules_nft +} diff --git a/init.d/openwrt/custom.d.examples/10-inherit-tpws4http-nfqws4https b/init.d/openwrt/custom.d.examples/10-inherit-tpws4http-nfqws4https new file mode 100644 index 0000000..752b1a2 --- /dev/null +++ b/init.d/openwrt/custom.d.examples/10-inherit-tpws4http-nfqws4https @@ -0,0 +1,35 @@ +# this custom script demonstrates how to apply tpws to http and nfqws to https and quic +# it's desired that inherited basic rules are low priority to allow specializations and exceptions in other custom scripts + +nfqws_tpws_inheritor() +{ + # $1 - inherited function + # $2 - 1 - run, 0 - stop + + [ "$MODE_HTTP" = "1" ] && { + MODE_OVERRIDE=tpws MODE_HTTPS=0 MODE_QUIC=0 $1 $2 + } + + [ "$MODE_HTTPS" = "1" -o "$MODE_QUIC" = "1" ] && { + MODE_OVERRIDE=nfqws MODE_HTTP=0 $1 $2 + } +} + +zapret_custom_daemons() +{ + # stop logic is managed by procd + + nfqws_tpws_inheritor start_daemons_procd +} +zapret_custom_firewall() +{ + # $1 - 1 - run, 0 - stop + + nfqws_tpws_inheritor zapret_do_firewall_rules_ipt $1 +} +zapret_custom_firewall_nft() +{ + # stop logic is not required + + nfqws_tpws_inheritor zapret_apply_firewall_rules_nft +} diff --git a/init.d/openwrt/custom-nfqws-dht4all b/init.d/openwrt/custom.d.examples/50-dht4all similarity index 60% rename from init.d/openwrt/custom-nfqws-dht4all rename to init.d/openwrt/custom.d.examples/50-dht4all index 069aa4b..1c3c475 100644 --- a/init.d/openwrt/custom-nfqws-dht4all +++ b/init.d/openwrt/custom.d.examples/50-dht4all @@ -1,47 +1,38 @@ -# this custom script in addition to MODE=nfqws runs desync to DHT packets with udp payload length 101..399 , without ipset/hostlist filtering +# this custom script runs desync to DHT packets with udp payload length 101..399 , without ipset/hostlist filtering # need to add to config : NFQWS_OPT_DESYNC_DHT="--dpi-desync=fake --dpi-desync-ttl=5" -QNUM2=$(($QNUM+20)) +alloc_dnum DNUM_DHT4ALL +alloc_qnum QNUM_DHT4ALL zapret_custom_daemons() { # stop logic is managed by procd - local MODE_OVERRIDE=nfqws - local opt - - start_daemons_procd - - opt="--qnum=$QNUM2 $NFQWS_OPT_BASE $NFQWS_OPT_DESYNC_DHT" - run_daemon 100 $NFQWS "$opt" + local opt="--qnum=$QNUM_DHT4ALL $NFQWS_OPT_BASE $NFQWS_OPT_DESYNC_DHT" + run_daemon $DNUM_DHT4ALL $NFQWS "$opt" } zapret_custom_firewall() { # $1 - 1 - run, 0 - stop - local MODE_OVERRIDE=nfqws local f uf4 uf6 local first_packet_only="$ipt_connbytes 1:1" local desync="-m mark ! --mark $DESYNC_MARK/$DESYNC_MARK" - zapret_do_firewall_rules_ipt $1 - f='-p udp -m length --length 109:407 -m u32 --u32' uf4='0>>22&0x3C@8>>16=0x6431' uf6='48>>16=0x6431' - fw_nfqws_post $1 "$f $uf4 $desync $first_packet_only" "$f $uf6 $desync $first_packet_only" $QNUM2 + fw_nfqws_post $1 "$f $uf4 $desync $first_packet_only" "$f $uf6 $desync $first_packet_only" $QNUM_DHT4ALL + } zapret_custom_firewall_nft() { # stop logic is not required - local MODE_OVERRIDE=nfqws local f local first_packet_only="$nft_connbytes 1" local desync="mark and $DESYNC_MARK == 0" - zapret_apply_firewall_rules_nft - f="meta length 109-407 meta l4proto udp @th,64,16 0x6431" - nft_fw_nfqws_post "$f $desync $first_packet_only" "$f $desync $first_packet_only" $QNUM2 + nft_fw_nfqws_post "$f $desync $first_packet_only" "$f $desync $first_packet_only" $QNUM_DHT4ALL } diff --git a/init.d/openwrt/custom.d.examples/50-discord b/init.d/openwrt/custom.d.examples/50-discord new file mode 100644 index 0000000..dc04c03 --- /dev/null +++ b/init.d/openwrt/custom.d.examples/50-discord @@ -0,0 +1,77 @@ +# this custom script in addition to MODE=nfqws runs desync of some udp packets to discord subnets +# idea taken from community. not tested and not optimized by author. + +# can override in config : +NFQWS_OPT_DESYNC_DISCORD="${NFQWS_OPT_DESYNC_DISCORD:---dpi-desync=fake --dpi-desync-repeats=6 --dpi-desync-any-protocol}" +DISCORD_PORTS=${DISCORD_PORTS:-50000-50099} +DISCORD_SUBNETS="${DISCORD_SUBNETS:-5.200.14.249 18.165.140.0/25 23.227.38.74 34.0.48.0/24 34.0.49.64/26 34.0.50.0/25 34.0.51.0/24 34.0.52.0/22 34.0.56.0/23 34.0.59.0/24 34.0.60.0/24 34.0.62.128/25 34.0.63.228 34.0.64.0/23 34.0.66.130 34.0.82.140 34.0.129.128/25 34.0.130.0/24 34.0.131.130 34.0.132.139 34.0.133.75 34.0.134.0/24 34.0.135.251 34.0.136.51 34.0.137.0/24 34.0.139.0/24 34.0.140.0/23 34.0.142.0/25 34.0.144.0/23 34.0.146.0/24 34.0.148.25 34.0.149.101 34.0.151.0/25 34.0.153.0/24 34.0.155.0/24 34.0.156.101 34.0.157.0/25 34.0.158.247 34.0.159.188 34.0.192.0/25 34.0.193.0/24 34.0.194.0/24 34.0.195.172 34.0.196.200/29 34.0.197.81 34.0.198.25 34.0.199.0/24 34.0.200.0/24 34.0.201.81 34.0.202.34 34.0.203.0/24 34.0.204.0/23 34.0.206.0/25 34.0.207.0/25 34.0.208.195 34.0.209.0/24 34.0.210.20 34.0.211.0/26 34.0.212.0/24 34.0.213.64/26 34.0.215.128/25 34.0.216.238 34.0.217.0/24 34.0.218.83 34.0.220.103 34.0.221.0/24 34.0.222.193 34.0.223.68 34.0.227.0/24 34.0.240.0/21 34.0.248.0/23 34.0.250.0/24 34.0.251.0/25 34.1.216.0/24 34.1.221.166 35.207.64.0/23 35.207.67.116 35.207.71.0/24 35.207.72.32 35.207.73.0/24 35.207.74.0/24 35.207.75.128/25 35.207.76.128/26 35.207.77.0/24 35.207.78.129 35.207.79.0/24 35.207.80.76 35.207.81.248/30 35.207.82.0/23 35.207.84.0/24 35.207.85.160 35.207.86.41 35.207.87.184 35.207.89.188 35.207.91.146 35.207.92.230 35.207.95.0/24 35.207.97.174 35.207.99.134 35.207.100.64/26 35.207.101.130 35.207.103.64/26 35.207.104.0/24 35.207.106.128/26 35.207.107.19 35.207.108.192/27 35.207.109.185 35.207.110.0/24 35.207.111.174 35.207.114.16 35.207.115.163 35.207.116.51 35.207.117.0/24 35.207.121.204 35.207.122.0/25 35.207.124.145 35.207.125.116 35.207.126.30 35.207.129.0/24 35.207.131.128/27 35.207.132.247 35.207.135.147 35.207.136.69 35.207.137.0/24 35.207.139.0/24 35.207.140.241 35.207.141.119 35.207.142.0/24 35.207.143.96/27 35.207.144.0/25 35.207.145.0/24 35.207.146.89 35.207.147.0/24 35.207.149.0/24 35.207.150.0/24 35.207.151.61 35.207.153.117 35.207.154.0/24 35.207.155.128/25 35.207.156.254 35.207.157.7 35.207.158.192 35.207.160.160 35.207.162.239 35.207.163.0/24 35.207.164.0/25 35.207.165.147 35.207.166.0/25 35.207.167.0/24 35.207.168.116 35.207.170.0/23 35.207.172.0/24 35.207.174.55 35.207.176.128/25 35.207.178.0/24 35.207.180.152 35.207.181.76 35.207.182.125 35.207.184.101 35.207.185.192 35.207.186.128/25 35.207.187.228 35.207.188.0/24 35.207.189.0/25 35.207.190.194 35.207.191.64/26 35.207.193.165 35.207.195.75 35.207.196.0/24 35.207.198.0/23 35.207.201.186 35.207.202.169 35.207.205.211 35.207.207.4 35.207.209.0/25 35.207.210.191 35.207.211.253 35.207.213.97 35.207.214.0/24 35.207.220.147 35.207.221.58 35.207.222.105 35.207.224.151 35.207.225.210 35.207.227.0/24 35.207.229.212 35.207.232.26 35.207.234.182 35.207.238.0/24 35.207.240.0/24 35.207.245.0/24 35.207.249.0/24 35.207.250.212 35.207.251.0/27 35.212.4.134 35.212.12.148 35.212.88.11 35.212.102.50 35.212.111.0/26 35.212.117.247 35.212.120.122 35.213.0.0/24 35.213.2.8 35.213.4.185 35.213.6.118 35.213.7.128/25 35.213.8.168 35.213.10.0/24 35.213.11.21 35.213.12.224/27 35.213.13.19 35.213.14.217 35.213.16.67 35.213.17.235 35.213.23.166 35.213.25.164 35.213.26.62 35.213.27.252 35.213.32.0/24 35.213.33.74 35.213.34.204 35.213.37.81 35.213.38.186 35.213.39.253 35.213.42.0/24 35.213.43.79 35.213.45.0/24 35.213.46.136 35.213.49.17 35.213.50.0/24 35.213.51.213 35.213.52.0/25 35.213.53.0/24 35.213.54.0/24 35.213.56.0/25 35.213.59.0/24 35.213.61.58 35.213.65.0/24 35.213.67.0/24 35.213.68.192/26 35.213.70.151 35.213.72.128/25 35.213.73.245 35.213.74.131 35.213.78.0/24 35.213.79.137 35.213.80.0/25 35.213.83.128/25 35.213.84.245 35.213.85.0/24 35.213.88.145 35.213.89.80/28 35.213.90.0/24 35.213.91.195 35.213.92.0/24 35.213.93.254 35.213.94.78 35.213.95.145 35.213.96.87 35.213.98.0/24 35.213.99.126 35.213.101.214 35.213.102.0/24 35.213.105.0/24 35.213.106.128/25 35.213.107.158 35.213.109.0/24 35.213.110.40 35.213.111.0/25 35.213.115.0/25 35.213.120.0/24 35.213.122.0/24 35.213.124.89 35.213.125.40 35.213.126.185 35.213.127.0/24 35.213.128.0/22 35.213.132.0/23 35.213.134.140 35.213.135.0/24 35.213.136.0/23 35.213.138.128/25 35.213.139.0/24 35.213.140.0/25 35.213.141.164 35.213.142.128/25 35.213.143.0/24 35.213.144.0/22 35.213.148.0/23 35.213.150.0/24 35.213.152.0/23 35.213.154.137 35.213.155.134 35.213.156.144 35.213.157.0/24 35.213.158.64/26 35.213.160.90 35.213.161.253 35.213.162.0/25 35.213.163.0/24 35.213.164.0/23 35.213.166.106 35.213.167.160/27 35.213.168.0/24 35.213.169.179 35.213.170.0/24 35.213.171.201 35.213.172.159 35.213.173.0/24 35.213.174.128/25 35.213.175.128/26 35.213.176.0/24 35.213.177.0/25 35.213.179.139 35.213.180.0/24 35.213.181.0/25 35.213.182.0/23 35.213.184.0/23 35.213.186.70 35.213.187.0/24 35.213.188.128/25 35.213.190.158 35.213.191.0/24 35.213.192.240/31 35.213.193.74 35.213.194.0/25 35.213.195.178 35.213.196.38 35.213.197.68 35.213.198.0/23 35.213.200.0/23 35.213.202.0/25 35.213.203.195 35.213.204.32/27 35.213.205.170 35.213.207.128/25 35.213.208.85 35.213.210.0/24 35.213.211.176/29 35.213.212.0/24 35.213.213.225 35.213.214.0/25 35.213.215.255 35.213.217.0/24 35.213.218.248 35.213.219.0/25 35.213.220.211 35.213.221.0/24 35.213.222.215 35.213.223.0/24 35.213.225.0/24 35.213.227.227 35.213.229.17 35.213.230.89 35.213.231.0/24 35.213.233.0/24 35.213.234.134 35.213.236.0/24 35.213.237.212 35.213.238.0/24 35.213.240.212 35.213.241.0/24 35.213.242.10 35.213.243.219 35.213.244.146 35.213.245.119 35.213.246.0/23 35.213.249.79 35.213.250.0/24 35.213.251.74 35.213.252.0/24 35.213.253.155 35.213.254.89 35.214.128.248 35.214.129.220 35.214.130.217 35.214.131.144 35.214.132.189 35.214.133.0/24 35.214.134.163 35.214.137.0/24 35.214.138.0/25 35.214.140.0/24 35.214.142.0/24 35.214.143.41 35.214.144.26 35.214.145.200 35.214.146.9 35.214.147.135 35.214.148.89 35.214.149.110 35.214.151.128/25 35.214.152.0/24 35.214.156.115 35.214.158.181 35.214.159.128/25 35.214.160.128/25 35.214.161.217 35.214.162.0/24 35.214.163.28 35.214.165.102 35.214.167.77 35.214.169.0/24 35.214.170.2 35.214.171.0/25 35.214.172.128/25 35.214.173.0/24 35.214.175.0/24 35.214.177.183 35.214.179.46 35.214.180.0/23 35.214.184.179 35.214.185.28 35.214.186.3 35.214.187.0/24 35.214.191.0/24 35.214.192.128/25 35.214.193.0/24 35.214.194.128/25 35.214.195.0/25 35.214.196.64/26 35.214.197.0/24 35.214.198.7 35.214.199.224 35.214.201.0/25 35.214.203.155 35.214.204.0/23 35.214.207.0/24 35.214.208.128/25 35.214.209.64 35.214.210.0/24 35.214.211.3 35.214.212.64/26 35.214.213.0/25 35.214.214.0/24 35.214.215.64/26 35.214.216.0/23 35.214.218.140 35.214.219.0/24 35.214.220.149 35.214.221.0/24 35.214.222.149 35.214.223.0/24 35.214.224.71 35.214.225.0/24 35.214.226.0/23 35.214.228.0/23 35.214.231.187 35.214.233.8 35.214.235.38 35.214.237.0/24 35.214.238.0/25 35.214.239.0/24 35.214.240.87 35.214.241.0/24 35.214.243.21 35.214.244.0/24 35.214.245.16/28 35.214.246.106 35.214.248.119 35.214.249.154 35.214.250.0/24 35.214.251.128/25 35.214.252.187 35.214.253.0/24 35.214.255.154 35.215.72.85 35.215.73.65 35.215.83.0 35.215.108.111 35.215.115.120 35.215.126.35 35.215.127.34 35.215.128.0/21 35.215.136.0/26 35.215.137.0/24 35.215.138.0/23 35.215.140.0/24 35.215.141.64/27 35.215.142.0/24 35.215.143.83 35.215.144.128/25 35.215.145.0/24 35.215.146.0/24 35.215.147.86 35.215.148.0/23 35.215.150.0/26 35.215.151.0/24 35.215.152.0/24 35.215.153.128/25 35.215.154.240/28 35.215.155.20 35.215.156.0/24 35.215.158.0/23 35.215.160.192/26 35.215.161.0/24 35.215.163.0/24 35.215.164.0/24 35.215.165.236 35.215.166.128/25 35.215.167.128/25 35.215.168.0/24 35.215.169.12 35.215.170.0/23 35.215.172.0/22 35.215.176.0/24 35.215.177.72 35.215.178.0/24 35.215.179.161 35.215.180.0/22 35.215.184.253 35.215.185.64/26 35.215.186.0/25 35.215.187.0/24 35.215.188.0/23 35.215.190.0/24 35.215.191.61 35.215.192.0/23 35.215.194.192/28 35.215.195.0/24 35.215.196.0/25 35.215.197.0/25 35.215.198.230 35.215.199.204 35.215.200.0/23 35.215.202.0/24 35.215.203.0/25 35.215.204.128/25 35.215.205.0/25 35.215.206.0/23 35.215.208.0/24 35.215.209.0/25 35.215.210.0/23 35.215.212.0/22 35.215.216.0/22 35.215.221.0/24 35.215.222.128/25 35.215.223.126 35.215.224.0/23 35.215.226.0/24 35.215.227.0/25 35.215.228.0/24 35.215.229.64 35.215.230.89 35.215.231.0/24 35.215.232.0/24 35.215.233.0/25 35.215.234.37 35.215.235.0/24 35.215.238.0/25 35.215.239.119 35.215.240.0/24 35.215.241.128/25 35.215.242.0/25 35.215.243.0/24 35.215.244.0/23 35.215.246.222 35.215.247.0/24 35.215.248.0/22 35.215.252.0/24 35.215.253.118 35.215.254.0/23 35.217.0.0/24 35.217.1.64/26 35.217.2.5 35.217.3.0/24 35.217.4.72 35.217.5.0/25 35.217.6.0/24 35.217.8.0/25 35.217.9.0/24 35.217.11.186 35.217.12.0/24 35.217.14.192/26 35.217.15.65 35.217.16.75 35.217.17.128/25 35.217.18.0/24 35.217.19.183 35.217.20.0/24 35.217.21.128/25 35.217.22.128/25 35.217.23.128/25 35.217.24.0/24 35.217.25.81 35.217.26.0/24 35.217.27.128/25 35.217.28.128/25 35.217.29.0/24 35.217.30.0/25 35.217.31.0/25 35.217.32.128/25 35.217.33.0/24 35.217.35.128/25 35.217.36.0/23 35.217.38.179 35.217.39.186 35.217.40.176 35.217.41.204 35.217.43.0/24 35.217.45.248 35.217.46.0/24 35.217.47.128/25 35.217.48.195 35.217.49.160/27 35.217.50.0/25 35.217.51.0/24 35.217.52.117 35.217.53.128/25 35.217.54.0/25 35.217.55.96/27 35.217.56.6 35.217.57.184 35.217.58.0/24 35.217.59.64/26 35.217.60.0/24 35.217.61.128/25 35.217.62.0/24 35.217.63.128/25 35.219.225.149 35.219.226.57 35.219.227.0/24 35.219.228.37 35.219.229.128/25 35.219.230.0/23 35.219.235.0/24 35.219.236.198 35.219.238.115 35.219.239.0/24 35.219.241.0/24 35.219.242.221 35.219.243.191 35.219.244.1 35.219.245.0/24 35.219.246.159 35.219.247.0/26 35.219.248.0/24 35.219.249.126 35.219.251.186 35.219.252.0/23 35.219.254.0/24 64.233.161.207 64.233.162.207 64.233.163.207 64.233.164.207 64.233.165.207 66.22.196.0/26 66.22.197.0/24 66.22.198.0/26 66.22.199.0/24 66.22.200.0/26 66.22.202.0/26 66.22.204.0/24 66.22.206.0/24 66.22.208.0/25 66.22.210.0/26 66.22.212.0/24 66.22.214.0/24 66.22.216.0/23 66.22.220.0/25 66.22.221.0/24 66.22.222.0/23 66.22.224.0/25 66.22.225.0/26 66.22.226.0/25 66.22.227.0/25 66.22.228.0/22 66.22.233.0/24 66.22.234.0/24 66.22.236.0/23 66.22.238.0/24 66.22.240.0/22 66.22.244.0/23 66.22.248.0/24 74.125.131.207 74.125.205.207 104.17.51.93 104.17.117.93 104.18.4.161 104.18.5.161 104.18.8.105 104.18.9.105 104.18.30.128 104.18.31.128 104.21.2.204 104.21.25.51 104.21.40.151 104.21.59.128 104.21.72.221 104.21.82.160 108.177.14.207 138.128.140.240/28 142.250.150.207 142.251.1.207 162.159.128.232/30 162.159.129.232/30 162.159.130.232/30 162.159.133.232/30 162.159.134.232/30 162.159.135.232/30 162.159.136.232/30 162.159.137.232/30 162.159.138.232/30 172.65.202.19 172.66.41.34 172.66.42.222 172.67.152.224/28 172.67.155.163 172.67.159.89 172.67.177.131 172.67.222.182 173.194.73.207 173.194.220.207 173.194.221.207 173.194.222.207 188.114.96.2 188.114.97.2 188.114.98.224 188.114.99.224 204.11.56.48 209.85.233.207}" + +DISCORD_SET_NAME=discord +alloc_dnum DNUM_DISCORD +alloc_qnum QNUM_DISCORD + +zapret_custom_daemons() +{ + # $1 - 1 - run, 0 - stop + + local opt="--qnum=$QNUM_DISCORD $NFQWS_OPT_BASE $NFQWS_OPT_DESYNC_DISCORD" + run_daemon $DNUM_DISCORD $NFQWS "$opt" +} + +zapret_custom_firewall() +{ + # $1 - 1 - run, 0 - stop + + local f + local first_packets_only="$ipt_connbytes 1:1" + local desync="-m mark ! --mark $DESYNC_MARK/$DESYNC_MARK" + local DISCORD_PORTS_IPT=$(replace_char - : $DISCORD_PORTS) + local dest_set="-m set --match-set $DISCORD_SET_NAME dst" + local subnet + + local DISABLE_IPV6=1 + + [ "$1" = 1 ] && { + ipset create $DISCORD_SET_NAME hash:net hashsize 8192 maxelem 4096 2>/dev/null + ipset flush $DISCORD_SET_NAME + for subnet in $DISCORD_SUBNETS; do + echo add $DISCORD_SET_NAME $subnet + done | ipset -! restore + } + + f="-p udp -m multiport --dports $DISCORD_PORTS_IPT" + fw_nfqws_post $1 "$f $desync $first_packets_only $dest_set" "" $QNUM_DISCORD + + [ "$1" = 1 ] || { + ipset destroy $DISCORD_SET_NAME 2>/dev/null + } +} + +zapret_custom_firewall_nft() +{ + # stop logic is not required + + local f + local first_packets_only="$nft_connbytes 1" + local desync="mark and $DESYNC_MARK == 0" + local dest_set="ip daddr @$DISCORD_SET_NAME" + local subnets + + local DISABLE_IPV6=1 + + make_comma_list subnets $DISCORD_SUBNETS + nft_create_set $DISCORD_SET_NAME "type ipv4_addr; size 4096; auto-merge; flags interval;" + nft_flush_set $DISCORD_SET_NAME + nft_add_set_element $DISCORD_SET_NAME "$subnets" + + f="udp dport {$DISCORD_PORTS}" + nft_fw_nfqws_post "$f $desync $first_packets_only $dest_set" "" $QNUM_DISCORD +} + +zapret_custom_firewall_nft_flush() +{ + # this function is called after all nft fw rules are deleted + # however sets are not deleted. it's desired to clear sets here. + + nft_del_set $DISCORD_SET_NAME 2>/dev/null +} diff --git a/init.d/sysv/custom-nfqws-quic4all b/init.d/openwrt/custom.d.examples/50-quic4all similarity index 62% rename from init.d/sysv/custom-nfqws-quic4all rename to init.d/openwrt/custom.d.examples/50-quic4all index 37303b4..75f83df 100644 --- a/init.d/sysv/custom-nfqws-quic4all +++ b/init.d/openwrt/custom.d.examples/50-quic4all @@ -1,47 +1,37 @@ -# this custom script in addition to MODE=nfqws runs desync to all QUIC initial packets, without ipset/hostlist filtering +# this custom script runs desync to all QUIC initial packets, without ipset/hostlist filtering # need to add to config : NFQWS_OPT_DESYNC_QUIC="--dpi-desync=fake" # NOTE : do not use TTL fooling. chromium QUIC engine breaks sessions if TTL expired in transit received -QNUM2=$(($QNUM+10)) +alloc_dnum DNUM_QUIC4ALL +alloc_qnum QNUM_QUIC4ALL zapret_custom_daemons() { # $1 - 1 - run, 0 - stop - local MODE_OVERRIDE=nfqws - local opt - - zapret_do_daemons $1 - - opt="--qnum=$QNUM2 $NFQWS_OPT_BASE $NFQWS_OPT_DESYNC_QUIC" - do_nfqws $1 100 "$opt" + local opt="--qnum=$QNUM_QUIC4ALL $NFQWS_OPT_BASE $NFQWS_OPT_DESYNC_QUIC" + run_daemon $DNUM_QUIC4ALL $NFQWS "$opt" } zapret_custom_firewall() { # $1 - 1 - run, 0 - stop - local MODE_OVERRIDE=nfqws local f local first_packets_only="$ipt_connbytes 1:3" local desync="-m mark ! --mark $DESYNC_MARK/$DESYNC_MARK" - zapret_do_firewall_rules_ipt $1 - f="-p udp -m multiport --dports $QUIC_PORTS_IPT" - fw_nfqws_post $1 "$f $desync $first_packets_only" "$f $desync $first_packets_only" $QNUM2 + fw_nfqws_post $1 "$f $desync $first_packets_only" "$f $desync $first_packets_only" $QNUM_QUIC4ALL } zapret_custom_firewall_nft() { # stop logic is not required - local MODE_OVERRIDE=nfqws local f local first_packets_only="$nft_connbytes 1-3" local desync="mark and $DESYNC_MARK == 0" - zapret_apply_firewall_rules_nft - f="udp dport {$QUIC_PORTS}" - nft_fw_nfqws_post "$f $desync $first_packets_only" "$f $desync $first_packets_only" $QNUM2 + nft_fw_nfqws_post "$f $desync $first_packets_only" "$f $desync $first_packets_only" $QNUM_QUIC4ALL } diff --git a/init.d/openwrt/custom.d/.keep b/init.d/openwrt/custom.d/.keep new file mode 100644 index 0000000..e69de29 diff --git a/init.d/openwrt/custom.default b/init.d/openwrt/custom.default deleted file mode 100644 index 508013e..0000000 --- a/init.d/openwrt/custom.default +++ /dev/null @@ -1,33 +0,0 @@ -# this script contain your special code to launch daemons and configure firewall -# use helpers from "functions" file and "zapret" init script -# in case of upgrade keep this file only, do not modify others - -zapret_custom_daemons() -{ - # stop logic is managed by procd - - # PLACEHOLDER - echo !!! NEED ATTENTION !!! - echo Start daemon\(s\) - echo Study how other sections work - - run_daemon 1 /bin/sleep 20 -} -zapret_custom_firewall() -{ - # $1 - 1 - run, 0 - stop - - # PLACEHOLDER - echo !!! NEED ATTENTION !!! - echo Configure iptables for required actions - echo Study how other sections work -} -zapret_custom_firewall_nft() -{ - # stop logic is not required - - # PLACEHOLDER - echo !!! NEED ATTENTION !!! - echo Configure nftables for required actions - echo Study how other sections work -} diff --git a/init.d/openwrt/functions b/init.d/openwrt/functions index c46d866..3c1e8d0 100644 --- a/init.d/openwrt/functions +++ b/init.d/openwrt/functions @@ -12,6 +12,8 @@ ZAPRET_CONFIG=${ZAPRET_CONFIG:-"$ZAPRET_RW/config"} . "$ZAPRET_BASE/common/nft.sh" . "$ZAPRET_BASE/common/linux_fw.sh" . "$ZAPRET_BASE/common/list.sh" +. "$ZAPRET_BASE/common/custom.sh" +CUSTOM_DIR="$ZAPRET_RW/init.d/openwrt" [ -n "$QNUM" ] || QNUM=200 [ -n "$TPPORT" ] || TPPORT=988 @@ -27,9 +29,6 @@ LINKLOCAL_WAIT_SEC=5 IPSET_CR="$ZAPRET_BASE/ipset/create_ipset.sh" -CUSTOM_SCRIPT="$ZAPRET_BASE/init.d/openwrt/custom" -[ -f "$CUSTOM_SCRIPT" ] && . "$CUSTOM_SCRIPT" - IPSET_EXCLUDE="-m set ! --match-set nozapret" IPSET_EXCLUDE6="-m set ! --match-set nozapret6" diff --git a/init.d/openwrt/zapret b/init.d/openwrt/zapret index 46cd10b..c62760d 100755 --- a/init.d/openwrt/zapret +++ b/init.d/openwrt/zapret @@ -173,7 +173,7 @@ start_daemons_procd() } ;; custom) - existf zapret_custom_daemons && zapret_custom_daemons $1 + custom_runner zapret_custom_daemons $1 ;; esac diff --git a/init.d/sysv/custom-reuse-builtin-mode b/init.d/sysv/custom-reuse-builtin-mode deleted file mode 100644 index b36ac58..0000000 --- a/init.d/sysv/custom-reuse-builtin-mode +++ /dev/null @@ -1,47 +0,0 @@ -# this custom script demonstrates how to reuse built-in modes and add something from yourself - -MY_TPPORT=$(($TPPORT + 1)) -MY_TPWS_OPT="--methodeol --hostcase" -MY_DPORT=81 - -zapret_custom_daemons() -{ - # $1 - 1 - run, 0 - stop - - local MODE_OVERRIDE=tpws - local opt - - zapret_do_daemons $1 - - opt="--port=$MY_TPPORT $MY_TPWS_OPT" - filter_apply_hostlist_target opt - do_tpws $1 100 "$opt" -} -zapret_custom_firewall() -{ - # $1 - 1 - run, 0 - stop - - local MODE_OVERRIDE=tpws - local f4 f6 - - zapret_do_firewall_rules_ipt $1 - - f4="-p tcp --dport $MY_DPORT" - f6=$f4 - filter_apply_ipset_target f4 f6 - fw_tpws $1 "$f4" "$f6" $MY_TPPORT -} -zapret_custom_firewall_nft() -{ - # stop logic is not required - - local MODE_OVERRIDE=tpws - local f4 f6 - - zapret_apply_firewall_rules_nft - - f4="tcp dport $MY_DPORT" - f6=$f4 - nft_filter_apply_ipset_target f4 f6 - nft_fw_tpws "$f4" "$f6" $MY_TPPORT -} diff --git a/init.d/sysv/custom-tpws4http-nfqws4https b/init.d/sysv/custom-tpws4http-nfqws4https deleted file mode 100644 index 95042c0..0000000 --- a/init.d/sysv/custom-tpws4http-nfqws4https +++ /dev/null @@ -1,71 +0,0 @@ -# this custom script demonstrates how to apply tpws to http and nfqws to https -# it preserves config settings : MODE_HTTP, MODE_HTTPS, MODE_FILTER, TPWS_OPT, NFQWS_OPT_DESYNC, NFQWS_OPT_DESYNC_HTTPS - -zapret_custom_daemons() -{ - # $1 - 1 - run, 0 - stop - - local opt - - [ "$MODE_HTTP" = "1" ] && { - opt="--port=$TPPORT $TPWS_OPT" - filter_apply_hostlist_target opt - filter_apply_suffix opt "$TPWS_OPT_SUFFIX" - do_tpws $1 1 "$opt" - } - - [ "$MODE_HTTPS" = "1" ] && { - opt="--qnum=$QNUM $NFQWS_OPT_DESYNC_HTTPS" - filter_apply_hostlist_target opt - filter_apply_suffix opt "$NFQWS_OPT_DESYNC_HTTPS_SUFFIX" - do_nfqws $1 2 "$opt" - } -} -zapret_custom_firewall() -{ - # $1 - 1 - run, 0 - stop - - local f4 f6 - local first_packet_only="$ipt_connbytes 1:$(first_packets_for_mode)" - local desync="-m mark ! --mark $DESYNC_MARK/$DESYNC_MARK" - - [ "$MODE_HTTP" = "1" ] && { - f4="-p tcp -m multiport --dports $HTTP_PORTS_IPT" - f6=$f4 - filter_apply_ipset_target f4 f6 - fw_tpws $1 "$f4" "$f6" $TPPORT - } - - [ "$MODE_HTTPS" = "1" ] && { - f4="-p tcp -m multiport --dports $HTTPS_PORTS_IPT $first_packet_only" - f6=$f4 - filter_apply_ipset_target f4 f6 - fw_nfqws_post $1 "$f4 $desync" "$f6 $desync" $QNUM - # for modes that require incoming traffic - fw_reverse_nfqws_rule $1 "$f4" "$f6" $QNUM - } -} -zapret_custom_firewall_nft() -{ - # stop logic is not required - - local f4 f6 - local first_packet_only="$nft_connbytes 1-$(first_packets_for_mode)" - local desync="mark and $DESYNC_MARK == 0" - - [ "$MODE_HTTP" = "1" ] && { - f4="tcp dport {$HTTP_PORTS}" - f6=$f4 - nft_filter_apply_ipset_target f4 f6 - nft_fw_tpws "$f4" "$f6" $TPPORT - } - - [ "$MODE_HTTPS" = "1" ] && { - f4="tcp dport {$HTTPS_PORTS} $first_packet_only" - f6=$f4 - nft_filter_apply_ipset_target f4 f6 - nft_fw_nfqws_post "$f4 $desync" "$f6 $desync" $QNUM - # for modes that require incoming traffic - nft_fw_reverse_nfqws_rule "$f4" "$f6" $QNUM - } -} diff --git a/init.d/sysv/custom.d.examples/10-inherit-nfqws b/init.d/sysv/custom.d.examples/10-inherit-nfqws new file mode 100644 index 0000000..6002969 --- /dev/null +++ b/init.d/sysv/custom.d.examples/10-inherit-nfqws @@ -0,0 +1,22 @@ +# this custom script applies nfqws mode as it would be with MODE=nfqws + +OVERRIDE=nfqws + +zapret_custom_daemons() +{ + # $1 - 1 - run, 0 - stop + + MODE_OVERRIDE=$OVERRIDE zapret_do_daemons $1 +} +zapret_custom_firewall() +{ + # $1 - 1 - run, 0 - stop + + MODE_OVERRIDE=$OVERRIDE zapret_do_firewall_rules_ipt $1 +} +zapret_custom_firewall_nft() +{ + # stop logic is not required + + MODE_OVERRIDE=$OVERRIDE zapret_apply_firewall_rules_nft +} diff --git a/init.d/sysv/custom.d.examples/10-inherit-tpws b/init.d/sysv/custom.d.examples/10-inherit-tpws new file mode 100644 index 0000000..c1b183e --- /dev/null +++ b/init.d/sysv/custom.d.examples/10-inherit-tpws @@ -0,0 +1,22 @@ +# this custom script applies tpws mode as it would be with MODE=tpws + +OVERRIDE=tpws + +zapret_custom_daemons() +{ + # $1 - 1 - run, 0 - stop + + MODE_OVERRIDE=$OVERRIDE zapret_do_daemons $1 +} +zapret_custom_firewall() +{ + # $1 - 1 - run, 0 - stop + + MODE_OVERRIDE=$OVERRIDE zapret_do_firewall_rules_ipt $1 +} +zapret_custom_firewall_nft() +{ + # stop logic is not required + + MODE_OVERRIDE=$OVERRIDE zapret_apply_firewall_rules_nft +} diff --git a/init.d/sysv/custom.d.examples/10-inherit-tpws-socks b/init.d/sysv/custom.d.examples/10-inherit-tpws-socks new file mode 100644 index 0000000..7fcb0e2 --- /dev/null +++ b/init.d/sysv/custom.d.examples/10-inherit-tpws-socks @@ -0,0 +1,22 @@ +# this custom script applies tpws-socks mode as it would be with MODE=tpws-socks + +OVERRIDE=tpws-socks + +zapret_custom_daemons() +{ + # $1 - 1 - run, 0 - stop + + MODE_OVERRIDE=$OVERRIDE zapret_do_daemons $1 +} +zapret_custom_firewall() +{ + # $1 - 1 - run, 0 - stop + + MODE_OVERRIDE=$OVERRIDE zapret_do_firewall_rules_ipt $1 +} +zapret_custom_firewall_nft() +{ + # stop logic is not required + + MODE_OVERRIDE=$OVERRIDE zapret_apply_firewall_rules_nft +} diff --git a/init.d/sysv/custom.d.examples/10-inherit-tpws4http-nfqws4https b/init.d/sysv/custom.d.examples/10-inherit-tpws4http-nfqws4https new file mode 100644 index 0000000..f05d75e --- /dev/null +++ b/init.d/sysv/custom.d.examples/10-inherit-tpws4http-nfqws4https @@ -0,0 +1,35 @@ +# this custom script demonstrates how to apply tpws to http and nfqws to https and quic +# it's desired that inherited basic rules are low priority to allow specializations and exceptions in other custom scripts + +nfqws_tpws_inheritor() +{ + # $1 - inherited function + # $2 - 1 - run, 0 - stop + + [ "$MODE_HTTP" = "1" ] && { + MODE_OVERRIDE=tpws MODE_HTTPS=0 MODE_QUIC=0 $1 $2 + } + + [ "$MODE_HTTPS" = "1" -o "$MODE_QUIC" = "1" ] && { + MODE_OVERRIDE=nfqws MODE_HTTP=0 $1 $2 + } +} + +zapret_custom_daemons() +{ + # $1 - 1 - run, 0 - stop + + nfqws_tpws_inheritor zapret_do_daemons $1 +} +zapret_custom_firewall() +{ + # $1 - 1 - run, 0 - stop + + nfqws_tpws_inheritor zapret_do_firewall_rules_ipt $1 +} +zapret_custom_firewall_nft() +{ + # stop logic is not required + + nfqws_tpws_inheritor zapret_apply_firewall_rules_nft +} diff --git a/init.d/sysv/custom-nfqws-dht4all b/init.d/sysv/custom.d.examples/50-dht4all similarity index 60% rename from init.d/sysv/custom-nfqws-dht4all rename to init.d/sysv/custom.d.examples/50-dht4all index dbc9a3a..c67404a 100644 --- a/init.d/sysv/custom-nfqws-dht4all +++ b/init.d/sysv/custom.d.examples/50-dht4all @@ -1,49 +1,39 @@ -# this custom script in addition to MODE=nfqws runs desync to DHT packets with udp payload length 101..399 , without ipset/hostlist filtering +# this custom script runs desync to DHT packets with udp payload length 101..399 , without ipset/hostlist filtering # need to add to config : NFQWS_OPT_DESYNC_DHT="--dpi-desync=fake --dpi-desync-ttl=5" -QNUM2=$(($QNUM+20)) +alloc_dnum DNUM_DHT4ALL +alloc_qnum QNUM_DHT4ALL zapret_custom_daemons() { # stop logic is managed by procd - local MODE_OVERRIDE=nfqws - local opt - - zapret_do_daemons $1 - - opt="--qnum=$QNUM2 $NFQWS_OPT_BASE $NFQWS_OPT_DESYNC_DHT" - do_nfqws $1 100 "$opt" + local opt="--qnum=$QNUM_DHT4ALL $NFQWS_OPT_BASE $NFQWS_OPT_DESYNC_DHT" + do_nfqws $1 $DNUM_DHT4ALL "$opt" } zapret_custom_firewall() { # $1 - 1 - run, 0 - stop - local MODE_OVERRIDE=nfqws local f uf4 uf6 local first_packet_only="$ipt_connbytes 1:1" local desync="-m mark ! --mark $DESYNC_MARK/$DESYNC_MARK" - zapret_do_firewall_rules_ipt $1 - f='-p udp -m length --length 109:407 -m u32 --u32' uf4='0>>22&0x3C@8>>16=0x6431' uf6='48>>16=0x6431' - fw_nfqws_post $1 "$f $uf4 $desync $first_packet_only" "$f $uf6 $desync $first_packet_only" $QNUM2 + fw_nfqws_post $1 "$f $uf4 $desync $first_packet_only" "$f $uf6 $desync $first_packet_only" $QNUM_DHT4ALL } zapret_custom_firewall_nft() { # stop logic is not required - local MODE_OVERRIDE=nfqws local f local first_packet_only="$nft_connbytes 1" local desync="mark and $DESYNC_MARK == 0" - zapret_apply_firewall_rules_nft - f="meta length 109-407 meta l4proto udp @th,64,16 0x6431" - nft_fw_nfqws_post "$f $desync $first_packet_only" "$f $desync $first_packet_only" $QNUM2 + nft_fw_nfqws_post "$f $desync $first_packet_only" "$f $desync $first_packet_only" $QNUM_DHT4ALL } diff --git a/init.d/sysv/custom.d.examples/50-discord b/init.d/sysv/custom.d.examples/50-discord new file mode 100644 index 0000000..edb685a --- /dev/null +++ b/init.d/sysv/custom.d.examples/50-discord @@ -0,0 +1,77 @@ +# this custom script in addition to MODE=nfqws runs desync of some udp packets to discord subnets +# idea taken from community. not tested and not optimized by author. + +# can override in config : +NFQWS_OPT_DESYNC_DISCORD="${NFQWS_OPT_DESYNC_DISCORD:---dpi-desync=fake --dpi-desync-repeats=6 --dpi-desync-any-protocol}" +DISCORD_PORTS=${DISCORD_PORTS:-50000-50099} +DISCORD_SUBNETS="${DISCORD_SUBNETS:-5.200.14.249 18.165.140.0/25 23.227.38.74 34.0.48.0/24 34.0.49.64/26 34.0.50.0/25 34.0.51.0/24 34.0.52.0/22 34.0.56.0/23 34.0.59.0/24 34.0.60.0/24 34.0.62.128/25 34.0.63.228 34.0.64.0/23 34.0.66.130 34.0.82.140 34.0.129.128/25 34.0.130.0/24 34.0.131.130 34.0.132.139 34.0.133.75 34.0.134.0/24 34.0.135.251 34.0.136.51 34.0.137.0/24 34.0.139.0/24 34.0.140.0/23 34.0.142.0/25 34.0.144.0/23 34.0.146.0/24 34.0.148.25 34.0.149.101 34.0.151.0/25 34.0.153.0/24 34.0.155.0/24 34.0.156.101 34.0.157.0/25 34.0.158.247 34.0.159.188 34.0.192.0/25 34.0.193.0/24 34.0.194.0/24 34.0.195.172 34.0.196.200/29 34.0.197.81 34.0.198.25 34.0.199.0/24 34.0.200.0/24 34.0.201.81 34.0.202.34 34.0.203.0/24 34.0.204.0/23 34.0.206.0/25 34.0.207.0/25 34.0.208.195 34.0.209.0/24 34.0.210.20 34.0.211.0/26 34.0.212.0/24 34.0.213.64/26 34.0.215.128/25 34.0.216.238 34.0.217.0/24 34.0.218.83 34.0.220.103 34.0.221.0/24 34.0.222.193 34.0.223.68 34.0.227.0/24 34.0.240.0/21 34.0.248.0/23 34.0.250.0/24 34.0.251.0/25 34.1.216.0/24 34.1.221.166 35.207.64.0/23 35.207.67.116 35.207.71.0/24 35.207.72.32 35.207.73.0/24 35.207.74.0/24 35.207.75.128/25 35.207.76.128/26 35.207.77.0/24 35.207.78.129 35.207.79.0/24 35.207.80.76 35.207.81.248/30 35.207.82.0/23 35.207.84.0/24 35.207.85.160 35.207.86.41 35.207.87.184 35.207.89.188 35.207.91.146 35.207.92.230 35.207.95.0/24 35.207.97.174 35.207.99.134 35.207.100.64/26 35.207.101.130 35.207.103.64/26 35.207.104.0/24 35.207.106.128/26 35.207.107.19 35.207.108.192/27 35.207.109.185 35.207.110.0/24 35.207.111.174 35.207.114.16 35.207.115.163 35.207.116.51 35.207.117.0/24 35.207.121.204 35.207.122.0/25 35.207.124.145 35.207.125.116 35.207.126.30 35.207.129.0/24 35.207.131.128/27 35.207.132.247 35.207.135.147 35.207.136.69 35.207.137.0/24 35.207.139.0/24 35.207.140.241 35.207.141.119 35.207.142.0/24 35.207.143.96/27 35.207.144.0/25 35.207.145.0/24 35.207.146.89 35.207.147.0/24 35.207.149.0/24 35.207.150.0/24 35.207.151.61 35.207.153.117 35.207.154.0/24 35.207.155.128/25 35.207.156.254 35.207.157.7 35.207.158.192 35.207.160.160 35.207.162.239 35.207.163.0/24 35.207.164.0/25 35.207.165.147 35.207.166.0/25 35.207.167.0/24 35.207.168.116 35.207.170.0/23 35.207.172.0/24 35.207.174.55 35.207.176.128/25 35.207.178.0/24 35.207.180.152 35.207.181.76 35.207.182.125 35.207.184.101 35.207.185.192 35.207.186.128/25 35.207.187.228 35.207.188.0/24 35.207.189.0/25 35.207.190.194 35.207.191.64/26 35.207.193.165 35.207.195.75 35.207.196.0/24 35.207.198.0/23 35.207.201.186 35.207.202.169 35.207.205.211 35.207.207.4 35.207.209.0/25 35.207.210.191 35.207.211.253 35.207.213.97 35.207.214.0/24 35.207.220.147 35.207.221.58 35.207.222.105 35.207.224.151 35.207.225.210 35.207.227.0/24 35.207.229.212 35.207.232.26 35.207.234.182 35.207.238.0/24 35.207.240.0/24 35.207.245.0/24 35.207.249.0/24 35.207.250.212 35.207.251.0/27 35.212.4.134 35.212.12.148 35.212.88.11 35.212.102.50 35.212.111.0/26 35.212.117.247 35.212.120.122 35.213.0.0/24 35.213.2.8 35.213.4.185 35.213.6.118 35.213.7.128/25 35.213.8.168 35.213.10.0/24 35.213.11.21 35.213.12.224/27 35.213.13.19 35.213.14.217 35.213.16.67 35.213.17.235 35.213.23.166 35.213.25.164 35.213.26.62 35.213.27.252 35.213.32.0/24 35.213.33.74 35.213.34.204 35.213.37.81 35.213.38.186 35.213.39.253 35.213.42.0/24 35.213.43.79 35.213.45.0/24 35.213.46.136 35.213.49.17 35.213.50.0/24 35.213.51.213 35.213.52.0/25 35.213.53.0/24 35.213.54.0/24 35.213.56.0/25 35.213.59.0/24 35.213.61.58 35.213.65.0/24 35.213.67.0/24 35.213.68.192/26 35.213.70.151 35.213.72.128/25 35.213.73.245 35.213.74.131 35.213.78.0/24 35.213.79.137 35.213.80.0/25 35.213.83.128/25 35.213.84.245 35.213.85.0/24 35.213.88.145 35.213.89.80/28 35.213.90.0/24 35.213.91.195 35.213.92.0/24 35.213.93.254 35.213.94.78 35.213.95.145 35.213.96.87 35.213.98.0/24 35.213.99.126 35.213.101.214 35.213.102.0/24 35.213.105.0/24 35.213.106.128/25 35.213.107.158 35.213.109.0/24 35.213.110.40 35.213.111.0/25 35.213.115.0/25 35.213.120.0/24 35.213.122.0/24 35.213.124.89 35.213.125.40 35.213.126.185 35.213.127.0/24 35.213.128.0/22 35.213.132.0/23 35.213.134.140 35.213.135.0/24 35.213.136.0/23 35.213.138.128/25 35.213.139.0/24 35.213.140.0/25 35.213.141.164 35.213.142.128/25 35.213.143.0/24 35.213.144.0/22 35.213.148.0/23 35.213.150.0/24 35.213.152.0/23 35.213.154.137 35.213.155.134 35.213.156.144 35.213.157.0/24 35.213.158.64/26 35.213.160.90 35.213.161.253 35.213.162.0/25 35.213.163.0/24 35.213.164.0/23 35.213.166.106 35.213.167.160/27 35.213.168.0/24 35.213.169.179 35.213.170.0/24 35.213.171.201 35.213.172.159 35.213.173.0/24 35.213.174.128/25 35.213.175.128/26 35.213.176.0/24 35.213.177.0/25 35.213.179.139 35.213.180.0/24 35.213.181.0/25 35.213.182.0/23 35.213.184.0/23 35.213.186.70 35.213.187.0/24 35.213.188.128/25 35.213.190.158 35.213.191.0/24 35.213.192.240/31 35.213.193.74 35.213.194.0/25 35.213.195.178 35.213.196.38 35.213.197.68 35.213.198.0/23 35.213.200.0/23 35.213.202.0/25 35.213.203.195 35.213.204.32/27 35.213.205.170 35.213.207.128/25 35.213.208.85 35.213.210.0/24 35.213.211.176/29 35.213.212.0/24 35.213.213.225 35.213.214.0/25 35.213.215.255 35.213.217.0/24 35.213.218.248 35.213.219.0/25 35.213.220.211 35.213.221.0/24 35.213.222.215 35.213.223.0/24 35.213.225.0/24 35.213.227.227 35.213.229.17 35.213.230.89 35.213.231.0/24 35.213.233.0/24 35.213.234.134 35.213.236.0/24 35.213.237.212 35.213.238.0/24 35.213.240.212 35.213.241.0/24 35.213.242.10 35.213.243.219 35.213.244.146 35.213.245.119 35.213.246.0/23 35.213.249.79 35.213.250.0/24 35.213.251.74 35.213.252.0/24 35.213.253.155 35.213.254.89 35.214.128.248 35.214.129.220 35.214.130.217 35.214.131.144 35.214.132.189 35.214.133.0/24 35.214.134.163 35.214.137.0/24 35.214.138.0/25 35.214.140.0/24 35.214.142.0/24 35.214.143.41 35.214.144.26 35.214.145.200 35.214.146.9 35.214.147.135 35.214.148.89 35.214.149.110 35.214.151.128/25 35.214.152.0/24 35.214.156.115 35.214.158.181 35.214.159.128/25 35.214.160.128/25 35.214.161.217 35.214.162.0/24 35.214.163.28 35.214.165.102 35.214.167.77 35.214.169.0/24 35.214.170.2 35.214.171.0/25 35.214.172.128/25 35.214.173.0/24 35.214.175.0/24 35.214.177.183 35.214.179.46 35.214.180.0/23 35.214.184.179 35.214.185.28 35.214.186.3 35.214.187.0/24 35.214.191.0/24 35.214.192.128/25 35.214.193.0/24 35.214.194.128/25 35.214.195.0/25 35.214.196.64/26 35.214.197.0/24 35.214.198.7 35.214.199.224 35.214.201.0/25 35.214.203.155 35.214.204.0/23 35.214.207.0/24 35.214.208.128/25 35.214.209.64 35.214.210.0/24 35.214.211.3 35.214.212.64/26 35.214.213.0/25 35.214.214.0/24 35.214.215.64/26 35.214.216.0/23 35.214.218.140 35.214.219.0/24 35.214.220.149 35.214.221.0/24 35.214.222.149 35.214.223.0/24 35.214.224.71 35.214.225.0/24 35.214.226.0/23 35.214.228.0/23 35.214.231.187 35.214.233.8 35.214.235.38 35.214.237.0/24 35.214.238.0/25 35.214.239.0/24 35.214.240.87 35.214.241.0/24 35.214.243.21 35.214.244.0/24 35.214.245.16/28 35.214.246.106 35.214.248.119 35.214.249.154 35.214.250.0/24 35.214.251.128/25 35.214.252.187 35.214.253.0/24 35.214.255.154 35.215.72.85 35.215.73.65 35.215.83.0 35.215.108.111 35.215.115.120 35.215.126.35 35.215.127.34 35.215.128.0/21 35.215.136.0/26 35.215.137.0/24 35.215.138.0/23 35.215.140.0/24 35.215.141.64/27 35.215.142.0/24 35.215.143.83 35.215.144.128/25 35.215.145.0/24 35.215.146.0/24 35.215.147.86 35.215.148.0/23 35.215.150.0/26 35.215.151.0/24 35.215.152.0/24 35.215.153.128/25 35.215.154.240/28 35.215.155.20 35.215.156.0/24 35.215.158.0/23 35.215.160.192/26 35.215.161.0/24 35.215.163.0/24 35.215.164.0/24 35.215.165.236 35.215.166.128/25 35.215.167.128/25 35.215.168.0/24 35.215.169.12 35.215.170.0/23 35.215.172.0/22 35.215.176.0/24 35.215.177.72 35.215.178.0/24 35.215.179.161 35.215.180.0/22 35.215.184.253 35.215.185.64/26 35.215.186.0/25 35.215.187.0/24 35.215.188.0/23 35.215.190.0/24 35.215.191.61 35.215.192.0/23 35.215.194.192/28 35.215.195.0/24 35.215.196.0/25 35.215.197.0/25 35.215.198.230 35.215.199.204 35.215.200.0/23 35.215.202.0/24 35.215.203.0/25 35.215.204.128/25 35.215.205.0/25 35.215.206.0/23 35.215.208.0/24 35.215.209.0/25 35.215.210.0/23 35.215.212.0/22 35.215.216.0/22 35.215.221.0/24 35.215.222.128/25 35.215.223.126 35.215.224.0/23 35.215.226.0/24 35.215.227.0/25 35.215.228.0/24 35.215.229.64 35.215.230.89 35.215.231.0/24 35.215.232.0/24 35.215.233.0/25 35.215.234.37 35.215.235.0/24 35.215.238.0/25 35.215.239.119 35.215.240.0/24 35.215.241.128/25 35.215.242.0/25 35.215.243.0/24 35.215.244.0/23 35.215.246.222 35.215.247.0/24 35.215.248.0/22 35.215.252.0/24 35.215.253.118 35.215.254.0/23 35.217.0.0/24 35.217.1.64/26 35.217.2.5 35.217.3.0/24 35.217.4.72 35.217.5.0/25 35.217.6.0/24 35.217.8.0/25 35.217.9.0/24 35.217.11.186 35.217.12.0/24 35.217.14.192/26 35.217.15.65 35.217.16.75 35.217.17.128/25 35.217.18.0/24 35.217.19.183 35.217.20.0/24 35.217.21.128/25 35.217.22.128/25 35.217.23.128/25 35.217.24.0/24 35.217.25.81 35.217.26.0/24 35.217.27.128/25 35.217.28.128/25 35.217.29.0/24 35.217.30.0/25 35.217.31.0/25 35.217.32.128/25 35.217.33.0/24 35.217.35.128/25 35.217.36.0/23 35.217.38.179 35.217.39.186 35.217.40.176 35.217.41.204 35.217.43.0/24 35.217.45.248 35.217.46.0/24 35.217.47.128/25 35.217.48.195 35.217.49.160/27 35.217.50.0/25 35.217.51.0/24 35.217.52.117 35.217.53.128/25 35.217.54.0/25 35.217.55.96/27 35.217.56.6 35.217.57.184 35.217.58.0/24 35.217.59.64/26 35.217.60.0/24 35.217.61.128/25 35.217.62.0/24 35.217.63.128/25 35.219.225.149 35.219.226.57 35.219.227.0/24 35.219.228.37 35.219.229.128/25 35.219.230.0/23 35.219.235.0/24 35.219.236.198 35.219.238.115 35.219.239.0/24 35.219.241.0/24 35.219.242.221 35.219.243.191 35.219.244.1 35.219.245.0/24 35.219.246.159 35.219.247.0/26 35.219.248.0/24 35.219.249.126 35.219.251.186 35.219.252.0/23 35.219.254.0/24 64.233.161.207 64.233.162.207 64.233.163.207 64.233.164.207 64.233.165.207 66.22.196.0/26 66.22.197.0/24 66.22.198.0/26 66.22.199.0/24 66.22.200.0/26 66.22.202.0/26 66.22.204.0/24 66.22.206.0/24 66.22.208.0/25 66.22.210.0/26 66.22.212.0/24 66.22.214.0/24 66.22.216.0/23 66.22.220.0/25 66.22.221.0/24 66.22.222.0/23 66.22.224.0/25 66.22.225.0/26 66.22.226.0/25 66.22.227.0/25 66.22.228.0/22 66.22.233.0/24 66.22.234.0/24 66.22.236.0/23 66.22.238.0/24 66.22.240.0/22 66.22.244.0/23 66.22.248.0/24 74.125.131.207 74.125.205.207 104.17.51.93 104.17.117.93 104.18.4.161 104.18.5.161 104.18.8.105 104.18.9.105 104.18.30.128 104.18.31.128 104.21.2.204 104.21.25.51 104.21.40.151 104.21.59.128 104.21.72.221 104.21.82.160 108.177.14.207 138.128.140.240/28 142.250.150.207 142.251.1.207 162.159.128.232/30 162.159.129.232/30 162.159.130.232/30 162.159.133.232/30 162.159.134.232/30 162.159.135.232/30 162.159.136.232/30 162.159.137.232/30 162.159.138.232/30 172.65.202.19 172.66.41.34 172.66.42.222 172.67.152.224/28 172.67.155.163 172.67.159.89 172.67.177.131 172.67.222.182 173.194.73.207 173.194.220.207 173.194.221.207 173.194.222.207 188.114.96.2 188.114.97.2 188.114.98.224 188.114.99.224 204.11.56.48 209.85.233.207}" + +alloc_dnum DNUM_DISCORD +alloc_qnum QNUM_DISCORD +DISCORD_SET_NAME=discord + +zapret_custom_daemons() +{ + # $1 - 1 - run, 0 - stop + + local opt="--qnum=$QNUM_DISCORD $NFQWS_OPT_BASE $NFQWS_OPT_DESYNC_DISCORD" + do_nfqws $1 $DNUM_DISCORD "$opt" +} + +zapret_custom_firewall() +{ + # $1 - 1 - run, 0 - stop + + local f + local first_packets_only="$ipt_connbytes 1:1" + local desync="-m mark ! --mark $DESYNC_MARK/$DESYNC_MARK" + local DISCORD_PORTS_IPT=$(replace_char - : $DISCORD_PORTS) + local dest_set="-m set --match-set $DISCORD_SET_NAME dst" + local subnet + + local DISABLE_IPV6=1 + + [ "$1" = 1 ] && { + ipset create $DISCORD_SET_NAME hash:net hashsize 8192 maxelem 4096 2>/dev/null + ipset flush $DISCORD_SET_NAME + for subnet in $DISCORD_SUBNETS; do + echo add $DISCORD_SET_NAME $subnet + done | ipset -! restore + } + + f="-p udp -m multiport --dports $DISCORD_PORTS_IPT" + fw_nfqws_post $1 "$f $desync $first_packets_only $dest_set" "" $QNUM_DISCORD + + [ "$1" = 1 ] || { + ipset destroy $DISCORD_SET_NAME 2>/dev/null + } +} + +zapret_custom_firewall_nft() +{ + # stop logic is not required + + local f + local first_packets_only="$nft_connbytes 1" + local desync="mark and $DESYNC_MARK == 0" + local dest_set="ip daddr @$DISCORD_SET_NAME" + local subnets + + local DISABLE_IPV6=1 + + make_comma_list subnets $DISCORD_SUBNETS + nft_create_set $DISCORD_SET_NAME "type ipv4_addr; size 4096; auto-merge; flags interval;" + nft_flush_set $DISCORD_SET_NAME + nft_add_set_element $DISCORD_SET_NAME "$subnets" + + f="udp dport {$DISCORD_PORTS}" + nft_fw_nfqws_post "$f $desync $first_packets_only $dest_set" "" $QNUM_DISCORD +} + +zapret_custom_firewall_nft_flush() +{ + # this function is called after all nft fw rules are deleted + # however sets are not deleted. it's desired to clear sets here. + + nft_del_set $DISCORD_SET_NAME 2>/dev/null +} diff --git a/init.d/openwrt/custom-nfqws-quic4all b/init.d/sysv/custom.d.examples/50-quic4all similarity index 59% rename from init.d/openwrt/custom-nfqws-quic4all rename to init.d/sysv/custom.d.examples/50-quic4all index 26dfcc7..efd9031 100644 --- a/init.d/openwrt/custom-nfqws-quic4all +++ b/init.d/sysv/custom.d.examples/50-quic4all @@ -1,47 +1,37 @@ -# this custom script in addition to MODE=nfqws runs desync to all QUIC initial packets, without ipset/hostlist filtering +# this custom script runs desync to all QUIC initial packets, without ipset/hostlist filtering # need to add to config : NFQWS_OPT_DESYNC_QUIC="--dpi-desync=fake" # NOTE : do not use TTL fooling. chromium QUIC engine breaks sessions if TTL expired in transit received -QNUM2=$(($QNUM+10)) +alloc_dnum DNUM_QUIC4ALL +alloc_qnum QNUM_QUIC4ALL zapret_custom_daemons() { - # stop logic is managed by procd + # $1 - 1 - run, 0 - stop - local MODE_OVERRIDE=nfqws - local opt - - start_daemons_procd - - opt="--qnum=$QNUM2 $NFQWS_OPT_BASE $NFQWS_OPT_DESYNC_QUIC" - run_daemon 100 $NFQWS "$opt" + local opt="--qnum=$QNUM_QUIC4ALL $NFQWS_OPT_BASE $NFQWS_OPT_DESYNC_QUIC" + do_nfqws $1 $DNUM_QUIC4ALL "$opt" } zapret_custom_firewall() { # $1 - 1 - run, 0 - stop - local MODE_OVERRIDE=nfqws local f local first_packets_only="$ipt_connbytes 1:3" local desync="-m mark ! --mark $DESYNC_MARK/$DESYNC_MARK" - zapret_do_firewall_rules_ipt $1 - f="-p udp -m multiport --dports $QUIC_PORTS_IPT" - fw_nfqws_post $1 "$f $desync $first_packets_only" "$f $desync $first_packets_only" $QNUM2 + fw_nfqws_post $1 "$f $desync $first_packets_only" "$f $desync $first_packets_only" $QNUM_QUIC4ALL } zapret_custom_firewall_nft() { # stop logic is not required - local MODE_OVERRIDE=nfqws local f local first_packets_only="$nft_connbytes 1-3" local desync="mark and $DESYNC_MARK == 0" - zapret_apply_firewall_rules_nft - f="udp dport {$QUIC_PORTS}" - nft_fw_nfqws_post "$f $desync $first_packets_only" "$f $desync $first_packets_only" $QNUM2 + nft_fw_nfqws_post "$f $desync $first_packets_only" "$f $desync $first_packets_only" $QNUM_QUIC4ALL } diff --git a/init.d/sysv/custom.d/.keep b/init.d/sysv/custom.d/.keep new file mode 100644 index 0000000..e69de29 diff --git a/init.d/sysv/custom.default b/init.d/sysv/custom.default deleted file mode 100644 index 666d2d4..0000000 --- a/init.d/sysv/custom.default +++ /dev/null @@ -1,34 +0,0 @@ -# this script contain your special code to launch daemons and configure firewall -# use helpers from "functions" file -# in case of upgrade keep this file only, do not modify others - -zapret_custom_daemons() -{ - # $1 - 1 - run, 0 - stop - - # PLACEHOLDER - echo !!! NEED ATTENTION !!! - echo Start daemon\(s\) - echo Study how other sections work - - do_daemon $1 1 /bin/sleep 20 -} -zapret_custom_firewall() -{ - # $1 - 1 - run, 0 - stop - - # PLACEHOLDER - echo !!! NEED ATTENTION !!! - echo Configure iptables for required actions - echo Study how other sections work -} - -zapret_custom_firewall_nft() -{ - # stop logic is not required - - # PLACEHOLDER - echo !!! NEED ATTENTION !!! - echo Configure nftables for required actions - echo Study how other sections work -} diff --git a/init.d/sysv/functions b/init.d/sysv/functions index 519c1e0..9caa569 100644 --- a/init.d/sysv/functions +++ b/init.d/sysv/functions @@ -12,6 +12,8 @@ ZAPRET_CONFIG=${ZAPRET_CONFIG:-"$ZAPRET_RW/config"} . "$ZAPRET_BASE/common/nft.sh" . "$ZAPRET_BASE/common/linux_fw.sh" . "$ZAPRET_BASE/common/list.sh" +. "$ZAPRET_BASE/common/custom.sh" +CUSTOM_DIR="$ZAPRET_RW/init.d/sysv" user_exists() @@ -91,9 +93,6 @@ TPWS_OPT_BASE6_PRE="--bind-linklocal=prefer $TPWS_WAIT --bind-wait-ip-linklocal= # max wait time for the link local ipv6 on the LAN interface LINKLOCAL_WAIT_SEC=5 -CUSTOM_SCRIPT="$ZAPRET_BASE/init.d/sysv/custom" -[ -f "$CUSTOM_SCRIPT" ] && . "$CUSTOM_SCRIPT" - IPSET_EXCLUDE="-m set ! --match-set nozapret" IPSET_EXCLUDE6="-m set ! --match-set nozapret6" @@ -341,7 +340,7 @@ zapret_do_daemons() } ;; custom) - existf zapret_custom_daemons && zapret_custom_daemons $1 + custom_runner zapret_custom_daemons $1 ;; esac diff --git a/install_bin.sh b/install_bin.sh index fb33462..c4f1f3e 100755 --- a/install_bin.sh +++ b/install_bin.sh @@ -29,11 +29,11 @@ check_dir() fi [ -n "$out" ] else - echo "$exe is not executable. set proper chmod." + echo >&2 "$exe is not executable. set proper chmod." return 1 fi else - echo "$exe is absent" + echo >&2 "$exe is absent" return 2 fi } diff --git a/install_easy.sh b/install_easy.sh index 67364d8..c95ed61 100755 --- a/install_easy.sh +++ b/install_easy.sh @@ -138,6 +138,15 @@ select_mode_mode() echo ..edited.. done } + [ "$MODE" = custom ] && { + echo + echo "current custom scripts :" + [ -f "$CUSTOM_DIR/custom" ] && echo "legacy custom script $CUSTOM_DIR/custom" + echo "$CUSTOM_DIR/custom.d :" + [ -d "$CUSTOM_DIR/custom.d" ] && ls "$CUSTOM_DIR/custom.d" + echo "Make sure this is ok" + echo + } } select_mode_http() { @@ -210,10 +219,10 @@ select_getlist() echo if ask_yes_no $D "do you want to auto download ip/host list"; then if [ "$MODE_FILTER" = "hostlist" ] ; then - GETLISTS="get_antizapret_domains.sh get_reestr_resolvable_domains.sh get_reestr_hostlist.sh" + GETLISTS="get_refilter_domains.sh get_antizapret_domains.sh get_reestr_resolvable_domains.sh get_reestr_hostlist.sh" GETLIST_DEF="get_antizapret_domains.sh" else - GETLISTS="get_user.sh get_antifilter_ip.sh get_antifilter_ipsmart.sh get_antifilter_ipsum.sh get_antifilter_ipresolve.sh get_antifilter_allyouneed.sh get_reestr_resolve.sh get_reestr_preresolved.sh get_reestr_preresolved_smart.sh" + GETLISTS="get_user.sh get_refilter_ipsum.sh get_antifilter_ip.sh get_antifilter_ipsmart.sh get_antifilter_ipsum.sh get_antifilter_ipresolve.sh get_antifilter_allyouneed.sh get_reestr_resolve.sh get_reestr_preresolved.sh get_reestr_preresolved_smart.sh" GETLIST_DEF="get_antifilter_allyouneed.sh" fi ask_list GETLIST "$GETLISTS" "$GETLIST_DEF" && write_config_var GETLIST @@ -393,7 +402,7 @@ default_files() for dir in openwrt sysv macos; do [ -d "$1/init.d/$dir" ] && { [ -d "$2/init.d/$dir" ] || mkdir -p "$2/init.d/$dir" - [ -f "$2/init.d/$dir/custom" ] || cp "$1/init.d/$dir/custom.default" "$2/init.d/$dir/custom" + [ -d "$2/init.d/$dir/custom.d" ] || mkdir -p "$2/init.d/$dir/custom.d" } done } @@ -453,6 +462,8 @@ files/huawei/E8372/zapret \ files/huawei/E8372/run-zapret-ip \ ipset/get_exclude.sh \ ipset/clear_lists.sh \ +ipset/get_refilter_domains.sh \ +ipset/get_refilter_ipsum.sh \ ipset/get_antifilter_ipresolve.sh \ ipset/get_reestr_resolvable_domains.sh \ ipset/get_config.sh \ @@ -484,7 +495,11 @@ _backup_settings() { local i=0 for f in "$@"; do + # safety check + [ -z "$f" -o "$f" = "/" ] && continue + [ -f "$ZAPRET_TARGET/$f" ] && cp -f "$ZAPRET_TARGET/$f" "/tmp/zapret-bkp-$i" + [ -d "$ZAPRET_TARGET/$f" ] && cp -rf "$ZAPRET_TARGET/$f" "/tmp/zapret-bkp-$i" i=$(($i+1)) done } @@ -492,7 +507,14 @@ _restore_settings() { local i=0 for f in "$@"; do + # safety check + [ -z "$f" -o "$f" = "/" ] && continue + [ -f "/tmp/zapret-bkp-$i" ] && mv -f "/tmp/zapret-bkp-$i" "$ZAPRET_TARGET/$f" || rm -f "/tmp/zapret-bkp-$i" + [ -d "/tmp/zapret-bkp-$i" ] && { + [ -d "$ZAPRET_TARGET/$f" ] && rm -r "$ZAPRET_TARGET/$f" + mv -f "/tmp/zapret-bkp-$i" "$ZAPRET_TARGET/$f" || rm -r "/tmp/zapret-bkp-$i" + } i=$(($i+1)) done } @@ -500,7 +522,7 @@ backup_restore_settings() { # $1 - 1 - backup, 0 - restore local mode=$1 - on_off_function _backup_settings _restore_settings $mode "config" "init.d/sysv/custom" "init.d/openwrt/custom" "init.d/macos/custom" "ipset/zapret-hosts-user.txt" "ipset/zapret-hosts-user-exclude.txt" "ipset/zapret-hosts-user-ipban.txt" "ipset/zapret-hosts-auto.txt" + on_off_function _backup_settings _restore_settings $mode "config" "init.d/sysv/custom" "init.d/sysv/custom.d" "init.d/openwrt/custom" "init.d/openwrt/custom.d" "init.d/macos/custom" "init.d/macos/custom.d" "ipset/zapret-hosts-user.txt" "ipset/zapret-hosts-user-exclude.txt" "ipset/zapret-hosts-user-ipban.txt" "ipset/zapret-hosts-auto.txt" } check_location() @@ -623,6 +645,7 @@ check_dns() install_systemd() { INIT_SCRIPT_SRC="$EXEDIR/init.d/sysv/zapret" + CUSTOM_DIR="$ZAPRET_RW/init.d/sysv" check_bins require_root @@ -650,6 +673,8 @@ _install_sysv() { # $1 - install init script + CUSTOM_DIR="$ZAPRET_RW/init.d/sysv" + check_bins require_root check_readonly_system @@ -687,6 +712,7 @@ install_openrc() install_linux() { INIT_SCRIPT_SRC="$EXEDIR/init.d/sysv/zapret" + CUSTOM_DIR="$ZAPRET_RW/init.d/sysv" check_bins require_root @@ -757,6 +783,7 @@ deoffload_openwrt_firewall() install_openwrt() { INIT_SCRIPT_SRC="$EXEDIR/init.d/openwrt/zapret" + CUSTOM_DIR="$ZAPRET_RW/init.d/openwrt" FW_SCRIPT_SRC="$EXEDIR/init.d/openwrt/firewall.zapret" OPENWRT_FW_INCLUDE=/etc/firewall.zapret OPENWRT_IFACE_HOOK="$EXEDIR/init.d/openwrt/90-zapret" @@ -829,6 +856,7 @@ macos_fw_reload_trigger_set() install_macos() { INIT_SCRIPT_SRC="$EXEDIR/init.d/macos/zapret" + CUSTOM_DIR="$ZAPRET_RW/init.d/macos" # compile before root check_bins diff --git a/ipset/create_ipset.sh b/ipset/create_ipset.sh index f5eaaa5..a88137d 100755 --- a/ipset/create_ipset.sh +++ b/ipset/create_ipset.sh @@ -4,12 +4,12 @@ # $1=no-update - do not update ipset, only create if its absent # $1=clear - clear ipset -IPSET_DIR="$(dirname "$0")" -IPSET_DIR="$(cd "$IPSET_DIR"; pwd)" +EXEDIR="$(dirname "$0")" +EXEDIR="$(cd "$EXEDIR"; pwd)" -. "$IPSET_DIR/def.sh" -. "$IPSET_DIR/../common/fwtype.sh" -. "$IPSET_DIR/../common/nft.sh" +. "$EXEDIR/def.sh" +. "$ZAPRET_BASE/common/fwtype.sh" +. "$ZAPRET_BASE/common/nft.sh" IPSET_CMD="$TMPDIR/ipset_cmd.txt" IPSET_SAVERAM_CHUNK_SIZE=20000 @@ -119,13 +119,12 @@ nfset_get_script_multi() local set=$1 nonempty N=1 f shift - # first we need to make sure at least one element exists or nft will fail while : do eval f=\$$N [ -n "$f" ] || break - nonempty=$(zzexist "$f" && zzcat "$f" | head -n 1) + nonempty=$(zzexist "$f" && zzcat "$f" 2>/dev/null | head -n 1) [ -n "$nonempty" ] && break N=$(($N+1)) done diff --git a/ipset/def.sh b/ipset/def.sh index 4be9e8d..174cc35 100644 --- a/ipset/def.sh +++ b/ipset/def.sh @@ -1,10 +1,12 @@ -[ -n "$IPSET_DIR" ] || { - IPSET_DIR="$(dirname "$0")" - IPSET_DIR="$(cd "$IPSET_DIR"; pwd)" -} +EXEDIR="$(dirname "$0")" +EXEDIR="$(cd "$EXEDIR"; pwd)" +ZAPRET_BASE=${ZAPRET_BASE:-"$(cd "$EXEDIR/.."; pwd)"} +ZAPRET_RW=${ZAPRET_RW:-"$ZAPRET_BASE"} +ZAPRET_CONFIG=${ZAPRET_CONFIG:-"$ZAPRET_RW/config"} +IPSET_RW_DIR="$ZAPRET_RW/ipset" -. "$IPSET_DIR/../config" -. "$IPSET_DIR/../common/base.sh" +. "$ZAPRET_CONFIG" +. "$ZAPRET_BASE/common/base.sh" [ -z "$TMPDIR" ] && TMPDIR=/tmp [ -z "$GZIP_LISTS" ] && GZIP_LISTS=1 @@ -21,27 +23,27 @@ ZIPSET=zapret ZIPSET6=zapret6 ZIPSET_EXCLUDE=nozapret ZIPSET_EXCLUDE6=nozapret6 -ZIPLIST="$IPSET_DIR/zapret-ip.txt" -ZIPLIST6="$IPSET_DIR/zapret-ip6.txt" -ZIPLIST_EXCLUDE="$IPSET_DIR/zapret-ip-exclude.txt" -ZIPLIST_EXCLUDE6="$IPSET_DIR/zapret-ip-exclude6.txt" -ZIPLIST_USER="$IPSET_DIR/zapret-ip-user.txt" -ZIPLIST_USER6="$IPSET_DIR/zapret-ip-user6.txt" -ZUSERLIST="$IPSET_DIR/zapret-hosts-user.txt" -ZHOSTLIST="$IPSET_DIR/zapret-hosts.txt" +ZIPLIST="$IPSET_RW_DIR/zapret-ip.txt" +ZIPLIST6="$IPSET_RW_DIR/zapret-ip6.txt" +ZIPLIST_EXCLUDE="$IPSET_RW_DIR/zapret-ip-exclude.txt" +ZIPLIST_EXCLUDE6="$IPSET_RW_DIR/zapret-ip-exclude6.txt" +ZIPLIST_USER="$IPSET_RW_DIR/zapret-ip-user.txt" +ZIPLIST_USER6="$IPSET_RW_DIR/zapret-ip-user6.txt" +ZUSERLIST="$IPSET_RW_DIR/zapret-hosts-user.txt" +ZHOSTLIST="$IPSET_RW_DIR/zapret-hosts.txt" ZIPSET_IPBAN=ipban ZIPSET_IPBAN6=ipban6 -ZIPLIST_IPBAN="$IPSET_DIR/zapret-ip-ipban.txt" -ZIPLIST_IPBAN6="$IPSET_DIR/zapret-ip-ipban6.txt" -ZIPLIST_USER_IPBAN="$IPSET_DIR/zapret-ip-user-ipban.txt" -ZIPLIST_USER_IPBAN6="$IPSET_DIR/zapret-ip-user-ipban6.txt" -ZUSERLIST_IPBAN="$IPSET_DIR/zapret-hosts-user-ipban.txt" -ZUSERLIST_EXCLUDE="$IPSET_DIR/zapret-hosts-user-exclude.txt" +ZIPLIST_IPBAN="$IPSET_RW_DIR/zapret-ip-ipban.txt" +ZIPLIST_IPBAN6="$IPSET_RW_DIR/zapret-ip-ipban6.txt" +ZIPLIST_USER_IPBAN="$IPSET_RW_DIR/zapret-ip-user-ipban.txt" +ZIPLIST_USER_IPBAN6="$IPSET_RW_DIR/zapret-ip-user-ipban6.txt" +ZUSERLIST_IPBAN="$IPSET_RW_DIR/zapret-hosts-user-ipban.txt" +ZUSERLIST_EXCLUDE="$IPSET_RW_DIR/zapret-hosts-user-exclude.txt" -[ -n "$IP2NET" ] || IP2NET="$IPSET_DIR/../ip2net/ip2net" -[ -n "$MDIG" ] || MDIG="$IPSET_DIR/../mdig/mdig" +[ -n "$IP2NET" ] || IP2NET="$ZAPRET_BASE/ip2net/ip2net" +[ -n "$MDIG" ] || MDIG="$ZAPRET_BASE/mdig/mdig" [ -z "$MDIG_THREADS" ] && MDIG_THREADS=30 diff --git a/ipset/get_refilter_domains.sh b/ipset/get_refilter_domains.sh new file mode 100755 index 0000000..ed40738 --- /dev/null +++ b/ipset/get_refilter_domains.sh @@ -0,0 +1,42 @@ +#!/bin/sh + +IPSET_DIR="$(dirname "$0")" +IPSET_DIR="$(cd "$IPSET_DIR"; pwd)" + +. "$IPSET_DIR/def.sh" + +TMPLIST="$TMPDIR/list.txt" + +URL="https://github.com/1andrevich/Re-filter-lists/releases/latest/download/domains_all.lst" + +dl() +{ + # $1 - url + # $2 - file + # $3 - minsize + # $4 - maxsize + curl -L -H "Accept-Encoding: gzip" -k --fail --max-time 60 --connect-timeout 10 --retry 4 --max-filesize $4 -o "$TMPLIST" "$1" || + { + echo list download failed : $1 + exit 2 + } + dlsize=$(LANG=C wc -c "$TMPLIST" | xargs | cut -f 1 -d ' ') + if test $dlsize -lt $3; then + echo list is too small : $dlsize bytes. can be bad. + exit 2 + fi + zzcat "$TMPLIST" | tr -d '\015' | zz "$2" + rm -f "$TMPLIST" +} + +# useful in case ipban set is used in custom scripts +FAIL= +getipban || FAIL=1 +"$IPSET_DIR/create_ipset.sh" +[ -n "$FAIL" ] && exit + +dl "$URL" "$ZHOSTLIST" 32768 4194304 + +hup_zapret_daemons + +exit 0 diff --git a/ipset/get_refilter_ipsum.sh b/ipset/get_refilter_ipsum.sh new file mode 100755 index 0000000..811d9ba --- /dev/null +++ b/ipset/get_refilter_ipsum.sh @@ -0,0 +1,39 @@ +#!/bin/sh + +IPSET_DIR="$(dirname "$0")" +IPSET_DIR="$(cd "$IPSET_DIR"; pwd)" + +. "$IPSET_DIR/def.sh" + +TMPLIST="$TMPDIR/list.txt" + +URL="https://github.com/1andrevich/Re-filter-lists/releases/latest/download/ipsum.lst" + +dl() +{ + # $1 - url + # $2 - file + # $3 - minsize + # $4 - maxsize + curl -L -H "Accept-Encoding: gzip" -k --fail --max-time 60 --connect-timeout 10 --retry 4 --max-filesize $4 -o "$TMPLIST" "$1" || + { + echo list download failed : $1 + exit 2 + } + dlsize=$(LANG=C wc -c "$TMPLIST" | xargs | cut -f 1 -d ' ') + if test $dlsize -lt $3; then + echo list is too small : $dlsize bytes. can be bad. + exit 2 + fi + # remove DOS EOL \r + zzcat "$TMPLIST" | tr -d '\015' | zz "$2" + rm -f "$TMPLIST" +} + +getuser && { + [ "$DISABLE_IPV4" != "1" ] && { + dl "$URL" "$ZIPLIST" 32768 4194304 + } +} + +"$IPSET_DIR/create_ipset.sh" diff --git a/nfq/desync.c b/nfq/desync.c index aec2142..e1181e6 100644 --- a/nfq/desync.c +++ b/nfq/desync.c @@ -630,7 +630,6 @@ static uint8_t dpi_desync_tcp_packet_play(bool replay, size_t reasm_offset, uint { dp = ctrack->dp; ctrack_replay = ctrack; - maybe_cutoff(ctrack, IPPROTO_TCP); } if (dp) DLOG("using cached desync profile %d\n",dp->n); @@ -648,6 +647,7 @@ static uint8_t dpi_desync_tcp_packet_play(bool replay, size_t reasm_offset, uint DLOG("matching desync profile not found\n"); return verdict; } + maybe_cutoff(ctrack, IPPROTO_TCP); HostFailPoolPurgeRateLimited(&dp->hostlist_auto_fail_counters); @@ -1435,7 +1435,6 @@ static uint8_t dpi_desync_udp_packet_play(bool replay, size_t reasm_offset, uint { dp = ctrack->dp; ctrack_replay = ctrack; - maybe_cutoff(ctrack, IPPROTO_UDP); } if (dp) DLOG("using cached desync profile %d\n",dp->n); @@ -1453,6 +1452,7 @@ static uint8_t dpi_desync_udp_packet_play(bool replay, size_t reasm_offset, uint DLOG("matching desync profile not found\n"); return verdict; } + maybe_cutoff(ctrack, IPPROTO_UDP); HostFailPoolPurgeRateLimited(&dp->hostlist_auto_fail_counters); //ConntrackPoolDump(¶ms.conntrack); diff --git a/nfq/hostlist.c b/nfq/hostlist.c index 03ed441..abb415b 100644 --- a/nfq/hostlist.c +++ b/nfq/hostlist.c @@ -4,17 +4,27 @@ #include "helpers.h" // inplace tolower() and add to pool -static bool addpool(strpool **hostlist, char **s, const char *end) +static bool addpool(strpool **hostlist, char **s, const char *end, int *ct) { - char *p; - - // advance until eol lowering all chars - for (p = *s; p #include +void rtrim(char *s) +{ + if (s) + for (char *p = s + strlen(s) - 1; p >= s && (*p == '\n' || *p == '\r'); p--) *p = '\0'; +} + char *strncasestr(const char *s,const char *find, size_t slen) { char c, sc; @@ -81,7 +87,6 @@ void print_sockaddr(const struct sockaddr *sa) printf("%s",ip_port); } - // -1 = error, 0 = not local, 1 = local bool check_local_ip(const struct sockaddr *saddr) { @@ -178,6 +183,10 @@ void sacopy(struct sockaddr_storage *sa_dest, const struct sockaddr *sa) sa_dest->ss_family = 0; } } +void sa46copy(sockaddr_in46 *sa_dest, const struct sockaddr *sa) +{ + sacopy((struct sockaddr_storage*)sa_dest, sa); +} bool is_localnet(const struct sockaddr *a) { @@ -287,3 +296,101 @@ bool pf_is_empty(const port_filter *pf) { return !pf->neg && !pf->from && !pf->to; } + + +static void mask_from_preflen6_make(uint8_t plen, struct in6_addr *a) +{ + if (plen >= 128) + memset(a->s6_addr,0xFF,16); + else + { + uint8_t n = plen >> 3; + memset(a->s6_addr,0xFF,n); + memset(a->s6_addr+n,0x00,16-n); + a->s6_addr[n] = (uint8_t)(0xFF00 >> (plen & 7)); + } +} +struct in6_addr ip6_mask[129]; +void mask_from_preflen6_prepare(void) +{ + for (int plen=0;plen<=128;plen++) mask_from_preflen6_make(plen, ip6_mask+plen); +} + +#if defined(__GNUC__) && !defined(__llvm__) +__attribute__((optimize ("no-strict-aliasing"))) +#endif +void ip6_and(const struct in6_addr * restrict a, const struct in6_addr * restrict b, struct in6_addr * restrict result) +{ +#ifdef __SIZEOF_INT128__ + // gcc and clang have 128 bit int types on some 64-bit archs. take some advantage + *((unsigned __int128*)result->s6_addr) = *((unsigned __int128*)a->s6_addr) & *((unsigned __int128*)b->s6_addr); +#else + ((uint64_t*)result->s6_addr)[0] = ((uint64_t*)a->s6_addr)[0] & ((uint64_t*)b->s6_addr)[0]; + ((uint64_t*)result->s6_addr)[1] = ((uint64_t*)a->s6_addr)[1] & ((uint64_t*)b->s6_addr)[1]; +#endif +} + +void str_cidr4(char *s, size_t s_len, const struct cidr4 *cidr) +{ + char s_ip[16]; + *s_ip=0; + inet_ntop(AF_INET, &cidr->addr, s_ip, sizeof(s_ip)); + snprintf(s,s_len,cidr->preflen<32 ? "%s/%u" : "%s", s_ip, cidr->preflen); +} +void print_cidr4(const struct cidr4 *cidr) +{ + char s[19]; + str_cidr4(s,sizeof(s),cidr); + printf("%s",s); +} +void str_cidr6(char *s, size_t s_len, const struct cidr6 *cidr) +{ + char s_ip[40]; + *s_ip=0; + inet_ntop(AF_INET6, &cidr->addr, s_ip, sizeof(s_ip)); + snprintf(s,s_len,cidr->preflen<128 ? "%s/%u" : "%s", s_ip, cidr->preflen); +} +void print_cidr6(const struct cidr6 *cidr) +{ + char s[44]; + str_cidr6(s,sizeof(s),cidr); + printf("%s",s); +} +bool parse_cidr4(char *s, struct cidr4 *cidr) +{ + char *p,d; + bool b; + unsigned int plen; + + if ((p = strchr(s, '/'))) + { + if (sscanf(p + 1, "%u", &plen)!=1 || plen>32) + return false; + cidr->preflen = (uint8_t)plen; + d=*p; *p=0; // backup char + } + else + cidr->preflen = 32; + b = (inet_pton(AF_INET, s, &cidr->addr)==1); + if (p) *p=d; // restore char + return b; +} +bool parse_cidr6(char *s, struct cidr6 *cidr) +{ + char *p,d; + bool b; + unsigned int plen; + + if ((p = strchr(s, '/'))) + { + if (sscanf(p + 1, "%u", &plen)!=1 || plen>128) + return false; + cidr->preflen = (uint8_t)plen; + d=*p; *p=0; // backup char + } + else + cidr->preflen = 128; + b = (inet_pton(AF_INET6, s, &cidr->addr)==1); + if (p) *p=d; // restore char + return b; +} diff --git a/tpws/helpers.h b/tpws/helpers.h index 17ace35..0447809 100644 --- a/tpws/helpers.h +++ b/tpws/helpers.h @@ -8,6 +8,15 @@ #include #include +// this saves memory. sockaddr_storage is larger than required. it can be 128 bytes. sockaddr_in6 is 28 bytes. +typedef union +{ + struct sockaddr_in sa4; // size 16 + struct sockaddr_in6 sa6; // size 28 + char _align[32]; // force 16-byte alignment for ip6_and int128 ops +} sockaddr_in46; + +void rtrim(char *s); char *strncasestr(const char *s,const char *find, size_t slen); bool append_to_list_file(const char *filename, const char *s); @@ -26,6 +35,7 @@ uint16_t saport(const struct sockaddr *sa); bool saconvmapped(struct sockaddr_storage *a); void sacopy(struct sockaddr_storage *sa_dest, const struct sockaddr *sa); +void sa46copy(sockaddr_in46 *sa_dest, const struct sockaddr *sa); bool is_localnet(const struct sockaddr *a); bool is_linklocal(const struct sockaddr_in6* a); @@ -71,3 +81,33 @@ bool pf_is_empty(const port_filter *pf); #else #define IN6_EXTRACT_MAP4(a) (((const uint32_t *) (a))[3]) #endif + + +struct cidr4 +{ + struct in_addr addr; + uint8_t preflen; +}; +struct cidr6 +{ + struct in6_addr addr; + uint8_t preflen; +}; +void str_cidr4(char *s, size_t s_len, const struct cidr4 *cidr); +void print_cidr4(const struct cidr4 *cidr); +void str_cidr6(char *s, size_t s_len, const struct cidr6 *cidr); +void print_cidr6(const struct cidr6 *cidr); +bool parse_cidr4(char *s, struct cidr4 *cidr); +bool parse_cidr6(char *s, struct cidr6 *cidr); + +static inline uint32_t mask_from_preflen(uint32_t preflen) +{ + return preflen ? preflen<32 ? ~((1 << (32-preflen)) - 1) : 0xFFFFFFFF : 0; +} +void ip6_and(const struct in6_addr * restrict a, const struct in6_addr * restrict b, struct in6_addr * restrict result); +extern struct in6_addr ip6_mask[129]; +void mask_from_preflen6_prepare(void); +static inline const struct in6_addr *mask_from_preflen6(uint8_t preflen) +{ + return ip6_mask+preflen; +} diff --git a/tpws/hostlist.c b/tpws/hostlist.c index 7a8b8b4..b429dd8 100644 --- a/tpws/hostlist.c +++ b/tpws/hostlist.c @@ -5,17 +5,27 @@ #include "helpers.h" // inplace tolower() and add to pool -static bool addpool(strpool **hostlist, char **s, const char *end) +static bool addpool(strpool **hostlist, char **s, const char *end, int *ct) { - char *p; - - // advance until eol lowering all chars - for (p = *s; pn); + VPRINT("* hostlist check for profile %d\n",dp->n); if (*dp->hostlist_auto_filename) { time_t t = file_mod_time(dp->hostlist_auto_filename); diff --git a/tpws/hostlist.h b/tpws/hostlist.h index 0bdb94a..d909737 100644 --- a/tpws/hostlist.h +++ b/tpws/hostlist.h @@ -4,7 +4,7 @@ #include "pools.h" #include "params.h" -bool AppendHostList(strpool **hostlist, char *filename); +bool AppendHostList(strpool **hostlist, const char *filename); bool LoadHostLists(strpool **hostlist, struct str_list_head *file_list); bool LoadIncludeHostLists(); bool LoadExcludeHostLists(); diff --git a/tpws/ipset.c b/tpws/ipset.c new file mode 100644 index 0000000..93b60fd --- /dev/null +++ b/tpws/ipset.c @@ -0,0 +1,195 @@ +#include +#include "ipset.h" +#include "gzip.h" +#include "helpers.h" + +// inplace tolower() and add to pool +static bool addpool(ipset *ips, char **s, const char *end, int *ct) +{ + char *p, cidr[128]; + size_t l; + struct cidr4 c4; + struct cidr6 c6; + + // advance until eol + for (p=*s; p=sizeof(cidr)) l=sizeof(cidr)-1; + memcpy(cidr,*s,l); + cidr[l]=0; + rtrim(cidr); + + if (parse_cidr4(cidr,&c4)) + { + if (!ipset4AddCidr(&ips->ips4, &c4)) + { + ipsetDestroy(ips); + return false; + } + (*ct)++; + } + else if (parse_cidr6(cidr,&c6)) + { + if (!ipset6AddCidr(&ips->ips6, &c6)) + { + ipsetDestroy(ips); + return false; + } + (*ct)++; + } + else + DLOG_ERR("bad ip or subnet : %s\n",cidr); + } + + // advance to the next line + for (; pstr)) return false; + } + return true; +} + +bool LoadIncludeIpsets() +{ + struct desync_profile_list *dpl; + LIST_FOREACH(dpl, ¶ms.desync_profiles, next) + if (!LoadIpsets(&dpl->dp.ips, &dpl->dp.ipset_files)) + return false; + return true; +} +bool LoadExcludeIpsets() +{ + struct desync_profile_list *dpl; + LIST_FOREACH(dpl, ¶ms.desync_profiles, next) + if (!LoadIpsets(&dpl->dp.ips_exclude, &dpl->dp.ipset_exclude_files)) + return false; + return true; +} + +bool SearchIpset(const ipset *ips, const struct in_addr *ipv4, const struct in6_addr *ipv6) +{ + char s_ip[40]; + bool bInSet=false; + + if (!!ipv4 != !!ipv6) + { + *s_ip=0; + if (ipv4) + { + if (params.debug) inet_ntop(AF_INET, ipv4, s_ip, sizeof(s_ip)); + if (ips->ips4) bInSet = ipset4Check(ips->ips4, ipv4, 32); + } + if (ipv6) + { + if (params.debug) inet_ntop(AF_INET6, ipv6, s_ip, sizeof(s_ip)); + if (ips->ips6) bInSet = ipset6Check(ips->ips6, ipv6, 128); + } + VPRINT("ipset check for %s : %s\n", s_ip, bInSet ? "positive" : "negative"); + } + else + // ipv4 and ipv6 are both empty or non-empty + VPRINT("ipset check error !!!!!!!! ipv4=%p ipv6=%p\n",ipv4,ipv6); + return bInSet; +} + +static bool IpsetCheck_(const ipset *ips, const ipset *ips_exclude, const struct in_addr *ipv4, const struct in6_addr *ipv6) +{ + if (!IPSET_EMPTY(ips_exclude)) + { + VPRINT("exclude "); + if (SearchIpset(ips_exclude, ipv4, ipv6)) + return false; + } + if (!IPSET_EMPTY(ips)) + { + VPRINT("include "); + return SearchIpset(ips, ipv4, ipv6); + } + return true; +} + +bool IpsetCheck(struct desync_profile *dp, const struct in_addr *ipv4, const struct in6_addr *ipv6) +{ + if (!PROFILE_IPSETS_EMPTY(dp)) VPRINT("* ipset check for profile %d\n",dp->n); + return IpsetCheck_(&dp->ips,&dp->ips_exclude,ipv4,ipv6); +} diff --git a/tpws/ipset.h b/tpws/ipset.h new file mode 100644 index 0000000..ea9d1b8 --- /dev/null +++ b/tpws/ipset.h @@ -0,0 +1,11 @@ +#pragma once + +#include +#include +#include "params.h" +#include "pools.h" + +bool LoadIncludeIpsets(); +bool LoadExcludeIpsets(); +bool SearchIpset(const ipset *ips, const struct in_addr *ipv4, const struct in6_addr *ipv6); +bool IpsetCheck(struct desync_profile *dp, const struct in_addr *ipv4, const struct in6_addr *ipv6); diff --git a/tpws/params.c b/tpws/params.c index d31aac0..14d4a15 100644 --- a/tpws/params.c +++ b/tpws/params.c @@ -169,8 +169,12 @@ static void dp_entry_destroy(struct desync_profile_list *entry) { strlist_destroy(&entry->dp.hostlist_files); strlist_destroy(&entry->dp.hostlist_exclude_files); + strlist_destroy(&entry->dp.ipset_files); + strlist_destroy(&entry->dp.ipset_exclude_files); StrPoolDestroy(&entry->dp.hostlist_exclude); StrPoolDestroy(&entry->dp.hostlist); + ipsetDestroy(&entry->dp.ips); + ipsetDestroy(&entry->dp.ips_exclude); HostFailPoolDestroy(&entry->dp.hostlist_auto_fail_counters); free(entry); } diff --git a/tpws/params.h b/tpws/params.h index 3764fc7..2e9cb93 100644 --- a/tpws/params.h +++ b/tpws/params.h @@ -51,6 +51,9 @@ struct desync_profile bool filter_ipv4,filter_ipv6; port_filter pf_tcp; + uint32_t filter_l7; // L7_PROTO_* bits + ipset ips,ips_exclude; + struct str_list_head ipset_files, ipset_exclude_files; strpool *hostlist, *hostlist_exclude; struct str_list_head hostlist_files, hostlist_exclude_files; @@ -60,6 +63,8 @@ struct desync_profile hostfail_pool *hostlist_auto_fail_counters; }; +#define PROFILE_IPSETS_EMPTY(dp) (IPSET_EMPTY(&dp->ips) && IPSET_EMPTY(&dp->ips_exclude)) + struct desync_profile_list { struct desync_profile dp; LIST_ENTRY(desync_profile_list) next; diff --git a/tpws/pools.c b/tpws/pools.c index 785b04d..8d10f73 100644 --- a/tpws/pools.c +++ b/tpws/pools.c @@ -52,6 +52,12 @@ bool StrPoolAddStr(strpool **pp, const char *s) { return StrPoolAddStrLen(pp, s, strlen(s)); } +bool StrPoolAddUniqueStr(strpool **pp,const char *s) +{ + if (StrPoolCheckStr(*pp,s)) + return true; + return StrPoolAddStr(pp,s); +} bool StrPoolCheckStr(strpool *p, const char *s) { @@ -151,3 +157,127 @@ void strlist_destroy(struct str_list_head *head) strlist_entry_destroy(entry); } } + + + +void ipset4Destroy(ipset4 **ipset) +{ + ipset4 *elem, *tmp; + HASH_ITER(hh, *ipset, elem, tmp) + { + HASH_DEL(*ipset, elem); + free(elem); + } +} +bool ipset4Check(ipset4 *ipset, const struct in_addr *a, uint8_t preflen) +{ + uint32_t ip = ntohl(a->s_addr); + struct cidr4 cidr; + ipset4 *ips_found; + + // zero alignment bytes + memset(&cidr,0,sizeof(cidr)); + cidr.preflen = preflen+1; + do + { + cidr.preflen--; + cidr.addr.s_addr = htonl(ip & mask_from_preflen(cidr.preflen)); + HASH_FIND(hh, ipset, &cidr, sizeof(cidr), ips_found); + if (ips_found) return true; + } while(cidr.preflen); + + return false; +} +bool ipset4Add(ipset4 **ipset, const struct in_addr *a, uint8_t preflen) +{ + if (preflen>32) return false; + + // avoid dups + if (ipset4Check(*ipset, a, preflen)) return true; // already included + + struct ipset4 *entry = calloc(1,sizeof(ipset4)); + if (!entry) return false; + + entry->cidr.addr.s_addr = htonl(ntohl(a->s_addr) & mask_from_preflen(preflen)); + entry->cidr.preflen = preflen; + oom = false; + HASH_ADD(hh, *ipset, cidr, sizeof(entry->cidr), entry); + if (oom) { free(entry); return false; } + + return true; +} +void ipset4Print(ipset4 *ipset) +{ + ipset4 *ips, *tmp; + HASH_ITER(hh, ipset , ips, tmp) + { + print_cidr4(&ips->cidr); + printf("\n"); + } +} + +void ipset6Destroy(ipset6 **ipset) +{ + ipset6 *elem, *tmp; + HASH_ITER(hh, *ipset, elem, tmp) + { + HASH_DEL(*ipset, elem); + free(elem); + } +} +bool ipset6Check(ipset6 *ipset, const struct in6_addr *a, uint8_t preflen) +{ + struct cidr6 cidr; + ipset6 *ips_found; + + // zero alignment bytes + memset(&cidr,0,sizeof(cidr)); + cidr.preflen = preflen+1; + do + { + cidr.preflen--; + ip6_and(a, mask_from_preflen6(cidr.preflen), &cidr.addr); + HASH_FIND(hh, ipset, &cidr, sizeof(cidr), ips_found); + if (ips_found) return true; + } while(cidr.preflen); + + return false; +} +bool ipset6Add(ipset6 **ipset, const struct in6_addr *a, uint8_t preflen) +{ + if (preflen>128) return false; + + // avoid dups + if (ipset6Check(*ipset, a, preflen)) return true; // already included + + struct ipset6 *entry = calloc(1,sizeof(ipset6)); + if (!entry) return false; + + ip6_and(a, mask_from_preflen6(preflen), &entry->cidr.addr); + entry->cidr.preflen = preflen; + oom = false; + HASH_ADD(hh, *ipset, cidr, sizeof(entry->cidr), entry); + if (oom) { free(entry); return false; } + + return true; +} +void ipset6Print(ipset6 *ipset) +{ + ipset6 *ips, *tmp; + HASH_ITER(hh, ipset , ips, tmp) + { + print_cidr6(&ips->cidr); + printf("\n"); + } +} + +void ipsetDestroy(ipset *ipset) +{ + ipset4Destroy(&ipset->ips4); + ipset6Destroy(&ipset->ips6); +} +void ipsetPrint(ipset *ipset) +{ + ipset4Print(ipset->ips4); + ipset6Print(ipset->ips6); +} diff --git a/tpws/pools.h b/tpws/pools.h index ab58968..d1f1b9f 100644 --- a/tpws/pools.h +++ b/tpws/pools.h @@ -5,6 +5,8 @@ #include #include +#include "helpers.h" + //#define HASH_BLOOM 20 #define HASH_NONFATAL_OOM 1 #define HASH_FUNCTION HASH_BER @@ -17,6 +19,7 @@ typedef struct strpool { void StrPoolDestroy(strpool **pp); bool StrPoolAddStr(strpool **pp,const char *s); +bool StrPoolAddUniqueStr(strpool **pp,const char *s); bool StrPoolAddStrLen(strpool **pp,const char *s,size_t slen); bool StrPoolCheckStr(strpool *p,const char *s); @@ -44,3 +47,41 @@ void HostFailPoolDump(hostfail_pool *p); bool strlist_add(struct str_list_head *head, const char *filename); void strlist_destroy(struct str_list_head *head); + + +typedef struct ipset4 { + struct cidr4 cidr; /* key */ + UT_hash_handle hh; /* makes this structure hashable */ +} ipset4; +typedef struct ipset6 { + struct cidr6 cidr; /* key */ + UT_hash_handle hh; /* makes this structure hashable */ +} ipset6; +// combined ipset ipv4 and ipv6 +typedef struct ipset { + ipset4 *ips4; + ipset6 *ips6; +} ipset; + +#define IPSET_EMPTY(ips) (!(ips)->ips4 && !(ips)->ips6) + +void ipset4Destroy(ipset4 **ipset); +bool ipset4Add(ipset4 **ipset, const struct in_addr *a, uint8_t preflen); +static inline bool ipset4AddCidr(ipset4 **ipset, const struct cidr4 *cidr) +{ + return ipset4Add(ipset,&cidr->addr,cidr->preflen); +} +bool ipset4Check(ipset4 *ipset, const struct in_addr *a, uint8_t preflen); +void ipset4Print(ipset4 *ipset); + +void ipset6Destroy(ipset6 **ipset); +bool ipset6Add(ipset6 **ipset, const struct in6_addr *a, uint8_t preflen); +static inline bool ipset6AddCidr(ipset6 **ipset, const struct cidr6 *cidr) +{ + return ipset6Add(ipset,&cidr->addr,cidr->preflen); +} +bool ipset6Check(ipset6 *ipset, const struct in6_addr *a, uint8_t preflen); +void ipset6Print(ipset6 *ipset); + +void ipsetDestroy(ipset *ipset); +void ipsetPrint(ipset *ipset); diff --git a/tpws/resolver.c b/tpws/resolver.c index b9c204f..6fb25bb 100644 --- a/tpws/resolver.c +++ b/tpws/resolver.c @@ -103,7 +103,13 @@ static void *resolver_thread(void *arg) ri->ga_res = getaddrinfo(ri->dom,sport,&hints,&ai); if (!ri->ga_res) { - memcpy(&ri->ss, ai->ai_addr, ai->ai_addrlen); + if (ai->ai_addrlen>sizeof(ri->ss)) + { + DLOG_ERR("getaddrinfo returned too large address\n"); + ri->ga_res = EAI_FAIL; + } + else + memcpy(&ri->ss, ai->ai_addr, ai->ai_addrlen); freeaddrinfo(ai); } //printf("THREAD %d END JOB %s FIRST=%p\n", syscall(SYS_gettid), ri->dom, TAILQ_FIRST(&resolver.resolve_list)); diff --git a/tpws/resolver.h b/tpws/resolver.h index 3151717..d27c578 100644 --- a/tpws/resolver.h +++ b/tpws/resolver.h @@ -6,10 +6,12 @@ #include #include +#include "helpers.h" + struct resolve_item { char dom[256]; // request dom - struct sockaddr_storage ss; // resolve result + sockaddr_in46 ss; // resolve result int ga_res; // getaddrinfo result code uint16_t port; // request port void *ptr; diff --git a/tpws/tamper.c b/tpws/tamper.c index 8fc33ca..41f9626 100644 --- a/tpws/tamper.c +++ b/tpws/tamper.c @@ -1,22 +1,50 @@ #define _GNU_SOURCE -#include "tamper.h" -#include "hostlist.h" -#include "protocol.h" -#include "helpers.h" #include #include +#include "tamper.h" +#include "hostlist.h" +#include "ipset.h" +#include "protocol.h" +#include "helpers.h" -static bool dp_match_l3l4(struct desync_profile *dp, bool ipv6, uint16_t tcp_port) +const char *l7proto_str(t_l7proto l7) { - return \ - ((!ipv6 && dp->filter_ipv4) || (ipv6 && dp->filter_ipv6)) && - (!tcp_port || pf_in_range(tcp_port,&dp->pf_tcp)); -} -static bool dp_match(struct desync_profile *dp, bool ipv6, uint16_t tcp_port, const char *hostname) -{ - if (dp_match_l3l4(dp,ipv6,tcp_port)) + switch(l7) { + case HTTP: return "http"; + case TLS: return "tls"; + default: return "unknown"; + } +} +static bool l7_proto_match(t_l7proto l7proto, uint32_t filter_l7) +{ + return (l7proto==UNKNOWN && (filter_l7 & L7_PROTO_UNKNOWN)) || + (l7proto==HTTP && (filter_l7 & L7_PROTO_HTTP)) || + (l7proto==TLS && (filter_l7 & L7_PROTO_TLS)); +} + +static bool dp_match_l3l4(struct desync_profile *dp, const struct sockaddr *dest) +{ + return ((dest->sa_family==AF_INET && dp->filter_ipv4) || (dest->sa_family==AF_INET6 && dp->filter_ipv6)) && + pf_in_range(saport(dest), &dp->pf_tcp) && + IpsetCheck(dp, dest->sa_family==AF_INET ? &((struct sockaddr_in*)dest)->sin_addr : NULL, dest->sa_family==AF_INET6 ? &((struct sockaddr_in6*)dest)->sin6_addr : NULL); +} +static bool dp_impossible(struct desync_profile *dp, const char *hostname, t_l7proto l7proto) +{ + return !PROFILE_IPSETS_EMPTY(dp) && + ((dp->filter_l7 && !l7_proto_match(l7proto, dp->filter_l7)) || (!*dp->hostlist_auto_filename && !hostname && (dp->hostlist || dp->hostlist_exclude))); +} +static bool dp_match(struct desync_profile *dp, const struct sockaddr *dest, const char *hostname, t_l7proto l7proto) +{ + // impossible case, hard filter + // impossible check avoids relatively slow ipset search + if (!dp_impossible(dp,hostname,l7proto) && dp_match_l3l4(dp,dest)) + { + // soft filter + if (dp->filter_l7 && !l7_proto_match(l7proto, dp->filter_l7)) + return false; + // autohostlist profile matching l3/l4 filter always win if (*dp->hostlist_auto_filename) return true; @@ -32,13 +60,18 @@ static bool dp_match(struct desync_profile *dp, bool ipv6, uint16_t tcp_port, co } return false; } -static struct desync_profile *dp_find(struct desync_profile_list_head *head, bool ipv6, uint16_t tcp_port, const char *hostname) +static struct desync_profile *dp_find(struct desync_profile_list_head *head, const struct sockaddr *dest, const char *hostname, t_l7proto l7proto) { struct desync_profile_list *dpl; - VPRINT("desync profile search for hostname='%s' ipv6=%u tcp_port=%u\n", hostname ? hostname : "", ipv6, tcp_port); + if (params.debug) + { + char ip_port[48]; + ntop46_port(dest, ip_port,sizeof(ip_port)); + VPRINT("desync profile search for tcp target=%s l7proto=%s hostname='%s'\n", ip_port, l7proto_str(l7proto), hostname ? hostname : ""); + } LIST_FOREACH(dpl, head, next) { - if (dp_match(&dpl->dp,ipv6,tcp_port,hostname)) + if (dp_match(&dpl->dp,dest,hostname,l7proto)) { VPRINT("desync profile %d matches\n",dpl->dp.n); return &dpl->dp; @@ -49,7 +82,7 @@ static struct desync_profile *dp_find(struct desync_profile_list_head *head, boo } void apply_desync_profile(t_ctrack *ctrack, const struct sockaddr *dest) { - ctrack->dp = dp_find(¶ms.desync_profiles, dest->sa_family==AF_INET6, saport(dest), ctrack->hostname); + ctrack->dp = dp_find(¶ms.desync_profiles, dest, ctrack->hostname, ctrack->l7proto); } @@ -114,38 +147,54 @@ void tamper_out(t_ctrack *ctrack, const struct sockaddr *dest, uint8_t *segment, l7proto = UNKNOWN; } - if (ctrack->l7proto==UNKNOWN) ctrack->l7proto=l7proto; - if (bHaveHost) - { VPRINT("request hostname: %s\n", Host); - if (!ctrack->hostname) - { - if (!(ctrack->hostname=strdup(Host))) - { - DLOG_ERR("strdup hostname : out of memory\n"); - return; - } + if (ctrack->b_not_act) + { + VPRINT("Not acting on this request\n"); + return; + } - struct desync_profile *dp_prev = ctrack->dp; - apply_desync_profile(ctrack, dest); - if (ctrack->dp!=dp_prev) - VPRINT("desync profile changed by revealed hostname !\n"); - else if (*ctrack->dp->hostlist_auto_filename) - { - bool bHostExcluded; - if (!HostlistCheck(ctrack->dp, Host, &bHostExcluded)) - { - ctrack->b_ah_check = !bHostExcluded; - VPRINT("Not acting on this request\n"); - return; - } - } + bool bDiscoveredL7 = ctrack->l7proto==UNKNOWN && l7proto!=UNKNOWN; + if (bDiscoveredL7) + { + VPRINT("discovered l7 protocol\n"); + ctrack->l7proto=l7proto; + } + + bool bDiscoveredHostname = bHaveHost && !ctrack->hostname; + if (bDiscoveredHostname) + { + VPRINT("discovered hostname\n"); + if (!(ctrack->hostname=strdup(Host))) + { + DLOG_ERR("strdup hostname : out of memory\n"); + return; } } - - if (!ctrack->dp) return; + if (bDiscoveredL7 || bDiscoveredHostname) + { + struct desync_profile *dp_prev = ctrack->dp; + apply_desync_profile(ctrack, dest); + if (ctrack->dp!=dp_prev) + VPRINT("desync profile changed by revealed l7 protocol or hostname !\n"); + } + + if (bDiscoveredHostname && *ctrack->dp->hostlist_auto_filename) + { + bool bHostExcluded; + if (!HostlistCheck(ctrack->dp, Host, &bHostExcluded)) + { + ctrack->b_ah_check = !bHostExcluded; + VPRINT("Not acting on this request\n"); + ctrack->b_not_act = true; + return; + } + } + + if (!ctrack->dp) return; + switch(l7proto) { case HTTP: @@ -326,7 +375,7 @@ void tamper_out(t_ctrack *ctrack, const struct sockaddr *dest, uint8_t *segment, if (ctrack->dp->oob) *split_flags |= SPLIT_FLAG_OOB; } -static void auto_hostlist_reset_fail_counter(struct desync_profile *dp, const char *hostname) +static void auto_hostlist_reset_fail_counter(struct desync_profile *dp, const char *hostname, const char *client_ip_port, t_l7proto l7proto) { if (hostname) { @@ -337,12 +386,12 @@ static void auto_hostlist_reset_fail_counter(struct desync_profile *dp, const ch { HostFailPoolDel(&dp->hostlist_auto_fail_counters, fail_counter); VPRINT("auto hostlist (profile %d) : %s : fail counter reset. website is working.\n", dp->n, hostname); - HOSTLIST_DEBUGLOG_APPEND("%s : profile %d : fail counter reset. website is working.", hostname, dp->n); + HOSTLIST_DEBUGLOG_APPEND("%s : profile %d : client %s : proto %s : fail counter reset. website is working.", hostname, dp->n, client_ip_port, l7proto_str(l7proto)); } } } -static void auto_hostlist_failed(struct desync_profile *dp, const char *hostname) +static void auto_hostlist_failed(struct desync_profile *dp, const char *hostname, const char *client_ip_port, t_l7proto l7proto) { hostfail_pool *fail_counter; @@ -358,7 +407,7 @@ static void auto_hostlist_failed(struct desync_profile *dp, const char *hostname } fail_counter->counter++; VPRINT("auto hostlist (profile %d) : %s : fail counter %d/%d\n", dp->n , hostname, fail_counter->counter, dp->hostlist_auto_fail_threshold); - HOSTLIST_DEBUGLOG_APPEND("%s : profile %d : fail counter %d/%d", hostname, dp->n, fail_counter->counter, dp->hostlist_auto_fail_threshold); + HOSTLIST_DEBUGLOG_APPEND("%s : profile %d : client %s : proto %s : fail counter %d/%d", hostname, dp->n, client_ip_port, l7proto_str(l7proto), fail_counter->counter, dp->hostlist_auto_fail_threshold); if (fail_counter->counter >= dp->hostlist_auto_fail_threshold) { VPRINT("auto hostlist (profile %d) : fail threshold reached. adding %s to auto hostlist\n", dp->n , hostname); @@ -369,7 +418,7 @@ static void auto_hostlist_failed(struct desync_profile *dp, const char *hostname if (!HostlistCheck(dp, hostname, &bExcluded) && !bExcluded) { VPRINT("auto hostlist (profile %d) : adding %s to %s\n", dp->n, hostname, dp->hostlist_auto_filename); - HOSTLIST_DEBUGLOG_APPEND("%s : profile %d : adding to %s", hostname, dp->n, dp->hostlist_auto_filename); + HOSTLIST_DEBUGLOG_APPEND("%s : profile %d : client %s : proto %s : adding to %s", hostname, dp->n, client_ip_port, l7proto_str(l7proto), dp->hostlist_auto_filename); if (!StrPoolAddStr(&dp->hostlist, hostname)) { DLOG_ERR("StrPoolAddStr out of memory\n"); @@ -385,16 +434,22 @@ static void auto_hostlist_failed(struct desync_profile *dp, const char *hostname else { VPRINT("auto hostlist (profile %d) : NOT adding %s\n", dp->n, hostname); - HOSTLIST_DEBUGLOG_APPEND("%s : profile %d : NOT adding, duplicate detected", hostname, dp->n); + HOSTLIST_DEBUGLOG_APPEND("%s : profile %d : client %s : proto %s : NOT adding, duplicate detected", hostname, dp->n, client_ip_port, l7proto_str(l7proto)); } } } -void tamper_in(t_ctrack *ctrack, uint8_t *segment,size_t segment_buffer_size,size_t *size) +void tamper_in(t_ctrack *ctrack, const struct sockaddr *client, uint8_t *segment,size_t segment_buffer_size,size_t *size) { + DBGPRINT("tamper_in hostname=%s\n", ctrack->hostname); + bool bFail=false; - DBGPRINT("tamper_in hostname=%s\n", ctrack->hostname); + char client_ip_port[48]; + if (*params.hostlist_auto_debuglog) + ntop46_port((struct sockaddr*)client,client_ip_port,sizeof(client_ip_port)); + else + *client_ip_port=0; if (ctrack->dp && ctrack->b_ah_check) { @@ -409,7 +464,7 @@ void tamper_in(t_ctrack *ctrack, uint8_t *segment,size_t segment_buffer_size,siz if (bFail) { VPRINT("redirect to another domain detected. possibly DPI redirect.\n"); - HOSTLIST_DEBUGLOG_APPEND("%s : profile %d : redirect to another domain", ctrack->hostname, ctrack->dp->n); + HOSTLIST_DEBUGLOG_APPEND("%s : profile %d : client %s : proto %s : redirect to another domain", ctrack->hostname, ctrack->dp->n, client_ip_port, l7proto_str(ctrack->l7proto)); } else VPRINT("local or in-domain redirect detected. it's not a DPI redirect.\n"); @@ -419,17 +474,23 @@ void tamper_in(t_ctrack *ctrack, uint8_t *segment,size_t segment_buffer_size,siz // received not http reply. do not monitor this connection anymore VPRINT("incoming unknown HTTP data detected for hostname %s\n", ctrack->hostname); } - if (bFail) auto_hostlist_failed(ctrack->dp, ctrack->hostname); + if (bFail) auto_hostlist_failed(ctrack->dp, ctrack->hostname, client_ip_port, ctrack->l7proto); } - if (!bFail) auto_hostlist_reset_fail_counter(ctrack->dp, ctrack->hostname); + if (!bFail) auto_hostlist_reset_fail_counter(ctrack->dp, ctrack->hostname, client_ip_port, ctrack->l7proto); } ctrack->bTamperInCutoff = true; } -void rst_in(t_ctrack *ctrack) +void rst_in(t_ctrack *ctrack, const struct sockaddr *client) { DBGPRINT("rst_in hostname=%s\n", ctrack->hostname); + char client_ip_port[48]; + if (*params.hostlist_auto_debuglog) + ntop46_port((struct sockaddr*)client,client_ip_port,sizeof(client_ip_port)); + else + *client_ip_port=0; + if (ctrack->dp && ctrack->b_ah_check) { HostFailPoolPurgeRateLimited(&ctrack->dp->hostlist_auto_fail_counters); @@ -437,15 +498,21 @@ void rst_in(t_ctrack *ctrack) if (!ctrack->bTamperInCutoff && ctrack->hostname) { VPRINT("incoming RST detected for hostname %s\n", ctrack->hostname); - HOSTLIST_DEBUGLOG_APPEND("%s : profile %d : incoming RST", ctrack->hostname, ctrack->dp->n); - auto_hostlist_failed(ctrack->dp, ctrack->hostname); + HOSTLIST_DEBUGLOG_APPEND("%s : profile %d : client %s : proto %s : incoming RST", ctrack->hostname, ctrack->dp->n, client_ip_port, l7proto_str(ctrack->l7proto)); + auto_hostlist_failed(ctrack->dp, ctrack->hostname, client_ip_port, ctrack->l7proto); } } } -void hup_out(t_ctrack *ctrack) +void hup_out(t_ctrack *ctrack, const struct sockaddr *client) { DBGPRINT("hup_out hostname=%s\n", ctrack->hostname); + char client_ip_port[48]; + if (*params.hostlist_auto_debuglog) + ntop46_port((struct sockaddr*)client,client_ip_port,sizeof(client_ip_port)); + else + *client_ip_port=0; + if (ctrack->dp && ctrack->b_ah_check) { HostFailPoolPurgeRateLimited(&ctrack->dp->hostlist_auto_fail_counters); @@ -454,8 +521,8 @@ void hup_out(t_ctrack *ctrack) { // local leg dropped connection after first request. probably due to timeout. VPRINT("local leg closed connection after first request (timeout ?). hostname: %s\n", ctrack->hostname); - HOSTLIST_DEBUGLOG_APPEND("%s : profile %d : client closed connection without server reply", ctrack->hostname, ctrack->dp->n); - auto_hostlist_failed(ctrack->dp, ctrack->hostname); + HOSTLIST_DEBUGLOG_APPEND("%s : profile %d : client %s : proto %s : client closed connection without server reply", ctrack->hostname, ctrack->dp->n, client_ip_port, l7proto_str(ctrack->l7proto)); + auto_hostlist_failed(ctrack->dp, ctrack->hostname, client_ip_port, ctrack->l7proto); } } } diff --git a/tpws/tamper.h b/tpws/tamper.h index ccc5c6f..0cafee7 100644 --- a/tpws/tamper.h +++ b/tpws/tamper.h @@ -10,13 +10,18 @@ #define SPLIT_FLAG_OOB 0x02 typedef enum {UNKNOWN=0, HTTP, TLS} t_l7proto; +#define L7_PROTO_HTTP 1 +#define L7_PROTO_TLS 2 +#define L7_PROTO_UNKNOWN 0x80000000 +const char *l7proto_str(t_l7proto l7); + typedef struct { // common state t_l7proto l7proto; - bool bFirstReplyChecked; bool bTamperInCutoff; bool b_ah_check; + bool b_not_act; char *hostname; struct desync_profile *dp; // desync profile cache } t_ctrack; @@ -24,8 +29,8 @@ typedef struct void apply_desync_profile(t_ctrack *ctrack, const struct sockaddr *dest); void tamper_out(t_ctrack *ctrack, const struct sockaddr *dest, uint8_t *segment,size_t segment_buffer_size,size_t *size, size_t *split_pos, uint8_t *split_flags); -void tamper_in(t_ctrack *ctrack, uint8_t *segment,size_t segment_buffer_size,size_t *size); +void tamper_in(t_ctrack *ctrack, const struct sockaddr *client, uint8_t *segment,size_t segment_buffer_size,size_t *size); // connection reset by remote leg -void rst_in(t_ctrack *ctrack); +void rst_in(t_ctrack *ctrack, const struct sockaddr *client); // local leg closed connection (timeout waiting response ?) -void hup_out(t_ctrack *ctrack); +void hup_out(t_ctrack *ctrack, const struct sockaddr *client); diff --git a/tpws/tpws.c b/tpws/tpws.c index 3e49485..a9a1cc3 100644 --- a/tpws/tpws.c +++ b/tpws/tpws.c @@ -33,6 +33,7 @@ #include "tpws_conn.h" #include "hostlist.h" +#include "ipset.h" #include "params.h" #include "sec.h" #include "redirect.h" @@ -46,7 +47,7 @@ bool bHup = false; static void onhup(int sig) { printf("HUP received !\n"); - printf("Will reload hostlist on next request (if any)\n"); + printf("Will reload hostlists and ipsets on next request (if any)\n"); bHup = true; } // should be called in normal execution @@ -54,9 +55,9 @@ void dohup(void) { if (bHup) { - if (!LoadIncludeHostLists() || !LoadExcludeHostLists()) + if (!LoadIncludeHostLists() || !LoadExcludeHostLists() || !LoadIncludeIpsets() || !LoadExcludeIpsets()) { - // what will we do without hostlist ?? sure, gonna die + // what will we do without hostlist or ipset ?? sure, gonna die exit(1); } bHup = false; @@ -180,6 +181,9 @@ static void exithelp(void) " --new\t\t\t\t\t; begin new strategy\n" " --filter-l3=ipv4|ipv6\t\t\t; L3 protocol filter. multiple comma separated values allowed.\n" " --filter-tcp=[~]port1[-port2]\t\t; TCP port filter. ~ means negation\n" + " --filter-l7=[http|tls|unknown]\t\t; L6-L7 protocol filter. multiple comma separated values allowed.\n" + " --ipset=\t\t\t; ipset include filter (one ip/CIDR per line, ipv4 and ipv6 accepted, gzip supported, multiple ipsets allowed)\n" + " --ipset-exclude=\t\t; ipset exclude filter (one ip/CIDR per line, ipv4 and ipv6 accepted, gzip supported, multiple ipsets allowed)\n" "\nHOSTLIST FILTER:\n" " --hostlist=\t\t\t; only act on hosts in the list (one host per line, subdomains auto apply, gzip supported, multiple hostlists allowed)\n" " --hostlist-exclude=\t\t; do not act on hosts in the list (one host per line, subdomains auto apply, gzip supported, multiple hostlists allowed)\n" @@ -317,6 +321,35 @@ static bool wf_make_l3(char *opt, bool *ipv4, bool *ipv6) return true; } +static bool parse_l7_list(char *opt, uint32_t *l7) +{ + char *e,*p,c; + + for (p=opt,*l7=0 ; p ; ) + { + if ((e = strchr(p,','))) + { + c=*e; + *e=0; + } + + if (!strcmp(p,"http")) + *l7 |= L7_PROTO_HTTP; + else if (!strcmp(p,"tls")) + *l7 |= L7_PROTO_TLS; + else if (!strcmp(p,"unknown")) + *l7 |= L7_PROTO_UNKNOWN; + else return false; + + if (e) + { + *e++=c; + } + p = e; + } + return true; +} + void parse_params(int argc, char *argv[]) { int option_index = 0; @@ -409,21 +442,24 @@ void parse_params(int argc, char *argv[]) { "tamper-cutoff",required_argument,0,0 },// optidx=54 { "connect-bind-addr",required_argument,0,0 },// optidx=55 - { "new",no_argument,0,0 }, // optidx=56 - { "filter-l3",required_argument,0,0 }, // optidx=57 - { "filter-tcp",required_argument,0,0 }, // optidx=58 + { "new",no_argument,0,0 }, // optidx=56 + { "filter-l3",required_argument,0,0 }, // optidx=57 + { "filter-tcp",required_argument,0,0 }, // optidx=58 + { "filter-l7",required_argument,0,0 }, // optidx=59 + { "ipset",required_argument,0,0 }, // optidx=60 + { "ipset-exclude",required_argument,0,0 }, // optidx=61 #if defined(__FreeBSD__) - { "enable-pf",no_argument,0,0 },// optidx=59 + { "enable-pf",no_argument,0,0 },// optidx=62 #elif defined(__APPLE__) - { "local-tcp-user-timeout",required_argument,0,0 },// optidx=59 - { "remote-tcp-user-timeout",required_argument,0,0 },// optidx=60 + { "local-tcp-user-timeout",required_argument,0,0 }, // optidx=62 + { "remote-tcp-user-timeout",required_argument,0,0 }, // optidx=63 #elif defined(__linux__) - { "local-tcp-user-timeout",required_argument,0,0 },// optidx=59 - { "remote-tcp-user-timeout",required_argument,0,0 },// optidx=60 - { "mss",required_argument,0,0 },// optidx=61 + { "local-tcp-user-timeout",required_argument,0,0 }, // optidx=62 + { "remote-tcp-user-timeout",required_argument,0,0 }, // optidx=63 + { "mss",required_argument,0,0 }, // optidx=64 #ifdef SPLICE_PRESENT - { "nosplice",no_argument,0,0 },// optidx=62 + { "nosplice",no_argument,0,0 }, // optidx=65 #endif #endif { "hostlist-auto-retrans-threshold",optional_argument,0,0}, // ignored. for nfqws command line compatibility @@ -935,13 +971,36 @@ void parse_params(int argc, char *argv[]) exit_clean(1); } break; + case 59: /* filter-l7 */ + if (!parse_l7_list(optarg,&dp->filter_l7)) + { + DLOG_ERR("Invalid l7 filter : %s\n",optarg); + exit_clean(1); + } + break; + case 60: /* ipset */ + if (!strlist_add(&dp->ipset_files, optarg)) + { + DLOG_ERR("strlist_add failed\n"); + exit_clean(1); + } + params.tamper = true; + break; + case 61: /* ipset-exclude */ + if (!strlist_add(&dp->ipset_exclude_files, optarg)) + { + DLOG_ERR("strlist_add failed\n"); + exit_clean(1); + } + params.tamper = true; + break; #if defined(__FreeBSD__) - case 59: /* enable-pf */ + case 62: /* enable-pf */ params.pf_enable = true; break; #elif defined(__linux__) || defined(__APPLE__) - case 59: /* local-tcp-user-timeout */ + case 62: /* local-tcp-user-timeout */ params.tcp_user_timeout_local = atoi(optarg); if (params.tcp_user_timeout_local<0 || params.tcp_user_timeout_local>86400) { @@ -949,7 +1008,7 @@ void parse_params(int argc, char *argv[]) exit_clean(1); } break; - case 60: /* remote-tcp-user-timeout */ + case 63: /* remote-tcp-user-timeout */ params.tcp_user_timeout_remote = atoi(optarg); if (params.tcp_user_timeout_remote<0 || params.tcp_user_timeout_remote>86400) { @@ -960,7 +1019,7 @@ void parse_params(int argc, char *argv[]) #endif #if defined(__linux__) - case 61: /* mss */ + case 64: /* mss */ // this option does not work in any BSD and MacOS. OS may accept but it changes nothing dp->mss = atoi(optarg); if (dp->mss<88 || dp->mss>32767) @@ -970,7 +1029,7 @@ void parse_params(int argc, char *argv[]) } break; #ifdef SPLICE_PRESENT - case 62: /* nosplice */ + case 65: /* nosplice */ params.nosplice = true; break; #endif @@ -1021,6 +1080,16 @@ void parse_params(int argc, char *argv[]) DLOG_ERR("Exclude hostlist load failed\n"); exit_clean(1); } + if (!LoadIncludeIpsets()) + { + DLOG_ERR("Include ipset load failed\n"); + exit_clean(1); + } + if (!LoadExcludeIpsets()) + { + DLOG_ERR("Exclude ipset load failed\n"); + exit_clean(1); + } } @@ -1087,7 +1156,7 @@ static bool read_system_maxfiles(rlim_t *maxfile) return false; n=fscanf(F,"%ju",&um); fclose(F); - if (!n) return false; + if (n != 1) return false; *maxfile = (rlim_t)um; return true; #elif defined(BSD) @@ -1132,7 +1201,7 @@ static bool set_ulimit(void) // additional 1/2 for unpaired remote legs sending buffers // 16 for listen_fd, epoll, hostlist, ... #ifdef SPLICE_PRESENT - fdmax = (params.nosplice ? 2 : (params.tamper && !params.tamper_lim ? 4 : 6)) * params.maxconn; + fdmax = (rlim_t)(params.nosplice ? 2 : (params.tamper && !params.tamper_lim ? 4 : 6)) * (rlim_t)params.maxconn; #else fdmax = 2 * params.maxconn; #endif @@ -1177,6 +1246,8 @@ int main(int argc, char *argv[]) char ip_port[48]; srand(time(NULL)); + mask_from_preflen6_prepare(); + parse_params(argc, argv); if (params.daemon) daemonize(); diff --git a/tpws/tpws_conn.c b/tpws/tpws_conn.c index 3597ae8..66cbd21 100644 --- a/tpws/tpws_conn.c +++ b/tpws/tpws_conn.c @@ -569,7 +569,6 @@ static tproxy_conn_t* add_tcp_connection(int efd, struct tailhead *conn_list,int { struct sockaddr_storage orig_dst; tproxy_conn_t *conn; - int remote_fd=0; if (proxy_type==CONN_TYPE_TRANSPARENT) { @@ -597,19 +596,8 @@ static tproxy_conn_t* add_tcp_connection(int efd, struct tailhead *conn_list,int return 0; } - if (proxy_type==CONN_TYPE_TRANSPARENT) - { - if ((remote_fd = connect_remote((struct sockaddr *)&orig_dst, 0)) < 0) - { - DLOG_ERR("Failed to connect\n"); - close(local_fd); - return NULL; - } - } - if(!(conn = new_conn(local_fd, false))) { - if (remote_fd) close(remote_fd); close(local_fd); return NULL; } @@ -617,18 +605,33 @@ static tproxy_conn_t* add_tcp_connection(int efd, struct tailhead *conn_list,int conn->state = CONN_AVAILABLE; // accepted connection is immediately available conn->efd = efd; + socklen_t salen=sizeof(conn->client); + getpeername(conn->fd,(struct sockaddr *)&conn->client,&salen); + if (proxy_type==CONN_TYPE_TRANSPARENT) { - sacopy(&conn->dest, (struct sockaddr *)&orig_dst); + sa46copy(&conn->dest, (struct sockaddr *)&orig_dst); - if(!(conn->partner = new_conn(remote_fd, true))) + if(!(conn->partner = new_conn(0, true))) { free_conn(conn); - close(remote_fd); return NULL; } + conn->partner->partner = conn; conn->partner->efd = efd; + conn->partner->client = conn->client; + conn->partner->dest = conn->dest; + + apply_desync_profile(&conn->track, (struct sockaddr *)&conn->dest); + + if ((conn->partner->fd = connect_remote((struct sockaddr *)&orig_dst, conn->track.dp ? conn->track.dp->mss : 0)) < 0) + { + DLOG_ERR("Failed to connect\n"); + free_conn(conn->partner); + free_conn(conn); + return NULL; + } //remote_fd is connecting. Non-blocking connects are signaled as done by //socket being marked as ready for writing @@ -662,9 +665,6 @@ static tproxy_conn_t* add_tcp_connection(int efd, struct tailhead *conn_list,int TAILQ_INSERT_HEAD(conn_list, conn->partner, conn_ptrs); legs_remote++; } - - if (proxy_type==CONN_TYPE_TRANSPARENT) - apply_desync_profile(&conn->track, (struct sockaddr *)&conn->dest); return conn; } @@ -693,7 +693,7 @@ static bool check_connection_attempt(tproxy_conn_t *conn, int efd) { if (params.debug>=1) { - struct sockaddr_storage sa; + sockaddr_in46 sa; socklen_t salen=sizeof(sa); char ip_port[48]; @@ -815,6 +815,8 @@ static bool proxy_mode_connect_remote(tproxy_conn_t *conn, struct tailhead *conn } conn->partner->partner = conn; conn->partner->efd = conn->efd; + conn->partner->client = conn->client; + conn->partner->dest = conn->dest; if (!epoll_set(conn->partner, EPOLLOUT)) { DLOG_ERR("socks epoll_set error %d\n", errno); @@ -920,7 +922,7 @@ static bool handle_proxy_mode(tproxy_conn_t *conn, struct tailhead *conn_list) socks4_send_rep(conn->fd, S4_REP_FAILED); return false; } - conn->dest.ss_family = AF_INET; + ((struct sockaddr_in*)&conn->dest)->sin_family = AF_INET; ((struct sockaddr_in*)&conn->dest)->sin_port = m->port; ((struct sockaddr_in*)&conn->dest)->sin_addr.s_addr = m->ip; return proxy_mode_connect_remote(conn, conn_list); @@ -952,12 +954,12 @@ static bool handle_proxy_mode(tproxy_conn_t *conn, struct tailhead *conn_list) switch(m->atyp) { case S5_ATYP_IP4: - conn->dest.ss_family = AF_INET; + ((struct sockaddr_in*)&conn->dest)->sin_family = AF_INET; ((struct sockaddr_in*)&conn->dest)->sin_port = m->d4.port; ((struct sockaddr_in*)&conn->dest)->sin_addr = m->d4.addr; break; case S5_ATYP_IP6: - conn->dest.ss_family = AF_INET6; + ((struct sockaddr_in6*)&conn->dest)->sin6_family = AF_INET6; ((struct sockaddr_in6*)&conn->dest)->sin6_port = m->d6.port; ((struct sockaddr_in6*)&conn->dest)->sin6_addr = m->d6.addr; ((struct sockaddr_in6*)&conn->dest)->sin6_flowinfo = 0; @@ -1037,7 +1039,7 @@ static bool resolve_complete(struct resolve_item *ri, struct tailhead *conn_list DBGPRINT("resolve_complete put hostname : %s\n", ri->dom); conn->track.hostname = strdup(ri->dom); } - sacopy(&conn->dest, (struct sockaddr *)&ri->ss); + sa46copy(&conn->dest, (struct sockaddr *)&ri->ss); return proxy_mode_connect_remote(conn,conn_list); } } @@ -1074,7 +1076,7 @@ static void tamper(tproxy_conn_t *conn, uint8_t *segment, size_t segment_buffer_ if (conn->remote) { if (conn_partner_alive(conn) && !conn->partner->track.bTamperInCutoff) - tamper_in(&conn->partner->track,segment,segment_buffer_size,segment_size); + tamper_in(&conn->partner->track,(struct sockaddr*)&conn->partner->client,segment,segment_buffer_size,segment_size); } else { @@ -1524,18 +1526,11 @@ int event_loop(const int *listen_fd, size_t listen_fd_ct) else { print_legs(); - + if (params.debug>=1) { - struct sockaddr_storage sa; - socklen_t salen=sizeof(sa); char ip_port[48]; - - if (getpeername(conn->fd,(struct sockaddr *)&sa,&salen)) - *ip_port=0; - else - ntop46_port((struct sockaddr*)&sa,ip_port,sizeof(ip_port)); - + ntop46_port((struct sockaddr*)&conn->client,ip_port,sizeof(ip_port)); VPRINT("Socket fd=%d (local) connected from %s\n", conn->fd, ip_port); } set_user_timeout(conn->fd, params.tcp_user_timeout_local); @@ -1563,7 +1558,7 @@ int event_loop(const int *listen_fd, size_t listen_fd_ct) read_all_and_buffer(conn,3); if (errn==ECONNRESET && conn_partner_alive(conn)) { - if (conn->remote && params.tamper) rst_in(&conn->partner->track); + if (conn->remote && params.tamper) rst_in(&conn->partner->track,(struct sockaddr*)&conn->partner->client); struct linger lin; lin.l_onoff=1; @@ -1588,7 +1583,7 @@ int event_loop(const int *listen_fd, size_t listen_fd_ct) { DBGPRINT("EPOLLRDHUP\n"); read_all_and_buffer(conn,2); - if (!conn->remote && params.tamper) hup_out(&conn->track); + if (!conn->remote && params.tamper) hup_out(&conn->track,(struct sockaddr*)&conn->client); conn->state = CONN_RDHUP; // only writes. do not receive RDHUP anymore if (conn_has_unsent(conn)) diff --git a/tpws/tpws_conn.h b/tpws/tpws_conn.h index c52cbc8..9c81550 100644 --- a/tpws/tpws_conn.h +++ b/tpws/tpws_conn.h @@ -54,7 +54,7 @@ struct tproxy_conn int splice_pipe[2]; conn_state_t state; conn_type_t conn_type; - struct sockaddr_storage dest; + sockaddr_in46 client, dest; // ip:port of client, ip:port of target struct tproxy_conn *partner; // other leg time_t orphan_since;