mirror of
https://github.com/bol-van/zapret.git
synced 2024-11-26 20:20:53 +03:00
Compare commits
36 Commits
a8d8450230
...
5fe319e65c
Author | SHA1 | Date | |
---|---|---|---|
|
5fe319e65c | ||
|
97a36f3c18 | ||
|
0b2796c6da | ||
|
4628e65917 | ||
|
389b8337dc | ||
|
59c143ece5 | ||
|
f0957efc57 | ||
|
2eb6080cd0 | ||
|
cf4814df57 | ||
|
378f33d613 | ||
|
96f6f86787 | ||
|
bf82344e3b | ||
|
f9e24fa0a0 | ||
|
ab43cf14cb | ||
|
952902dc17 | ||
|
d9bd668f6e | ||
|
e6c918b8a6 | ||
|
4e1d93bf2c | ||
|
e1ecd8ecb0 | ||
|
7b3adeac82 | ||
|
6c8e67faab | ||
|
d760093f52 | ||
|
d3f540a62b | ||
|
755915a3ba | ||
|
e64a6bc9a4 | ||
|
fc200ac629 | ||
|
81ae646c5a | ||
|
2f46aec2be | ||
|
ebcb86844e | ||
|
ff85cd8c0c | ||
|
38fda46b74 | ||
|
e8012ee67f | ||
|
bd80daad97 | ||
|
916895e281 | ||
|
7ff4214b5b | ||
|
2cd6db3ba5 |
@ -1,3 +1,13 @@
|
|||||||
googlevideo.com
|
googlevideo.com
|
||||||
youtubei.googleapis.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
|
||||||
|
@ -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 --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-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=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
|
--dpi-desync=fake,disorder2 --dpi-desync-autottl=2 --dpi-desync-fooling=md5sig
|
||||||
|
@ -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 --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-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=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"
|
--dpi-desync=fake,disorder2 --dpi-desync-autottl=2 --dpi-desync-fooling=md5sig --hostlist-auto="%~dp0autohostlist.txt"
|
||||||
|
@ -964,6 +964,8 @@ report_strategy()
|
|||||||
# $3 - daemon
|
# $3 - daemon
|
||||||
echo
|
echo
|
||||||
if [ -n "$strategy" ]; then
|
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 "!!!!! $1: working strategy found for ipv${IPV} $2 : $3 $strategy !!!!!"
|
||||||
echo
|
echo
|
||||||
report_append "ipv${IPV} $2 $1 : $3 ${WF:+$WF }$strategy"
|
report_append "ipv${IPV} $2 $1 : $3 ${WF:+$WF }$strategy"
|
||||||
@ -1171,6 +1173,7 @@ pktws_check_domain_http_bypass()
|
|||||||
|
|
||||||
local strategy
|
local strategy
|
||||||
pktws_check_domain_http_bypass_ "$@"
|
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
|
report_strategy $1 $3 $PKTWSD
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1215,6 +1218,7 @@ pktws_check_domain_http3_bypass()
|
|||||||
|
|
||||||
local strategy
|
local strategy
|
||||||
pktws_check_domain_http3_bypass_ "$@"
|
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
|
report_strategy $1 $2 $PKTWSD
|
||||||
}
|
}
|
||||||
warn_mss()
|
warn_mss()
|
||||||
@ -1284,6 +1288,7 @@ tpws_check_domain_http_bypass()
|
|||||||
|
|
||||||
local strategy
|
local strategy
|
||||||
tpws_check_domain_http_bypass_ "$@"
|
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
|
report_strategy $1 $3 tpws
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -329,6 +329,25 @@ win_process_exists()
|
|||||||
tasklist /NH /FI "IMAGENAME eq ${1}.exe" | grep -q "^${1}.exe"
|
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()
|
std_ports()
|
||||||
{
|
{
|
||||||
HTTP_PORTS=${HTTP_PORTS:-80}
|
HTTP_PORTS=${HTTP_PORTS:-80}
|
||||||
|
43
common/custom.sh
Normal file
43
common/custom.sh
Normal file
@ -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
|
||||||
|
}
|
@ -3,15 +3,15 @@ readonly ipt_connbytes="-m connbytes --connbytes-dir=original --connbytes-mode=p
|
|||||||
|
|
||||||
ipt()
|
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()
|
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()
|
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()
|
ipt_add_del()
|
||||||
{
|
{
|
||||||
@ -134,7 +134,7 @@ unprepare_tpws_fw()
|
|||||||
ipt_print_op()
|
ipt_print_op()
|
||||||
{
|
{
|
||||||
if [ "$1" = "1" ]; then
|
if [ "$1" = "1" ]; then
|
||||||
echo "Adding ip$4tables rule for $3 : $2"
|
echo "Inserting ip$4tables rule for $3 : $2"
|
||||||
else
|
else
|
||||||
echo "Deleting ip$4tables rule for $3 : $2"
|
echo "Deleting ip$4tables rule for $3 : $2"
|
||||||
fi
|
fi
|
||||||
@ -437,7 +437,7 @@ zapret_do_firewall_rules_ipt()
|
|||||||
fi
|
fi
|
||||||
;;
|
;;
|
||||||
custom)
|
custom)
|
||||||
existf zapret_custom_firewall && zapret_custom_firewall $1
|
custom_runner zapret_custom_firewall $1
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
}
|
}
|
||||||
|
@ -199,7 +199,15 @@ nft_add_rule()
|
|||||||
# $2,$3,... - rule(s)
|
# $2,$3,... - rule(s)
|
||||||
local chain="$1"
|
local chain="$1"
|
||||||
shift
|
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()
|
nft_add_set_element()
|
||||||
{
|
{
|
||||||
@ -227,6 +235,7 @@ nft_clean_nfqws_rule()
|
|||||||
nft_add_nfqws_flow_exempt_rule()
|
nft_add_nfqws_flow_exempt_rule()
|
||||||
{
|
{
|
||||||
# $1 - rule (must be all filters in one var)
|
# $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\"
|
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
|
# 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\"
|
#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
|
# "$1" - rule for ipv4
|
||||||
# "$2" - rule for ipv6
|
# "$2" - rule for ipv6
|
||||||
# "$3" - comment
|
# "$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_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\"
|
[ "$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()
|
nft_print_op()
|
||||||
{
|
{
|
||||||
echo "Adding nftables ipv$3 rule for $2 : $1"
|
echo "Inserting nftables ipv$3 rule for $2 : $1"
|
||||||
}
|
}
|
||||||
_nft_fw_tpws4()
|
_nft_fw_tpws4()
|
||||||
{
|
{
|
||||||
@ -410,8 +420,8 @@ _nft_fw_tpws4()
|
|||||||
[ "$DISABLE_IPV4" = "1" -o -z "$1" ] || {
|
[ "$DISABLE_IPV4" = "1" -o -z "$1" ] || {
|
||||||
local filter="$1" port="$2"
|
local filter="$1" port="$2"
|
||||||
nft_print_op "$filter" "tpws (port $2)" 4
|
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_insert_rule dnat_output skuid != $WS_USER ${3:+oifname @wanif }$filter ip daddr != @nozapret $FW_EXTRA_POST 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_pre iifname @lanif $filter ip daddr != @nozapret $FW_EXTRA_POST dnat ip to $TPWS_LOCALHOST4:$port
|
||||||
prepare_route_localnet
|
prepare_route_localnet
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -425,9 +435,9 @@ _nft_fw_tpws6()
|
|||||||
[ "$DISABLE_IPV6" = "1" -o -z "$1" ] || {
|
[ "$DISABLE_IPV6" = "1" -o -z "$1" ] || {
|
||||||
local filter="$1" port="$2" DNAT6 i
|
local filter="$1" port="$2" DNAT6 i
|
||||||
nft_print_op "$filter" "tpws (port $port)" 6
|
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" ] && {
|
[ -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
|
for i in $3; do
|
||||||
_dnat6_target $i DNAT6
|
_dnat6_target $i DNAT6
|
||||||
# can be multiple tpws processes on different ports
|
# 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
|
nft_print_op "$filter" "nfqws postrouting (qnum $port)" 4
|
||||||
rule="${3:+oifname @wanif }$filter ip daddr != @nozapret"
|
rule="${3:+oifname @wanif }$filter ip daddr != @nozapret"
|
||||||
is_postnat && setmark="meta mark set meta mark or $DESYNC_MARK_POSTNAT"
|
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"
|
nft_add_nfqws_flow_exempt_rule "$rule"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -491,7 +501,7 @@ _nft_fw_nfqws_post6()
|
|||||||
nft_print_op "$filter" "nfqws postrouting (qnum $port)" 6
|
nft_print_op "$filter" "nfqws postrouting (qnum $port)" 6
|
||||||
rule="${3:+oifname @wanif6 }$filter ip6 daddr != @nozapret6"
|
rule="${3:+oifname @wanif6 }$filter ip6 daddr != @nozapret6"
|
||||||
is_postnat && setmark="meta mark set meta mark or $DESYNC_MARK_POSTNAT"
|
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"
|
nft_add_nfqws_flow_exempt_rule "$rule"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -515,7 +525,7 @@ _nft_fw_nfqws_pre4()
|
|||||||
local filter="$1" port="$2" rule
|
local filter="$1" port="$2" rule
|
||||||
nft_print_op "$filter" "nfqws prerouting (qnum $port)" 4
|
nft_print_op "$filter" "nfqws prerouting (qnum $port)" 4
|
||||||
rule="${3:+iifname @wanif }$filter ip saddr != @nozapret"
|
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()
|
_nft_fw_nfqws_pre6()
|
||||||
@ -528,7 +538,7 @@ _nft_fw_nfqws_pre6()
|
|||||||
local filter="$1" port="$2" rule
|
local filter="$1" port="$2" rule
|
||||||
nft_print_op "$filter" "nfqws prerouting (qnum $port)" 6
|
nft_print_op "$filter" "nfqws prerouting (qnum $port)" 6
|
||||||
rule="${3:+iifname @wanif6 }$filter ip6 saddr != @nozapret6"
|
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()
|
nft_fw_nfqws_pre()
|
||||||
@ -705,7 +715,7 @@ zapret_apply_firewall_rules_nft()
|
|||||||
POSTNAT=$POSTNAT_SAVE
|
POSTNAT=$POSTNAT_SAVE
|
||||||
;;
|
;;
|
||||||
custom)
|
custom)
|
||||||
existf zapret_custom_firewall_nft && zapret_custom_firewall_nft
|
custom_runner zapret_custom_firewall_nft
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
}
|
}
|
||||||
@ -734,6 +744,7 @@ zapret_unapply_firewall_nft()
|
|||||||
|
|
||||||
unprepare_route_localnet
|
unprepare_route_localnet
|
||||||
nft_del_firewall
|
nft_del_firewall
|
||||||
|
[ "$MODE" = custom ] && custom_runner zapret_custom_firewall_nft_flush
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
zapret_do_firewall_nft()
|
zapret_do_firewall_nft()
|
||||||
|
38
common/pf.sh
38
common/pf.sh
@ -106,6 +106,12 @@ pf_anchor_zapret_tables()
|
|||||||
|
|
||||||
eval $tblv="\"\$_tbl\""
|
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()
|
pf_anchor_port_target()
|
||||||
{
|
{
|
||||||
if [ "$MODE_HTTP" = "1" ] && [ "$MODE_HTTPS" = "1" ]; then
|
if [ "$MODE_HTTP" = "1" ] && [ "$MODE_HTTPS" = "1" ]; then
|
||||||
@ -119,9 +125,17 @@ pf_anchor_port_target()
|
|||||||
|
|
||||||
pf_anchor_zapret_v4_tpws()
|
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 lan in $IFACE_LAN; do
|
||||||
for t in $tbl; 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"
|
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
|
local tbl port
|
||||||
[ "$DISABLE_IPV4" = "1" ] || {
|
[ "$DISABLE_IPV4" = "1" ] || {
|
||||||
case $MODE in
|
case "${MODE_OVERRIDE:-$MODE}" in
|
||||||
tpws)
|
tpws)
|
||||||
[ ! "$MODE_HTTP" = "1" ] && [ ! "$MODE_HTTPS" = "1" ] && return
|
[ ! "$MODE_HTTP" = "1" ] && [ ! "$MODE_HTTPS" = "1" ] && return
|
||||||
pf_anchor_zapret_tables tbl zapret-user "$ZIPLIST_USER" zapret "$ZIPLIST"
|
pf_anchor_zapret_tables tbl zapret-user "$ZIPLIST_USER" zapret "$ZIPLIST"
|
||||||
@ -152,16 +166,24 @@ pf_anchor_zapret_v4()
|
|||||||
;;
|
;;
|
||||||
custom)
|
custom)
|
||||||
pf_anchor_zapret_tables tbl zapret-user "$ZIPLIST_USER" zapret "$ZIPLIST"
|
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
|
esac
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pf_anchor_zapret_v6_tpws()
|
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
|
# LAN link local is only for router
|
||||||
for lan in $IFACE_LAN; do
|
for lan in $IFACE_LAN; do
|
||||||
LL_LAN=$(get_ipv6_linklocal $lan)
|
LL_LAN=$(get_ipv6_linklocal $lan)
|
||||||
@ -188,7 +210,7 @@ pf_anchor_zapret_v6()
|
|||||||
local tbl port
|
local tbl port
|
||||||
|
|
||||||
[ "$DISABLE_IPV6" = "1" ] || {
|
[ "$DISABLE_IPV6" = "1" ] || {
|
||||||
case $MODE in
|
case "${MODE_OVERRIDE:-$MODE}" in
|
||||||
tpws)
|
tpws)
|
||||||
[ ! "$MODE_HTTP" = "1" ] && [ ! "$MODE_HTTPS" = "1" ] && return
|
[ ! "$MODE_HTTP" = "1" ] && [ ! "$MODE_HTTPS" = "1" ] && return
|
||||||
pf_anchor_zapret_tables tbl zapret6-user "$ZIPLIST_USER6" zapret6 "$ZIPLIST6"
|
pf_anchor_zapret_tables tbl zapret6-user "$ZIPLIST_USER6" zapret6 "$ZIPLIST6"
|
||||||
@ -196,7 +218,7 @@ pf_anchor_zapret_v6()
|
|||||||
;;
|
;;
|
||||||
custom)
|
custom)
|
||||||
pf_anchor_zapret_tables tbl zapret6-user "$ZIPLIST_USER6" zapret6 "$ZIPLIST6"
|
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
|
esac
|
||||||
}
|
}
|
||||||
|
@ -317,3 +317,15 @@ nfqws: multi-strategy
|
|||||||
v63:
|
v63:
|
||||||
|
|
||||||
tpws: multi-strategy
|
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
|
||||||
|
@ -19,8 +19,8 @@ For dpi desync attack :
|
|||||||
nft delete table inet ztest
|
nft delete table inet ztest
|
||||||
nft create table inet ztest
|
nft create table inet ztest
|
||||||
nft add chain inet ztest post "{type filter hook postrouting priority mangle;}"
|
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 meta mark and 0x40000000 == 0 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 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
|
# auto hostlist with avoiding wrong ACK numbers in RST,ACK packets sent by russian DPI
|
||||||
sysctl net.netfilter.nf_conntrack_tcp_be_liberal=1
|
sysctl net.netfilter.nf_conntrack_tcp_be_liberal=1
|
||||||
|
@ -97,7 +97,8 @@ Then we can reduce CPU load, refusing to process unnecessary packets.
|
|||||||
`iptables -t mangle -I POSTROUTING -o <external_interface> -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`
|
`iptables -t mangle -I POSTROUTING -o <external_interface> -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.
|
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 :
|
Some attacks require redirection of incoming packets :
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
zapret v.63
|
zapret v.64
|
||||||
|
|
||||||
English
|
English
|
||||||
-------
|
-------
|
||||||
@ -464,8 +464,8 @@ mark нужен, чтобы сгенерированный поддельный
|
|||||||
чтобы не допустить изменения порядка следования пакетов. Процессинг очереди - процесс отложенный.
|
чтобы не допустить изменения порядка следования пакетов. Процессинг очереди - процесс отложенный.
|
||||||
Если ядро имеет пакеты на отсылку вне очереди - оно их отправляет незамедлительно.
|
Если ядро имеет пакеты на отсылку вне очереди - оно их отправляет незамедлительно.
|
||||||
Изменение правильного порядка следования пакетов при десинхронизации ломает всю идею.
|
Изменение правильного порядка следования пакетов при десинхронизации ломает всю идею.
|
||||||
При отсутствии ограничения на connbytes, атака будет работать и без фильтра по mark.
|
Так же были замечены дедлоки при достаточно большой отсылке пакетов из nfqws и отсутствии mark фильтра.
|
||||||
Но лучше его все же оставить для увеличения скорости.
|
Процесс может зависнуть. Поэтому наличие фильтра по mark в ip/nf tables можно считать обязательным.
|
||||||
|
|
||||||
Почему --connbytes 1:6 :
|
Почему --connbytes 1:6 :
|
||||||
1 - для работы методов десинхронизации 0-й фазы и wssize
|
1 - для работы методов десинхронизации 0-й фазы и wssize
|
||||||
@ -981,10 +981,13 @@ Cкрипты с названием get_antifilter_* оперируют спис
|
|||||||
9) ipset/get_antifilter_allyouneed.sh. получает лист https://antifilter.download/list/allyouneed.lst.
|
9) ipset/get_antifilter_allyouneed.sh. получает лист https://antifilter.download/list/allyouneed.lst.
|
||||||
Суммарный список префиксов, созданный из ipsum.lst и subnet.lst.
|
Суммарный список префиксов, созданный из ipsum.lst и subnet.lst.
|
||||||
|
|
||||||
Все варианты рассмотренных скриптов автоматически создают и заполняют ipset.
|
10) ipset/get_refilter_ipsum.sh.
|
||||||
Варианты 2-9 дополнительно вызывают вариант 1.
|
Список берется отсюда : 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.
|
Если переменная не определена, то ресолвятся лишь листы для ipset nozapret/nozapret6.
|
||||||
|
|
||||||
Листы РКН все время изменяются. Возникают новые тенденции. Требования к RAM могут меняться.
|
Листы РКН все время изменяются. Возникают новые тенденции. Требования к RAM могут меняться.
|
||||||
@ -1111,7 +1114,11 @@ ipset/zapret-hosts-users-exclude.txt.gz или ipset/zapret-hosts-users-exclude.
|
|||||||
|
|
||||||
Поддомены учитываются автоматически. Например, строчка "ru" вносит в список "*.ru". Строчка "*.ru" в списке не сработает.
|
Поддомены учитываются автоматически. Например, строчка "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.
|
- кладется в ipset/zapret-hosts.txt.gz.
|
||||||
|
|
||||||
Чтобы обновить списки, перезапускать nfqws или tpws не нужно. Обновляете файлы, затем даете сигнал HUP.
|
Чтобы обновить списки, перезапускать nfqws или tpws не нужно. Обновляете файлы, затем даете сигнал HUP.
|
||||||
@ -1572,35 +1579,76 @@ nfset-ы принадлежат только одной таблице, след
|
|||||||
Вариант custom
|
Вариант custom
|
||||||
--------------
|
--------------
|
||||||
|
|
||||||
custom код вынесен в отдельный shell include
|
custom код вынесен в отдельные shell includes.
|
||||||
|
Поддерживается старый вариант в
|
||||||
/opt/zapret/init.d/sysv/custom
|
/opt/zapret/init.d/sysv/custom
|
||||||
или
|
|
||||||
/opt/zapret/init.d/openwrt/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_daemons
|
||||||
zapret_custom_firewall
|
zapret_custom_firewall
|
||||||
zapret_custom_firewall_nft
|
zapret_custom_firewall_nft
|
||||||
|
zapret_custom_firewall_nft_flush
|
||||||
|
|
||||||
В файле custom пишите ваш код, пользуясь хелперами из "functions" или "zapret".
|
Для macos
|
||||||
Смотрите как там сделано добавление iptables или запуск демонов.
|
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, является ли система роутером, имена интерфейсов, ...
|
типа наличия/отсутствия ipv6, является ли система роутером, имена интерфейсов, ...
|
||||||
Хелперы это учитывают, вам нужно сосредоточиться лишь на фильтрах {ip,nf}tables и
|
Хелперы это учитывают, вам нужно сосредоточиться лишь на фильтрах {ip,nf}tables и
|
||||||
параметрах демонов.
|
параметрах демонов.
|
||||||
|
|
||||||
Код для openwrt и sysv немного отличается. В sysv нужно обрабатывать и запуск, и остановку демонов.
|
|
||||||
Запуск это или остановка передается в параметре $1 (0 или 1).
|
|
||||||
В openwrt за остановку отвечает procd.
|
|
||||||
|
|
||||||
Для фаервола кастом пишется отдельно для iptables и nftables. Все очень похоже, но отличается
|
|
||||||
написание фильтров и названия процедур хелперов. Если вам не нужны iptables или nftables -
|
|
||||||
можете не писать соответствующую функцию.
|
|
||||||
|
|
||||||
Готовый custom скрипт custom-tpws4http-nfqws4https позволяет применить дурение
|
|
||||||
tpws к http и nfqws к https. При этом поддерживаются установки из config.
|
|
||||||
Его можно использовать как стартовую точку для написания своих скриптов.
|
|
||||||
|
|
||||||
|
|
||||||
Простая установка
|
Простая установка
|
||||||
-----------------
|
-----------------
|
||||||
|
@ -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> <zapret6> <zapret-user> ...
|
|
||||||
|
|
||||||
zapret_custom_firewall_v4()
|
|
||||||
{
|
|
||||||
pf_anchor_zapret_v4_tpws $TPPORT_MY
|
|
||||||
}
|
|
||||||
zapret_custom_firewall_v6()
|
|
||||||
{
|
|
||||||
pf_anchor_zapret_v6_tpws $TPPORT_MY
|
|
||||||
}
|
|
31
init.d/macos/custom.d.examples/50-extra-tpws
Normal file
31
init.d/macos/custom.d.examples/50-extra-tpws
Normal file
@ -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> <zapret6> <zapret-user> ...
|
||||||
|
|
||||||
|
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)
|
||||||
|
}
|
18
init.d/macos/custom.d.examples/90-inherit-tpws
Normal file
18
init.d/macos/custom.d.examples/90-inherit-tpws
Normal file
@ -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
|
||||||
|
}
|
18
init.d/macos/custom.d.examples/90-inherit-tpws-socks
Normal file
18
init.d/macos/custom.d.examples/90-inherit-tpws-socks
Normal file
@ -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
|
||||||
|
}
|
0
init.d/macos/custom.d/.keep
Normal file
0
init.d/macos/custom.d/.keep
Normal file
@ -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> <zapret6> <zapret-user> ...
|
|
||||||
|
|
||||||
zapret_custom_firewall_v4()
|
|
||||||
{
|
|
||||||
:
|
|
||||||
}
|
|
||||||
zapret_custom_firewall_v6()
|
|
||||||
{
|
|
||||||
:
|
|
||||||
}
|
|
@ -7,6 +7,8 @@ ZAPRET_CONFIG=${ZAPRET_CONFIG:-"$ZAPRET_RW/config"}
|
|||||||
. "$ZAPRET_BASE/common/base.sh"
|
. "$ZAPRET_BASE/common/base.sh"
|
||||||
. "$ZAPRET_BASE/common/pf.sh"
|
. "$ZAPRET_BASE/common/pf.sh"
|
||||||
. "$ZAPRET_BASE/common/list.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=$ZAPRET_BASE/ipset
|
||||||
. "$IPSET_DIR/def.sh"
|
. "$IPSET_DIR/def.sh"
|
||||||
@ -184,7 +186,7 @@ zapret_do_daemons()
|
|||||||
filter)
|
filter)
|
||||||
;;
|
;;
|
||||||
custom)
|
custom)
|
||||||
existf zapret_custom_daemons && zapret_custom_daemons $1
|
custom_runner zapret_custom_daemons $1
|
||||||
;;
|
;;
|
||||||
*)
|
*)
|
||||||
echo "unsupported MODE=$MODE"
|
echo "unsupported MODE=$MODE"
|
||||||
|
@ -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
|
|
||||||
}
|
|
@ -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
|
|
||||||
}
|
|
||||||
}
|
|
22
init.d/openwrt/custom.d.examples/10-inherit-nfqws
Normal file
22
init.d/openwrt/custom.d.examples/10-inherit-nfqws
Normal file
@ -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
|
||||||
|
}
|
22
init.d/openwrt/custom.d.examples/10-inherit-tpws
Normal file
22
init.d/openwrt/custom.d.examples/10-inherit-tpws
Normal file
@ -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
|
||||||
|
}
|
22
init.d/openwrt/custom.d.examples/10-inherit-tpws-socks
Normal file
22
init.d/openwrt/custom.d.examples/10-inherit-tpws-socks
Normal file
@ -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
|
||||||
|
}
|
@ -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
|
||||||
|
}
|
@ -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"
|
# 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()
|
zapret_custom_daemons()
|
||||||
{
|
{
|
||||||
# stop logic is managed by procd
|
# stop logic is managed by procd
|
||||||
|
|
||||||
local MODE_OVERRIDE=nfqws
|
local opt="--qnum=$QNUM_DHT4ALL $NFQWS_OPT_BASE $NFQWS_OPT_DESYNC_DHT"
|
||||||
local opt
|
run_daemon $DNUM_DHT4ALL $NFQWS "$opt"
|
||||||
|
|
||||||
start_daemons_procd
|
|
||||||
|
|
||||||
opt="--qnum=$QNUM2 $NFQWS_OPT_BASE $NFQWS_OPT_DESYNC_DHT"
|
|
||||||
run_daemon 100 $NFQWS "$opt"
|
|
||||||
}
|
}
|
||||||
zapret_custom_firewall()
|
zapret_custom_firewall()
|
||||||
{
|
{
|
||||||
# $1 - 1 - run, 0 - stop
|
# $1 - 1 - run, 0 - stop
|
||||||
|
|
||||||
local MODE_OVERRIDE=nfqws
|
|
||||||
local f uf4 uf6
|
local f uf4 uf6
|
||||||
local first_packet_only="$ipt_connbytes 1:1"
|
local first_packet_only="$ipt_connbytes 1:1"
|
||||||
local desync="-m mark ! --mark $DESYNC_MARK/$DESYNC_MARK"
|
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'
|
f='-p udp -m length --length 109:407 -m u32 --u32'
|
||||||
uf4='0>>22&0x3C@8>>16=0x6431'
|
uf4='0>>22&0x3C@8>>16=0x6431'
|
||||||
uf6='48>>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()
|
zapret_custom_firewall_nft()
|
||||||
{
|
{
|
||||||
# stop logic is not required
|
# stop logic is not required
|
||||||
|
|
||||||
local MODE_OVERRIDE=nfqws
|
|
||||||
local f
|
local f
|
||||||
local first_packet_only="$nft_connbytes 1"
|
local first_packet_only="$nft_connbytes 1"
|
||||||
local desync="mark and $DESYNC_MARK == 0"
|
local desync="mark and $DESYNC_MARK == 0"
|
||||||
|
|
||||||
zapret_apply_firewall_rules_nft
|
|
||||||
|
|
||||||
f="meta length 109-407 meta l4proto udp @th,64,16 0x6431"
|
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
|
||||||
}
|
}
|
77
init.d/openwrt/custom.d.examples/50-discord
Normal file
77
init.d/openwrt/custom.d.examples/50-discord
Normal file
File diff suppressed because one or more lines are too long
@ -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"
|
# 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
|
# 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()
|
zapret_custom_daemons()
|
||||||
{
|
{
|
||||||
# $1 - 1 - run, 0 - stop
|
# $1 - 1 - run, 0 - stop
|
||||||
|
|
||||||
local MODE_OVERRIDE=nfqws
|
local opt="--qnum=$QNUM_QUIC4ALL $NFQWS_OPT_BASE $NFQWS_OPT_DESYNC_QUIC"
|
||||||
local opt
|
run_daemon $DNUM_QUIC4ALL $NFQWS "$opt"
|
||||||
|
|
||||||
zapret_do_daemons $1
|
|
||||||
|
|
||||||
opt="--qnum=$QNUM2 $NFQWS_OPT_BASE $NFQWS_OPT_DESYNC_QUIC"
|
|
||||||
do_nfqws $1 100 "$opt"
|
|
||||||
}
|
}
|
||||||
zapret_custom_firewall()
|
zapret_custom_firewall()
|
||||||
{
|
{
|
||||||
# $1 - 1 - run, 0 - stop
|
# $1 - 1 - run, 0 - stop
|
||||||
|
|
||||||
local MODE_OVERRIDE=nfqws
|
|
||||||
local f
|
local f
|
||||||
local first_packets_only="$ipt_connbytes 1:3"
|
local first_packets_only="$ipt_connbytes 1:3"
|
||||||
local desync="-m mark ! --mark $DESYNC_MARK/$DESYNC_MARK"
|
local desync="-m mark ! --mark $DESYNC_MARK/$DESYNC_MARK"
|
||||||
|
|
||||||
zapret_do_firewall_rules_ipt $1
|
|
||||||
|
|
||||||
f="-p udp -m multiport --dports $QUIC_PORTS_IPT"
|
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()
|
zapret_custom_firewall_nft()
|
||||||
{
|
{
|
||||||
# stop logic is not required
|
# stop logic is not required
|
||||||
|
|
||||||
local MODE_OVERRIDE=nfqws
|
|
||||||
local f
|
local f
|
||||||
local first_packets_only="$nft_connbytes 1-3"
|
local first_packets_only="$nft_connbytes 1-3"
|
||||||
local desync="mark and $DESYNC_MARK == 0"
|
local desync="mark and $DESYNC_MARK == 0"
|
||||||
|
|
||||||
zapret_apply_firewall_rules_nft
|
|
||||||
|
|
||||||
f="udp dport {$QUIC_PORTS}"
|
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
|
||||||
}
|
}
|
0
init.d/openwrt/custom.d/.keep
Normal file
0
init.d/openwrt/custom.d/.keep
Normal file
@ -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
|
|
||||||
}
|
|
@ -12,6 +12,8 @@ ZAPRET_CONFIG=${ZAPRET_CONFIG:-"$ZAPRET_RW/config"}
|
|||||||
. "$ZAPRET_BASE/common/nft.sh"
|
. "$ZAPRET_BASE/common/nft.sh"
|
||||||
. "$ZAPRET_BASE/common/linux_fw.sh"
|
. "$ZAPRET_BASE/common/linux_fw.sh"
|
||||||
. "$ZAPRET_BASE/common/list.sh"
|
. "$ZAPRET_BASE/common/list.sh"
|
||||||
|
. "$ZAPRET_BASE/common/custom.sh"
|
||||||
|
CUSTOM_DIR="$ZAPRET_RW/init.d/openwrt"
|
||||||
|
|
||||||
[ -n "$QNUM" ] || QNUM=200
|
[ -n "$QNUM" ] || QNUM=200
|
||||||
[ -n "$TPPORT" ] || TPPORT=988
|
[ -n "$TPPORT" ] || TPPORT=988
|
||||||
@ -27,9 +29,6 @@ LINKLOCAL_WAIT_SEC=5
|
|||||||
|
|
||||||
IPSET_CR="$ZAPRET_BASE/ipset/create_ipset.sh"
|
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_EXCLUDE="-m set ! --match-set nozapret"
|
||||||
IPSET_EXCLUDE6="-m set ! --match-set nozapret6"
|
IPSET_EXCLUDE6="-m set ! --match-set nozapret6"
|
||||||
|
|
||||||
|
@ -173,7 +173,7 @@ start_daemons_procd()
|
|||||||
}
|
}
|
||||||
;;
|
;;
|
||||||
custom)
|
custom)
|
||||||
existf zapret_custom_daemons && zapret_custom_daemons $1
|
custom_runner zapret_custom_daemons $1
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
|
|
||||||
|
@ -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
|
|
||||||
}
|
|
@ -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
|
|
||||||
}
|
|
||||||
}
|
|
22
init.d/sysv/custom.d.examples/10-inherit-nfqws
Normal file
22
init.d/sysv/custom.d.examples/10-inherit-nfqws
Normal file
@ -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
|
||||||
|
}
|
22
init.d/sysv/custom.d.examples/10-inherit-tpws
Normal file
22
init.d/sysv/custom.d.examples/10-inherit-tpws
Normal file
@ -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
|
||||||
|
}
|
22
init.d/sysv/custom.d.examples/10-inherit-tpws-socks
Normal file
22
init.d/sysv/custom.d.examples/10-inherit-tpws-socks
Normal file
@ -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
|
||||||
|
}
|
@ -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
|
||||||
|
}
|
@ -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"
|
# 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()
|
zapret_custom_daemons()
|
||||||
{
|
{
|
||||||
# stop logic is managed by procd
|
# stop logic is managed by procd
|
||||||
|
|
||||||
local MODE_OVERRIDE=nfqws
|
local opt="--qnum=$QNUM_DHT4ALL $NFQWS_OPT_BASE $NFQWS_OPT_DESYNC_DHT"
|
||||||
local opt
|
do_nfqws $1 $DNUM_DHT4ALL "$opt"
|
||||||
|
|
||||||
zapret_do_daemons $1
|
|
||||||
|
|
||||||
opt="--qnum=$QNUM2 $NFQWS_OPT_BASE $NFQWS_OPT_DESYNC_DHT"
|
|
||||||
do_nfqws $1 100 "$opt"
|
|
||||||
}
|
}
|
||||||
zapret_custom_firewall()
|
zapret_custom_firewall()
|
||||||
{
|
{
|
||||||
# $1 - 1 - run, 0 - stop
|
# $1 - 1 - run, 0 - stop
|
||||||
|
|
||||||
local MODE_OVERRIDE=nfqws
|
|
||||||
local f uf4 uf6
|
local f uf4 uf6
|
||||||
local first_packet_only="$ipt_connbytes 1:1"
|
local first_packet_only="$ipt_connbytes 1:1"
|
||||||
local desync="-m mark ! --mark $DESYNC_MARK/$DESYNC_MARK"
|
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'
|
f='-p udp -m length --length 109:407 -m u32 --u32'
|
||||||
uf4='0>>22&0x3C@8>>16=0x6431'
|
uf4='0>>22&0x3C@8>>16=0x6431'
|
||||||
uf6='48>>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()
|
zapret_custom_firewall_nft()
|
||||||
{
|
{
|
||||||
# stop logic is not required
|
# stop logic is not required
|
||||||
|
|
||||||
local MODE_OVERRIDE=nfqws
|
|
||||||
local f
|
local f
|
||||||
local first_packet_only="$nft_connbytes 1"
|
local first_packet_only="$nft_connbytes 1"
|
||||||
local desync="mark and $DESYNC_MARK == 0"
|
local desync="mark and $DESYNC_MARK == 0"
|
||||||
|
|
||||||
zapret_apply_firewall_rules_nft
|
|
||||||
|
|
||||||
f="meta length 109-407 meta l4proto udp @th,64,16 0x6431"
|
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
|
||||||
}
|
}
|
||||||
|
|
77
init.d/sysv/custom.d.examples/50-discord
Normal file
77
init.d/sysv/custom.d.examples/50-discord
Normal file
File diff suppressed because one or more lines are too long
@ -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"
|
# 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
|
# 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()
|
zapret_custom_daemons()
|
||||||
{
|
{
|
||||||
# stop logic is managed by procd
|
# $1 - 1 - run, 0 - stop
|
||||||
|
|
||||||
local MODE_OVERRIDE=nfqws
|
local opt="--qnum=$QNUM_QUIC4ALL $NFQWS_OPT_BASE $NFQWS_OPT_DESYNC_QUIC"
|
||||||
local opt
|
do_nfqws $1 $DNUM_QUIC4ALL "$opt"
|
||||||
|
|
||||||
start_daemons_procd
|
|
||||||
|
|
||||||
opt="--qnum=$QNUM2 $NFQWS_OPT_BASE $NFQWS_OPT_DESYNC_QUIC"
|
|
||||||
run_daemon 100 $NFQWS "$opt"
|
|
||||||
}
|
}
|
||||||
zapret_custom_firewall()
|
zapret_custom_firewall()
|
||||||
{
|
{
|
||||||
# $1 - 1 - run, 0 - stop
|
# $1 - 1 - run, 0 - stop
|
||||||
|
|
||||||
local MODE_OVERRIDE=nfqws
|
|
||||||
local f
|
local f
|
||||||
local first_packets_only="$ipt_connbytes 1:3"
|
local first_packets_only="$ipt_connbytes 1:3"
|
||||||
local desync="-m mark ! --mark $DESYNC_MARK/$DESYNC_MARK"
|
local desync="-m mark ! --mark $DESYNC_MARK/$DESYNC_MARK"
|
||||||
|
|
||||||
zapret_do_firewall_rules_ipt $1
|
|
||||||
|
|
||||||
f="-p udp -m multiport --dports $QUIC_PORTS_IPT"
|
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()
|
zapret_custom_firewall_nft()
|
||||||
{
|
{
|
||||||
# stop logic is not required
|
# stop logic is not required
|
||||||
|
|
||||||
local MODE_OVERRIDE=nfqws
|
|
||||||
local f
|
local f
|
||||||
local first_packets_only="$nft_connbytes 1-3"
|
local first_packets_only="$nft_connbytes 1-3"
|
||||||
local desync="mark and $DESYNC_MARK == 0"
|
local desync="mark and $DESYNC_MARK == 0"
|
||||||
|
|
||||||
zapret_apply_firewall_rules_nft
|
|
||||||
|
|
||||||
f="udp dport {$QUIC_PORTS}"
|
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
|
||||||
}
|
}
|
0
init.d/sysv/custom.d/.keep
Normal file
0
init.d/sysv/custom.d/.keep
Normal file
@ -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
|
|
||||||
}
|
|
@ -12,6 +12,8 @@ ZAPRET_CONFIG=${ZAPRET_CONFIG:-"$ZAPRET_RW/config"}
|
|||||||
. "$ZAPRET_BASE/common/nft.sh"
|
. "$ZAPRET_BASE/common/nft.sh"
|
||||||
. "$ZAPRET_BASE/common/linux_fw.sh"
|
. "$ZAPRET_BASE/common/linux_fw.sh"
|
||||||
. "$ZAPRET_BASE/common/list.sh"
|
. "$ZAPRET_BASE/common/list.sh"
|
||||||
|
. "$ZAPRET_BASE/common/custom.sh"
|
||||||
|
CUSTOM_DIR="$ZAPRET_RW/init.d/sysv"
|
||||||
|
|
||||||
|
|
||||||
user_exists()
|
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
|
# max wait time for the link local ipv6 on the LAN interface
|
||||||
LINKLOCAL_WAIT_SEC=5
|
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_EXCLUDE="-m set ! --match-set nozapret"
|
||||||
IPSET_EXCLUDE6="-m set ! --match-set nozapret6"
|
IPSET_EXCLUDE6="-m set ! --match-set nozapret6"
|
||||||
|
|
||||||
@ -341,7 +340,7 @@ zapret_do_daemons()
|
|||||||
}
|
}
|
||||||
;;
|
;;
|
||||||
custom)
|
custom)
|
||||||
existf zapret_custom_daemons && zapret_custom_daemons $1
|
custom_runner zapret_custom_daemons $1
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
|
|
||||||
|
@ -29,11 +29,11 @@ check_dir()
|
|||||||
fi
|
fi
|
||||||
[ -n "$out" ]
|
[ -n "$out" ]
|
||||||
else
|
else
|
||||||
echo "$exe is not executable. set proper chmod."
|
echo >&2 "$exe is not executable. set proper chmod."
|
||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
else
|
else
|
||||||
echo "$exe is absent"
|
echo >&2 "$exe is absent"
|
||||||
return 2
|
return 2
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
@ -138,6 +138,15 @@ select_mode_mode()
|
|||||||
echo ..edited..
|
echo ..edited..
|
||||||
done
|
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()
|
select_mode_http()
|
||||||
{
|
{
|
||||||
@ -210,10 +219,10 @@ select_getlist()
|
|||||||
echo
|
echo
|
||||||
if ask_yes_no $D "do you want to auto download ip/host list"; then
|
if ask_yes_no $D "do you want to auto download ip/host list"; then
|
||||||
if [ "$MODE_FILTER" = "hostlist" ] ; 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"
|
GETLIST_DEF="get_antizapret_domains.sh"
|
||||||
else
|
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"
|
GETLIST_DEF="get_antifilter_allyouneed.sh"
|
||||||
fi
|
fi
|
||||||
ask_list GETLIST "$GETLISTS" "$GETLIST_DEF" && write_config_var GETLIST
|
ask_list GETLIST "$GETLISTS" "$GETLIST_DEF" && write_config_var GETLIST
|
||||||
@ -393,7 +402,7 @@ default_files()
|
|||||||
for dir in openwrt sysv macos; do
|
for dir in openwrt sysv macos; do
|
||||||
[ -d "$1/init.d/$dir" ] && {
|
[ -d "$1/init.d/$dir" ] && {
|
||||||
[ -d "$2/init.d/$dir" ] || mkdir -p "$2/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
|
done
|
||||||
}
|
}
|
||||||
@ -453,6 +462,8 @@ files/huawei/E8372/zapret \
|
|||||||
files/huawei/E8372/run-zapret-ip \
|
files/huawei/E8372/run-zapret-ip \
|
||||||
ipset/get_exclude.sh \
|
ipset/get_exclude.sh \
|
||||||
ipset/clear_lists.sh \
|
ipset/clear_lists.sh \
|
||||||
|
ipset/get_refilter_domains.sh \
|
||||||
|
ipset/get_refilter_ipsum.sh \
|
||||||
ipset/get_antifilter_ipresolve.sh \
|
ipset/get_antifilter_ipresolve.sh \
|
||||||
ipset/get_reestr_resolvable_domains.sh \
|
ipset/get_reestr_resolvable_domains.sh \
|
||||||
ipset/get_config.sh \
|
ipset/get_config.sh \
|
||||||
@ -484,7 +495,11 @@ _backup_settings()
|
|||||||
{
|
{
|
||||||
local i=0
|
local i=0
|
||||||
for f in "$@"; do
|
for f in "$@"; do
|
||||||
|
# safety check
|
||||||
|
[ -z "$f" -o "$f" = "/" ] && continue
|
||||||
|
|
||||||
[ -f "$ZAPRET_TARGET/$f" ] && cp -f "$ZAPRET_TARGET/$f" "/tmp/zapret-bkp-$i"
|
[ -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))
|
i=$(($i+1))
|
||||||
done
|
done
|
||||||
}
|
}
|
||||||
@ -492,7 +507,14 @@ _restore_settings()
|
|||||||
{
|
{
|
||||||
local i=0
|
local i=0
|
||||||
for f in "$@"; do
|
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"
|
[ -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))
|
i=$(($i+1))
|
||||||
done
|
done
|
||||||
}
|
}
|
||||||
@ -500,7 +522,7 @@ backup_restore_settings()
|
|||||||
{
|
{
|
||||||
# $1 - 1 - backup, 0 - restore
|
# $1 - 1 - backup, 0 - restore
|
||||||
local mode=$1
|
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()
|
check_location()
|
||||||
@ -623,6 +645,7 @@ check_dns()
|
|||||||
install_systemd()
|
install_systemd()
|
||||||
{
|
{
|
||||||
INIT_SCRIPT_SRC="$EXEDIR/init.d/sysv/zapret"
|
INIT_SCRIPT_SRC="$EXEDIR/init.d/sysv/zapret"
|
||||||
|
CUSTOM_DIR="$ZAPRET_RW/init.d/sysv"
|
||||||
|
|
||||||
check_bins
|
check_bins
|
||||||
require_root
|
require_root
|
||||||
@ -650,6 +673,8 @@ _install_sysv()
|
|||||||
{
|
{
|
||||||
# $1 - install init script
|
# $1 - install init script
|
||||||
|
|
||||||
|
CUSTOM_DIR="$ZAPRET_RW/init.d/sysv"
|
||||||
|
|
||||||
check_bins
|
check_bins
|
||||||
require_root
|
require_root
|
||||||
check_readonly_system
|
check_readonly_system
|
||||||
@ -687,6 +712,7 @@ install_openrc()
|
|||||||
install_linux()
|
install_linux()
|
||||||
{
|
{
|
||||||
INIT_SCRIPT_SRC="$EXEDIR/init.d/sysv/zapret"
|
INIT_SCRIPT_SRC="$EXEDIR/init.d/sysv/zapret"
|
||||||
|
CUSTOM_DIR="$ZAPRET_RW/init.d/sysv"
|
||||||
|
|
||||||
check_bins
|
check_bins
|
||||||
require_root
|
require_root
|
||||||
@ -757,6 +783,7 @@ deoffload_openwrt_firewall()
|
|||||||
install_openwrt()
|
install_openwrt()
|
||||||
{
|
{
|
||||||
INIT_SCRIPT_SRC="$EXEDIR/init.d/openwrt/zapret"
|
INIT_SCRIPT_SRC="$EXEDIR/init.d/openwrt/zapret"
|
||||||
|
CUSTOM_DIR="$ZAPRET_RW/init.d/openwrt"
|
||||||
FW_SCRIPT_SRC="$EXEDIR/init.d/openwrt/firewall.zapret"
|
FW_SCRIPT_SRC="$EXEDIR/init.d/openwrt/firewall.zapret"
|
||||||
OPENWRT_FW_INCLUDE=/etc/firewall.zapret
|
OPENWRT_FW_INCLUDE=/etc/firewall.zapret
|
||||||
OPENWRT_IFACE_HOOK="$EXEDIR/init.d/openwrt/90-zapret"
|
OPENWRT_IFACE_HOOK="$EXEDIR/init.d/openwrt/90-zapret"
|
||||||
@ -829,6 +856,7 @@ macos_fw_reload_trigger_set()
|
|||||||
install_macos()
|
install_macos()
|
||||||
{
|
{
|
||||||
INIT_SCRIPT_SRC="$EXEDIR/init.d/macos/zapret"
|
INIT_SCRIPT_SRC="$EXEDIR/init.d/macos/zapret"
|
||||||
|
CUSTOM_DIR="$ZAPRET_RW/init.d/macos"
|
||||||
|
|
||||||
# compile before root
|
# compile before root
|
||||||
check_bins
|
check_bins
|
||||||
|
@ -4,12 +4,12 @@
|
|||||||
# $1=no-update - do not update ipset, only create if its absent
|
# $1=no-update - do not update ipset, only create if its absent
|
||||||
# $1=clear - clear ipset
|
# $1=clear - clear ipset
|
||||||
|
|
||||||
IPSET_DIR="$(dirname "$0")"
|
EXEDIR="$(dirname "$0")"
|
||||||
IPSET_DIR="$(cd "$IPSET_DIR"; pwd)"
|
EXEDIR="$(cd "$EXEDIR"; pwd)"
|
||||||
|
|
||||||
. "$IPSET_DIR/def.sh"
|
. "$EXEDIR/def.sh"
|
||||||
. "$IPSET_DIR/../common/fwtype.sh"
|
. "$ZAPRET_BASE/common/fwtype.sh"
|
||||||
. "$IPSET_DIR/../common/nft.sh"
|
. "$ZAPRET_BASE/common/nft.sh"
|
||||||
|
|
||||||
IPSET_CMD="$TMPDIR/ipset_cmd.txt"
|
IPSET_CMD="$TMPDIR/ipset_cmd.txt"
|
||||||
IPSET_SAVERAM_CHUNK_SIZE=20000
|
IPSET_SAVERAM_CHUNK_SIZE=20000
|
||||||
@ -119,13 +119,12 @@ nfset_get_script_multi()
|
|||||||
local set=$1 nonempty N=1 f
|
local set=$1 nonempty N=1 f
|
||||||
|
|
||||||
shift
|
shift
|
||||||
|
|
||||||
# first we need to make sure at least one element exists or nft will fail
|
# first we need to make sure at least one element exists or nft will fail
|
||||||
while :
|
while :
|
||||||
do
|
do
|
||||||
eval f=\$$N
|
eval f=\$$N
|
||||||
[ -n "$f" ] || break
|
[ -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 "$nonempty" ] && break
|
||||||
N=$(($N+1))
|
N=$(($N+1))
|
||||||
done
|
done
|
||||||
|
46
ipset/def.sh
46
ipset/def.sh
@ -1,10 +1,12 @@
|
|||||||
[ -n "$IPSET_DIR" ] || {
|
EXEDIR="$(dirname "$0")"
|
||||||
IPSET_DIR="$(dirname "$0")"
|
EXEDIR="$(cd "$EXEDIR"; pwd)"
|
||||||
IPSET_DIR="$(cd "$IPSET_DIR"; 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"
|
. "$ZAPRET_CONFIG"
|
||||||
. "$IPSET_DIR/../common/base.sh"
|
. "$ZAPRET_BASE/common/base.sh"
|
||||||
|
|
||||||
[ -z "$TMPDIR" ] && TMPDIR=/tmp
|
[ -z "$TMPDIR" ] && TMPDIR=/tmp
|
||||||
[ -z "$GZIP_LISTS" ] && GZIP_LISTS=1
|
[ -z "$GZIP_LISTS" ] && GZIP_LISTS=1
|
||||||
@ -21,27 +23,27 @@ ZIPSET=zapret
|
|||||||
ZIPSET6=zapret6
|
ZIPSET6=zapret6
|
||||||
ZIPSET_EXCLUDE=nozapret
|
ZIPSET_EXCLUDE=nozapret
|
||||||
ZIPSET_EXCLUDE6=nozapret6
|
ZIPSET_EXCLUDE6=nozapret6
|
||||||
ZIPLIST="$IPSET_DIR/zapret-ip.txt"
|
ZIPLIST="$IPSET_RW_DIR/zapret-ip.txt"
|
||||||
ZIPLIST6="$IPSET_DIR/zapret-ip6.txt"
|
ZIPLIST6="$IPSET_RW_DIR/zapret-ip6.txt"
|
||||||
ZIPLIST_EXCLUDE="$IPSET_DIR/zapret-ip-exclude.txt"
|
ZIPLIST_EXCLUDE="$IPSET_RW_DIR/zapret-ip-exclude.txt"
|
||||||
ZIPLIST_EXCLUDE6="$IPSET_DIR/zapret-ip-exclude6.txt"
|
ZIPLIST_EXCLUDE6="$IPSET_RW_DIR/zapret-ip-exclude6.txt"
|
||||||
ZIPLIST_USER="$IPSET_DIR/zapret-ip-user.txt"
|
ZIPLIST_USER="$IPSET_RW_DIR/zapret-ip-user.txt"
|
||||||
ZIPLIST_USER6="$IPSET_DIR/zapret-ip-user6.txt"
|
ZIPLIST_USER6="$IPSET_RW_DIR/zapret-ip-user6.txt"
|
||||||
ZUSERLIST="$IPSET_DIR/zapret-hosts-user.txt"
|
ZUSERLIST="$IPSET_RW_DIR/zapret-hosts-user.txt"
|
||||||
ZHOSTLIST="$IPSET_DIR/zapret-hosts.txt"
|
ZHOSTLIST="$IPSET_RW_DIR/zapret-hosts.txt"
|
||||||
|
|
||||||
ZIPSET_IPBAN=ipban
|
ZIPSET_IPBAN=ipban
|
||||||
ZIPSET_IPBAN6=ipban6
|
ZIPSET_IPBAN6=ipban6
|
||||||
ZIPLIST_IPBAN="$IPSET_DIR/zapret-ip-ipban.txt"
|
ZIPLIST_IPBAN="$IPSET_RW_DIR/zapret-ip-ipban.txt"
|
||||||
ZIPLIST_IPBAN6="$IPSET_DIR/zapret-ip-ipban6.txt"
|
ZIPLIST_IPBAN6="$IPSET_RW_DIR/zapret-ip-ipban6.txt"
|
||||||
ZIPLIST_USER_IPBAN="$IPSET_DIR/zapret-ip-user-ipban.txt"
|
ZIPLIST_USER_IPBAN="$IPSET_RW_DIR/zapret-ip-user-ipban.txt"
|
||||||
ZIPLIST_USER_IPBAN6="$IPSET_DIR/zapret-ip-user-ipban6.txt"
|
ZIPLIST_USER_IPBAN6="$IPSET_RW_DIR/zapret-ip-user-ipban6.txt"
|
||||||
ZUSERLIST_IPBAN="$IPSET_DIR/zapret-hosts-user-ipban.txt"
|
ZUSERLIST_IPBAN="$IPSET_RW_DIR/zapret-hosts-user-ipban.txt"
|
||||||
ZUSERLIST_EXCLUDE="$IPSET_DIR/zapret-hosts-user-exclude.txt"
|
ZUSERLIST_EXCLUDE="$IPSET_RW_DIR/zapret-hosts-user-exclude.txt"
|
||||||
|
|
||||||
|
|
||||||
[ -n "$IP2NET" ] || IP2NET="$IPSET_DIR/../ip2net/ip2net"
|
[ -n "$IP2NET" ] || IP2NET="$ZAPRET_BASE/ip2net/ip2net"
|
||||||
[ -n "$MDIG" ] || MDIG="$IPSET_DIR/../mdig/mdig"
|
[ -n "$MDIG" ] || MDIG="$ZAPRET_BASE/mdig/mdig"
|
||||||
[ -z "$MDIG_THREADS" ] && MDIG_THREADS=30
|
[ -z "$MDIG_THREADS" ] && MDIG_THREADS=30
|
||||||
|
|
||||||
|
|
||||||
|
42
ipset/get_refilter_domains.sh
Executable file
42
ipset/get_refilter_domains.sh
Executable file
@ -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
|
39
ipset/get_refilter_ipsum.sh
Executable file
39
ipset/get_refilter_ipsum.sh
Executable file
@ -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"
|
@ -630,7 +630,6 @@ static uint8_t dpi_desync_tcp_packet_play(bool replay, size_t reasm_offset, uint
|
|||||||
{
|
{
|
||||||
dp = ctrack->dp;
|
dp = ctrack->dp;
|
||||||
ctrack_replay = ctrack;
|
ctrack_replay = ctrack;
|
||||||
maybe_cutoff(ctrack, IPPROTO_TCP);
|
|
||||||
}
|
}
|
||||||
if (dp)
|
if (dp)
|
||||||
DLOG("using cached desync profile %d\n",dp->n);
|
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");
|
DLOG("matching desync profile not found\n");
|
||||||
return verdict;
|
return verdict;
|
||||||
}
|
}
|
||||||
|
maybe_cutoff(ctrack, IPPROTO_TCP);
|
||||||
|
|
||||||
HostFailPoolPurgeRateLimited(&dp->hostlist_auto_fail_counters);
|
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;
|
dp = ctrack->dp;
|
||||||
ctrack_replay = ctrack;
|
ctrack_replay = ctrack;
|
||||||
maybe_cutoff(ctrack, IPPROTO_UDP);
|
|
||||||
}
|
}
|
||||||
if (dp)
|
if (dp)
|
||||||
DLOG("using cached desync profile %d\n",dp->n);
|
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");
|
DLOG("matching desync profile not found\n");
|
||||||
return verdict;
|
return verdict;
|
||||||
}
|
}
|
||||||
|
maybe_cutoff(ctrack, IPPROTO_UDP);
|
||||||
|
|
||||||
HostFailPoolPurgeRateLimited(&dp->hostlist_auto_fail_counters);
|
HostFailPoolPurgeRateLimited(&dp->hostlist_auto_fail_counters);
|
||||||
//ConntrackPoolDump(¶ms.conntrack);
|
//ConntrackPoolDump(¶ms.conntrack);
|
||||||
|
@ -4,25 +4,35 @@
|
|||||||
#include "helpers.h"
|
#include "helpers.h"
|
||||||
|
|
||||||
// inplace tolower() and add to pool
|
// 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;
|
char *p=*s;
|
||||||
|
|
||||||
|
// comment line
|
||||||
|
if ( *p == '#' || *p == ';' || *p == '/' || *p == '\r' || *p == '\n')
|
||||||
|
{
|
||||||
|
// advance until eol
|
||||||
|
for (; p<end && *p && *p!='\r' && *p != '\n'; p++);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
// advance until eol lowering all chars
|
// advance until eol lowering all chars
|
||||||
for (p = *s; p<end && *p && *p!='\r' && *p != '\n'; p++) *p=tolower(*p);
|
for (; p<end && *p && *p!='\r' && *p != '\n'; p++) *p=tolower(*p);
|
||||||
if (!StrPoolAddStrLen(hostlist, *s, p-*s))
|
if (!StrPoolAddStrLen(hostlist, *s, p-*s))
|
||||||
{
|
{
|
||||||
StrPoolDestroy(hostlist);
|
StrPoolDestroy(hostlist);
|
||||||
*hostlist = NULL;
|
*hostlist = NULL;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
(*ct)++;
|
||||||
|
}
|
||||||
// advance to the next line
|
// advance to the next line
|
||||||
for (; p<end && (!*p || *p=='\r' || *p=='\n') ; p++);
|
for (; p<end && (!*p || *p=='\r' || *p=='\n') ; p++);
|
||||||
*s = p;
|
*s = p;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AppendHostList(strpool **hostlist, char *filename)
|
bool AppendHostList(strpool **hostlist, const char *filename)
|
||||||
{
|
{
|
||||||
char *p, *e, s[256], *zbuf;
|
char *p, *e, s[256], *zbuf;
|
||||||
size_t zsize;
|
size_t zsize;
|
||||||
@ -50,14 +60,12 @@ bool AppendHostList(strpool **hostlist, char *filename)
|
|||||||
e = zbuf + zsize;
|
e = zbuf + zsize;
|
||||||
while(p<e)
|
while(p<e)
|
||||||
{
|
{
|
||||||
if ( *p == '#' || *p == ';' || *p == '/' || *p == '\n' ) continue;
|
if (!addpool(hostlist,&p,e,&ct))
|
||||||
if (!addpool(hostlist,&p,e))
|
|
||||||
{
|
{
|
||||||
DLOG_ERR("Not enough memory to store host list : %s\n", filename);
|
DLOG_ERR("Not enough memory to store host list : %s\n", filename);
|
||||||
free(zbuf);
|
free(zbuf);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
ct++;
|
|
||||||
}
|
}
|
||||||
free(zbuf);
|
free(zbuf);
|
||||||
}
|
}
|
||||||
@ -71,17 +79,15 @@ bool AppendHostList(strpool **hostlist, char *filename)
|
|||||||
{
|
{
|
||||||
DLOG_CONDUP("loading plain text list\n");
|
DLOG_CONDUP("loading plain text list\n");
|
||||||
|
|
||||||
while (fgets(s, 256, F))
|
while (fgets(s, sizeof(s), F))
|
||||||
{
|
{
|
||||||
p = s;
|
p = s;
|
||||||
if ( *p == '#' || *p == ';' || *p == '/' || *p == '\n' ) continue;
|
if (!addpool(hostlist,&p,p+strlen(p),&ct))
|
||||||
if (!addpool(hostlist,&p,p+strlen(p)))
|
|
||||||
{
|
{
|
||||||
DLOG_ERR("Not enough memory to store host list : %s\n", filename);
|
DLOG_ERR("Not enough memory to store host list : %s\n", filename);
|
||||||
fclose(F);
|
fclose(F);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
ct++;
|
|
||||||
}
|
}
|
||||||
fclose(F);
|
fclose(F);
|
||||||
}
|
}
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
#include "pools.h"
|
#include "pools.h"
|
||||||
#include "params.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 LoadHostLists(strpool **hostlist, struct str_list_head *file_list);
|
||||||
bool LoadIncludeHostLists();
|
bool LoadIncludeHostLists();
|
||||||
bool LoadExcludeHostLists();
|
bool LoadExcludeHostLists();
|
||||||
|
109
tpws/helpers.c
109
tpws/helpers.c
@ -11,6 +11,12 @@
|
|||||||
#include <time.h>
|
#include <time.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
|
|
||||||
|
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 *strncasestr(const char *s,const char *find, size_t slen)
|
||||||
{
|
{
|
||||||
char c, sc;
|
char c, sc;
|
||||||
@ -81,7 +87,6 @@ void print_sockaddr(const struct sockaddr *sa)
|
|||||||
printf("%s",ip_port);
|
printf("%s",ip_port);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// -1 = error, 0 = not local, 1 = local
|
// -1 = error, 0 = not local, 1 = local
|
||||||
bool check_local_ip(const struct sockaddr *saddr)
|
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;
|
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)
|
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;
|
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;
|
||||||
|
}
|
||||||
|
@ -8,6 +8,15 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
|
|
||||||
|
// 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);
|
char *strncasestr(const char *s,const char *find, size_t slen);
|
||||||
|
|
||||||
bool append_to_list_file(const char *filename, const char *s);
|
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);
|
bool saconvmapped(struct sockaddr_storage *a);
|
||||||
|
|
||||||
void sacopy(struct sockaddr_storage *sa_dest, const struct sockaddr *sa);
|
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_localnet(const struct sockaddr *a);
|
||||||
bool is_linklocal(const struct sockaddr_in6* a);
|
bool is_linklocal(const struct sockaddr_in6* a);
|
||||||
@ -71,3 +81,33 @@ bool pf_is_empty(const port_filter *pf);
|
|||||||
#else
|
#else
|
||||||
#define IN6_EXTRACT_MAP4(a) (((const uint32_t *) (a))[3])
|
#define IN6_EXTRACT_MAP4(a) (((const uint32_t *) (a))[3])
|
||||||
#endif
|
#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;
|
||||||
|
}
|
||||||
|
@ -5,25 +5,35 @@
|
|||||||
#include "helpers.h"
|
#include "helpers.h"
|
||||||
|
|
||||||
// inplace tolower() and add to pool
|
// 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;
|
char *p=*s;
|
||||||
|
|
||||||
|
// comment line
|
||||||
|
if ( *p == '#' || *p == ';' || *p == '/' || *p == '\r' || *p == '\n')
|
||||||
|
{
|
||||||
|
// advance until eol
|
||||||
|
for (; p<end && *p && *p!='\r' && *p != '\n'; p++);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
// advance until eol lowering all chars
|
// advance until eol lowering all chars
|
||||||
for (p = *s; p<end && *p && *p!='\r' && *p != '\n'; p++) *p=tolower(*p);
|
for (; p<end && *p && *p!='\r' && *p != '\n'; p++) *p=tolower(*p);
|
||||||
if (!StrPoolAddStrLen(hostlist, *s, p-*s))
|
if (!StrPoolAddStrLen(hostlist, *s, p-*s))
|
||||||
{
|
{
|
||||||
StrPoolDestroy(hostlist);
|
StrPoolDestroy(hostlist);
|
||||||
*hostlist = NULL;
|
*hostlist = NULL;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
(*ct)++;
|
||||||
|
}
|
||||||
// advance to the next line
|
// advance to the next line
|
||||||
for (; p<end && (!*p || *p=='\r' || *p=='\n') ; p++);
|
for (; p<end && (!*p || *p=='\r' || *p=='\n') ; p++);
|
||||||
*s = p;
|
*s = p;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AppendHostList(strpool **hostlist, char *filename)
|
bool AppendHostList(strpool **hostlist, const char *filename)
|
||||||
{
|
{
|
||||||
char *p, *e, s[256], *zbuf;
|
char *p, *e, s[256], *zbuf;
|
||||||
size_t zsize;
|
size_t zsize;
|
||||||
@ -51,14 +61,12 @@ bool AppendHostList(strpool **hostlist, char *filename)
|
|||||||
e = zbuf + zsize;
|
e = zbuf + zsize;
|
||||||
while(p<e)
|
while(p<e)
|
||||||
{
|
{
|
||||||
if ( *p == '#' || *p == ';' || *p == '/' || *p == '\n' ) continue;
|
if (!addpool(hostlist,&p,e,&ct))
|
||||||
if (!addpool(hostlist,&p,e))
|
|
||||||
{
|
{
|
||||||
DLOG_ERR("Not enough memory to store host list : %s\n", filename);
|
DLOG_ERR("Not enough memory to store host list : %s\n", filename);
|
||||||
free(zbuf);
|
free(zbuf);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
ct++;
|
|
||||||
}
|
}
|
||||||
free(zbuf);
|
free(zbuf);
|
||||||
}
|
}
|
||||||
@ -72,17 +80,15 @@ bool AppendHostList(strpool **hostlist, char *filename)
|
|||||||
{
|
{
|
||||||
DLOG_CONDUP("loading plain text list\n");
|
DLOG_CONDUP("loading plain text list\n");
|
||||||
|
|
||||||
while (fgets(s, 256, F))
|
while (fgets(s, sizeof(s), F))
|
||||||
{
|
{
|
||||||
p = s;
|
p = s;
|
||||||
if ( *p == '#' || *p == ';' || *p == '/' || *p == '\n' ) continue;
|
if (!addpool(hostlist,&p,p+strlen(p),&ct))
|
||||||
if (!addpool(hostlist,&p,p+strlen(p)))
|
|
||||||
{
|
{
|
||||||
DLOG_ERR("Not enough memory to store host list : %s\n", filename);
|
DLOG_ERR("Not enough memory to store host list : %s\n", filename);
|
||||||
fclose(F);
|
fclose(F);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
ct++;
|
|
||||||
}
|
}
|
||||||
fclose(F);
|
fclose(F);
|
||||||
}
|
}
|
||||||
@ -166,10 +172,9 @@ static bool LoadIncludeHostListsForProfile(struct desync_profile *dp)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// return : true = apply fooling, false = do not apply
|
|
||||||
bool HostlistCheck(struct desync_profile *dp, const char *host, bool *excluded)
|
bool HostlistCheck(struct desync_profile *dp, const char *host, bool *excluded)
|
||||||
{
|
{
|
||||||
VPRINT("* Hostlist check for profile %d\n",dp->n);
|
VPRINT("* hostlist check for profile %d\n",dp->n);
|
||||||
if (*dp->hostlist_auto_filename)
|
if (*dp->hostlist_auto_filename)
|
||||||
{
|
{
|
||||||
time_t t = file_mod_time(dp->hostlist_auto_filename);
|
time_t t = file_mod_time(dp->hostlist_auto_filename);
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
#include "pools.h"
|
#include "pools.h"
|
||||||
#include "params.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 LoadHostLists(strpool **hostlist, struct str_list_head *file_list);
|
||||||
bool LoadIncludeHostLists();
|
bool LoadIncludeHostLists();
|
||||||
bool LoadExcludeHostLists();
|
bool LoadExcludeHostLists();
|
||||||
|
195
tpws/ipset.c
Normal file
195
tpws/ipset.c
Normal file
@ -0,0 +1,195 @@
|
|||||||
|
#include <stdio.h>
|
||||||
|
#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<end && *p && *p!='\r' && *p != '\n'; p++);
|
||||||
|
|
||||||
|
// comment line
|
||||||
|
if (!(**s == '#' || **s == ';' || **s == '/' || **s == '\r' || **s == '\n' ))
|
||||||
|
{
|
||||||
|
l = p-*s;
|
||||||
|
if (l>=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 (; p<end && (!*p || *p=='\r' || *p=='\n') ; p++);
|
||||||
|
*s = p;
|
||||||
|
return true;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool AppendIpset(ipset *ips, const char *filename)
|
||||||
|
{
|
||||||
|
char *p, *e, s[256], *zbuf;
|
||||||
|
size_t zsize;
|
||||||
|
int ct = 0;
|
||||||
|
FILE *F;
|
||||||
|
int r;
|
||||||
|
|
||||||
|
DLOG_CONDUP("Loading ipset %s\n",filename);
|
||||||
|
|
||||||
|
if (!(F = fopen(filename, "rb")))
|
||||||
|
{
|
||||||
|
DLOG_ERR("Could not open %s\n", filename);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (is_gzip(F))
|
||||||
|
{
|
||||||
|
r = z_readfile(F,&zbuf,&zsize);
|
||||||
|
fclose(F);
|
||||||
|
if (r==Z_OK)
|
||||||
|
{
|
||||||
|
DLOG_CONDUP("zlib compression detected. uncompressed size : %zu\n", zsize);
|
||||||
|
|
||||||
|
p = zbuf;
|
||||||
|
e = zbuf + zsize;
|
||||||
|
while(p<e)
|
||||||
|
{
|
||||||
|
if (!addpool(ips,&p,e,&ct))
|
||||||
|
{
|
||||||
|
DLOG_ERR("Not enough memory to store ipset : %s\n", filename);
|
||||||
|
free(zbuf);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
free(zbuf);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DLOG_ERR("zlib decompression failed : result %d\n",r);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DLOG_CONDUP("loading plain text list\n");
|
||||||
|
|
||||||
|
while (fgets(s, sizeof(s)-1, F))
|
||||||
|
{
|
||||||
|
p = s;
|
||||||
|
if (!addpool(ips,&p,p+strlen(p),&ct))
|
||||||
|
{
|
||||||
|
DLOG_ERR("Not enough memory to store ipset : %s\n", filename);
|
||||||
|
fclose(F);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fclose(F);
|
||||||
|
}
|
||||||
|
|
||||||
|
DLOG_CONDUP("Loaded %d ip/subnets from %s\n", ct, filename);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool LoadIpsets(ipset *ips, struct str_list_head *file_list)
|
||||||
|
{
|
||||||
|
struct str_list *file;
|
||||||
|
|
||||||
|
ipsetDestroy(ips);
|
||||||
|
|
||||||
|
LIST_FOREACH(file, file_list, next)
|
||||||
|
{
|
||||||
|
if (!AppendIpset(ips, file->str)) 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);
|
||||||
|
}
|
11
tpws/ipset.h
Normal file
11
tpws/ipset.h
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <arpa/inet.h>
|
||||||
|
#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);
|
@ -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_files);
|
||||||
strlist_destroy(&entry->dp.hostlist_exclude_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_exclude);
|
||||||
StrPoolDestroy(&entry->dp.hostlist);
|
StrPoolDestroy(&entry->dp.hostlist);
|
||||||
|
ipsetDestroy(&entry->dp.ips);
|
||||||
|
ipsetDestroy(&entry->dp.ips_exclude);
|
||||||
HostFailPoolDestroy(&entry->dp.hostlist_auto_fail_counters);
|
HostFailPoolDestroy(&entry->dp.hostlist_auto_fail_counters);
|
||||||
free(entry);
|
free(entry);
|
||||||
}
|
}
|
||||||
|
@ -51,6 +51,9 @@ struct desync_profile
|
|||||||
|
|
||||||
bool filter_ipv4,filter_ipv6;
|
bool filter_ipv4,filter_ipv6;
|
||||||
port_filter pf_tcp;
|
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;
|
strpool *hostlist, *hostlist_exclude;
|
||||||
struct str_list_head hostlist_files, hostlist_exclude_files;
|
struct str_list_head hostlist_files, hostlist_exclude_files;
|
||||||
@ -60,6 +63,8 @@ struct desync_profile
|
|||||||
hostfail_pool *hostlist_auto_fail_counters;
|
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_list {
|
||||||
struct desync_profile dp;
|
struct desync_profile dp;
|
||||||
LIST_ENTRY(desync_profile_list) next;
|
LIST_ENTRY(desync_profile_list) next;
|
||||||
|
130
tpws/pools.c
130
tpws/pools.c
@ -52,6 +52,12 @@ bool StrPoolAddStr(strpool **pp, const char *s)
|
|||||||
{
|
{
|
||||||
return StrPoolAddStrLen(pp, s, strlen(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)
|
bool StrPoolCheckStr(strpool *p, const char *s)
|
||||||
{
|
{
|
||||||
@ -151,3 +157,127 @@ void strlist_destroy(struct str_list_head *head)
|
|||||||
strlist_entry_destroy(entry);
|
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);
|
||||||
|
}
|
||||||
|
41
tpws/pools.h
41
tpws/pools.h
@ -5,6 +5,8 @@
|
|||||||
#include <sys/queue.h>
|
#include <sys/queue.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
|
|
||||||
|
#include "helpers.h"
|
||||||
|
|
||||||
//#define HASH_BLOOM 20
|
//#define HASH_BLOOM 20
|
||||||
#define HASH_NONFATAL_OOM 1
|
#define HASH_NONFATAL_OOM 1
|
||||||
#define HASH_FUNCTION HASH_BER
|
#define HASH_FUNCTION HASH_BER
|
||||||
@ -17,6 +19,7 @@ typedef struct strpool {
|
|||||||
|
|
||||||
void StrPoolDestroy(strpool **pp);
|
void StrPoolDestroy(strpool **pp);
|
||||||
bool StrPoolAddStr(strpool **pp,const char *s);
|
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 StrPoolAddStrLen(strpool **pp,const char *s,size_t slen);
|
||||||
bool StrPoolCheckStr(strpool *p,const char *s);
|
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);
|
bool strlist_add(struct str_list_head *head, const char *filename);
|
||||||
void strlist_destroy(struct str_list_head *head);
|
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);
|
||||||
|
@ -103,6 +103,12 @@ static void *resolver_thread(void *arg)
|
|||||||
ri->ga_res = getaddrinfo(ri->dom,sport,&hints,&ai);
|
ri->ga_res = getaddrinfo(ri->dom,sport,&hints,&ai);
|
||||||
if (!ri->ga_res)
|
if (!ri->ga_res)
|
||||||
{
|
{
|
||||||
|
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);
|
memcpy(&ri->ss, ai->ai_addr, ai->ai_addrlen);
|
||||||
freeaddrinfo(ai);
|
freeaddrinfo(ai);
|
||||||
}
|
}
|
||||||
|
@ -6,10 +6,12 @@
|
|||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
#include <netdb.h>
|
#include <netdb.h>
|
||||||
|
|
||||||
|
#include "helpers.h"
|
||||||
|
|
||||||
struct resolve_item
|
struct resolve_item
|
||||||
{
|
{
|
||||||
char dom[256]; // request dom
|
char dom[256]; // request dom
|
||||||
struct sockaddr_storage ss; // resolve result
|
sockaddr_in46 ss; // resolve result
|
||||||
int ga_res; // getaddrinfo result code
|
int ga_res; // getaddrinfo result code
|
||||||
uint16_t port; // request port
|
uint16_t port; // request port
|
||||||
void *ptr;
|
void *ptr;
|
||||||
|
149
tpws/tamper.c
149
tpws/tamper.c
@ -1,22 +1,50 @@
|
|||||||
#define _GNU_SOURCE
|
#define _GNU_SOURCE
|
||||||
|
|
||||||
#include "tamper.h"
|
|
||||||
#include "hostlist.h"
|
|
||||||
#include "protocol.h"
|
|
||||||
#include "helpers.h"
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#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 \
|
switch(l7)
|
||||||
((!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))
|
|
||||||
{
|
{
|
||||||
|
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
|
// autohostlist profile matching l3/l4 filter always win
|
||||||
if (*dp->hostlist_auto_filename) return true;
|
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;
|
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;
|
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)
|
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);
|
VPRINT("desync profile %d matches\n",dpl->dp.n);
|
||||||
return &dpl->dp;
|
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)
|
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,35 +147,51 @@ void tamper_out(t_ctrack *ctrack, const struct sockaddr *dest, uint8_t *segment,
|
|||||||
l7proto = UNKNOWN;
|
l7proto = UNKNOWN;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ctrack->l7proto==UNKNOWN) ctrack->l7proto=l7proto;
|
|
||||||
|
|
||||||
if (bHaveHost)
|
if (bHaveHost)
|
||||||
{
|
|
||||||
VPRINT("request hostname: %s\n", Host);
|
VPRINT("request hostname: %s\n", Host);
|
||||||
if (!ctrack->hostname)
|
if (ctrack->b_not_act)
|
||||||
{
|
{
|
||||||
|
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)))
|
if (!(ctrack->hostname=strdup(Host)))
|
||||||
{
|
{
|
||||||
DLOG_ERR("strdup hostname : out of memory\n");
|
DLOG_ERR("strdup hostname : out of memory\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bDiscoveredL7 || bDiscoveredHostname)
|
||||||
|
{
|
||||||
struct desync_profile *dp_prev = ctrack->dp;
|
struct desync_profile *dp_prev = ctrack->dp;
|
||||||
apply_desync_profile(ctrack, dest);
|
apply_desync_profile(ctrack, dest);
|
||||||
if (ctrack->dp!=dp_prev)
|
if (ctrack->dp!=dp_prev)
|
||||||
VPRINT("desync profile changed by revealed hostname !\n");
|
VPRINT("desync profile changed by revealed l7 protocol or hostname !\n");
|
||||||
else if (*ctrack->dp->hostlist_auto_filename)
|
}
|
||||||
|
|
||||||
|
if (bDiscoveredHostname && *ctrack->dp->hostlist_auto_filename)
|
||||||
{
|
{
|
||||||
bool bHostExcluded;
|
bool bHostExcluded;
|
||||||
if (!HostlistCheck(ctrack->dp, Host, &bHostExcluded))
|
if (!HostlistCheck(ctrack->dp, Host, &bHostExcluded))
|
||||||
{
|
{
|
||||||
ctrack->b_ah_check = !bHostExcluded;
|
ctrack->b_ah_check = !bHostExcluded;
|
||||||
VPRINT("Not acting on this request\n");
|
VPRINT("Not acting on this request\n");
|
||||||
|
ctrack->b_not_act = true;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!ctrack->dp) return;
|
if (!ctrack->dp) return;
|
||||||
|
|
||||||
@ -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;
|
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)
|
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);
|
HostFailPoolDel(&dp->hostlist_auto_fail_counters, fail_counter);
|
||||||
VPRINT("auto hostlist (profile %d) : %s : fail counter reset. website is working.\n", dp->n, hostname);
|
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;
|
hostfail_pool *fail_counter;
|
||||||
|
|
||||||
@ -358,7 +407,7 @@ static void auto_hostlist_failed(struct desync_profile *dp, const char *hostname
|
|||||||
}
|
}
|
||||||
fail_counter->counter++;
|
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);
|
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)
|
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);
|
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)
|
if (!HostlistCheck(dp, hostname, &bExcluded) && !bExcluded)
|
||||||
{
|
{
|
||||||
VPRINT("auto hostlist (profile %d) : adding %s to %s\n", dp->n, hostname, dp->hostlist_auto_filename);
|
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))
|
if (!StrPoolAddStr(&dp->hostlist, hostname))
|
||||||
{
|
{
|
||||||
DLOG_ERR("StrPoolAddStr out of memory\n");
|
DLOG_ERR("StrPoolAddStr out of memory\n");
|
||||||
@ -385,16 +434,22 @@ static void auto_hostlist_failed(struct desync_profile *dp, const char *hostname
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
VPRINT("auto hostlist (profile %d) : NOT adding %s\n", dp->n, hostname);
|
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;
|
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)
|
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)
|
if (bFail)
|
||||||
{
|
{
|
||||||
VPRINT("redirect to another domain detected. possibly DPI redirect.\n");
|
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
|
else
|
||||||
VPRINT("local or in-domain redirect detected. it's not a DPI redirect.\n");
|
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
|
// received not http reply. do not monitor this connection anymore
|
||||||
VPRINT("incoming unknown HTTP data detected for hostname %s\n", ctrack->hostname);
|
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;
|
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);
|
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)
|
if (ctrack->dp && ctrack->b_ah_check)
|
||||||
{
|
{
|
||||||
HostFailPoolPurgeRateLimited(&ctrack->dp->hostlist_auto_fail_counters);
|
HostFailPoolPurgeRateLimited(&ctrack->dp->hostlist_auto_fail_counters);
|
||||||
@ -437,15 +498,21 @@ void rst_in(t_ctrack *ctrack)
|
|||||||
if (!ctrack->bTamperInCutoff && ctrack->hostname)
|
if (!ctrack->bTamperInCutoff && ctrack->hostname)
|
||||||
{
|
{
|
||||||
VPRINT("incoming RST detected for hostname %s\n", 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);
|
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);
|
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);
|
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)
|
if (ctrack->dp && ctrack->b_ah_check)
|
||||||
{
|
{
|
||||||
HostFailPoolPurgeRateLimited(&ctrack->dp->hostlist_auto_fail_counters);
|
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.
|
// 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);
|
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);
|
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);
|
auto_hostlist_failed(ctrack->dp, ctrack->hostname, client_ip_port, ctrack->l7proto);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -10,13 +10,18 @@
|
|||||||
#define SPLIT_FLAG_OOB 0x02
|
#define SPLIT_FLAG_OOB 0x02
|
||||||
|
|
||||||
typedef enum {UNKNOWN=0, HTTP, TLS} t_l7proto;
|
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
|
typedef struct
|
||||||
{
|
{
|
||||||
// common state
|
// common state
|
||||||
t_l7proto l7proto;
|
t_l7proto l7proto;
|
||||||
bool bFirstReplyChecked;
|
|
||||||
bool bTamperInCutoff;
|
bool bTamperInCutoff;
|
||||||
bool b_ah_check;
|
bool b_ah_check;
|
||||||
|
bool b_not_act;
|
||||||
char *hostname;
|
char *hostname;
|
||||||
struct desync_profile *dp; // desync profile cache
|
struct desync_profile *dp; // desync profile cache
|
||||||
} t_ctrack;
|
} t_ctrack;
|
||||||
@ -24,8 +29,8 @@ typedef struct
|
|||||||
void apply_desync_profile(t_ctrack *ctrack, const struct sockaddr *dest);
|
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_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
|
// 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 ?)
|
// local leg closed connection (timeout waiting response ?)
|
||||||
void hup_out(t_ctrack *ctrack);
|
void hup_out(t_ctrack *ctrack, const struct sockaddr *client);
|
||||||
|
105
tpws/tpws.c
105
tpws/tpws.c
@ -33,6 +33,7 @@
|
|||||||
|
|
||||||
#include "tpws_conn.h"
|
#include "tpws_conn.h"
|
||||||
#include "hostlist.h"
|
#include "hostlist.h"
|
||||||
|
#include "ipset.h"
|
||||||
#include "params.h"
|
#include "params.h"
|
||||||
#include "sec.h"
|
#include "sec.h"
|
||||||
#include "redirect.h"
|
#include "redirect.h"
|
||||||
@ -46,7 +47,7 @@ bool bHup = false;
|
|||||||
static void onhup(int sig)
|
static void onhup(int sig)
|
||||||
{
|
{
|
||||||
printf("HUP received !\n");
|
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;
|
bHup = true;
|
||||||
}
|
}
|
||||||
// should be called in normal execution
|
// should be called in normal execution
|
||||||
@ -54,9 +55,9 @@ void dohup(void)
|
|||||||
{
|
{
|
||||||
if (bHup)
|
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);
|
exit(1);
|
||||||
}
|
}
|
||||||
bHup = false;
|
bHup = false;
|
||||||
@ -180,6 +181,9 @@ static void exithelp(void)
|
|||||||
" --new\t\t\t\t\t; begin new strategy\n"
|
" --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-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-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=<filename>\t\t\t; ipset include filter (one ip/CIDR per line, ipv4 and ipv6 accepted, gzip supported, multiple ipsets allowed)\n"
|
||||||
|
" --ipset-exclude=<filename>\t\t; ipset exclude filter (one ip/CIDR per line, ipv4 and ipv6 accepted, gzip supported, multiple ipsets allowed)\n"
|
||||||
"\nHOSTLIST FILTER:\n"
|
"\nHOSTLIST FILTER:\n"
|
||||||
" --hostlist=<filename>\t\t\t; only act on hosts in the list (one host per line, subdomains auto apply, gzip supported, multiple hostlists allowed)\n"
|
" --hostlist=<filename>\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=<filename>\t\t; do not act on hosts in the list (one host per line, subdomains auto apply, gzip supported, multiple hostlists allowed)\n"
|
" --hostlist-exclude=<filename>\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;
|
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[])
|
void parse_params(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
int option_index = 0;
|
int option_index = 0;
|
||||||
@ -412,18 +445,21 @@ void parse_params(int argc, char *argv[])
|
|||||||
{ "new",no_argument,0,0 }, // optidx=56
|
{ "new",no_argument,0,0 }, // optidx=56
|
||||||
{ "filter-l3",required_argument,0,0 }, // optidx=57
|
{ "filter-l3",required_argument,0,0 }, // optidx=57
|
||||||
{ "filter-tcp",required_argument,0,0 }, // optidx=58
|
{ "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__)
|
#if defined(__FreeBSD__)
|
||||||
{ "enable-pf",no_argument,0,0 },// optidx=59
|
{ "enable-pf",no_argument,0,0 },// optidx=62
|
||||||
#elif defined(__APPLE__)
|
#elif defined(__APPLE__)
|
||||||
{ "local-tcp-user-timeout",required_argument,0,0 },// optidx=59
|
{ "local-tcp-user-timeout",required_argument,0,0 }, // optidx=62
|
||||||
{ "remote-tcp-user-timeout",required_argument,0,0 },// optidx=60
|
{ "remote-tcp-user-timeout",required_argument,0,0 }, // optidx=63
|
||||||
#elif defined(__linux__)
|
#elif defined(__linux__)
|
||||||
{ "local-tcp-user-timeout",required_argument,0,0 },// optidx=59
|
{ "local-tcp-user-timeout",required_argument,0,0 }, // optidx=62
|
||||||
{ "remote-tcp-user-timeout",required_argument,0,0 },// optidx=60
|
{ "remote-tcp-user-timeout",required_argument,0,0 }, // optidx=63
|
||||||
{ "mss",required_argument,0,0 },// optidx=61
|
{ "mss",required_argument,0,0 }, // optidx=64
|
||||||
#ifdef SPLICE_PRESENT
|
#ifdef SPLICE_PRESENT
|
||||||
{ "nosplice",no_argument,0,0 },// optidx=62
|
{ "nosplice",no_argument,0,0 }, // optidx=65
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
{ "hostlist-auto-retrans-threshold",optional_argument,0,0}, // ignored. for nfqws command line compatibility
|
{ "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);
|
exit_clean(1);
|
||||||
}
|
}
|
||||||
break;
|
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__)
|
#if defined(__FreeBSD__)
|
||||||
case 59: /* enable-pf */
|
case 62: /* enable-pf */
|
||||||
params.pf_enable = true;
|
params.pf_enable = true;
|
||||||
break;
|
break;
|
||||||
#elif defined(__linux__) || defined(__APPLE__)
|
#elif defined(__linux__) || defined(__APPLE__)
|
||||||
case 59: /* local-tcp-user-timeout */
|
case 62: /* local-tcp-user-timeout */
|
||||||
params.tcp_user_timeout_local = atoi(optarg);
|
params.tcp_user_timeout_local = atoi(optarg);
|
||||||
if (params.tcp_user_timeout_local<0 || params.tcp_user_timeout_local>86400)
|
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);
|
exit_clean(1);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 60: /* remote-tcp-user-timeout */
|
case 63: /* remote-tcp-user-timeout */
|
||||||
params.tcp_user_timeout_remote = atoi(optarg);
|
params.tcp_user_timeout_remote = atoi(optarg);
|
||||||
if (params.tcp_user_timeout_remote<0 || params.tcp_user_timeout_remote>86400)
|
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
|
#endif
|
||||||
|
|
||||||
#if defined(__linux__)
|
#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
|
// this option does not work in any BSD and MacOS. OS may accept but it changes nothing
|
||||||
dp->mss = atoi(optarg);
|
dp->mss = atoi(optarg);
|
||||||
if (dp->mss<88 || dp->mss>32767)
|
if (dp->mss<88 || dp->mss>32767)
|
||||||
@ -970,7 +1029,7 @@ void parse_params(int argc, char *argv[])
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
#ifdef SPLICE_PRESENT
|
#ifdef SPLICE_PRESENT
|
||||||
case 62: /* nosplice */
|
case 65: /* nosplice */
|
||||||
params.nosplice = true;
|
params.nosplice = true;
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
@ -1021,6 +1080,16 @@ void parse_params(int argc, char *argv[])
|
|||||||
DLOG_ERR("Exclude hostlist load failed\n");
|
DLOG_ERR("Exclude hostlist load failed\n");
|
||||||
exit_clean(1);
|
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;
|
return false;
|
||||||
n=fscanf(F,"%ju",&um);
|
n=fscanf(F,"%ju",&um);
|
||||||
fclose(F);
|
fclose(F);
|
||||||
if (!n) return false;
|
if (n != 1) return false;
|
||||||
*maxfile = (rlim_t)um;
|
*maxfile = (rlim_t)um;
|
||||||
return true;
|
return true;
|
||||||
#elif defined(BSD)
|
#elif defined(BSD)
|
||||||
@ -1132,7 +1201,7 @@ static bool set_ulimit(void)
|
|||||||
// additional 1/2 for unpaired remote legs sending buffers
|
// additional 1/2 for unpaired remote legs sending buffers
|
||||||
// 16 for listen_fd, epoll, hostlist, ...
|
// 16 for listen_fd, epoll, hostlist, ...
|
||||||
#ifdef SPLICE_PRESENT
|
#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
|
#else
|
||||||
fdmax = 2 * params.maxconn;
|
fdmax = 2 * params.maxconn;
|
||||||
#endif
|
#endif
|
||||||
@ -1177,6 +1246,8 @@ int main(int argc, char *argv[])
|
|||||||
char ip_port[48];
|
char ip_port[48];
|
||||||
|
|
||||||
srand(time(NULL));
|
srand(time(NULL));
|
||||||
|
mask_from_preflen6_prepare();
|
||||||
|
|
||||||
parse_params(argc, argv);
|
parse_params(argc, argv);
|
||||||
|
|
||||||
if (params.daemon) daemonize();
|
if (params.daemon) daemonize();
|
||||||
|
@ -569,7 +569,6 @@ static tproxy_conn_t* add_tcp_connection(int efd, struct tailhead *conn_list,int
|
|||||||
{
|
{
|
||||||
struct sockaddr_storage orig_dst;
|
struct sockaddr_storage orig_dst;
|
||||||
tproxy_conn_t *conn;
|
tproxy_conn_t *conn;
|
||||||
int remote_fd=0;
|
|
||||||
|
|
||||||
if (proxy_type==CONN_TYPE_TRANSPARENT)
|
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;
|
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(!(conn = new_conn(local_fd, false)))
|
||||||
{
|
{
|
||||||
if (remote_fd) close(remote_fd);
|
|
||||||
close(local_fd);
|
close(local_fd);
|
||||||
return NULL;
|
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->state = CONN_AVAILABLE; // accepted connection is immediately available
|
||||||
conn->efd = efd;
|
conn->efd = efd;
|
||||||
|
|
||||||
|
socklen_t salen=sizeof(conn->client);
|
||||||
|
getpeername(conn->fd,(struct sockaddr *)&conn->client,&salen);
|
||||||
|
|
||||||
if (proxy_type==CONN_TYPE_TRANSPARENT)
|
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);
|
free_conn(conn);
|
||||||
close(remote_fd);
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
conn->partner->partner = conn;
|
conn->partner->partner = conn;
|
||||||
conn->partner->efd = efd;
|
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
|
//remote_fd is connecting. Non-blocking connects are signaled as done by
|
||||||
//socket being marked as ready for writing
|
//socket being marked as ready for writing
|
||||||
@ -663,9 +666,6 @@ static tproxy_conn_t* add_tcp_connection(int efd, struct tailhead *conn_list,int
|
|||||||
legs_remote++;
|
legs_remote++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (proxy_type==CONN_TYPE_TRANSPARENT)
|
|
||||||
apply_desync_profile(&conn->track, (struct sockaddr *)&conn->dest);
|
|
||||||
|
|
||||||
return conn;
|
return conn;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -693,7 +693,7 @@ static bool check_connection_attempt(tproxy_conn_t *conn, int efd)
|
|||||||
{
|
{
|
||||||
if (params.debug>=1)
|
if (params.debug>=1)
|
||||||
{
|
{
|
||||||
struct sockaddr_storage sa;
|
sockaddr_in46 sa;
|
||||||
socklen_t salen=sizeof(sa);
|
socklen_t salen=sizeof(sa);
|
||||||
char ip_port[48];
|
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->partner = conn;
|
||||||
conn->partner->efd = conn->efd;
|
conn->partner->efd = conn->efd;
|
||||||
|
conn->partner->client = conn->client;
|
||||||
|
conn->partner->dest = conn->dest;
|
||||||
if (!epoll_set(conn->partner, EPOLLOUT))
|
if (!epoll_set(conn->partner, EPOLLOUT))
|
||||||
{
|
{
|
||||||
DLOG_ERR("socks epoll_set error %d\n", errno);
|
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);
|
socks4_send_rep(conn->fd, S4_REP_FAILED);
|
||||||
return false;
|
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_port = m->port;
|
||||||
((struct sockaddr_in*)&conn->dest)->sin_addr.s_addr = m->ip;
|
((struct sockaddr_in*)&conn->dest)->sin_addr.s_addr = m->ip;
|
||||||
return proxy_mode_connect_remote(conn, conn_list);
|
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)
|
switch(m->atyp)
|
||||||
{
|
{
|
||||||
case S5_ATYP_IP4:
|
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_port = m->d4.port;
|
||||||
((struct sockaddr_in*)&conn->dest)->sin_addr = m->d4.addr;
|
((struct sockaddr_in*)&conn->dest)->sin_addr = m->d4.addr;
|
||||||
break;
|
break;
|
||||||
case S5_ATYP_IP6:
|
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_port = m->d6.port;
|
||||||
((struct sockaddr_in6*)&conn->dest)->sin6_addr = m->d6.addr;
|
((struct sockaddr_in6*)&conn->dest)->sin6_addr = m->d6.addr;
|
||||||
((struct sockaddr_in6*)&conn->dest)->sin6_flowinfo = 0;
|
((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);
|
DBGPRINT("resolve_complete put hostname : %s\n", ri->dom);
|
||||||
conn->track.hostname = strdup(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);
|
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->remote)
|
||||||
{
|
{
|
||||||
if (conn_partner_alive(conn) && !conn->partner->track.bTamperInCutoff)
|
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
|
else
|
||||||
{
|
{
|
||||||
@ -1527,15 +1529,8 @@ int event_loop(const int *listen_fd, size_t listen_fd_ct)
|
|||||||
|
|
||||||
if (params.debug>=1)
|
if (params.debug>=1)
|
||||||
{
|
{
|
||||||
struct sockaddr_storage sa;
|
|
||||||
socklen_t salen=sizeof(sa);
|
|
||||||
char ip_port[48];
|
char ip_port[48];
|
||||||
|
ntop46_port((struct sockaddr*)&conn->client,ip_port,sizeof(ip_port));
|
||||||
if (getpeername(conn->fd,(struct sockaddr *)&sa,&salen))
|
|
||||||
*ip_port=0;
|
|
||||||
else
|
|
||||||
ntop46_port((struct sockaddr*)&sa,ip_port,sizeof(ip_port));
|
|
||||||
|
|
||||||
VPRINT("Socket fd=%d (local) connected from %s\n", conn->fd, 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);
|
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);
|
read_all_and_buffer(conn,3);
|
||||||
if (errn==ECONNRESET && conn_partner_alive(conn))
|
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;
|
struct linger lin;
|
||||||
lin.l_onoff=1;
|
lin.l_onoff=1;
|
||||||
@ -1588,7 +1583,7 @@ int event_loop(const int *listen_fd, size_t listen_fd_ct)
|
|||||||
{
|
{
|
||||||
DBGPRINT("EPOLLRDHUP\n");
|
DBGPRINT("EPOLLRDHUP\n");
|
||||||
read_all_and_buffer(conn,2);
|
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
|
conn->state = CONN_RDHUP; // only writes. do not receive RDHUP anymore
|
||||||
if (conn_has_unsent(conn))
|
if (conn_has_unsent(conn))
|
||||||
|
@ -54,7 +54,7 @@ struct tproxy_conn
|
|||||||
int splice_pipe[2];
|
int splice_pipe[2];
|
||||||
conn_state_t state;
|
conn_state_t state;
|
||||||
conn_type_t conn_type;
|
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
|
struct tproxy_conn *partner; // other leg
|
||||||
time_t orphan_since;
|
time_t orphan_since;
|
||||||
|
Loading…
Reference in New Issue
Block a user