mirror of
https://github.com/bol-van/zapret.git
synced 2024-11-11 17:29:16 +05:00
Fixed typos, misspellings, abbreviations, Markdown linting, etc.
This commit is contained in:
parent
b15ca040df
commit
03312cbb67
2
.gitattributes
vendored
2
.gitattributes
vendored
@ -1,4 +1,4 @@
|
||||
* text=auto eol=lf
|
||||
binaries/win64/readme.txt eol=crlf
|
||||
binaries/win64/readme.md eol=crlf
|
||||
*.cmd eol=crlf
|
||||
*.bat eol=crlf
|
||||
|
@ -480,7 +480,7 @@ curl_supports_tls13() {
|
||||
$CURL --tlsv1.3 -Is -o /dev/null --max-time 1 http://127.0.0.1:65535 2>/dev/null
|
||||
# return code 2 = init failed. likely bad command line options
|
||||
[ $? = 2 ] && return 1
|
||||
# curl can have tlsv1.3 key present but ssl library without TLS 1.3 support
|
||||
# curl can have TLSv1.3 key present but SSL library without TLS 1.3 support
|
||||
# this is online test because there's no other way to trigger library incompatibility case
|
||||
$CURL --tlsv1.3 --max-time "$CURL_MAX_TIME" -Is -o /dev/null https://w3.org 2>/dev/null
|
||||
r=$?
|
||||
@ -522,7 +522,7 @@ hdrfile_location() {
|
||||
curl_with_subst_ip() {
|
||||
# $1 - domain
|
||||
# $2 - port
|
||||
# $3 - ip
|
||||
# $3 - IP
|
||||
# $4+ - curl params
|
||||
local connect_to="--connect-to $1::[$3]${2:+:$2}" arg
|
||||
shift
|
||||
@ -552,7 +552,7 @@ curl_probe() {
|
||||
# $1 - IP version: 4/6
|
||||
# $2 - domain name
|
||||
# $3 - port
|
||||
# $4 - subst ip
|
||||
# $4 - subst IP
|
||||
# $5+ - curl params
|
||||
local ipv="$1" dom="$2" port="$3" subst="$4"
|
||||
shift
|
||||
@ -568,7 +568,7 @@ curl_probe() {
|
||||
curl_test_http() {
|
||||
# $1 - IP version: 4/6
|
||||
# $2 - domain name
|
||||
# $3 - subst ip
|
||||
# $3 - subst IP
|
||||
# $4 - "detail" - detail info
|
||||
|
||||
local code loc
|
||||
@ -603,7 +603,7 @@ curl_test_http() {
|
||||
curl_test_https_tls12() {
|
||||
# $1 - IP version: 4/6
|
||||
# $2 - domain name
|
||||
# $3 - subst ip
|
||||
# $3 - subst IP
|
||||
|
||||
# do not use TLS 1.3 to make sure server certificate is not encrypted
|
||||
curl_probe "$1" "$2" "$HTTPS_PORT" "$3" -ISs -A "$USER_AGENT" --max-time "$CURL_MAX_TIME" "$CURL_OPT" --tlsv1.2 "$TLSMAX12" "https://$2" -o /dev/null 2>&1
|
||||
@ -611,7 +611,7 @@ curl_test_https_tls12() {
|
||||
curl_test_https_tls13() {
|
||||
# $1 - IP version: 4/6
|
||||
# $2 - domain name
|
||||
# $3 - subst ip
|
||||
# $3 - subst IP
|
||||
|
||||
# force TLS1.3 mode
|
||||
curl_probe "$1" "$2" "$HTTPS_PORT" "$3" -ISs -A "$USER_AGENT" --max-time "$CURL_MAX_TIME" "$CURL_OPT" --tlsv1.3 "$TLSMAX13" "https://$2" -o /dev/null 2>&1
|
||||
@ -925,7 +925,7 @@ warn_fool() {
|
||||
}
|
||||
pktws_curl_test_update_vary() {
|
||||
# $1 - test function
|
||||
# $2 - encrypted test : 0 = plain, 1 - encrypted with server reply risk, 2 - encrypted without server reply risk
|
||||
# $2 - encrypted test: 0 = plain, 1 - encrypted with server reply risk, 2 - encrypted without server reply risk
|
||||
# $3 - domain
|
||||
# $4 - desync mode
|
||||
# $5,$6,... - strategy
|
||||
@ -956,7 +956,7 @@ pktws_curl_test_update_vary() {
|
||||
|
||||
pktws_check_domain_http_bypass_() {
|
||||
# $1 - test function
|
||||
# $2 - encrypted test : 0 = plain, 1 - encrypted with server reply risk, 2 - encrypted without server reply risk
|
||||
# $2 - encrypted test: 0 = plain, 1 - encrypted with server reply risk, 2 - encrypted without server reply risk
|
||||
# $3 - domain
|
||||
|
||||
local tests='fake' ret ok ttls s f e desync pos fooling frag sec="$2" delta hostcase
|
||||
@ -1093,13 +1093,13 @@ pktws_check_domain_http_bypass_() {
|
||||
pktws_curl_test_update_vary "$1" "$2" "$3" $desync --dpi-desync-fake-syndata="$ZAPRET_BASE/files/fake/$s" "$e" && [ "$SCANLEVEL" = quick ] && return
|
||||
done
|
||||
|
||||
# do not do wssize test for http and TLS 1.3. it's useless
|
||||
# do not do wssize test for HTTP and TLS 1.3. it's useless
|
||||
[ "$sec" = 1 ] || break
|
||||
done
|
||||
}
|
||||
pktws_check_domain_http_bypass() {
|
||||
# $1 - test function
|
||||
# $2 - encrypted test : 0 = plain, 1 - encrypted with server reply risk, 2 - encrypted without server reply risk
|
||||
# $2 - encrypted test: 0 = plain, 1 - encrypted with server reply risk, 2 - encrypted without server reply risk
|
||||
# $3 - domain
|
||||
|
||||
local strategy
|
||||
@ -1155,7 +1155,7 @@ warn_mss() {
|
||||
|
||||
tpws_check_domain_http_bypass_() {
|
||||
# $1 - test function
|
||||
# $2 - encrypted test : 0 = plain, 1 - encrypted with server reply risk, 2 - encrypted without server reply risk
|
||||
# $2 - encrypted test: 0 = plain, 1 - encrypted with server reply risk, 2 - encrypted without server reply risk
|
||||
# $3 - domain
|
||||
|
||||
local s mss s2 s3 pos sec="$2"
|
||||
@ -1200,14 +1200,14 @@ tpws_check_domain_http_bypass_() {
|
||||
break
|
||||
}
|
||||
done
|
||||
# only linux supports mss
|
||||
# only Linux supports mss
|
||||
[ "$UNAME" = Linux -a "$sec" = 1 ] || break
|
||||
done
|
||||
fi
|
||||
}
|
||||
tpws_check_domain_http_bypass() {
|
||||
# $1 - test function
|
||||
# $2 - encrypted test : 0 = plain, 1 - encrypted with server reply risk, 2 - encrypted without server reply risk
|
||||
# $2 - encrypted test: 0 = plain, 1 - encrypted with server reply risk, 2 - encrypted without server reply risk
|
||||
# $3 - domain
|
||||
|
||||
local strategy
|
||||
@ -1271,7 +1271,7 @@ check_domain_prolog() {
|
||||
}
|
||||
code=$?
|
||||
curl_has_reason_to_continue $code || {
|
||||
report_append "ipv${IPV} $3 $1 : test aborted, no reason to continue. curl code $(curl_translate_code $code)"
|
||||
report_append "ipv${IPV} $3 $1: test aborted, no reason to continue. curl code $(curl_translate_code $code)"
|
||||
return 1
|
||||
}
|
||||
return 0
|
||||
@ -1279,7 +1279,7 @@ check_domain_prolog() {
|
||||
check_domain_http_tcp() {
|
||||
# $1 - test function
|
||||
# $2 - port
|
||||
# $3 - encrypted test : 0 = plain, 1 - encrypted with server reply risk, 2 - encrypted without server reply risk
|
||||
# $3 - encrypted test: 0 = plain, 1 - encrypted with server reply risk, 2 - encrypted without server reply risk
|
||||
# $4 - domain
|
||||
|
||||
# in case was interrupted before
|
||||
@ -1385,8 +1385,8 @@ configure_defrag() {
|
||||
|
||||
[ "$UNAME" = "Linux" ] && {
|
||||
linux_ipv6_defrag_can_be_disabled || {
|
||||
echo "WARNING ! ipv6 defrag can only be effectively disabled in linux kernel 4.16+"
|
||||
echo "WARNING ! ipv6 ipfrag tests are disabled"
|
||||
echo "WARNING ! IPv6 defrag can only be effectively disabled in Linux kernel 4.16+"
|
||||
echo "WARNING ! IPv6 ipfrag tests are disabled"
|
||||
echo
|
||||
return
|
||||
}
|
||||
@ -1434,15 +1434,15 @@ ask_params() {
|
||||
}
|
||||
|
||||
echo "specify domain(s) to test. multiple domains are space separated."
|
||||
printf "domain(s) (default: $DOMAINS) : "
|
||||
printf "domain(s) (default: $DOMAINS): "
|
||||
local dom
|
||||
read dom
|
||||
[ -n "$dom" ] && DOMAINS="$dom"
|
||||
|
||||
local IPVS_def=4
|
||||
# yandex public dns
|
||||
# Yandex public DNS
|
||||
pingtest 6 2a02:6b8::feed:0ff && IPVS_def=46
|
||||
printf "ip protocol version(s) - 4, 6 or 46 for both (default: $IPVS_def) : "
|
||||
printf "ip protocol version(s) - 4, 6 or 46 for both (default: $IPVS_def): "
|
||||
read IPVS
|
||||
[ -n "$IPVS" ] || IPVS=$IPVS_def
|
||||
[ "$IPVS" = 4 -o "$IPVS" = 6 -o "$IPVS" = 46 ] || {
|
||||
@ -1455,11 +1455,11 @@ ask_params() {
|
||||
|
||||
ENABLE_HTTP=1
|
||||
echo
|
||||
ask_yes_no_var ENABLE_HTTP "check http"
|
||||
ask_yes_no_var ENABLE_HTTP "check HTTP"
|
||||
|
||||
ENABLE_HTTPS_TLS12=1
|
||||
echo
|
||||
ask_yes_no_var ENABLE_HTTPS_TLS12 "check https tls 1.2"
|
||||
ask_yes_no_var ENABLE_HTTPS_TLS12 "check HTTPS TLS 1.2"
|
||||
|
||||
ENABLE_HTTPS_TLS13=0
|
||||
echo
|
||||
@ -1469,7 +1469,7 @@ ask_params() {
|
||||
echo "What works for TLS 1.2 will also work for TLS 1.3 but not vice versa."
|
||||
echo "Most sites nowadays support TLS 1.3 but not all. If you can't find a strategy for TLS 1.2 use this test."
|
||||
echo "TLS 1.3 only strategy is better than nothing."
|
||||
ask_yes_no_var ENABLE_HTTPS_TLS13 "check https tls 1.3"
|
||||
ask_yes_no_var ENABLE_HTTPS_TLS13 "check HTTPS TLS 1.3"
|
||||
else
|
||||
echo "installed curl version does not support TLS 1.3 . tests disabled."
|
||||
fi
|
||||
@ -1479,25 +1479,25 @@ ask_params() {
|
||||
if [ -n "$HTTP3" ]; then
|
||||
echo "make sure target domain(s) support QUIC or result will be negative in any case"
|
||||
ENABLE_HTTP3=1
|
||||
ask_yes_no_var ENABLE_HTTP3 "check http3 QUIC"
|
||||
ask_yes_no_var ENABLE_HTTP3 "check HTTP3 QUIC"
|
||||
else
|
||||
echo "installed curl version does not support http3 QUIC. tests disabled."
|
||||
echo "installed curl version does not support HTTP3 QUIC. tests disabled."
|
||||
fi
|
||||
|
||||
IGNORE_CA=0
|
||||
CURL_OPT=
|
||||
[ $ENABLE_HTTPS_TLS13 = 1 -o $ENABLE_HTTPS_TLS12 = 1 ] && {
|
||||
echo
|
||||
echo "on limited systems like openwrt CA certificates might not be installed to preserve space"
|
||||
echo "on limited systems like OpenWrt CA certificates might not be installed to preserve space"
|
||||
echo "in such a case curl cannot verify server certificate and you should either install ca-bundle or disable verification"
|
||||
echo "however disabling verification will break https check if ISP does MitM attack and substitutes server certificate"
|
||||
echo "however disabling verification will break HTTPS check if ISP does MitM attack and substitutes server certificate"
|
||||
ask_yes_no_var IGNORE_CA "do not verify server certificate"
|
||||
[ "$IGNORE_CA" = 1 ] && CURL_OPT=-k
|
||||
}
|
||||
|
||||
echo
|
||||
echo "sometimes ISPs use multiple DPIs or load balancing. bypass strategies may work unstable."
|
||||
printf "how many times to repeat each test (default: 1) : "
|
||||
printf "how many times to repeat each test (default: 1): "
|
||||
read REPEATS
|
||||
REPEATS=$((0 + ${REPEATS:-1}))
|
||||
[ "$REPEATS" = 0 ] && {
|
||||
@ -1536,7 +1536,7 @@ pingtest() {
|
||||
# $2 - domain or IP
|
||||
|
||||
# ping command can vary a lot. some implementations have -4/-6 options. others don.t
|
||||
# WARNING ! macos ping6 command does not have timeout option. ping6 will fail
|
||||
# WARNING ! macOS ping6 command does not have timeout option. ping6 will fail
|
||||
|
||||
local PING=ping ret
|
||||
if [ "$1" = 6 ]; then
|
||||
@ -1547,12 +1547,12 @@ pingtest() {
|
||||
fi
|
||||
else
|
||||
if [ "$UNAME" = Darwin -o "$UNAME" = FreeBSD -o "$UNAME" = OpenBSD ]; then
|
||||
# ping by default pings ipv4, ping6 only pings ipv6
|
||||
# ping by default pings IPv4, ping6 only pings IPv6
|
||||
# in FreeBSD -4/-6 options are supported, in others not
|
||||
PING=ping
|
||||
else
|
||||
# this can be linux or cygwin
|
||||
# in linux it's not possible for sure to figure out if it supports -4/-6. only try and check for result code=2 (invalid option)
|
||||
# this can be Linux or cygwin
|
||||
# in Linux it's not possible for sure to figure out if it supports -4/-6. only try and check for result code=2 (invalid option)
|
||||
PING="ping -4"
|
||||
fi
|
||||
fi
|
||||
|
@ -143,7 +143,7 @@ linux_get_subsys() {
|
||||
elif [ -x "/bin/ndm" ]; then
|
||||
SUBSYS=keenetic
|
||||
else
|
||||
# generic linux
|
||||
# generic Linux
|
||||
SUBSYS=
|
||||
fi
|
||||
}
|
||||
|
@ -43,7 +43,7 @@ ask_list() {
|
||||
echo $n: "$m"
|
||||
n=$(($n + 1))
|
||||
done
|
||||
printf "your choice (default : $M_DEFAULT) : "
|
||||
printf "your choice (default: $M_DEFAULT): "
|
||||
read m
|
||||
[ -n "$m" ] && M=$(echo "$2" | cut -d ' ' -f"$m" 2>/dev/null)
|
||||
[ -z "$M" ] && M="$M_DEFAULT"
|
||||
|
@ -22,7 +22,7 @@ linux_fwtype() {
|
||||
fi
|
||||
else
|
||||
SUBSYS=
|
||||
# generic linux
|
||||
# generic Linux
|
||||
# flowtable is implemented since kernel 4.16
|
||||
if linux_nft_avail && linux_min_version 4 16; then
|
||||
FWTYPE=nftables
|
||||
|
@ -47,7 +47,7 @@ edit_vars() {
|
||||
# $1,$2,... - var names
|
||||
local n=1 var v tmp="/tmp/zvars"
|
||||
rm -f "$tmp"
|
||||
while [ 1=1 ]; do
|
||||
while true; do
|
||||
eval var="\$$n"
|
||||
[ -n "$var" ] || break
|
||||
eval v="\$$var"
|
||||
@ -60,7 +60,7 @@ edit_vars() {
|
||||
|
||||
openrc_test() {
|
||||
exists rc-update || return 1
|
||||
# some systems do not usse openrc-init but launch openrc from inittab
|
||||
# some systems do not use openrc-init but launch openrc from inittab
|
||||
[ "$INIT" = "openrc-init" ] || grep -qE "sysinit.*openrc" /etc/inittab 2>/dev/null
|
||||
}
|
||||
check_system() {
|
||||
@ -103,9 +103,9 @@ check_system() {
|
||||
elif openrc_test; then
|
||||
SYSTEM=openrc
|
||||
else
|
||||
echo system is not either systemd, openrc or openwrt based
|
||||
echo system is not either systemd, openrc or OpenWrt based
|
||||
echo easy installer can set up config settings but can\'t configure auto start
|
||||
echo you have to do it manually. check readme.txt for manual setup info.
|
||||
echo you have to do it manually. check readme.md for manual setup info.
|
||||
if [ -n "$1" ] || ask_yes_no N "do you want to continue"; then
|
||||
SYSTEM=linux
|
||||
else
|
||||
@ -116,7 +116,7 @@ check_system() {
|
||||
elif [ "$UNAME" = "Darwin" ]; then
|
||||
SYSTEM=macos
|
||||
else
|
||||
echo easy installer only supports Linux and MacOS. check readme.txt for supported systems and manual setup info.
|
||||
echo easy installer only supports Linux and macOS. check readme.md for supported systems and manual setup info.
|
||||
exitp 5
|
||||
fi
|
||||
echo system is based on $SYSTEM
|
||||
@ -142,7 +142,7 @@ crontab_del() {
|
||||
CRONTMP=/tmp/cron.tmp
|
||||
crontab -l >$CRONTMP 2>/dev/null
|
||||
if grep -q "$GET_LIST_PREFIX" $CRONTMP; then
|
||||
echo removing following entries from crontab :
|
||||
echo removing following entries from crontab:
|
||||
grep "$GET_LIST_PREFIX" $CRONTMP
|
||||
grep -v "$GET_LIST_PREFIX" $CRONTMP >$CRONTMP.2
|
||||
crontab $CRONTMP.2
|
||||
@ -172,7 +172,7 @@ crontab_add() {
|
||||
CRONTMP=/tmp/cron.tmp
|
||||
crontab -l >$CRONTMP 2>/dev/null
|
||||
if grep -q "$GET_LIST_PREFIX" $CRONTMP; then
|
||||
echo some entries already exist in crontab. check if this is corrent :
|
||||
echo some entries already exist in crontab. check if this is corrent:
|
||||
grep "$GET_LIST_PREFIX" $CRONTMP
|
||||
else
|
||||
end_with_newline <"$CRONTMP" || echo >>"$CRONTMP"
|
||||
@ -358,7 +358,6 @@ install_openwrt_firewall() {
|
||||
echo should specify MODE in "$ZAPRET_CONFIG"
|
||||
exitp 7
|
||||
}
|
||||
|
||||
echo "linking: $FW_SCRIPT_SRC => $OPENWRT_FW_INCLUDE"
|
||||
ln -fs "$FW_SCRIPT_SRC" "$OPENWRT_FW_INCLUDE"
|
||||
|
||||
@ -614,7 +613,7 @@ select_ipv6() {
|
||||
[ "$DISABLE_IPV6" != '1' ] && T=Y
|
||||
local old6=$DISABLE_IPV6
|
||||
echo
|
||||
if ask_yes_no $T "enable ipv6 support"; then
|
||||
if ask_yes_no $T "enable IPv6 support"; then
|
||||
DISABLE_IPV6=0
|
||||
else
|
||||
DISABLE_IPV6=1
|
||||
@ -625,7 +624,7 @@ select_fwtype() {
|
||||
echo
|
||||
[ $(get_ram_mb) -le 400 ] && {
|
||||
echo WARNING ! you are running a low RAM system
|
||||
echo WARNING ! nft requires lots of RAM to load huge ip sets, much more than ipsets require
|
||||
echo WARNING ! nft requires lots of RAM to load huge ip sets, much more than IP sets require
|
||||
echo WARNING ! if you need large lists it may be necessary to fall back to iptables+ipset firewall
|
||||
}
|
||||
echo select firewall type :
|
||||
|
@ -111,9 +111,9 @@ unprepare_tpws_fw() {
|
||||
|
||||
ipt_print_op() {
|
||||
if [ "$1" = "1" ]; then
|
||||
echo "Adding ip$4tables rule for $3 : $2"
|
||||
echo "Adding ip$4tables rule for $3: $2"
|
||||
else
|
||||
echo "Deleting ip$4tables rule for $3 : $2"
|
||||
echo "Deleting ip$4tables rule for $3: $2"
|
||||
fi
|
||||
}
|
||||
|
||||
@ -121,8 +121,8 @@ _fw_tpws4() {
|
||||
# $1 - 1 - add, 0 - del
|
||||
# $2 - iptable filter for ipv4
|
||||
# $3 - tpws port
|
||||
# $4 - lan interface names space separated
|
||||
# $5 - wan interface names space separated
|
||||
# $4 - LAN interface names space separated
|
||||
# $5 - WAN interface names space separated
|
||||
[ "$DISABLE_IPV4" = "1" -o -z "$2" ] || {
|
||||
local i rule
|
||||
|
||||
@ -149,8 +149,8 @@ _fw_tpws6() {
|
||||
# $1 - 1 - add, 0 - del
|
||||
# $2 - iptable filter for ipv6
|
||||
# $3 - tpws port
|
||||
# $4 - lan interface names space separated
|
||||
# $5 - wan interface names space separated
|
||||
# $4 - LAN interface names space separated
|
||||
# $5 - WAN interface names space separated
|
||||
|
||||
[ "$DISABLE_IPV6" = "1" -o -z "$2" ] || {
|
||||
local i rule DNAT6
|
||||
@ -186,7 +186,7 @@ _fw_nfqws_post4() {
|
||||
# $1 - 1 - add, 0 - del
|
||||
# $2 - iptable filter for ipv4
|
||||
# $3 - queue number
|
||||
# $4 - wan interface names space separated
|
||||
# $4 - WAN interface names space separated
|
||||
[ "$DISABLE_IPV4" = "1" -o -z "$2" ] || {
|
||||
local i
|
||||
|
||||
@ -206,7 +206,7 @@ _fw_nfqws_post6() {
|
||||
# $1 - 1 - add, 0 - del
|
||||
# $2 - iptable filter for ipv6
|
||||
# $3 - queue number
|
||||
# $4 - wan interface names space separated
|
||||
# $4 - WAN interface names space separated
|
||||
[ "$DISABLE_IPV6" = "1" -o -z "$2" ] || {
|
||||
local i
|
||||
|
||||
@ -235,7 +235,7 @@ _fw_nfqws_pre4() {
|
||||
# $1 - 1 - add, 0 - del
|
||||
# $2 - iptable filter for ipv4
|
||||
# $3 - queue number
|
||||
# $4 - wan interface names space separated
|
||||
# $4 - WAN interface names space separated
|
||||
[ "$DISABLE_IPV4" = "1" -o -z "$2" ] || {
|
||||
local i
|
||||
|
||||
@ -258,7 +258,7 @@ _fw_nfqws_pre6() {
|
||||
# $1 - 1 - add, 0 - del
|
||||
# $2 - iptable filter for ipv6
|
||||
# $3 - queue number
|
||||
# $4 - wan interface names space separated
|
||||
# $4 - WAN interface names space separated
|
||||
[ "$DISABLE_IPV6" = "1" -o -z "$2" ] || {
|
||||
local i
|
||||
|
||||
@ -415,7 +415,7 @@ zapret_do_firewall_ipt() {
|
||||
|
||||
[ "$mode" = "tpws-socks" ] && return 0
|
||||
|
||||
# always create ipsets. ip_exclude ipset is required
|
||||
# always create IP sets. ip_exclude ipset is required
|
||||
[ "$1" = 1 ] && create_ipset no-update
|
||||
|
||||
zapret_do_firewall_rules_ipt "$@"
|
||||
|
@ -16,7 +16,7 @@ zapret_do_firewall() {
|
||||
;;
|
||||
esac
|
||||
|
||||
# russian DPI sends RST,ACK with wrong ACK.
|
||||
# Russian DPI sends RST,ACK with wrong ACK.
|
||||
# this is sometimes treated by conntrack as invalid and connbytes fw rules do not pass RST packet to nfqws.
|
||||
# switch on liberal mode on zapret firewall start and switch off on zapret firewall stop
|
||||
# this is only required for processing incoming bad RSTs. incoming rules are only applied in autohostlist mode
|
||||
|
@ -1,4 +1,4 @@
|
||||
# there's no route_localnet for ipv6
|
||||
# there's no route_localnet for IPv6
|
||||
# the best we can is to route to link local of the incoming interface
|
||||
# OUTPUT - can DNAT to ::1
|
||||
# PREROUTING - can't DNAT to ::1. can DNAT to link local of -i interface or to any global addr
|
||||
|
@ -1,7 +1,7 @@
|
||||
[ -n "$ZAPRET_NFT_TABLE" ] || ZAPRET_NFT_TABLE=zapret
|
||||
readonly nft_connbytes="ct original packets"
|
||||
|
||||
# required for : nft -f -
|
||||
# required for: nft -f -
|
||||
create_dev_stdin
|
||||
std_ports
|
||||
|
||||
@ -100,7 +100,7 @@ nft_create_chains() {
|
||||
EOF
|
||||
[ -n "$POSTNAT_ALL" ] && {
|
||||
nft_flush_chain predefrag_nfqws
|
||||
nft_add_rule predefrag_nfqws notrack comment \"do not track nfqws generated packets to avoid nat tampering and defragmentation\"
|
||||
nft_add_rule predefrag_nfqws notrack comment \"do not track nfqws generated packets to avoid NAT tampering and defragmentation\"
|
||||
}
|
||||
}
|
||||
nft_del_chains() {
|
||||
@ -130,12 +130,12 @@ nft_del_flowtable() {
|
||||
nft_create_or_update_flowtable() {
|
||||
# $1 = flags ('offload' for hw offload)
|
||||
# $2,$3,$4,... - interfaces
|
||||
# can be called multiple times to add interfaces. interfaces can only be added , not removed
|
||||
# can be called multiple times to add interfaces. interfaces can only be added, not removed
|
||||
local flags=$1 devices makelist
|
||||
shift
|
||||
# warning ! nft versions at least up to 1.0.1 do not allow interface names starting with digit in flowtable and do not allow quoting
|
||||
# warning ! openwrt fixes this in post-21.x snapshots with special nft patch
|
||||
# warning ! in traditional linux distros nft is unpatched and will fail with quoted interface definitions if unfixed
|
||||
# warning ! OpenWrt fixes this in post-21.x snapshots with special nft patch
|
||||
# warning ! in traditional Linux distros nft is unpatched and will fail with quoted interface definitions if unfixed
|
||||
[ -n "$flags" ] && flags="flags $flags;"
|
||||
for makelist in make_quoted_comma_list make_comma_list; do
|
||||
$makelist devices "$@"
|
||||
@ -172,7 +172,7 @@ nft_del_firewall() {
|
||||
nft_del_chains
|
||||
nft_del_flowtable
|
||||
nft_flush_link_local
|
||||
# leave ifsets and ipsets because they may be used by custom rules
|
||||
# leave ifsets and IP sets because they may be used by custom rules
|
||||
}
|
||||
|
||||
nft_add_rule() {
|
||||
@ -363,7 +363,7 @@ nft_print_op() {
|
||||
_nft_fw_tpws4() {
|
||||
# $1 - filter ipv4
|
||||
# $2 - tpws port
|
||||
# $3 - not-empty if wan interface filtering required
|
||||
# $3 - not-empty if WAN interface filtering required
|
||||
|
||||
[ "$DISABLE_IPV4" = "1" -o -z "$1" ] || {
|
||||
local filter="$1" port="$2"
|
||||
@ -376,8 +376,8 @@ _nft_fw_tpws4() {
|
||||
_nft_fw_tpws6() {
|
||||
# $1 - filter ipv6
|
||||
# $2 - tpws port
|
||||
# $3 - lan interface names space separated
|
||||
# $4 - not-empty if wan interface filtering required
|
||||
# $3 - LAN interface names space separated
|
||||
# $4 - not-empty if WAN interface filtering required
|
||||
|
||||
[ "$DISABLE_IPV6" = "1" -o -z "$1" ] || {
|
||||
local filter="$1" port="$2" DNAT6 i
|
||||
@ -421,7 +421,7 @@ get_prechain() {
|
||||
_nft_fw_nfqws_post4() {
|
||||
# $1 - filter ipv4
|
||||
# $2 - queue number
|
||||
# $3 - not-empty if wan interface filtering required
|
||||
# $3 - not-empty if WAN interface filtering required
|
||||
|
||||
[ "$DISABLE_IPV4" = "1" -o -z "$1" ] || {
|
||||
local filter="$1" port="$2" rule chain=$(get_postchain) setmark
|
||||
@ -435,7 +435,7 @@ _nft_fw_nfqws_post4() {
|
||||
_nft_fw_nfqws_post6() {
|
||||
# $1 - filter ipv6
|
||||
# $2 - queue number
|
||||
# $3 - not-empty if wan interface filtering required
|
||||
# $3 - not-empty if WAN interface filtering required
|
||||
|
||||
[ "$DISABLE_IPV6" = "1" -o -z "$1" ] || {
|
||||
local filter="$1" port="$2" rule chain=$(get_postchain) setmark
|
||||
@ -458,7 +458,7 @@ nft_fw_nfqws_post() {
|
||||
_nft_fw_nfqws_pre4() {
|
||||
# $1 - filter ipv4
|
||||
# $2 - queue number
|
||||
# $3 - not-empty if wan interface filtering required
|
||||
# $3 - not-empty if WAN interface filtering required
|
||||
|
||||
[ "$DISABLE_IPV4" = "1" -o -z "$1" ] || {
|
||||
local filter="$1" port="$2" rule
|
||||
@ -470,7 +470,7 @@ _nft_fw_nfqws_pre4() {
|
||||
_nft_fw_nfqws_pre6() {
|
||||
# $1 - filter ipv6
|
||||
# $2 - queue number
|
||||
# $3 - not-empty if wan interface filtering required
|
||||
# $3 - not-empty if WAN interface filtering required
|
||||
|
||||
[ "$DISABLE_IPV6" = "1" -o -z "$1" ] || {
|
||||
local filter="$1" port="$2" rule
|
||||
|
@ -7,13 +7,13 @@
|
||||
# redefine user for zapret daemons. required on Keenetic
|
||||
#WS_USER=nobody
|
||||
|
||||
# override firewall type : iptables,nftables,ipfw
|
||||
# override firewall type: iptables,nftables,ipfw
|
||||
#FWTYPE=iptables
|
||||
|
||||
# options for ipsets
|
||||
# options for IP sets
|
||||
# maximum number of elements in sets. also used for nft sets
|
||||
SET_MAXELEM=522288
|
||||
# too low hashsize can cause memory allocation errors on low RAM systems , even if RAM is enough
|
||||
# too low hashsize can cause memory allocation errors on low RAM systems, even if RAM is enough
|
||||
# too large hashsize will waste lots of RAM
|
||||
IPSET_OPT="hashsize 262144 maxelem $SET_MAXELEM"
|
||||
# dynamically generate additional ip. $1 = ipset/nfset/table name
|
||||
@ -35,7 +35,7 @@ MDIG_THREADS=30
|
||||
# ipset/*.sh can compress large lists
|
||||
GZIP_LISTS=1
|
||||
# command to reload ip/host lists after update
|
||||
# comment or leave empty for auto backend selection : ipset or ipfw if present
|
||||
# comment or leave empty for auto backend selection: ipset or ipfw if present
|
||||
# on BSD systems with PF no auto reloading happens. you must provide your own command
|
||||
# set to "-" to disable reload
|
||||
#LISTS_RELOAD="pfctl -f /etc/pf.conf"
|
||||
@ -46,20 +46,20 @@ GZIP_LISTS=1
|
||||
#QUIC_PORTS=443,444
|
||||
|
||||
# CHOOSE OPERATION MODE
|
||||
# MODE : nfqws,tpws,tpws-socks,filter,custom
|
||||
# nfqws : nfqws for dpi desync
|
||||
# tpws : tpws transparent mode
|
||||
# tpws-socks : tpws socks mode
|
||||
# filter : no daemon, just create ipset or download hostlist
|
||||
# custom : custom mode. should modify custom init script and add your own code
|
||||
# MODE: nfqws,tpws,tpws-socks,filter,custom
|
||||
# nfqws: nfqws for dpi desync
|
||||
# tpws: tpws transparent mode
|
||||
# tpws-socks: tpws socks mode
|
||||
# filter: no daemon, just create ipset or download hostlist
|
||||
# custom: custom mode. should modify custom init script and add your own code
|
||||
MODE=tpws
|
||||
# apply fooling to http
|
||||
# apply fooling to HTTP
|
||||
MODE_HTTP=1
|
||||
# for nfqws only. support http keep alives. enable only if DPI checks for http request in any outgoing packet
|
||||
# for nfqws only. support HTTP keep alives. enable only if DPI checks for HTTP request in any outgoing packet
|
||||
MODE_HTTP_KEEPALIVE=0
|
||||
# apply fooling to https
|
||||
# apply fooling to HTTPS
|
||||
MODE_HTTPS=1
|
||||
# apply fooling to quic
|
||||
# apply fooling to QUIC
|
||||
MODE_QUIC=0
|
||||
# none,ipset,hostlist,autohostlist
|
||||
MODE_FILTER=none
|
||||
@ -78,26 +78,26 @@ NFQWS_OPT_DESYNC_QUIC="--dpi-desync=fake --dpi-desync-repeats=6"
|
||||
# CHOOSE TPWS DAEMON OPTIONS. run "tpws/tpws --help" for option list
|
||||
TPWS_OPT="--hostspell=HOST --split-http-req=method --split-pos=3 --oob"
|
||||
|
||||
# openwrt only : donttouch,none,software,hardware
|
||||
# OpenWrt only: donttouch,none,software,hardware
|
||||
FLOWOFFLOAD=donttouch
|
||||
|
||||
# openwrt: specify networks to be treated as LAN. default is "lan"
|
||||
# OpenWrt: specify networks to be treated as LAN. default is "lan"
|
||||
#OPENWRT_LAN="lan lan2 lan3"
|
||||
# openwrt: specify networks to be treated as WAN. default wans are interfaces with default route
|
||||
# OpenWrt: specify networks to be treated as WAN. default wans are interfaces with default route
|
||||
#OPENWRT_WAN4="wan vpn"
|
||||
#OPENWRT_WAN6="wan6 vpn6"
|
||||
|
||||
# for routers based on desktop linux and macos. has no effect in openwrt.
|
||||
# for routers based on desktop Linux and macOS. has no effect in OpenWrt.
|
||||
# CHOOSE LAN and optinally WAN/WAN6 NETWORK INTERFACES
|
||||
# or leave them commented if its not router
|
||||
# it's possible to specify multiple interfaces like this : IFACE_LAN="eth0 eth1 eth2"
|
||||
# it's possible to specify multiple interfaces like this: IFACE_LAN="eth0 eth1 eth2"
|
||||
# if IFACE_WAN6 is not defined it take the value of IFACE_WAN
|
||||
#IFACE_LAN=eth0
|
||||
#IFACE_WAN=eth1
|
||||
#IFACE_WAN6="ipsec0 wireguard0 he_net"
|
||||
|
||||
# should start/stop command of init scripts apply firewall rules ?
|
||||
# not applicable to openwrt with firewall3+iptables
|
||||
# not applicable to OpenWrt with firewall3+iptables
|
||||
INIT_APPLY_FW=1
|
||||
# firewall apply hooks
|
||||
#INIT_FW_PRE_UP_HOOK="/etc/firewall.zapret.hook.pre_up"
|
||||
@ -105,12 +105,12 @@ INIT_APPLY_FW=1
|
||||
#INIT_FW_PRE_DOWN_HOOK="/etc/firewall.zapret.hook.pre_down"
|
||||
#INIT_FW_POST_DOWN_HOOK="/etc/firewall.zapret.hook.post_down"
|
||||
|
||||
# do not work with ipv4
|
||||
# do not work with IPv4
|
||||
#DISABLE_IPV4=1
|
||||
# do not work with ipv6
|
||||
# do not work with IPv6
|
||||
DISABLE_IPV6=1
|
||||
|
||||
# select which init script will be used to get ip or host list
|
||||
# possible values : get_user.sh get_antizapret.sh get_combined.sh get_reestr.sh get_hostlist.sh
|
||||
# possible values: get_user.sh get_antizapret.sh get_combined.sh get_reestr.sh get_hostlist.sh
|
||||
# comment if not required
|
||||
GETLIST=get_antifilter_ipsmart.sh
|
||||
|
@ -1,6 +1,6 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2016-2021 bol-van
|
||||
Copyright (c) 2016-2024 bol-van
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
|
@ -27,7 +27,7 @@ To compile sources:
|
||||
|
||||
- FreeBSD: `make`
|
||||
- OpenBSD: `make bsd`
|
||||
- MacOS: `make mac`
|
||||
- macOS: `make mac`
|
||||
|
||||
Compile all programs:
|
||||
|
||||
@ -66,7 +66,6 @@ It works for the moment but who knows. Such a usage is not very documented.
|
||||
|
||||
`mdig` and `ip2net` are fully compatible with BSD.
|
||||
|
||||
|
||||
## FreeBSD
|
||||
|
||||
Divert sockets require special kernel module `ipdivert`.
|
||||
@ -100,7 +99,7 @@ pkill ^dvtws$
|
||||
/opt/zapret/nfq/dvtws --port=989 --daemon --dpi-desync=split2
|
||||
```
|
||||
|
||||
To restart firewall and daemons run : `/etc/rc.d/ipfw restart`
|
||||
To restart firewall and daemons run: `/etc/rc.d/ipfw restart`
|
||||
|
||||
Assume `LAN="em1"`, `WAN="em0"`.
|
||||
|
||||
@ -180,6 +179,7 @@ They can be filtered out using 'diverted'. IPv4 frames are filtered using `socka
|
||||
### PF in FreeBSD
|
||||
|
||||
The setup is similar to OpenBSD, but there are important nuances.
|
||||
|
||||
1. PF support is disabled by default in FreeBSD. Use parameter `--enable-pf`.
|
||||
2. It's not possible to redirect to `::1`. Need to redirect to the link-local address of the incoming interface.
|
||||
Look for `fe80:...` address in `ifconfig` and use it for redirection target.
|
||||
@ -190,6 +190,7 @@ The setup is similar to OpenBSD, but there are important nuances.
|
||||
Someone posted kernel patch but 14-RELEASE is still broken.
|
||||
|
||||
`/etc/pf.conf`:
|
||||
|
||||
```
|
||||
rdr pass on em1 inet6 proto tcp to port {80,443} -> fe80::31c:29ff:dee2:1c4d port 988
|
||||
rdr pass on em1 inet proto tcp to port {80,443} -> 127.0.0.1 port 988
|
||||
@ -252,6 +253,7 @@ Only PF redirection works. PF does not allow to freely add and delete rules. Onl
|
||||
To make an anchor work it must be referred from the main ruleset. But it's managed by pfsense scripts.
|
||||
|
||||
One possible solution would be to modify `/etc/inc/filter.inc` as follows:
|
||||
|
||||
```
|
||||
.................
|
||||
/* MOD */
|
||||
@ -264,6 +266,7 @@ One possible solution would be to modify `/etc/inc/filter.inc` as follows:
|
||||
```
|
||||
|
||||
Write the anchor code to `/etc/zapret.anchor`:
|
||||
|
||||
```
|
||||
rdr pass on em1 inet proto tcp to port {80,443} -> 127.0.0.1 port 988
|
||||
rdr pass on em1 inet6 proto tcp to port {80,443} -> fe80::20c:29ff:5ae3:4821 port 988
|
||||
@ -280,6 +283,7 @@ tpws --daemon --port=988 --enable-pf --bind-addr=127.0.0.1 --bind-iface6=em1 --b
|
||||
```
|
||||
|
||||
After reboot check that anchor is created and referred from the main ruleset:
|
||||
|
||||
```
|
||||
[root@pfSense /]# pfctl -s nat
|
||||
no nat proto carp all
|
||||
@ -309,6 +313,7 @@ Use `--bind-addr=0.0.0.0 --bind-addr=::` to achieve the same default bind as in
|
||||
`tpws` for forwarded traffic only :
|
||||
|
||||
`/etc/pf.conf`:
|
||||
|
||||
```
|
||||
pass in quick on em1 inet proto tcp to port {80,443} rdr-to 127.0.0.1 port 988
|
||||
pass in quick on em1 inet6 proto tcp to port {80,443} rdr-to ::1 port 988
|
||||
@ -327,6 +332,7 @@ rdr-to support is done using `/dev/pf`, that's why transparent mode requires roo
|
||||
`dvtws` for all traffic:
|
||||
|
||||
`/etc/pf.conf`:
|
||||
|
||||
```
|
||||
pass in quick on em0 proto tcp from port {80,443} flags SA/SA divert-packet port 989 no state
|
||||
pass in quick on em0 proto tcp from port {80,443} no state
|
||||
@ -343,6 +349,7 @@ pfctl -f /etc/pf.conf
|
||||
`dwtws` only for table zapret with the exception of table nozapret :
|
||||
|
||||
`/etc/pf.conf`:
|
||||
|
||||
```
|
||||
set limit table-entries 2000000
|
||||
table <zapret> file "/opt/zapret/ipset/zapret-ip.txt"
|
||||
@ -414,11 +421,12 @@ crontab -e
|
||||
```
|
||||
|
||||
Then write the line:
|
||||
|
||||
```
|
||||
0 12 */2 * * /opt/zapret/ipset/get_config.sh
|
||||
```
|
||||
|
||||
## MacOS
|
||||
## macOS
|
||||
|
||||
Initially, the kernel of this OS was based on BSD. That's why it is still BSD but a lot was modified by Apple.
|
||||
As usual a mass commercial project priorities differ from their free counterparts. Apple guys do what they want.
|
||||
@ -463,6 +471,7 @@ If you don't like this solution you can assign an additional static IPv6 address
|
||||
`tpws` transparent mode only for outgoing connections.
|
||||
|
||||
`/etc/pf.conf`:
|
||||
|
||||
```
|
||||
rdr pass on lo0 inet proto tcp from !127.0.0.0/8 to any port {80,443} -> 127.0.0.1 port 988
|
||||
rdr pass on lo0 inet6 proto tcp from !::1 to any port {80,443} -> fe80::1 port 988
|
||||
@ -485,6 +494,7 @@ ifconfig en1 | grep fe80
|
||||
```
|
||||
|
||||
`/etc/pf.conf`:
|
||||
|
||||
```
|
||||
rdr pass on en1 inet proto tcp from any to any port {80,443} -> 127.0.0.1 port 988
|
||||
rdr pass on en1 inet6 proto tcp from any to any port {80,443} -> fe80::bbbb:bbbb:bbbb:bbbb port 988
|
||||
@ -501,7 +511,7 @@ pfctl -ef /etc/pf.conf
|
||||
/opt/zapret/tpws/tpws --user=root --port=988 --bind-addr=127.0.0.1 --bind-iface6=lo0 --bind-linklocal=force --bind-iface6=en1 --bind-linklocal=force
|
||||
```
|
||||
|
||||
Build from source : `make -C /opt/zapret mac`
|
||||
Build from source: `make -C /opt/zapret mac`
|
||||
|
||||
`ipset/*.sh` scripts work.
|
||||
|
||||
@ -571,10 +581,11 @@ Do not ignore it.
|
||||
|
||||
In that case you need to manually insert "zapret" anchors to your `pf.conf`
|
||||
(keeping the right rule type ordering):
|
||||
|
||||
```
|
||||
rdr-anchor "zapret"
|
||||
anchor "zapret"
|
||||
unistall_easy.sh unpatches pf.conf
|
||||
uninstall_easy.sh unpatches pf.conf
|
||||
```
|
||||
|
||||
`start-fw` creates 3 anchor files in `/etc/pf.anchors`:
|
||||
|
@ -390,7 +390,7 @@ crontab -e
|
||||
|
||||
# macOS
|
||||
|
||||
Иначально ядро этой ОС "darwin" основывалось на BSD, потому в ней много похожего на другие версии BSD.
|
||||
Изначально ядро этой ОС "darwin" основывалось на BSD, потому в ней много похожего на другие версии BSD.
|
||||
Однако, как и в других массовых коммерческих проектах, приоритеты смещаются в сторону от оригинала.
|
||||
Яблочники что хотят, то и творят.
|
||||
Раньше был `ipfw`, потом его убрали, заменили на PF.
|
||||
@ -411,8 +411,8 @@ crontab -e
|
||||
Поскольку `tpws` вынужден работать под root, для исключения рекурсии приходится пускать исходящий от root трафик напрямую.
|
||||
Отсюда имеем недостаток: обход DPI для рута работать не будет.
|
||||
|
||||
Если вы пользуетесь MaсOS в качестве ipv6 роутера, то нужно будет решить вопрос с регулярно изменяемым link-local адресом.
|
||||
С некоторых версий MacOS использует по умолчанию постоянные "secured" ipv6 адреса вместо генерируемых на базе MAC адреса.
|
||||
Если вы пользуетесь MaсOS в качестве IPv6 роутера, то нужно будет решить вопрос с регулярно изменяемым link-local адресом.
|
||||
С некоторых версий macOS использует по умолчанию постоянные "secured" IPv6 адреса вместо генерируемых на базе MAC адреса.
|
||||
Все замечательно, но есть одна проблема. Постоянными остаются только global scope адреса.
|
||||
Link locals периодически меняются. Смена завязана на системное время. Перезагрузки адрес не меняют,
|
||||
Но если перевести время на день вперед и перезагрузиться - link local станет другим. (по крайней мере в VMware это так)
|
||||
|
@ -32,12 +32,12 @@
|
||||
## What is it for
|
||||
|
||||
A stand-alone (without 3rd party servers) DPI circumvention tool.
|
||||
May allow to bypass http(s) website blocking or speed shaping, resist signature tcp/udp protocol discovery.
|
||||
May allow to bypass HTTPS(S) website blocking or speed shaping, resist signature TCP/UDP protocol discovery.
|
||||
|
||||
The project is mainly aimed at the Russian audience to fight Russian regulator named "Roskomnadzor".
|
||||
Some features of the project are Russian reality specific (such as getting list of sites blocked by Roskomnadzor), but most others are common.
|
||||
|
||||
Mainly OpenWRT targeted but also supports traditional Linux, FreeBSD, OpenBSD, Windows, partially MacOS.
|
||||
Mainly OpenWrt targeted but also supports traditional Linux, FreeBSD, OpenBSD, Windows, partially macOS.
|
||||
|
||||
Most features are also supported in Windows.
|
||||
|
||||
@ -46,7 +46,7 @@ Most features are also supported in Windows.
|
||||
In the simplest case you are dealing with passive DPI.
|
||||
Passive DPI can read passthrough traffic, inject its own packets, but cannot drop packets.
|
||||
|
||||
If the request is prohibited the passive DPI will inject its own RST packet and optionally http redirect packet.
|
||||
If the request is prohibited the passive DPI will inject its own RST packet and optionally HTTP redirect packet.
|
||||
|
||||
If fake packets from DPI are only sent to client, you can use `iptables` commands to drop them if you can write correct filter rules.
|
||||
This requires manual in-deep traffic analysis and tuning for specific ISP.
|
||||
@ -59,7 +59,7 @@ This project is aimed at preventing the ban rather than eliminating its conseque
|
||||
|
||||
To do that send what DPI does not expect and what breaks its algorithm of recognizing requests and blocking them.
|
||||
|
||||
Some DPIs cannot recognize the http request if it is divided into TCP segments.
|
||||
Some DPIs cannot recognize the HTTP request if it is divided into TCP segments.
|
||||
For example, a request of the form `GET / HTTP / 1.1 \ r \ nHost: kinozal.tv ......`
|
||||
we send in 2 parts: first go `GET`, then `/ HTTP / 1.1 \ r \ nHost: kinozal.tv .....`.
|
||||
|
||||
@ -70,7 +70,7 @@ or adding a dot at the end of the host name: `Host: kinozal.tv.`
|
||||
|
||||
There is also more advanced magic for bypassing DPI at the packet level.
|
||||
|
||||
## How to put this into practice in the linux system
|
||||
## How to put this into practice in the Linux system
|
||||
|
||||
In short, the options can be classified according to the following scheme:
|
||||
|
||||
@ -103,7 +103,7 @@ DNAT on localhost works in the OUTPUT chain, but does not work in the PREROUTING
|
||||
sysctl -w net.ipv4.conf.<internal_interface>.route_localnet=1
|
||||
```
|
||||
|
||||
You can use `-j REDIRECT --to-port 988` instead of DNAT, but in this case the transparent proxy process
|
||||
You can use `-j REDIRECT --to-port 988` instead of DNAT, but in this case the transparent proxy process
|
||||
should listen on the ip address of the incoming interface or on all addresses. Listen all - not good
|
||||
in terms of security. Listening one (local) is possible, but automated scripts will have to recognize it,
|
||||
then dynamically enter it into the command. In any case, additional efforts are required.
|
||||
@ -129,7 +129,7 @@ into IP addresses and put them to ipset 'zapret', then add a filter to the comma
|
||||
|
||||
`iptables -t mangle -I POSTROUTING -o <external_interface> -p tcp --dport 80 -m set --match-set zapret dst -j NFQUEUE --queue-num 200 --queue-bypass`
|
||||
|
||||
Some DPIs catch only the first http request, ignoring subsequent requests in a keep-alive session.
|
||||
Some DPIs catch only the first HTTP request, ignoring subsequent requests in a keep-alive session.
|
||||
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`
|
||||
@ -145,15 +145,14 @@ Incoming packets are filtered by incoming interface, source port and IP. This is
|
||||
|
||||
Some techniques that break NAT are possible only with nftables.
|
||||
|
||||
|
||||
## ip6tables
|
||||
|
||||
ip6tables work almost exactly the same way as ipv4, but there are a number of important nuances.
|
||||
ip6tables work almost exactly the same way as IPv4, but there are a number of important nuances.
|
||||
In DNAT, you should take the address --to in square brackets. For example :
|
||||
|
||||
`ip6tables -t nat -I OUTPUT -o <external_interface> -p tcp --dport 80 -m owner ! --uid-owner tpws -j DNAT --to [::1]:988`
|
||||
|
||||
The route_localnet parameter does not exist for ipv6.
|
||||
The route_localnet parameter does not exist for IPv6.
|
||||
DNAT to localhost (:: 1) is possible only in the OUTPUT chain.
|
||||
In the PREROUTING DNAT chain, it is possible to any global address or to the link local address of the same interface
|
||||
the packet came from.
|
||||
@ -173,14 +172,13 @@ nft version `1.0.2` or higher is recommended. But the higher is version the bett
|
||||
Some techniques can be fully used only with `nftables`. It's not possible to queue packets after NAT in `iptables`.
|
||||
This limits techniques that break NAT.
|
||||
|
||||
|
||||
## When it will not work
|
||||
|
||||
* If DNS server returns false responses. ISP can return false IP addresses or not return anything
|
||||
when blocked domains are queried. If this is the case change DNS to public ones, such as 8.8.8.8 or 1.1.1.1.Sometimes ISP hijacks queries to any DNS server. Dnscrypt or dns-over-tls help.
|
||||
* If blocking is done by IP.
|
||||
* If a connection passes through a filter capable of reconstructing a TCP connection, and which
|
||||
follows all standards. For example, we are routed to squid. Connection goes through the full OS tcpip stack, fragmentation disappears immediately as a means of circumvention. Squid is correct, it will find everything as it should, it is useless to deceive him. BUT. Only small providers can afford using squid, since it is very resource intensive. Large companies usually use DPI, which is designed for much greater bandwidth.
|
||||
- If DNS server returns false responses. ISP can return false IP addresses or not return anything
|
||||
when blocked domains are queried. If this is the case change DNS to public ones, such as 8.8.8.8 or 1.1.1.1.Sometimes ISP hijacks queries to any DNS server. DNSCrypt or DNS-over-TLS help.
|
||||
- If blocking is done by IP.
|
||||
- If a connection passes through a filter capable of reconstructing a TCP connection, and which
|
||||
follows all standards. For example, we are routed to squid. Connection goes through the full OS TCP/IP stack, fragmentation disappears immediately as a means of circumvention. Squid is correct, it will find everything as it should, it is useless to deceive him. BUT. Only small providers can afford using squid, since it is very resource intensive. Large companies usually use DPI, which is designed for much greater bandwidth.
|
||||
|
||||
## `nfqws`
|
||||
|
||||
@ -193,10 +191,10 @@ nfqws takes the following parameters:
|
||||
--qnum=<nfqueue_number>
|
||||
--daemon ; daemonize
|
||||
--pidfile=<filename> ; write pid to file
|
||||
--user=<username> ; drop root privs
|
||||
--uid=uid[:gid] ; drop root privs
|
||||
--bind-fix4 ; apply outgoing interface selection fix for generated ipv4 packets
|
||||
--bind-fix6 ; apply outgoing interface selection fix for generated ipv6 packets
|
||||
--user=<username> ; drop root privileges
|
||||
--uid=uid[:gid] ; drop root privileges
|
||||
--bind-fix4 ; apply outgoing interface selection fix for generated IPv4 packets
|
||||
--bind-fix6 ; apply outgoing interface selection fix for generated IPv6 packets
|
||||
--wsize=<window_size>[:<scale_factor>] ; set window size. 0 = do not modify. OBSOLETE !
|
||||
--wssize=<window_size>[:<scale_factor>] ; set window size for server. 0 = do not modify. default scale_factor = 0.
|
||||
--wssize-cutoff=[n|d|s]N ; apply server wsize only to packet numbers (n, default), data packet numbers (d), relative sequence (s) less than N
|
||||
@ -204,18 +202,18 @@ nfqws takes the following parameters:
|
||||
--hostcase ; change Host: => host:
|
||||
--hostspell ; exact spelling of "Host" header. must be 4 chars. default is "host"
|
||||
--hostnospace ; remove space after Host: and add it to User-Agent: to preserve packet size
|
||||
--domcase ; mix domain case : Host: TeSt.cOm
|
||||
--dpi-desync=[<mode0>,]<mode>[,<mode2>] ; try to desync dpi state. modes : synack fake fakeknown rst rstack hopbyhop destopt ipfrag1 disorder disorder2 split split2 ipfrag2 udplen tamper
|
||||
--domcase ; mix domain case: Host: TeSt.cOm
|
||||
--dpi-desync=[<mode0>,]<mode>[,<mode2>] ; try to desync dpi state. modes: synack fake fakeknown rst rstack hopbyhop destopt ipfrag1 disorder disorder2 split split2 ipfrag2 udplen tamper
|
||||
--dpi-desync-fwmark=<int|0xHEX> ; override fwmark for desync packet. default = 0x40000000 (1073741824)
|
||||
--dpi-desync-ttl=<int> ; set ttl for desync packet
|
||||
--dpi-desync-ttl6=<int> ; set ipv6 hop limit for desync packet. by default ttl value is used.
|
||||
--dpi-desync-autottl=[<delta>[:<min>[-<max>]]] ; auto ttl mode for both ipv4 and ipv6. default: 1:3-20
|
||||
--dpi-desync-autottl6=[<delta>[:<min>[-<max>]]] ; overrides --dpi-desync-autottl for ipv6 only
|
||||
--dpi-desync-fooling=<mode>[,<mode>] ; can use multiple comma separated values. modes : none md5sig ts badseq badsum datanoack hopbyhop hopbyhop2
|
||||
--dpi-desync-ttl=<int> ; set TTL for desync packet
|
||||
--dpi-desync-ttl6=<int> ; set IPv6 hop limit for desync packet. by default TTL value is used.
|
||||
--dpi-desync-autottl=[<delta>[:<min>[-<max>]]] ; auto TTL mode for both IPv4 and IPv6. default: 1:3-20
|
||||
--dpi-desync-autottl6=[<delta>[:<min>[-<max>]]] ; overrides --dpi-desync-autottl for IPv6 only
|
||||
--dpi-desync-fooling=<mode>[,<mode>] ; can use multiple comma separated values. modes: none md5sig ts badseq badsum datanoack hopbyhop hopbyhop2
|
||||
--dpi-desync-repeats=<N> ; send every desync packet N times
|
||||
--dpi-desync-skip-nosni=0|1 ; 1(default)=do not act on ClientHello without SNI (ESNI ?)
|
||||
--dpi-desync-split-pos=<1..9216> ; data payload split position
|
||||
--dpi-desync-split-http-req=method|host ; split at specified logical part of plain http request
|
||||
--dpi-desync-split-http-req=method|host ; split at specified logical part of plain HTTP request
|
||||
--dpi-desync-split-tls=sni|sniext ; split at specified logical part of TLS ClientHello
|
||||
--dpi-desync-split-seqovl=<int> ; use sequence overlap before first sent original split segment
|
||||
--dpi-desync-split-seqovl-pattern=<filename>|0xHEX ; pattern for the fake part of overlap
|
||||
@ -223,26 +221,26 @@ nfqws takes the following parameters:
|
||||
--dpi-desync-ipfrag-pos-udp=<8..9216> ; ip frag position starting from the transport header. multiple of 8, default 32.
|
||||
--dpi-desync-badseq-increment=<int|0xHEX> ; badseq fooling seq signed increment. default -10000
|
||||
--dpi-desync-badack-increment=<int|0xHEX> ; badseq fooling ackseq signed increment. default -66000
|
||||
--dpi-desync-any-protocol=0|1 ; 0(default)=desync only http and tls 1=desync any nonempty data packet
|
||||
--dpi-desync-fake-http=<filename>|0xHEX ; file containing fake http request
|
||||
--dpi-desync-fake-tls=<filename>|0xHEX ; file containing fake TLS ClientHello (for https)
|
||||
--dpi-desync-any-protocol=0|1 ; 0(default)=desync only HTTP and TLS 1=desync any nonempty data packet
|
||||
--dpi-desync-fake-http=<filename>|0xHEX ; file containing fake HTTP request
|
||||
--dpi-desync-fake-tls=<filename>|0xHEX ; file containing fake TLS ClientHello (for HTTPS)
|
||||
--dpi-desync-fake-unknown=<filename>|0xHEX ; file containing unknown protocol fake payload
|
||||
--dpi-desync-fake-syndata=<filename>|0xHEX ; file containing SYN data payload
|
||||
--dpi-desync-fake-quic=<filename>|0xHEX ; file containing fake QUIC Initial
|
||||
--dpi-desync-fake-wireguard=<filename>|0xHEX ; file containing fake wireguard handshake initiation
|
||||
--dpi-desync-fake-wireguard=<filename>|0xHEX ; file containing fake WireGuard handshake initiation
|
||||
--dpi-desync-fake-dht=<filename>|0xHEX ; file containing fake DHT (d1..e)
|
||||
--dpi-desync-fake-unknown-udp=<filename>|0xHEX ; file containing unknown udp protocol fake payload
|
||||
--dpi-desync-udplen-increment=<int> ; increase or decrease udp packet length by N bytes (default 2). negative values decrease length.
|
||||
--dpi-desync-udplen-pattern=<filename>|0xHEX ; udp tail fill pattern
|
||||
--dpi-desync-fake-unknown-udp=<filename>|0xHEX ; file containing unknown UDP protocol fake payload
|
||||
--dpi-desync-udplen-increment=<int> ; increase or decrease UDP packet length by N bytes (default 2). negative values decrease length.
|
||||
--dpi-desync-udplen-pattern=<filename>|0xHEX ; UDP tail fill pattern
|
||||
--dpi-desync-start=[n|d|s]N ; apply dpi desync only to packet numbers (n, default), data packet numbers (d), relative sequence (s) greater or equal than N
|
||||
--dpi-desync-cutoff=[n|d|s]N ; apply dpi desync only to packet numbers (n, default), data packet numbers (d), relative sequence (s) less than N
|
||||
--hostlist=<filename> ; apply dpi desync only to the listed hosts (one host per line, subdomains auto apply, gzip supported, multiple hostlists allowed)
|
||||
--hostlist-exclude=<filename> ; do not apply dpi desync to the listed hosts (one host per line, subdomains auto apply, gzip supported, multiple hostlists allowed)
|
||||
--hostlist-auto=<filename> ; detect DPI blocks and build hostlist automatically
|
||||
--hostlist-auto-fail-threshold=<int> ; how many failed attempts cause hostname to be added to auto hostlist (default : 3)
|
||||
--hostlist-auto-fail-time=<int> ; all failed attemps must be within these seconds (default : 60)
|
||||
--hostlist-auto-retrans-threshold=<int> ; how many request retransmissions cause attempt to fail (default : 3)
|
||||
--hostlist-auto-debug=<logfile> ; debug auto hostlist positives
|
||||
--hostlist-auto-fail-threshold=<int> ; how many failed attempts cause hostname to be added to auto hostlist (default: 3)
|
||||
--hostlist-auto-fail-time=<int> ; all failed attempts must be within these seconds (default: 60)
|
||||
--hostlist-auto-retrans-threshold=<int> ; how many request retransmissions cause attempt to fail (default: 3)
|
||||
--hostlist-auto-debug=<logfile> ; debug auto hostlist positives
|
||||
```
|
||||
|
||||
The manipulation parameters can be combined in any way.
|
||||
@ -251,63 +249,63 @@ WARNING. `--wsize` parameter is now not used anymore in scripts. TCP split can b
|
||||
|
||||
### DPI desync attack
|
||||
|
||||
After completion of the tcp 3-way handshake, the first data packet from the client goes.
|
||||
After completion of the TCP 3-way handshake, the first data packet from the client goes.
|
||||
It usually has `GET / ...` or TLS ClientHello. We drop this packet, replacing with something else.
|
||||
It can be a fake version with another harmless but valid http or https request (`fake`), tcp reset packet (`rst`,`rstack`),
|
||||
It can be a fake version with another harmless but valid HTTP or HTTPS request (`fake`), TCP reset packet (`rst`,`rstack`),
|
||||
split into 2 segments original packet with fake segment in the middle (`split`).
|
||||
`fakeknown` sends fake only in response to known application protocol.
|
||||
In articles these attack have names **TCB desynchronization** and **TCB teardown**.
|
||||
Fake packet must reach DPI, but do not reach the destination server.
|
||||
The following means are available: set a low TTL, send a packet with bad checksum,
|
||||
add tcp option **MD5 signature**. All of them have their own disadvantages :
|
||||
add TCP option **MD5 signature**. All of them have their own disadvantages :
|
||||
|
||||
* md5sig does not work on all servers
|
||||
* badsum doesn't work if your device is behind NAT which does not pass invalid packets.
|
||||
- md5sig does not work on all servers
|
||||
- badsum doesn't work if your device is behind NAT which does not pass invalid packets.
|
||||
The most common Linux NAT router configuration does not pass them. Most home routers are Linux based.
|
||||
The default sysctl configuration `net.netfilter.nf_conntrack_checksum=1` causes contrack to verify tcp and udp checksums
|
||||
The default sysctl configuration `net.netfilter.nf_conntrack_checksum=1` causes conntrack to verify TCP and UDP checksums
|
||||
and set INVALID state for packets with invalid checksum.
|
||||
Typically, iptables rules include a rule for dropping packets with INVALID state in the FORWARD chain.
|
||||
The combination of these factors does not allow badsum packets to pass through the router.
|
||||
In openwrt mentioned sysctl is set to 0 from the box, in other routers its often left in the default "1" state.
|
||||
In OpenWrt mentioned sysctl is set to 0 from the box, in other routers its often left in the default "1" state.
|
||||
For nfqws to work properly through the router set `net.netfilter.nf_conntrack_checksum=0` on the router.
|
||||
System never verifies checksums of locally generated packets so nfqws will always work on the router itself.
|
||||
If you are behind another NAT, such as a ISP, and it does not pass invalid packages, there is nothing you can do about it.
|
||||
But usually ISPs pass badsum.
|
||||
Some adapters/switches/drivers enable hardware filtering of rx badsum not allowing it to pass to the OS.
|
||||
This behavior was observed on a Mediatek MT7621 based device.
|
||||
Tried to modify mediatek ethernet driver with no luck, likely hardware enforced limitation.
|
||||
Tried to modify mediatek Ethernet driver with no luck, likely hardware enforced limitation.
|
||||
However the device allowed to send badsum packets, problem only existed for passthrough traffic from clients.
|
||||
* badseq packets will be dropped by server, but DPI also can ignore them.
|
||||
default badseq increment is set to -10000 because some DPIs drop packets outside of the small tcp window.
|
||||
- badseq packets will be dropped by server, but DPI also can ignore them.
|
||||
default badseq increment is set to -10000 because some DPIs drop packets outside of the small TCP window.
|
||||
But this also can cause troubles when `--dpi-desync-any-protocol` is enabled.
|
||||
To be 100% sure fake packet cannot fit to server tcp window consider setting badseq increment to 0x80000000
|
||||
* TTL looks like the best option, but it requires special tuning for each ISP. If DPI is further than local ISP websites
|
||||
you can cut access to them. Manual IP exclude list is required. Its possible to use md5sig with ttl.
|
||||
To be 100% sure fake packet cannot fit to server TCP window consider setting badseq increment to 0x80000000
|
||||
- TTL looks like the best option, but it requires special tuning for each ISP. If DPI is further than local ISP websites
|
||||
you can cut access to them. Manual IP exclude list is required. Its possible to use md5sig with TTL.
|
||||
This way you cant hurt anything, but good chances it will help to open local ISP websites.
|
||||
If automatic solution cannot be found then use `zapret-hosts-user-exclude.txt`.
|
||||
Some router stock firmwares fix outgoing TTL. Without switching this option off TTL fooling will not work.
|
||||
* `hopbyhop` is ipv6 only. This fooling adds empty extension header `hop-by-hop options` or two headers in case of `hopbyhop2`.
|
||||
- `hopbyhop` is IPv6 only. This fooling adds empty extension header `hop-by-hop options` or two headers in case of `hopbyhop2`.
|
||||
Packets with two hop-by-hop headers violate RFC and discarded by all operating systems.
|
||||
All OS accept packets with one hop-by-hop header.
|
||||
Some ISPs/operators drop ipv6 packets with hop-by-hop options. Fakes will not be processed by the server either because
|
||||
Some ISPs/operators drop IPv6 packets with hop-by-hop options. Fakes will not be processed by the server either because
|
||||
ISP drops them or because there are two same headers.
|
||||
DPIs may still anaylize packets with one or two hop-by-hop headers.
|
||||
* `datanoack` sends tcp fakes without ACK flag. Servers do not accept this but DPI may accept.
|
||||
DPIs may still analyze packets with one or two hop-by-hop headers.
|
||||
- `datanoack` sends TCP fakes without ACK flag. Servers do not accept this but DPI may accept.
|
||||
This mode may break NAT and may not work with iptables if masquerade is used, even from the router itself.
|
||||
Works with nftables properly. Likely requires external IP address (some ISPs pass these packets through their NAT).
|
||||
* `autottl` tries to automatically guess TTL value that allows DPI to receive fakes and does not allow them to reach the server.
|
||||
This tech relies on well known TTL values used by OS : 64,128,255. nfqws takes first incoming packet (YES, you need to redirect it too),
|
||||
- `autottl` tries to automatically guess TTL value that allows DPI to receive fakes and does not allow them to reach the server.
|
||||
This tech relies on well known TTL values used by OS: 64,128,255. nfqws takes first incoming packet (YES, you need to redirect it too),
|
||||
guesses path length and decreases by `delta` value (default 1). If resulting value is outside the range (min,max - default 3,20)
|
||||
then its normalized to min or max. If the path shorter than the value then autottl fails and falls back to the fixed value.
|
||||
This can help if multiple DPIs exists on backbone channels, not just near the ISP.
|
||||
Can fail if inbound and outbound paths are not symmetric.
|
||||
|
||||
|
||||
`--dpi-desync-fooling` takes multiple comma separated values.
|
||||
|
||||
For fake,rst,rstack modes original packet is sent after the fake.
|
||||
For `fake`,`rst`,`rstack` modes original packet is sent after the fake.
|
||||
|
||||
Disorder mode splits original packet and sends packets in the following order :
|
||||
|
||||
1. 2nd segment
|
||||
2. fake 1st segment, data filled with zeroes
|
||||
3. 1st segment
|
||||
@ -329,7 +327,7 @@ Split mode is very similar to disorder but without segment reordering :
|
||||
|
||||
Mode `split2` disables sending of fake segments. It can be used as a faster alternative to --wsize.
|
||||
|
||||
In `disorder2` and 'split2` modes no fake packets are sent, so ttl and fooling options are not required.
|
||||
In `disorder2` and 'split2` modes no fake packets are sent, so TTL and fooling options are not required.
|
||||
|
||||
`seqovl` adds to the first sent original segment (1st for split, 2nd for disorder) seqovl bytes to the beginning and decreases
|
||||
sequence number.
|
||||
@ -341,15 +339,15 @@ Disorder requires `seqovl` to be less than `split_pos`. Either statically define
|
||||
Otherwise desync is not possible and will not happen.
|
||||
Method allows to avoid separate fakes. Fakes and real data are mixed.
|
||||
|
||||
`hopbyhop`, `destopt` and `ipfrag1` desync modes (they're not the same as `hopbyhop` fooling !) are ipv6 only. One `hop-by-hop`,
|
||||
`hopbyhop`, `destopt` and `ipfrag1` desync modes (they're not the same as `hopbyhop` fooling !) are IPv6 only. One `hop-by-hop`,
|
||||
`destination options` or `fragment` header is added to all desynced packets.
|
||||
Extra header increases packet size and can't be applied to the maximum size packets.
|
||||
If it's not possible to send modified packet original one will be sent.
|
||||
The idea here is that DPI sees 0 in the next header field of the main ipv6 header and does not
|
||||
walk through the extension header chain until transport header is found.
|
||||
`hopbyhop`, `destopt`, `ipfrag1` modes can be used with any second phase mode except `ipfrag1+ipfrag2`.
|
||||
For example, `hopbyhop,split2` means split original tcp packet into 2 pieces and add hop-by-hop header to both.
|
||||
With `hopbyhop,ipfrag2` header sequence will be : `ipv6,hop-by-hop,fragment,tcp/udp`.
|
||||
For example, `hopbyhop,split2` means split original TCP packet into 2 pieces and add hop-by-hop header to both.
|
||||
With `hopbyhop,ipfrag2` header sequence will be: `ipv6,hop-by-hop,fragment,tcp/udp`.
|
||||
`ipfrag1` mode may not always work without special preparations. See "IP Fragmentation" notices.
|
||||
|
||||
There are DPIs that analyze responses from the server, particularly the certificate from the ServerHello
|
||||
@ -365,7 +363,7 @@ Otherwise it is hardly possible to overcome this without the help of the server.
|
||||
The best solution is to enable TLS 1.3 support on the server. TLS 1.3 sends the server certificate in encrypted form.
|
||||
This is recommendation to all admins of blocked sites. Enable TLS 1.3. You will give more opportunities to overcome DPI.
|
||||
|
||||
Hosts are extracted from plain http request Host: header and SNI of ClientHello TLS message.
|
||||
Hosts are extracted from plain HTTP request Host: header and SNI of ClientHello TLS message.
|
||||
Subdomains are applied automatically. gzip lists are supported.
|
||||
|
||||
iptables for performing the attack on the first packet :
|
||||
@ -374,8 +372,8 @@ iptables for performing the attack on the first packet :
|
||||
iptables -t mangle -I POSTROUTING -o <external_interface> -p tcp -m multiport --dports 80,443 -m connbytes --connbytes-dir=original --connbytes-mode=packets --connbytes 1:6 -m mark ! --mark 0x40000000/0x40000000 -j NFQUEUE --queue-num 200 --queue-bypass
|
||||
```
|
||||
|
||||
This is good if DPI does not track all requests in http keep-alive session.
|
||||
If it does, then pass all outgoing packets for http and only first data packet for https :
|
||||
This is good if DPI does not track all requests in HTTP keep-alive session.
|
||||
If it does, then pass all outgoing packets for HTTP and only first data packet for HTTPS :
|
||||
|
||||
```sh
|
||||
iptables -t mangle -I POSTROUTING -o <external_interface> -p tcp --dport 443 -m connbytes --connbytes-dir=original --connbytes-mode=packets --connbytes 1:6 -m mark ! --mark 0x40000000/0x40000000 -j NFQUEUE --queue-num 200 --queue-bypass
|
||||
@ -389,7 +387,7 @@ packet ordering can be changed breaking the whole idea of desync attack.
|
||||
### DPI desync combos
|
||||
|
||||
dpi-desync parameter takes up to 3 comma separated arguments.
|
||||
zero phase means tcp connection establishement (before sending data payload). Mode can be `synack`.
|
||||
zero phase means TCP connection establishment (before sending data payload). Mode can be `synack`.
|
||||
Hostlist filter is not applicable to the zero phase.
|
||||
Next phases work on packets with data payload.
|
||||
1st phase mode can be `fake`,`rst`,`rstack`, 2nd phase mode - `disorder`,`disorder2`,`split`,`split2`,`ipfrag2`.
|
||||
@ -401,16 +399,18 @@ In geneva docs it's called **TCP turnaround**. Attempt to make the DPI believe t
|
||||
|
||||
!!! This mode breaks NAT operation and can be used only if there's no NAT between the attacker's device and the DPI !
|
||||
|
||||
In linux it's required to remove standard firewall rule dropping INVALID packets in the OUTPUT chain,
|
||||
for example : `-A OUTPUT -m state --state INVALID -j DROP`
|
||||
In Linux it's required to remove standard firewall rule dropping INVALID packets in the OUTPUT chain,
|
||||
for example: `-A OUTPUT -m state --state INVALID -j DROP`
|
||||
|
||||
In OpenWrt it's possible to disable the rule for both FORWARD and OUTPUT chains in /etc/config/firewall :
|
||||
|
||||
In openwrt it's possible to disable the rule for both FORWARD and OUTPUT chains in /etc/config/firewall :
|
||||
```
|
||||
config zone
|
||||
option name 'wan'
|
||||
.........
|
||||
option masq_allow_invalid '1'
|
||||
```
|
||||
|
||||
Unfortunately there's no OUTPUT only switch. It's not desired to remove the rule from the FORWARD chain.
|
||||
Add the following lines to `/etc/firewall.user` :
|
||||
|
||||
@ -433,7 +433,7 @@ Without extra parameter payload is 16 zero bytes.
|
||||
### Virtual Machines
|
||||
|
||||
Most of nfqws packet magic does not work from VMs powered by virtualbox and vmware when network is NATed.
|
||||
Hypervisor forcibly changes ttl and does not forward fake packets.
|
||||
Hypervisor forcibly changes TTL and does not forward fake packets.
|
||||
Set up bridge networking.
|
||||
|
||||
### CONNTRACK
|
||||
@ -456,7 +456,7 @@ A connection is deleted from the table as soon as it's no more required to satis
|
||||
|
||||
There're 3 timeouts for each connection state. They can be changed in `--ctrack-timeouts` parameter.
|
||||
|
||||
`--wssize` changes tcp window size for the server to force it to send split replies.
|
||||
`--wssize` changes TCP window size for the server to force it to send split replies.
|
||||
In order for this to affect all server operating systems, it is necessary to change the window size in each outgoing packet
|
||||
before sending the message, the answer to which must be split (for example, TLS ClientHello).
|
||||
That's why conntrack is required to know when to stop applying low window size.
|
||||
@ -464,14 +464,14 @@ That's why conntrack is required to know when to stop applying low window size.
|
||||
If you do not stop and set the low wssize all the time, the speed will drop catastrophically.
|
||||
Linux can overcome this using connbytes filter but other OS may not include similar filter.
|
||||
|
||||
In http(s) case wssize stops after the first http request or TLS ClientHello.
|
||||
In HTTPS(S) case wssize stops after the first HTTP request or TLS ClientHello.
|
||||
|
||||
If you deal with a non-http(s) protocol you need `--wssize-cutoff`. It sets the threshold where wssize stops.
|
||||
If you deal with a non-HTTPS(S) protocol you need `--wssize-cutoff`. It sets the threshold where wssize stops.
|
||||
|
||||
Threshold can be prefixed with 'n' (packet number starting from 1), 'd' (data packet number starting from 1),
|
||||
Threshold can be prefixed with 'n' (packet number starting from 1), 'd' (data packet number starting from 1),
|
||||
's' (relative sequence number - sent by client bytes + 1).
|
||||
|
||||
If a http request or TLS ClientHello packet is detected wssize stops immediately ignoring wssize-cutoff option.
|
||||
If a HTTP request or TLS ClientHello packet is detected wssize stops immediately ignoring wssize-cutoff option.
|
||||
|
||||
If your protocol is prone to long inactivity, you should increase ESTABLISHED phase timeout using `--ctrack-timeouts`.
|
||||
|
||||
@ -480,12 +480,12 @@ Default timeout is low - only 5 mins.
|
||||
Don't forget that nfqws feeds with redirected packets. If you have limited redirection with connbytes
|
||||
ESTABLISHED entries can remain in the table until dropped by timeout.
|
||||
|
||||
To diagnose conntrack state send SIGUSR1 signal to nfqws : `killall -SIGUSR1 nfqws`.
|
||||
To diagnose conntrack state send SIGUSR1 signal to nfqws: `killall -SIGUSR1 nfqws`.
|
||||
|
||||
nfqws will dump current conntrack table to stdout.
|
||||
|
||||
Typically, in a SYN packet, client sends TCP extension **scaling factor** in addition to window size.
|
||||
scaling factor is the power of two by which the window size is multiplied : 0=>1, 1=>2, 2=>4, ..., 8=>256, ...
|
||||
scaling factor is the power of two by which the window size is multiplied: 0=>1, 1=>2, 2=>4, ..., 8=>256, ...
|
||||
|
||||
The wssize parameter specifies the scaling factor after a colon.
|
||||
|
||||
@ -520,12 +520,11 @@ If nfqws receives a partial ClientHello it begins reassemble session. Packets ar
|
||||
Then they go through desync using fully reassembled message.
|
||||
On any error reassemble is cancelled and all delayed packets are sent immediately without desync.
|
||||
|
||||
There is special support for all tcp split options for multi segment TLS. Split position is treated
|
||||
There is special support for all TCP split options for multi segment TLS. Split position is treated
|
||||
as message-oriented, not packet oriented. For example, if your client sends TLS ClientHello with size 2000
|
||||
and SNI is at 1700, desync mode is fake,split2, then fake is sent first, then original first segment
|
||||
and the last splitted segment. 3 segments total.
|
||||
|
||||
|
||||
### UDP support
|
||||
|
||||
UDP attacks are limited. Its not possible to fragment UDP on transport level, only on network (ip) level.
|
||||
@ -533,12 +532,12 @@ Only desync modes `fake`,`hopbyhop`,`destopt`,`ipfrag1` and `ipfrag2` are applic
|
||||
`fake`,`hopbyhop`,`destopt` can be used in combo with `ipfrag2`.
|
||||
`fake` can be used in combo with `udplen` and `tamper`.
|
||||
|
||||
`udplen` increases udp payload size by `--dpi-desync-udplen-increment` bytes. Padding is filled with zeroes by default but can be overriden with a pattern.
|
||||
`udplen` increases UDP payload size by `--dpi-desync-udplen-increment` bytes. Padding is filled with zeroes by default but can be overriden with a pattern.
|
||||
This option can resist DPIs that track outgoing UDP packet sizes.
|
||||
Requires that application protocol does not depend on udp payload size.
|
||||
Requires that application protocol does not depend on UDP payload size.
|
||||
|
||||
QUIC initial packets are recognized. Decryption and hostname extraction is supported so `--hostlist` parameter will work.
|
||||
Wireguard handshake initiation and DHT packets are also recognized.
|
||||
WireGuard handshake initiation and DHT packets are also recognized.
|
||||
For other protocols desync use `--dpi-desync-any-protocol`.
|
||||
|
||||
Conntrack supports udp. `--dpi-desync-cutoff` will work. UDP conntrack timeout can be set in the 4th parameter of `--ctrack-timeouts`.
|
||||
@ -548,19 +547,19 @@ By default fake payload is 64 zeroes. Can be overriden using `--dpi-desync-fake-
|
||||
|
||||
### IP fragmentation
|
||||
|
||||
Modern network can be very hostile to IP fragmentation. Fragmented packets are often not delivered or refragmented/reassembled on the way.
|
||||
Frag position is set independently for tcp and udp. By default 24 and 8, must be multiple of 8.
|
||||
Modern network can be very hostile to IP fragmentation. Fragmented packets are often not delivered or refragmented/reassembled on the way.
|
||||
Frag position is set independently for TCP and UDP. By default 24 and 8, must be multiple of 8.
|
||||
Offset starts from the transport header.
|
||||
|
||||
tcp fragments are almost always filtered. It's absolutely not suitable for arbitrary websites.
|
||||
udp fragments have good chances to survive but not everywhere. It's good to assume success rate on QUIC between 50..75%.
|
||||
TCP fragments are almost always filtered. It's absolutely not suitable for arbitrary websites.
|
||||
UDP fragments have good chances to survive but not everywhere. It's good to assume success rate on QUIC between 50..75%.
|
||||
Likely more with your VPS. Sometimes filtered by DDoS protection.
|
||||
|
||||
There are important nuances when working with fragments in Linux.
|
||||
|
||||
ipv4 : Linux allows to send ipv4 fragments but standard firewall rules in OUTPUT chain can cause raw send to fail.
|
||||
IPv4: Linux allows to send IPv4 fragments but standard firewall rules in OUTPUT chain can cause raw send to fail.
|
||||
|
||||
ipv6 : There's no way for an application to reliably send fragments without defragmentation by conntrack.
|
||||
IPv6: There's no way for an application to reliably send fragments without defragmentation by conntrack.
|
||||
Sometimes it works, sometimes system defragments packets.
|
||||
Looks like kernels <4.16 have no simple way to solve this problem. Unloading of `nf_conntrack` module
|
||||
and its dependency `nf_defrag_ipv6` helps but this severely impacts functionality.
|
||||
@ -568,15 +567,16 @@ Kernels 4.16+ exclude from defragmentation untracked packets.
|
||||
See `blockcheck.sh` code for example.
|
||||
|
||||
Sometimes it's required to load `ip6table_raw` kernel module with parameter `raw_before_defrag=1`.
|
||||
In openwrt module parameters are specified after module names separated by space in files located in `/etc/modules.d`.
|
||||
In OpenWrt module parameters are specified after module names separated by space in files located in `/etc/modules.d`.
|
||||
|
||||
In traditional linux check whether `iptables-legacy` or `iptables-nft` is used. If legacy create the file
|
||||
In traditional Linux check whether `iptables-legacy` or `iptables-nft` is used. If legacy create the file
|
||||
`/etc/modprobe.d/ip6table_raw.conf` with the following content :
|
||||
|
||||
```sh
|
||||
options ip6table_raw raw_before_defrag=1
|
||||
```
|
||||
In some linux distros its possible to change current ip6tables using this command: `update-alternatives --config ip6tables`.
|
||||
|
||||
In some Linux distros its possible to change current ip6tables using this command: `update-alternatives --config ip6tables`.
|
||||
If you want to stay with `nftables-nft` you need to patch and recompile your version.
|
||||
In `nft.c` find :
|
||||
|
||||
@ -594,6 +594,7 @@ In `nft.c` find :
|
||||
.hook = NF_INET_LOCAL_OUT,
|
||||
},
|
||||
```
|
||||
|
||||
and replace -300 to -450.
|
||||
|
||||
It must be done manually, `blockcheck.sh` cannot auto fix this for you.
|
||||
@ -613,47 +614,47 @@ tpws is transparent proxy.
|
||||
```
|
||||
--debug=0|1|2|syslog|@<filename> ; 1 and 2 means log to console and set debug level. for other targets use --debug-level.
|
||||
--debug-level=0|1|2 ; specify debug level for syslog and @<filename>
|
||||
--bind-addr=<v4_addr>|<v6_addr>; for v6 link locals append %interface_name : fe80::1%br-lan
|
||||
--bind-iface4=<interface_name> ; bind to the first ipv4 addr of interface
|
||||
--bind-iface6=<interface_name> ; bind to the first ipv6 addr of interface
|
||||
--bind-addr=<v4_addr>|<v6_addr>; for v6 link locals append %interface_name: fe80::1%br-lan
|
||||
--bind-iface4=<interface_name> ; bind to the first IPv4 addr of interface
|
||||
--bind-iface6=<interface_name> ; bind to the first IPv6 addr of interface
|
||||
--bind-linklocal=no|unwanted|prefer|force
|
||||
; no : bind only to global ipv6
|
||||
; unwanted (default) : prefer global address, then LL
|
||||
; prefer : prefer LL, then global
|
||||
; force : LL only
|
||||
; no: bind only to global IPv6
|
||||
; unwanted (default): prefer global address, then LL
|
||||
; prefer: prefer LL, then global
|
||||
; force: LL only
|
||||
--bind-wait-ifup=<sec> ; wait for interface to appear and up
|
||||
--bind-wait-ip=<sec> ; after ifup wait for ip address to appear up to N seconds
|
||||
--bind-wait-ip-linklocal=<sec> ; accept only link locals first N seconds then any
|
||||
--bind-wait-only ; wait for bind conditions satisfaction then exit. return code 0 if success.
|
||||
--bind-wait-only ; wait for bind conditions satisfaction then exit. return code 0 if success.
|
||||
--connect-bind-addr=<v4_addr>|<v6_addr> ; address for outbound connections. for v6 link locals append %%interface_name
|
||||
--port=<port> ; port number to listen on
|
||||
--socks ; implement socks4/5 proxy instead of transparent proxy
|
||||
--local-rcvbuf=<bytes> ; SO_RCVBUF for local legs
|
||||
--local-sndbuf=<bytes> ; SO_SNDBUF for local legs
|
||||
--port=<port> ; port number to listen on
|
||||
--socks ; implement socks4/5 proxy instead of transparent proxy
|
||||
--local-rcvbuf=<bytes> ; SO_RCVBUF for local legs
|
||||
--local-sndbuf=<bytes> ; SO_SNDBUF for local legs
|
||||
--remote-rcvbuf=<bytes> ; SO_RCVBUF for remote legs
|
||||
--remote-sndbuf=<bytes> ; SO_SNDBUF for remote legs
|
||||
--remote-sndbuf=<bytes> ; SO_SNDBUF for remote legs
|
||||
--nosplice ; do not use splice to transfer data between sockets
|
||||
--skip-nodelay ; do not set TCP_NODELAY for outgoing connections. incompatible with split.
|
||||
--local-tcp-user-timeout=<seconds> ; set tcp user timeout for local leg (default : 10, 0 = system default)
|
||||
--remote-tcp-user-timeout=<seconds> ; set tcp user timeout for remote leg (default : 20, 0 = system default)
|
||||
--no-resolve ; disable socks5 remote dns
|
||||
--skip-nodelay ; do not set TCP_NODELAY for outgoing connections. incompatible with split.
|
||||
--local-tcp-user-timeout=<seconds> ; set TCP user timeout for local leg (default: 10, 0 = system default)
|
||||
--remote-tcp-user-timeout=<seconds> ; set TCP user timeout for remote leg (default: 20, 0 = system default)
|
||||
--no-resolve ; disable socks5 remote DNS
|
||||
--resolver-threads=<int> ; number of resolver worker threads
|
||||
--maxconn=<max_connections> ; max number of local legs
|
||||
--maxfiles=<max_open_files> ; max file descriptors (setrlimit). min requirement is (X*connections+16), where X=6 in tcp proxy mode, X=4 in tampering mode.
|
||||
; its worth to make a reserve with 1.5 multiplier. by default maxfiles is (X*connections)*1.5+16
|
||||
--max-orphan-time=<sec> ; if local leg sends something and closes and remote leg is still connecting then cancel connection attempt after N seconds
|
||||
--maxconn=<max_connections> ; max number of local legs
|
||||
--maxfiles=<max_open_files> ; max file descriptors (setrlimit). min requirement is (X*connections+16), where X=6 in TCP proxy mode, X=4 in tampering mode.
|
||||
; its worth to make a reserve with 1.5 multiplier. by default maxfiles is (X*connections)*1.5+16
|
||||
--max-orphan-time=<sec> ; if local leg sends something and closes and remote leg is still connecting then cancel connection attempt after N seconds
|
||||
|
||||
--hostlist=<filename> ; only act on hosts in the list (one host per line, subdomains auto apply, gzip supported, multiple hostlists allowed)
|
||||
--hostlist-exclude=<filename> ; do not act on hosts in the list (one host per line, subdomains auto apply, gzip supported, multiple hostlists allowed)
|
||||
--hostlist-auto=<filename> ; detect DPI blocks and build hostlist automatically
|
||||
--hostlist-auto-fail-threshold=<int> ; how many failed attempts cause hostname to be added to auto hostlist (default : 3)
|
||||
--hostlist-auto-fail-time=<int> ; all failed attemps must be within these seconds (default : 60)
|
||||
--hostlist-auto-debug=<logfile> ; debug auto hostlist positives
|
||||
--hostlist-auto-fail-threshold=<int> ; how many failed attempts cause hostname to be added to auto hostlist (default: 3)
|
||||
--hostlist-auto-fail-time=<int> ; all failed attempts must be within these seconds (default: 60)
|
||||
--hostlist-auto-debug=<logfile> ; debug auto hostlist positives
|
||||
|
||||
--split-http-req=method|host ; split http request at specified logical position.
|
||||
--split-http-req=method|host ; split HTTP request at specified logical position.
|
||||
--split-tls=sni|sniext ; split at specified logical part of TLS ClientHello
|
||||
--split-pos=<numeric_offset> ; split at specified pos. split-http-req takes precedence over split-pos for http reqs.
|
||||
--split-any-protocol ; split not only http and https
|
||||
--split-pos=<numeric_offset> ; split at specified pos. split-http-req takes precedence over split-pos for HTTP requests.
|
||||
--split-any-protocol ; split not only HTTP and HTTPS
|
||||
--disorder[=http|tls] ; when splitting simulate sending second fragment first
|
||||
--oob[=http|tls] ; when splitting send out of band byte. default is HEX 0x00.
|
||||
--oob-data=<char>|0xHEX ; override default 0x00 OOB byte.
|
||||
@ -662,8 +663,8 @@ tpws is transparent proxy.
|
||||
--hostdot ; add "." after Host: name
|
||||
--hosttab ; add tab after Host: name
|
||||
--hostnospace ; remove space after Host:
|
||||
--hostpad=<bytes> ; add dummy padding headers before Host:
|
||||
--domcase ; mix domain case after Host: like this : TeSt.cOm
|
||||
--hostpad=<bytes> ; add dummy padding headers before Host:
|
||||
--domcase ; mix domain case after Host: like this: TeSt.cOm
|
||||
--methodspace ; add extra space after method
|
||||
--methodeol ; add end-of-line before method
|
||||
--unixeol ; replace 0D0A to 0A
|
||||
@ -675,15 +676,15 @@ tpws is transparent proxy.
|
||||
--tamper-cutoff=[n]<pos> ; do not tamper anymore after specified outbound stream position. byte pos or block number ('n'). default is unlimited.
|
||||
--daemon ; daemonize
|
||||
--pidfile=<filename> ; write pid to file
|
||||
--user=<username> ; drop root privs
|
||||
--uid=uid[:gid] ; drop root privs
|
||||
--user=<username> ; drop root privileges
|
||||
--uid=uid[:gid] ; drop root privileges
|
||||
```
|
||||
|
||||
The manipulation parameters can be combined in any way.
|
||||
|
||||
`split-http-req` takes precedence over split-pos for http reqs.
|
||||
`split-http-req` takes precedence over split-pos for HTTP requests.
|
||||
|
||||
split-pos works by default only on http and TLS ClientHello. use `--split-any-protocol` to act on any packet
|
||||
split-pos works by default only on HTTP and TLS ClientHello. use `--split-any-protocol` to act on any packet
|
||||
|
||||
tpws can bind to multiple interfaces and IP addresses (up to 32).
|
||||
|
||||
@ -693,22 +694,22 @@ Parameters `--bind-iface*` and `--bind-addr` create new bind.
|
||||
|
||||
Other parameters `--bind-*` are related to the last bind.
|
||||
|
||||
link local ipv6 (`fe80::/8`) mode selection :
|
||||
link local IPv6 (`fe80::/8`) mode selection :
|
||||
|
||||
```
|
||||
--bind-iface6 --bind-linklocal=no : first selects private address fc00::/7, then global address
|
||||
--bind-iface6 --bind-linklocal=unwanted : first selects private address fc00::/7, then global address, then LL
|
||||
--bind-iface6 --bind-linklocal=prefer : first selects LL, then private address fc00::/7, then global address
|
||||
--bind-iface6 --bind-linklocal=force : select only LL
|
||||
--bind-iface6 --bind-linklocal=no: first selects private address fc00::/7, then global address
|
||||
--bind-iface6 --bind-linklocal=unwanted: first selects private address fc00::/7, then global address, then LL
|
||||
--bind-iface6 --bind-linklocal=prefer: first selects LL, then private address fc00::/7, then global address
|
||||
--bind-iface6 --bind-linklocal=force: select only LL
|
||||
```
|
||||
|
||||
To bind to all ipv4 specify `--bind-addr "0.0.0.0"`, all ipv6 - `::`.
|
||||
To bind to all IPv4 specify `--bind-addr "0.0.0.0"`, all IPv6 - `::`.
|
||||
|
||||
`--bind-addr=""` - mean bind to all ipv4 and ipv6.
|
||||
`--bind-addr=""` - mean bind to all IPv4 and IPv6.
|
||||
|
||||
If no binds are specified default bind to all ipv4 and ipv6 addresses is created.
|
||||
If no binds are specified default bind to all IPv4 and IPv6 addresses is created.
|
||||
|
||||
To bind to a specific link local address do : `--bind-iface6=fe80::aaaa:bbbb:cccc:dddd%iface-name`
|
||||
To bind to a specific link local address do: `--bind-iface6=fe80::aaaa:bbbb:cccc:dddd%iface-name`
|
||||
|
||||
The `--bind-wait*` parameters can help in situations where you need to get IP from the interface, but it is not there yet, it is not raised
|
||||
or not configured.
|
||||
@ -717,21 +718,21 @@ In different systems, ifup events are caught in different ways and do not guaran
|
||||
|
||||
In the general case, there is no single mechanism to hang oneself on an event of the type "link local address appeared on the X interface."
|
||||
|
||||
To bind to a specific ip when its interface may not be configured yet do : `--bind-addr=192.168.5.3 --bind-wait-ip=20`
|
||||
To bind to a specific ip when its interface may not be configured yet do: `--bind-addr=192.168.5.3 --bind-wait-ip=20`
|
||||
|
||||
It's possible to bind to any nonexistent address in transparent mode but in socks mode address must exist.
|
||||
It's possible to bind to any nonexistent address in transparent mode but in SOCKS mode address must exist.
|
||||
|
||||
In SOCKS proxy mode no additional system privileges are required. Connections to local IPs of the system where tpws runs are prohibited.
|
||||
tpws supports remote DNS resolving (curl: `--socks5-hostname` firefox: `socks_remote_dns=true`), but does it in blocking mode.
|
||||
|
||||
tpws uses async sockets for all activities. Domain names are resolved in multi threaded pool.
|
||||
Resolving does not freeze other connections. But if there're too many requests resolving delays may increase.
|
||||
Number of resolver threads is choosen automatically proportinally to `--maxconn` and can be overriden using `--resolver-threads`.
|
||||
Number of resolver threads is chosen automatically proportionally to `--maxconn` and can be overriden using `--resolver-threads`.
|
||||
To disable hostname resolve use `--no-resolve` option.
|
||||
|
||||
`--disorder` is an additional flag to any split option.
|
||||
It tries to simulate `--disorder2` option of `nfqws` using standard socket API without the need of additional privileges.
|
||||
This works fine in Linux and MacOS but unexpectedly in FreeBSD and OpenBSD
|
||||
This works fine in Linux and macOS but unexpectedly in FreeBSD and OpenBSD
|
||||
(system sends second fragment then the whole packet instead of the first fragment).
|
||||
|
||||
`--tlsrec` and `--tlsrec-pos` allow to split TLS ClientHello into 2 TLS records in one TCP segment.
|
||||
@ -746,16 +747,15 @@ Use of `--tlsrec` without filters is discouraged.
|
||||
Server replies with it's own MSS in SYN,ACK packet. Usually servers lower their packet sizes but they still don't
|
||||
fit to supplied MSS. The greater MSS client sets the bigger server's packets will be.
|
||||
If it's enough to split TLS 1.2 ServerHello, it may fool DPI that checks certificate domain name.
|
||||
This scheme may significantly lower speed. Hostlist filter is possible only in socks mode if client uses remote resolving (firefox `network.proxy.socks_remote_dns`).
|
||||
This scheme may significantly lower speed. Hostlist filter is possible only in SOCKS mode if client uses remote resolving (firefox `network.proxy.socks_remote_dns`).
|
||||
TLS version filters are not possible.
|
||||
`--mss-pf` sets port filter for MSS. Use `mss-pf=443` to apply MSS only for https.
|
||||
`--mss-pf` sets port filter for MSS. Use `mss-pf=443` to apply MSS only for HTTPS.
|
||||
Likely not required for TLS1.3. If TLS1.3 is negotiable then MSS make things only worse.
|
||||
Use only if nothing better is available. Works only in Linux, not BSD or MacOS.
|
||||
|
||||
Use only if nothing better is available. Works only in Linux, not BSD or macOS.
|
||||
|
||||
## Ways to get a list of blocked IP
|
||||
|
||||
nftables can't work with ipsets. Native nf sets require lots of RAM to load large ip lists with subnets and intervals.
|
||||
nftables can't work with IP sets. Native nf sets require lots of RAM to load large ip lists with subnets and intervals.
|
||||
In case you're on a low RAM system and need large lists it may be required to fall back to iptables+ipset.
|
||||
|
||||
1. Enter the blocked domains to `ipset/zapret-hosts-user.txt` and run `ipset/get_user.sh`
|
||||
@ -767,7 +767,7 @@ At the output, you get `ipset/zapret-ip-user.txt` with IP addresses.
|
||||
|
||||
4. `ipset/get_config.sh`. This script calls what is written into the GETLIST variable from the config file.
|
||||
|
||||
If the variable is not defined, then only lists for ipsets nozapret/nozapret6 are resolved.
|
||||
If the variable is not defined, then only lists for IP sets nozapret/nozapret6 are resolved.
|
||||
|
||||
So, if you're not Russian, the only way for you is to manually add blocked domains.
|
||||
Or write your own `ipset/get_iran_blocklist.sh`, if you know where to download this one.
|
||||
@ -799,20 +799,20 @@ User lists are not gzipped because they are not expected to be very large.
|
||||
You can add a list of domains to `ipset/zapret-hosts-user-ipban.txt`. Their ip addresses will be placed
|
||||
in a separate ipset "ipban". It can be used to route connections to transparent proxy "redsocks" or VPN.
|
||||
|
||||
IPV6: if ipv6 is enabled, then additional txt's are created with the same name, but with a "6" at the end before the extension.
|
||||
IPV6: if IPv6 is enabled, then additional txt's are created with the same name, but with a "6" at the end before the extension.
|
||||
|
||||
`zapret-ip.txt` => `zapret-ip6.txt`
|
||||
|
||||
The ipsets zapret6 and ipban6 are created.
|
||||
The IP sets zapret6 and ipban6 are created.
|
||||
|
||||
IP EXCLUSION SYSTEM. All scripts resolve `zapret-hosts-user-exclude.txt` file, creating `zapret-ip-exclude.txt` and `zapret-ip-exclude6.txt`.
|
||||
|
||||
They are the source for ipsets nozapret/nozapret6. All rules created by init scripts are created with these ipsets in mind.
|
||||
They are the source for IP sets nozapret/nozapret6. All rules created by init scripts are created with these IP sets in mind.
|
||||
The IPs placed in them are not involved in the process.
|
||||
zapret-hosts-user-exclude.txt can contain domains, ipv4 and ipv6 addresses or subnets.
|
||||
zapret-hosts-user-exclude.txt can contain domains, IPv4 and IPv6 addresses or subnets.
|
||||
|
||||
FreeBSD. `ipset/*.sh` scripts also work in FreeBSD. Instead of ipset they create ipfw lookup tables with the same names as in Linux.
|
||||
ipfw tables can store both ipv4 and ipv6 addresses and subnets. There's no 4 and 6 separation.
|
||||
ipfw tables can store both IPv4 and IPv6 addresses and subnets. There's no 4 and 6 separation.
|
||||
|
||||
LISTS_RELOAD config parameter defines a custom lists reloading command.
|
||||
Its useful on BSD systems with PF.
|
||||
@ -822,7 +822,7 @@ LISTS_RELOAD=- disables reloading ip list backend.
|
||||
|
||||
An alternative to ipset is to use tpws or nfqws with a list(s) of domains.
|
||||
Both `tpws` and `nfqws` take any number of include (`--hostlist`) and exclude (`--hostlist-exclude`) domain lists.
|
||||
All lists of the same type are combined internally leaving only 2 lists : include and exclude.
|
||||
All lists of the same type are combined internally leaving only 2 lists: include and exclude.
|
||||
|
||||
Exclude list is checked first. Fooling is cancelled if domain belongs to exclude list.
|
||||
If include list is present and domain does not belong to that list fooling is also cancelled.
|
||||
@ -840,7 +840,7 @@ and 1 exclude list
|
||||
|
||||
If `MODE_FILTER=hostlist` all present lists are passed to `nfqws` or `tpws`.
|
||||
If all include lists are empty it works like no include lists exist at all.
|
||||
If you need "all except" mode you dont have to delete zapret-hosts-users.txt. Just make it empty.
|
||||
If you need "all except" mode you don't have to delete zapret-hosts-users.txt. Just make it empty.
|
||||
|
||||
Subdomains auto apply. For example, "ru" in the list affects "*.ru" .
|
||||
|
||||
@ -860,11 +860,12 @@ In case of nfqws it's required to redirect both incoming and outgoing traffic to
|
||||
It's strongly recommended to use connbytes filter or nfqws will process gigabytes of incoming traffic.
|
||||
For the same reason it's not recommended to use autohostlist mode in BSDs. BSDs do not support connbytes or similar mechanism.
|
||||
|
||||
nfqws и tpws detect the folowing situations :
|
||||
nfqws и tpws detect the following situations :
|
||||
|
||||
1) [nfqws] Multiple retransmissions of the first request inside a TCP session having host.
|
||||
2) [nfqws,tpws] RST in response to the first request.
|
||||
3) [nfqws,tpws] HTTP redirect in response to the first http request with 2nd level domain diferent from the original.
|
||||
4) [tpws] Client closes connection after first request without having server reply (no reponse from server, timeout).
|
||||
3) [nfqws,tpws] HTTP redirect in response to the first HTTP request with 2nd level domain different from the original.
|
||||
4) [tpws] Client closes connection after first request without having server reply (no response from server, timeout).
|
||||
|
||||
To minimize false positives there's fail counter. If in specific time occurs more than specified number of fails
|
||||
the host is added to the list. Then DPI bypass strategy start to apply immediately.
|
||||
@ -890,18 +891,17 @@ If a process modified autohostlist, all others will reread it automatically.
|
||||
All processes must run with the same uid.
|
||||
|
||||
If zapret scripts are used then autohostlist is `ipset/zapret-hosts-auto.txt`
|
||||
and exlude list is `ipset/zapret-hosts-user-exclude.txt`. autohostlist mode
|
||||
and exclude list is `ipset/zapret-hosts-user-exclude.txt`. autohostlist mode
|
||||
includes hostlist mode. You can use `ipset/zapret-hosts-user.txt`.
|
||||
|
||||
|
||||
## Choosing parameters
|
||||
|
||||
The file `/opt/zapret/config` is used by various components of the system and contains basic settings.
|
||||
It needs to be viewed and edited if necessary.
|
||||
|
||||
Which firewall type use on linux systems : `nftables` or `iptables`.
|
||||
Which firewall type use on Linux systems: `nftables` or `iptables`.
|
||||
On traditional systems `nftables` is selected by default if `nft` is installed.
|
||||
On openwrt by default `nftables` is selected on `firewall4` based systems.
|
||||
On OpenWrt by default `nftables` is selected on `firewall4` based systems.
|
||||
|
||||
`FWTYPE=iptables`
|
||||
|
||||
@ -909,8 +909,8 @@ Main mode :
|
||||
|
||||
```
|
||||
tpws - tpws transparent mode
|
||||
tpws-socks - tpws socks mode
|
||||
binds to localhost and LAN interface (if IFACE_LAN is specified or the system is OpenWRT). port 988
|
||||
tpws-socks - tpws SOCKS mode
|
||||
binds to localhost and LAN interface (if IFACE_LAN is specified or the system is OpenWrt). port 988
|
||||
nfqws - nfqws
|
||||
filter - only fill ipset or load hostlist
|
||||
custom - use custom script for running daemons and establishing firewall rules
|
||||
@ -918,24 +918,25 @@ custom - use custom script for running daemons and establishing firewall rules
|
||||
|
||||
`MODE=tpws`
|
||||
|
||||
Enable http fooling :
|
||||
Enable HTTP fooling :
|
||||
|
||||
`MODE_HTTP=1`
|
||||
|
||||
Apply fooling to keep alive http sessions. Only applicable to nfqws. Tpws always fool keepalives.
|
||||
Apply fooling to keep alive HTTP sessions. Only applicable to nfqws. Tpws always fool keepalives.
|
||||
Not enabling this can save CPU time.
|
||||
|
||||
`MODE_HTTP_KEEPALIVE=0`
|
||||
|
||||
Enable https fooling :
|
||||
Enable HTTPS fooling :
|
||||
|
||||
`MODE_HTTPS=1`
|
||||
|
||||
Enable quic fooling :
|
||||
Enable QUIC fooling :
|
||||
|
||||
`MODE_QUIC=1`
|
||||
|
||||
Host filtering mode :
|
||||
|
||||
```
|
||||
none - apply fooling to all hosts
|
||||
ipset - limit fooling to hosts from ipset zapret/zapret6
|
||||
@ -957,7 +958,7 @@ DESYNC_MARK_POSTNAT=0x20000000
|
||||
NFQWS_OPT_DESYNC="--dpi-desync=fake --dpi-desync-ttl=0 --dpi-desync-fooling=badsum --dpi-desync-fwmark=$DESYNC_MARK"
|
||||
```
|
||||
|
||||
Separate nfqws options for http and https and ip protocol versions 4,6:
|
||||
Separate nfqws options for HTTP and HTTPS and ip protocol versions 4,6:
|
||||
|
||||
```sh
|
||||
NFQWS_OPT_DESYNC_HTTP="--dpi-desync=split --dpi-desync-ttl=0 --dpi-desync-fooling=badsum"
|
||||
@ -982,14 +983,13 @@ NFQWS_OPT_DESYNC_QUIC6="--dpi-desync=hopbyhop"
|
||||
|
||||
If `NFQWS_OPT_DESYNC_QUIC6` is not specified `NFQWS_OPT_DESYNC_QUIC` is taken.
|
||||
|
||||
|
||||
flow offloading control (if supported)
|
||||
|
||||
```
|
||||
donttouch : disable system flow offloading setting if selected mode is incompatible with it, dont touch it otherwise and dont configure selective flow offloading
|
||||
none : always disable system flow offloading setting and dont configure selective flow offloading
|
||||
software : always disable system flow offloading setting and configure selective software flow offloading
|
||||
hardware : always disable system flow offloading setting and configure selective hardware flow offloading
|
||||
donttouch: disable system flow offloading setting if selected mode is incompatible with it, don't touch it otherwise and don't configure selective flow offloading
|
||||
none: always disable system flow offloading setting and don't configure selective flow offloading
|
||||
software: always disable system flow offloading setting and configure selective software flow offloading
|
||||
hardware: always disable system flow offloading setting and configure selective hardware flow offloading
|
||||
```
|
||||
|
||||
`FLOWOFFLOAD=donttouch`
|
||||
@ -1000,7 +1000,7 @@ Its called via `get_config.sh` from scheduled tasks (crontab or systemd timer).
|
||||
Put here the name of the script that you will use to update the lists.
|
||||
If not, then the parameter should be commented out.
|
||||
|
||||
You can individually disable ipv4 or ipv6. If the parameter is commented out or not equal to "1",
|
||||
You can individually disable IPv4 or IPv6. If the parameter is commented out or not equal to "1",
|
||||
use of the protocol is permitted.
|
||||
|
||||
```sh
|
||||
@ -1027,9 +1027,9 @@ IPSET_OPT="hashsize 262144 maxelem 2097152
|
||||
Kernel automatically increases hashsize if ipset is too large for the current hashsize.
|
||||
This procedure requires internal reallocation and may require additional memory.
|
||||
On low RAM systems it can cause errors.
|
||||
Do not use too high hashsize. This way you waste your RAM. And dont use too low hashsize to avoid reallocs.
|
||||
Do not use too high hashsize. This way you waste your RAM. And don't use too low hashsize to avoid reallocations.
|
||||
|
||||
ip2net options. separate for ipv4 and ipv6.
|
||||
ip2net options. separate for IPv4 and IPv6.
|
||||
|
||||
```sh
|
||||
IP2NET_OPT4="--prefix-length=22-30 --v4-threshold=3/4"
|
||||
@ -1050,19 +1050,19 @@ Enable gzip compression for large lists. Used by ipset/*.sh scripts.
|
||||
`GZIP_LISTS=1`
|
||||
|
||||
Command to reload ip/host lists after update.
|
||||
Comment or leave empty for auto backend selection : ipset or ipfw if present.
|
||||
Comment or leave empty for auto backend selection: ipset or ipfw if present.
|
||||
On BSD systems with PF no auto reloading happens. You must provide your own command.
|
||||
Newer FreeBSD versions support table only reloading : `pfctl -Tl -f /etc/pf.conf`
|
||||
Newer FreeBSD versions support table only reloading: `pfctl -Tl -f /etc/pf.conf`
|
||||
Set to "-" to disable reload.
|
||||
|
||||
`LISTS_RELOAD="pfctl -f /etc/pf.conf"`
|
||||
|
||||
In openwrt there's default network `lan`. Only traffic coming from this network is redirected to tpws by default.
|
||||
In OpenWrt there's default network `lan`. Only traffic coming from this network is redirected to tpws by default.
|
||||
To override this behaviour set the following variable :
|
||||
|
||||
`OPENWRT_LAN="lan lan2 lan3"`
|
||||
|
||||
In openwrt wan interfaces are those having default route. Separately for ipv4 and ipv6.
|
||||
In OpenWrt WAN interfaces are those having default route. Separately for IPv4 and IPv6.
|
||||
This can be redefined :
|
||||
|
||||
```sh
|
||||
@ -1073,9 +1073,9 @@ OPENWRT_WAN6="wan6 vpn6"
|
||||
The `INIT_APPLY_FW=1` parameter enables the init script to independently apply iptables rules.
|
||||
With other values or if the parameter is commented out, the rules will not be applied.
|
||||
This is useful if you have a firewall management system, in the settings of which you should tie the rules.
|
||||
Not applicable to `OpenWRT` if used with `firewall3+iptables`.
|
||||
Not applicable to `OpenWrt` if used with `firewall3+iptables`.
|
||||
|
||||
The following settings are not relevant for openwrt :
|
||||
The following settings are not relevant for OpenWrt :
|
||||
|
||||
If your system works as a router, then you need to enter the names of the internal and external interfaces:
|
||||
|
||||
@ -1084,12 +1084,12 @@ IFACE_LAN=eth0
|
||||
IFACE_WAN=eth1
|
||||
IFACE_WAN6="henet ipsec0"
|
||||
```
|
||||
|
||||
Multiple interfaces are space separated. IF IFACE_WAN6 is omitted then IFACE_WAN value is taken.
|
||||
|
||||
IMPORTANT: configuring routing, masquerade, etc. not a zapret task.
|
||||
Only modes that intercept transit traffic are enabled.
|
||||
It's possible to specify multiple interfaces like this : `IFACE_LAN="eth0 eth1 eth2"`
|
||||
|
||||
It's possible to specify multiple interfaces like this: `IFACE_LAN="eth0 eth1 eth2"`
|
||||
|
||||
## Screwing to the firewall control system or your launch system
|
||||
|
||||
@ -1113,7 +1113,7 @@ And you can start or stop the demons separately from the firewall:
|
||||
/opt/zapret/init.d/sysv/zapret restart_daemons
|
||||
```
|
||||
|
||||
nftables nearly eliminate conflicts betweeen firewall control systems because they allow
|
||||
nftables nearly eliminate conflicts between firewall control systems because they allow
|
||||
separate tables and netfilter hooks. `zapret` nf table is used for zapret purposes.
|
||||
If your system does not touch it everything will likely be OK.
|
||||
|
||||
@ -1150,7 +1150,7 @@ INIT_FW_POST_DOWN_HOOK="/etc/firewall.zapret.hook.post_down"
|
||||
```
|
||||
|
||||
Hooks are extremely useful if you need nftables sets populated by zapret scripts.
|
||||
nfsets can only belong to one table. You have to write rule there and synchorize them with zapret scripts.
|
||||
nfsets can only belong to one table. You have to write rule there and synchronize them with zapret scripts.
|
||||
|
||||
## Installation
|
||||
|
||||
@ -1164,14 +1164,14 @@ to their servers `blockcheck.sh` also checks that all returned answers are uniqu
|
||||
ISP returns single ip for all blocked domains to redirect you to their "access denied" page.
|
||||
`blockcheck.sh` works in Linux and FreeBSD.
|
||||
|
||||
### desktop linux system
|
||||
### desktop Linux system
|
||||
|
||||
Simple install works on most modern linux distributions with systemd or openrc, OpenWRT and MacOS.
|
||||
Simple install works on most modern Linux distributions with systemd or openrc, OpenWrt and macOS.
|
||||
Run `install_easy.sh` and answer its questions.
|
||||
|
||||
### OpenWRT
|
||||
### OpenWrt
|
||||
|
||||
`install_easy.sh` works on openwrt but there're additional challenges.
|
||||
`install_easy.sh` works on OpenWrt but there're additional challenges.
|
||||
They are mainly about possibly low flash free space.
|
||||
Simple install will not work if it has no space to install itself and required packages from the repo.
|
||||
|
||||
@ -1182,7 +1182,7 @@ It's also not too hard to use 'nc' (netcat) for file transfer.
|
||||
The best way to start is to put zapret dir to `/tmp` and run `/tmp/zapret/install_easy.sh` from there.
|
||||
After installation remove `/tmp/zapret` to free RAM.
|
||||
|
||||
The absolute minimum for openwrt is 64/8 system, 64/16 is comfortable, 128/extroot is recommended.
|
||||
The absolute minimum for OpenWrt is 64/8 system, 64/16 is comfortable, 128/extroot is recommended.
|
||||
|
||||
### Android
|
||||
|
||||
@ -1199,18 +1199,18 @@ Android does not use /etc/passwd, `tpws --user` won't work. There's replacement.
|
||||
Use numeric uids in `--uid` option.
|
||||
Its recommended to use gid 3003 (AID_INET), otherwise tpws will not have inet access.
|
||||
|
||||
Example : `--uid 1:3003`
|
||||
Example: `--uid 1:3003`
|
||||
|
||||
In iptables use : `! --uid-owner 1` instead of `! --uid-owner tpws`.
|
||||
In iptables use: `! --uid-owner 1` instead of `! --uid-owner tpws`.
|
||||
|
||||
Nfqws should be executed with `--uid 1`. Otherwise on some devices or firmwares kernel may partially hang. Looks like processes with certain uids can be suspended. With buggy chineese cellular interface driver this can lead to device hang.
|
||||
Nfqws should be executed with `--uid 1`. Otherwise on some devices or firmwares kernel may partially hang. Looks like processes with certain uids can be suspended. With buggy chinese cellular interface driver this can lead to device hang.
|
||||
|
||||
Write your own shell script with iptables and tpws, run it using your root manager.
|
||||
Autorun scripts are here :
|
||||
|
||||
magisk : `/data/adb/service.d`
|
||||
magisk: `/data/adb/service.d`
|
||||
|
||||
supersu : `/system/su.d`
|
||||
supersu: `/system/su.d`
|
||||
|
||||
How to run tpws on root-less android.
|
||||
You can't write to `/system`, `/data`, can't run from sd card.
|
||||
@ -1226,7 +1226,7 @@ chcon u:object_r:system_file:s0 /data/local/tmp/zapret/tpws
|
||||
|
||||
Now its possible to run `/data/local/tmp/zapret/tpws` from any app such as tasker.
|
||||
|
||||
### FreeBSD, OpenBSD, MacOS
|
||||
### FreeBSD, OpenBSD, macOS
|
||||
|
||||
see docs/bsd.eng.md
|
||||
|
||||
@ -1243,16 +1243,17 @@ Most closed stock firmwares are not designed for custom usage and sometimes acti
|
||||
In the latter case you have to hack into it and reverse engineer. Its not easy.
|
||||
Binaries are universal. They can run on almost all firmwares.
|
||||
You will need :
|
||||
* root shell access. true sh shell, not microtik-like console
|
||||
* startup hook
|
||||
* r/w partition to store binaries and startup script with executable permission (+x)
|
||||
* tpws can be run almost anywhere but nfqws require kernel support for NFQUEUE. Its missing in most firmwares.
|
||||
* too old 2.6 kernels are unsupported and can cause errors. newer 2.6 kernels are OK.
|
||||
If binaries crash with segfault (rare but happens on some kernels) try to unpack upx like this : upx -d tpws.
|
||||
|
||||
- root shell access. true sh shell, not Mikrotik-like console
|
||||
- startup hook
|
||||
- r/w partition to store binaries and startup script with executable permission (+x)
|
||||
- tpws can be run almost anywhere but nfqws require kernel support for NFQUEUE. Its missing in most firmwares.
|
||||
- too old 2.6 kernels are unsupported and can cause errors. newer 2.6 kernels are OK.
|
||||
If binaries crash with segfault (rare but happens on some kernels) try to unpack upx like this: upx -d tpws.
|
||||
|
||||
First manually debug your scenario. Run iptables + daemon and check if its what you want.
|
||||
Write your own script with iptables magic and run required daemon from there. Put it to startup.
|
||||
Dont ask me how to do it. Its different for all firmwares and requires studying.
|
||||
Don't ask me how to do it. Its different for all firmwares and requires studying.
|
||||
Find manual or reverse engineer yourself.
|
||||
Check for race conditions. Firmware can clear or modify iptables after your startup script.
|
||||
If this is the case then run another script in background and add some delay there.
|
||||
|
@ -11,18 +11,18 @@ Using `WSL` (Windows subsystem for Linux) it's possible to run `tpws` in SOCKS m
|
||||
It's not required to install any Linux distributions as suggested in most articles.
|
||||
`tpws` is static binary. It doesn't need a distribution.
|
||||
|
||||
Install `WSL` : `dism.exe /online /enable-feature /featurename:Microsoft-Windows-Subsystem-Linux /all`
|
||||
Install `WSL`: `dism.exe /online /enable-feature /featurename:Microsoft-Windows-Subsystem-Linux /all`
|
||||
|
||||
Copy `binaries/x86_64/tpws_wsl.tgz` to the target system.
|
||||
Run : `wsl --import tpws "%USERPROFILE%\tpws" tpws_wsl.tgz`
|
||||
Run: `wsl --import tpws "%USERPROFILE%\tpws" tpws_wsl.tgz`
|
||||
|
||||
Run `tpws`: `wsl -d tpws --exec /tpws --uid=1 --no-resolve --socks --bind-addr=127.0.0.1 --port=1080 <fooling_options>`
|
||||
|
||||
Configure socks as `127.0.0.1:1080` in a browser or another program.
|
||||
Configure SOCKS as `127.0.0.1:1080` in a browser or another program.
|
||||
|
||||
Cleanup : `wsl --unregister tpws`
|
||||
Cleanup: `wsl --unregister tpws`
|
||||
|
||||
Tested in windows 10 build 19041 (20.04).
|
||||
Tested in Windows 10 build 19041 (20.04).
|
||||
|
||||
`--oob`, `--mss` and `--disorder` do not work.
|
||||
RST detection in autohostlist scheme may not work.
|
||||
@ -63,15 +63,15 @@ Task of `iptables` is done inside `winws` through `windivert` filters.
|
||||
|
||||
`--wf-l3`, `--wf-tcp`, `--wf-udp` can take multiple comma separated arguments.
|
||||
|
||||
Interface indexes can be discovered using this command : `netsh int ip show int`
|
||||
Interface indexes can be discovered using this command: `netsh int ip show int`
|
||||
|
||||
If you can't find index this way use `winws --debug` to see index there. Subinterface index is almost always 0 and you can omit it.
|
||||
|
||||
Multiple `winws` processes are allowed. However, it's discouraged to intersect their filters.
|
||||
|
||||
`--ssid-filter` allows to enable `winws` only if specified wifi networks are connected. `winws` auto detects SSID appearance and disappearance.
|
||||
`--ssid-filter` allows to enable `winws` only if specified Wi-Fi networks are connected. `winws` auto detects SSID appearance and disappearance.
|
||||
SSID names must be written in the same case as the system sees them. This option does not analyze routing and does not detect where traffic actually goes.
|
||||
If multiple connections are available, the only thing that triggers `winws` operation is wifi connection presence. That's why it's a good idea to add also `--wf-iface` filter to not break ethernet, for example.
|
||||
If multiple connections are available, the only thing that triggers `winws` operation is Wi-Fi connection presence. That's why it's a good idea to add also `--wf-iface` filter to not break Ethernet, for example.
|
||||
|
||||
`--nlm-filter` is like `--ssid-filter` but works with names or GUIDs from Network List Manager.
|
||||
NLM names are those you see in Control Panel "Network and Sharing Center".
|
||||
@ -83,7 +83,8 @@ That's why NLM is more universal than `ssid-filter`.
|
||||
That's why exists separate standalone version in `binaries/win64/zapret-tpws`.
|
||||
`Cygwin` is required for `blockcheck.sh` support but `winws` itself can be run standalone without cygwin.
|
||||
|
||||
How to get `windows 7` and `winws` compatible `cygwin` :
|
||||
How to get `Windows 7` and `winws` compatible `cygwin` :
|
||||
|
||||
```
|
||||
curl -O https://www.cygwin.com/setup-x86_64.exe
|
||||
setup-x86_64.exe --allow-unsupported-windows --no-verify --site http://ctm.crouchingtigerhiddenfruitbat.org/pub/cygwin/circa/64bit/2024/01/30/231215
|
||||
@ -97,12 +98,12 @@ It's possible to build x86 32-bit version but this version is not shipped. You h
|
||||
32-bit `windivert` can be downloaded from it's developer GitHub. Required version is 2.2.2.
|
||||
There's no `arm64` signed `windivert` driver and no `cygwin`.
|
||||
But it's possible to use unsigned driver version in test mode and user mode components with x64 emulation.
|
||||
x64 emulation requires `windows 11` and not supported in `windows 10`.
|
||||
x64 emulation requires `Windows 11` and not supported in `Windows 10`.
|
||||
|
||||
## Windows 7 windivert signing
|
||||
|
||||
Requirements for windows driver signing have changed in 2021.
|
||||
Official free updates of windows 7 ended in 2020.
|
||||
Requirements for Windows driver signing have changed in 2021.
|
||||
Official free updates of Windows 7 ended in 2020.
|
||||
After 2020 for the years paid updates were available (ESU).
|
||||
One of the updates from ESU enables signatures used in `windivert 2.2.2-A`.
|
||||
There are several options:
|
||||
@ -119,22 +120,22 @@ If you are in Russia or Belarus temporary change region in Control Panel.
|
||||
|
||||
## `blockcheck`
|
||||
|
||||
`blockcheck.sh` is written in posix shell and uses some standard posix utilites.
|
||||
`blockcheck.sh` is written in posix shell and uses some standard posix utilities.
|
||||
Windows does not have them. To execute `blockcheck.sh` use `cygwin` command prompt run as administrator.
|
||||
It's not possible to use `WSL`. It's not the same as `cygwin`.
|
||||
First run once `install_bin.sh` then `blockcheck.sh`.
|
||||
|
||||
Backslashes in windows paths shoud be doubled. Or use cygwin path notation.
|
||||
Backslashes in Windows paths should be doubled. Or use cygwin path notation.
|
||||
|
||||
```
|
||||
cd "C:\\Users\\vasya"
|
||||
cd "C:/Users/vasya"
|
||||
cd "/cygdrive/c/Users/vasya"
|
||||
```
|
||||
`Cygwin` is required only for `blockcheck.sh`. Standalone `winws` can be run without it.
|
||||
|
||||
## Autostart
|
||||
|
||||
To start `winws` with windows use windows task scheduler. There are `task_*.cmd` batch files in `binaries/win64/zapret-winws`.
|
||||
To start `winws` with Windows use Windows task scheduler. There are `task_*.cmd` batch files in `binaries/win64/zapret-winws`.
|
||||
They create, remove, start and stop scheduled task `winws1`. They must be run as administrator.
|
||||
|
||||
Edit `task_create.cmd` and write your `winws` parameters to `%WINWS1%` variable.
|
||||
@ -148,11 +149,11 @@ Also you can use Windows services the same way with `service_*.cmd`.
|
||||
|
||||
To make your life easier there's ready to use [bundle](https://github.com/bol-van/zapret-win-bundle) with `cygwin`, `blockcheck` and `winws`.
|
||||
|
||||
* `/zapret-winws` - standalone version of `winws` for everyday use. does not require any other folders.
|
||||
* `/zapret-winws/_CMD_ADMIN.cmd` - open `cmd` as administrator in the current folder
|
||||
* `/blockcheck/blockcheck.cmd` - run `blockcheck` with logging to `blockcheck/blockcheck.log`
|
||||
* `/cygwin/cygwin.cmd` - run `cygwin` shell as current user
|
||||
* `/cygwin/cygwin-admin.cmd` - run `cygwin` shell as administrator
|
||||
- `/zapret-winws` - standalone version of `winws` for everyday use. does not require any other folders.
|
||||
- `/zapret-winws/_CMD_ADMIN.cmd` - open `cmd` as administrator in the current folder
|
||||
- `/blockcheck/blockcheck.cmd` - run `blockcheck` with logging to `blockcheck/blockcheck.log`
|
||||
- `/cygwin/cygwin.cmd` - run `cygwin` shell as current user
|
||||
- `/cygwin/cygwin-admin.cmd` - run `cygwin` shell as administrator
|
||||
|
||||
There're aliases in `cygwin` shell for `winws`, `blockcheck`, `ip2net`, `mdig`. No need to mess with paths.
|
||||
It's possible to send signals to `winws` using standard unix utilities: `pidof`, `kill`, `killall`, `pgrep`, `pkill`.
|
||||
@ -166,4 +167,4 @@ winws --debug --wf-tcp=80,443 | tee winws.log
|
||||
unix2dos winws.log
|
||||
```
|
||||
|
||||
`winws.log` will be in `cygwin/home/<username>`. `unix2dos` helps with `windows 7` notepad. It's not necessary in `Windows 10` and later.
|
||||
`winws.log` will be in `cygwin/home/<username>`. `unix2dos` helps with `Windows 7` notepad. It's not necessary in `Windows 10` and later.
|
||||
|
@ -6,7 +6,7 @@ Index: WireGuard-0.0.20190123/src/cookie.c
|
||||
xchacha20poly1305_encrypt(dst->encrypted_cookie, cookie, COOKIE_LEN,
|
||||
macs->mac1, COOKIE_LEN, dst->nonce,
|
||||
checker->cookie_encryption_key);
|
||||
+ // MOD : randomize trash
|
||||
+ // MOD: randomize trash
|
||||
+ dst->header.trash = gen_trash();
|
||||
}
|
||||
|
||||
@ -34,7 +34,7 @@ Index: WireGuard-0.0.20190123/src/messages.h
|
||||
};
|
||||
+*/
|
||||
+
|
||||
+// MOD : message type
|
||||
+// MOD: message type
|
||||
+enum message_type {
|
||||
+ MESSAGE_INVALID = 0xE319CCD0,
|
||||
+ MESSAGE_HANDSHAKE_INITIATION = 0x48ADE198,
|
||||
@ -43,7 +43,7 @@ Index: WireGuard-0.0.20190123/src/messages.h
|
||||
+ MESSAGE_DATA = 0x391820AA
|
||||
+};
|
||||
+
|
||||
+// MOD : generate fast trash without true RNG
|
||||
+// MOD: generate fast trash without true RNG
|
||||
+__le32 gen_trash(void);
|
||||
|
||||
struct message_header {
|
||||
@ -63,7 +63,7 @@ Index: WireGuard-0.0.20190123/src/messages.h
|
||||
+ * we achieve the same thing, and it makes checking faster.
|
||||
+ */
|
||||
+
|
||||
+ // MOD : trash field to change message size and add 4 byte offset to all fields
|
||||
+ // MOD: trash field to change message size and add 4 byte offset to all fields
|
||||
+ __le32 trash;
|
||||
+
|
||||
+ __le32 type;
|
||||
@ -79,7 +79,7 @@ Index: WireGuard-0.0.20190123/src/noise.c
|
||||
#include <crypto/algapi.h>
|
||||
|
||||
+
|
||||
+// MOD : trash generator
|
||||
+// MOD: trash generator
|
||||
+__le32 gtrash = 0;
|
||||
+__le32 gen_trash(void)
|
||||
+{
|
||||
@ -99,7 +99,7 @@ Index: WireGuard-0.0.20190123/src/noise.c
|
||||
|
||||
handshake->state = HANDSHAKE_CREATED_INITIATION;
|
||||
+
|
||||
+ // MOD : randomize trash
|
||||
+ // MOD: randomize trash
|
||||
+ dst->header.trash = gen_trash();
|
||||
+
|
||||
ret = true;
|
||||
@ -110,7 +110,7 @@ Index: WireGuard-0.0.20190123/src/noise.c
|
||||
|
||||
handshake->state = HANDSHAKE_CREATED_RESPONSE;
|
||||
+
|
||||
+ // MOD : randomize trash
|
||||
+ // MOD: randomize trash
|
||||
+ dst->header.trash = gen_trash();
|
||||
+
|
||||
ret = true;
|
||||
@ -125,7 +125,7 @@ Index: WireGuard-0.0.20190123/src/send.c
|
||||
header->key_idx = keypair->remote_index;
|
||||
header->counter = cpu_to_le64(PACKET_CB(skb)->nonce);
|
||||
+
|
||||
+ // MOD : randomize trash
|
||||
+ // MOD: randomize trash
|
||||
+ header->header.trash = gen_trash();
|
||||
+
|
||||
pskb_put(skb, trailer, trailer_len);
|
||||
|
@ -1,6 +1,6 @@
|
||||
#!/system/bin/busybox sh
|
||||
|
||||
# download hostlist from http(s) (need curl, its absent by default),
|
||||
# download hostlist from HTTPS(S) (need curl, its absent by default),
|
||||
# feed it to zapret. save flash write cycles
|
||||
|
||||
u="https://your.host.com/censorship/hoslist.txt"
|
||||
|
@ -1,6 +1,6 @@
|
||||
#!/system/bin/busybox sh
|
||||
|
||||
# download hostlist from http(s) (need curl, its absent by default),
|
||||
# download hostlist from HTTPS(S) (need curl, its absent by default),
|
||||
# resolve to ip list, feed to zapret-ip. save flash write cycles
|
||||
|
||||
u="https://your.host.com/censorship/hoslist.txt"
|
||||
|
@ -1,4 +1,4 @@
|
||||
# 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 in addition to MODE=nfqws runs desync to DHT packets with udp payload length 101..399, without ipset/hostlist filtering
|
||||
# need to add to config : NFQWS_OPT_DESYNC_DHT="--dpi-desync=fake --dpi-desync-ttl=5"
|
||||
|
||||
QNUM2=$(($QNUM + 20))
|
||||
|
@ -1,4 +1,4 @@
|
||||
# this custom script demonstrates how to apply tpws to http and nfqws to https
|
||||
# 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() {
|
||||
|
@ -22,7 +22,7 @@ ZAPRET_CONFIG=${ZAPRET_CONFIG:-"$ZAPRET_RW/config"}
|
||||
|
||||
TPWS_LOCALHOST4=127.0.0.127
|
||||
|
||||
# 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
|
||||
|
||||
IPSET_CR="$ZAPRET_BASE/ipset/create_ipset.sh"
|
||||
@ -38,7 +38,7 @@ apply_unspecified_desync_modes
|
||||
# can be multiple IPv6 outgoing interfaces
|
||||
# uplink from ISP, tunnelbroker, VPN, ...
|
||||
# want them all. who knows what's the real one that blocks sites
|
||||
# dont want any manual configuration - want to do it automatically
|
||||
# don't want any manual configuration - want to do it automatically
|
||||
# standard network_find_wan[6] return only the first
|
||||
# we use low level function from network.sh to avoid this limitation
|
||||
# it can change theoretically and stop working
|
||||
|
@ -1,4 +1,4 @@
|
||||
# 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 in addition to MODE=nfqws runs desync to DHT packets with udp payload length 101..399, without ipset/hostlist filtering
|
||||
# need to add to config : NFQWS_OPT_DESYNC_DHT="--dpi-desync=fake --dpi-desync-ttl=5"
|
||||
|
||||
QNUM2=$(($QNUM + 20))
|
||||
|
@ -1,4 +1,4 @@
|
||||
# this custom script demonstrates how to apply tpws to http and nfqws to https
|
||||
# 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,4 +1,4 @@
|
||||
# init script functions library for desktop linux systems
|
||||
# init script functions library for desktop Linux systems
|
||||
|
||||
ZAPRET_BASE=${ZAPRET_BASE:-/opt/zapret}
|
||||
ZAPRET_RW=${ZAPRET_RW:-"$ZAPRET_BASE"}
|
||||
@ -81,10 +81,10 @@ TPWS_OPT_BASE4="--bind-addr=$TPWS_LOCALHOST4"
|
||||
TPWS_OPT_BASE6="--bind-addr=::1"
|
||||
TPWS_WAIT="--bind-wait-ifup=30 --bind-wait-ip=30"
|
||||
TPWS_WAIT_SOCKS6="$TPWS_WAIT --bind-wait-ip-linklocal=30"
|
||||
# first wait for lan to ifup, then wait for bind-wait-ip-linklocal seconds for link local address and bind-wait-ip for any ipv6 as the worst case
|
||||
# first wait for LAN to ifup, then wait for bind-wait-ip-linklocal seconds for link local address and bind-wait-ip for any IPv6 as the worst case
|
||||
TPWS_OPT_BASE6_PRE="--bind-linklocal=prefer $TPWS_WAIT --bind-wait-ip-linklocal=3"
|
||||
|
||||
# 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
|
||||
|
||||
CUSTOM_SCRIPT="$ZAPRET_BASE/init.d/sysv/custom"
|
||||
|
@ -45,8 +45,8 @@ ccp() {
|
||||
local F="$(basename "$1")"
|
||||
[ -d "$ZAPRET_BASE/$2" ] || mkdir "$ZAPRET_BASE/$2"
|
||||
[ -f "$ZAPRET_BASE/$2/$F" ] && rm -f "$ZAPRET_BASE/$2/$F"
|
||||
ln -fs "../$BINS/$1" "$ZAPRET_BASE/$2" && echo linking : "../$BINS/$1" =\> "$ZAPRET_BASE/$2"
|
||||
#cp -f "../$BINS/$1" "$ZAPRET_BASE/$2" && echo copying : "../$BINS/$1" =\> "$ZAPRET_BASE/$2"
|
||||
ln -fs "../$BINS/$1" "$ZAPRET_BASE/$2" && echo linking: "../$BINS/$1" =\> "$ZAPRET_BASE/$2"
|
||||
#cp -f "../$BINS/$1" "$ZAPRET_BASE/$2" && echo copying: "../$BINS/$1" =\> "$ZAPRET_BASE/$2"
|
||||
}
|
||||
|
||||
UNAME=$(uname)
|
||||
|
@ -139,23 +139,23 @@ select_mode_mode() {
|
||||
select_mode_http() {
|
||||
[ "$MODE" != "filter" ] && [ "$MODE" != "tpws-socks" ] && {
|
||||
echo
|
||||
ask_yes_no_var MODE_HTTP "enable http support"
|
||||
ask_yes_no_var MODE_HTTP "enable HTTP support"
|
||||
write_config_var MODE_HTTP
|
||||
}
|
||||
}
|
||||
select_mode_keepalive() {
|
||||
[ "$MODE" = "nfqws" ] && [ "$MODE_HTTP" = "1" ] && {
|
||||
echo
|
||||
echo enable keep alive support only if DPI checks every outgoing packet for http signature
|
||||
echo dont enable otherwise because it consumes more cpu resources
|
||||
ask_yes_no_var MODE_HTTP_KEEPALIVE "enable http keep alive support"
|
||||
echo enable keep alive support only if DPI checks every outgoing packet for HTTP signature
|
||||
echo "don't enable otherwise because it consumes more cpu resources"
|
||||
ask_yes_no_var MODE_HTTP_KEEPALIVE "enable HTTP keep alive support"
|
||||
write_config_var MODE_HTTP_KEEPALIVE
|
||||
}
|
||||
}
|
||||
select_mode_https() {
|
||||
[ "$MODE" != "filter" ] && [ "$MODE" != "tpws-socks" ] && {
|
||||
echo
|
||||
ask_yes_no_var MODE_HTTPS "enable https support"
|
||||
ask_yes_no_var MODE_HTTPS "enable HTTPS support"
|
||||
write_config_var MODE_HTTPS
|
||||
}
|
||||
}
|
||||
@ -166,13 +166,13 @@ select_mode_quic() {
|
||||
echo "WARNING ! This firmware requires additional manual iptables setup to support udp desync properly."
|
||||
echo "WARNING ! Keenetic uses proprietary ndmmark to limit MASQUERADE."
|
||||
echo "WARNING ! Desynced packets may go outside without MASQUERADE with LAN source ip."
|
||||
echo "WARNING ! To fix this you need to add additional MASQUERADE rule to iptables nat table."
|
||||
echo "WARNING ! To fix this you need to add additional MASQUERADE rule to iptables NAT table."
|
||||
echo "WARNING ! Installer WILL NOT fix it for you automatically."
|
||||
echo "WARNING ! If you cannot understand what it is all about - do not enable QUIC."
|
||||
}
|
||||
[ "$MODE" != "filter" ] && [ "$MODE" != "tpws-socks" ] && [ "$MODE" != "tpws" ] && {
|
||||
echo
|
||||
ask_yes_no_var MODE_QUIC "enable quic support"
|
||||
ask_yes_no_var MODE_QUIC "enable QUIC support"
|
||||
write_config_var MODE_QUIC
|
||||
}
|
||||
}
|
||||
@ -225,8 +225,8 @@ ask_config_offload() {
|
||||
echo flow offloading can greatly increase speed on slow devices and high speed links \(usually 150+ mbits\)
|
||||
if [ "$SYSTEM" = openwrt ]; then
|
||||
echo unfortuantely its not compatible with most nfqws options. nfqws traffic must be exempted from flow offloading.
|
||||
echo donttouch = disable system flow offloading setting if nfqws mode was selected, dont touch it otherwise and dont configure selective flow offloading
|
||||
echo none = always disable system flow offloading setting and dont configure selective flow offloading
|
||||
echo "donttouch = disable system flow offloading setting if nfqws mode was selected, don't touch it otherwise and don't configure selective flow offloading"
|
||||
echo "none = always disable system flow offloading setting and don't configure selective flow offloading"
|
||||
echo software = always disable system flow offloading setting and configure selective software flow offloading
|
||||
echo hardware = always disable system flow offloading setting and configure selective hardware flow offloading
|
||||
else
|
||||
@ -249,7 +249,7 @@ ask_config_tmpdir() {
|
||||
# ask tmpdir change for low ram systems with enough free disk space
|
||||
[ -n "$GETLIST" ] && [ $(get_free_space_mb "$EXEDIR/tmp") -ge 128 ] && [ $(get_ram_mb) -le 400 ] && {
|
||||
echo
|
||||
echo /tmp in openwrt is tmpfs. on low RAM systems there may be not enough RAM to store downloaded files
|
||||
echo /tmp in OpenWrt is tmpfs. on low RAM systems there may be not enough RAM to store downloaded files
|
||||
echo default tmpfs has size of 50% RAM
|
||||
echo "RAM: $(get_ram_mb) Mb"
|
||||
echo "DISK: $(get_free_space_mb) Mb"
|
||||
@ -307,7 +307,7 @@ select_mode_iface() {
|
||||
# filter just creates ip tables, no daemons involved
|
||||
# nfqws sits in POSTROUTING chain and unable to filter by incoming interface
|
||||
# tpws redirection works in PREROUTING chain
|
||||
# in tpws-socks mode IFACE_LAN specifies additional bind interface for the socks listener
|
||||
# in tpws-socks mode IFACE_LAN specifies additional bind interface for the SOCKS listener
|
||||
# it's not possible to instruct tpws to route outgoing connection to an interface (OS routing table decides)
|
||||
# custom mode can also benefit from interface names (depends on custom script code)
|
||||
|
||||
@ -666,7 +666,7 @@ install_linux() {
|
||||
echo '!!! WARNING. YOUR SETUP IS INCOMPLETE !!!'
|
||||
echo you must manually add to auto start: "$INIT_SCRIPT_SRC" start
|
||||
echo make sure it\'s executed after your custom/firewall iptables configuration
|
||||
echo "if your system uses sysv init : ln -fs $INIT_SCRIPT_SRC /etc/init.d/zapret ; chkconfig zapret on"
|
||||
echo "if your system uses sysv init: ln -fs $INIT_SCRIPT_SRC /etc/init.d/zapret ; chkconfig zapret on"
|
||||
}
|
||||
|
||||
deoffload_openwrt_firewall() {
|
||||
@ -741,7 +741,7 @@ install_openwrt() {
|
||||
clear_ipset
|
||||
download_list
|
||||
crontab_del_quiet
|
||||
# router system : works 24/7. night is the best time
|
||||
# router system: works 24/7. night is the best time
|
||||
crontab_add 0 6
|
||||
cron_ensure_running
|
||||
install_openwrt_iface_hook
|
||||
|
@ -1,7 +1,7 @@
|
||||
// group ipv4/ipv6 list from stdout into subnets
|
||||
// each line must contain either ip or ip/bitcount
|
||||
// valid ip/bitcount and ip1-ip2 are passed through without modification
|
||||
// ips are groupped into subnets
|
||||
// group IPv4/IPv6 list from stdout into subnets
|
||||
// each line must contain either IP or IP/bitcount
|
||||
// valid IP/bitcount and IP1-IP2 are passed through without modification
|
||||
// IPs are grouped into subnets
|
||||
|
||||
// can be compiled in mingw. msvc not supported because of absent getopt
|
||||
|
||||
@ -300,7 +300,7 @@ int main(int argc, char **argv)
|
||||
|
||||
parse_params(argc, argv);
|
||||
|
||||
if (params.ipv6) // ipv6
|
||||
if (params.ipv6) // IPv6
|
||||
{
|
||||
char *s;
|
||||
struct in6_addr a, *iplist = NULL, *iplist_new;
|
||||
@ -380,7 +380,7 @@ int main(int argc, char **argv)
|
||||
break;
|
||||
if (ip_ct >= params.v6_threshold)
|
||||
{
|
||||
// network found. but is there smaller network with the same ip_ct ? dont do carpet bombing if possible, use smaller subnets
|
||||
// network found. but is there smaller network with the same ip_ct? don't do carpet bombing if possible, use smaller subnets
|
||||
if (!ip_ct_best || ip_ct == ip_ct_best)
|
||||
{
|
||||
ip_ct_best = ip_ct;
|
||||
@ -470,7 +470,7 @@ int main(int argc, char **argv)
|
||||
break;
|
||||
if (ip_ct >= (subnet_ct * params.pctmult / params.pctdiv))
|
||||
{
|
||||
// network found. but is there smaller network with the same ip_ct ? dont do carpet bombing if possible, use smaller subnets
|
||||
// network found. but is there smaller network with the same ip_ct? don't do carpet bombing if possible, use smaller subnets
|
||||
if (!ip_ct_best || ip_ct == ip_ct_best)
|
||||
{
|
||||
ip_ct_best = ip_ct;
|
||||
|
@ -1,4 +1,4 @@
|
||||
// multi thread dns resolver
|
||||
// multi thread DNS resolver
|
||||
// domain list <stdin
|
||||
// ip list >stdout
|
||||
// errors, verbose >stderr
|
||||
@ -342,7 +342,7 @@ static void exithelp(void)
|
||||
{
|
||||
printf(
|
||||
" --threads=<threads_number>\n"
|
||||
" --family=<4|6|46>\t; ipv4, ipv6, ipv4+ipv6\n"
|
||||
" --family=<4|6|46>\t; IPv4, IPv6, IPv4+IPv6\n"
|
||||
" --verbose\t\t; print query progress to stderr\n"
|
||||
" --stats=N\t\t; print resolve stats to stderr every N domains\n"
|
||||
" --log-resolved=<file>\t; log successfully resolved domains to a file\n"
|
||||
|
@ -11,7 +11,7 @@ static uint16_t from64to16(uint64_t x)
|
||||
return (uint16_t)u + (uint16_t)(u >> 16);
|
||||
}
|
||||
|
||||
// this function preserves data alignment requirements (otherwise it will be damn slow on mips arch)
|
||||
// this function preserves data alignment requirements (otherwise it will be damn slow on MIPS arch)
|
||||
// and uses 64-bit arithmetics to improve speed
|
||||
// taken from Linux source code
|
||||
static uint16_t do_csum(const uint8_t *buff, size_t len)
|
||||
|
@ -494,7 +494,7 @@ bool ip6_insert_simple_hdr(uint8_t type, uint8_t *data_pkt, size_t len_pkt, uint
|
||||
return false;
|
||||
}
|
||||
|
||||
// split ipv4 packet into 2 fragments at data payload position frag_pos
|
||||
// split IPv4 packet into 2 fragments at data payload position frag_pos
|
||||
bool ip_frag4(
|
||||
const uint8_t *pkt, size_t pkt_size,
|
||||
size_t frag_pos, uint32_t ident,
|
||||
@ -1610,7 +1610,7 @@ static int rawsend_sendto_divert(sa_family_t family, int sock, const void *buf,
|
||||
socklen_t slen;
|
||||
|
||||
#ifdef __FreeBSD__
|
||||
// since FreeBSD 14 it requires hardcoded ipv4 values, although can also send ipv6 frames
|
||||
// since FreeBSD 14 it requires hardcoded IPv4 values, although can also send IPv6 frames
|
||||
family = AF_INET;
|
||||
slen = sizeof(struct sockaddr_in);
|
||||
#else
|
||||
@ -1687,13 +1687,13 @@ static int rawsend_socket(sa_family_t family)
|
||||
// printf("rawsend_socket: family %d",family);
|
||||
|
||||
#ifdef __FreeBSD__
|
||||
// IPPROTO_RAW with ipv6 in FreeBSD always returns EACCES on sendto.
|
||||
// must use IPPROTO_TCP for ipv6. IPPROTO_RAW works for ipv4
|
||||
// IPPROTO_RAW with IPv6 in FreeBSD always returns EACCES on sendto.
|
||||
// must use IPPROTO_TCP for IPv6. IPPROTO_RAW works for IPv4
|
||||
// divert sockets are always v4 but accept both v4 and v6
|
||||
*sock = rawsend_socket_divert(AF_INET);
|
||||
#elif defined(__OpenBSD__) || defined(__APPLE__)
|
||||
// OpenBSD does not allow sending TCP frames through raw sockets
|
||||
// I dont know about macos. They have dropped ipfw in recent versions and their PF does not support divert-packet
|
||||
// I don't know about macOS. They have dropped ipfw in recent versions and their PF does not support divert-packet
|
||||
*sock = rawsend_socket_divert(family);
|
||||
#else
|
||||
*sock = rawsend_socket_raw(family, IPPROTO_RAW);
|
||||
|
@ -127,7 +127,7 @@ bool prepare_udp_segment(
|
||||
|
||||
bool ip6_insert_simple_hdr(uint8_t type, uint8_t *data_pkt, size_t len_pkt, uint8_t *buf, size_t *buflen);
|
||||
|
||||
// ipv4: ident==-1 - copy ip_id from original ipv4 packet
|
||||
// IPv4: ident==-1 - copy ip_id from original IPv4 packet
|
||||
bool ip_frag4(
|
||||
const uint8_t *pkt, size_t pkt_size,
|
||||
size_t frag_pos, uint32_t ident,
|
||||
|
@ -397,7 +397,7 @@ static uint8_t ct_new_postnat_fix(const t_ctrack *ctrack, struct ip *ip, struct
|
||||
#ifdef __linux__
|
||||
// if used in postnat chain, dropping initial packet will cause conntrack connection teardown
|
||||
// so we need to workaround this.
|
||||
// we can't use low ttl because TCP/IP stack listens to ttl expired ICMPs and notify socket
|
||||
// we can't use low TTL because TCP/IP stack listens to TTL expired ICMPs and notify socket
|
||||
// we also can't use fooling because DPI would accept fooled packets
|
||||
if (ctrack && ctrack->pcounter_orig == 1)
|
||||
{
|
||||
@ -603,7 +603,7 @@ static uint8_t dpi_desync_tcp_packet_play(bool replay, size_t reasm_offset, uint
|
||||
}
|
||||
else
|
||||
{
|
||||
// received not http reply. do not monitor this connection anymore
|
||||
// received not HTTP reply. do not monitor this connection anymore
|
||||
DLOG("incoming unknown HTTP data detected for hostname %s\n", ctrack->hostname);
|
||||
}
|
||||
}
|
||||
@ -738,7 +738,7 @@ static uint8_t dpi_desync_tcp_packet_play(bool replay, size_t reasm_offset, uint
|
||||
if (ctrack && !ctrack->l7proto)
|
||||
ctrack->l7proto = HTTP;
|
||||
|
||||
// we do not reassemble http
|
||||
// we do not reassemble HTTP
|
||||
reasm_orig_cancel(ctrack);
|
||||
|
||||
forced_wssize_cutoff(ctrack);
|
||||
@ -755,7 +755,7 @@ static uint8_t dpi_desync_tcp_packet_play(bool replay, size_t reasm_offset, uint
|
||||
}
|
||||
if (ctrack)
|
||||
{
|
||||
// we do not reassemble http
|
||||
// we do not reassemble HTTP
|
||||
if (!ctrack->req_seq_present)
|
||||
{
|
||||
ctrack->req_seq_start = ctrack->seq_last;
|
||||
|
30
nfq/nfqws.c
30
nfq/nfqws.c
@ -308,7 +308,7 @@ static int dvt_main(void)
|
||||
|
||||
#ifdef __OpenBSD__
|
||||
{
|
||||
// in OpenBSD must use separate divert sockets for ipv4 and ipv6
|
||||
// in OpenBSD must use separate divert sockets for IPv4 and IPv6
|
||||
struct sockaddr_in6 bp6;
|
||||
memset(&bp6, 0, sizeof(bp6));
|
||||
bp6.sin6_family = AF_INET6;
|
||||
@ -818,12 +818,12 @@ static void exithelp(void)
|
||||
" --daemon\t\t\t\t\t; daemonize\n"
|
||||
" --pidfile=<filename>\t\t\t\t; write pid to file\n"
|
||||
#ifndef __CYGWIN__
|
||||
" --user=<username>\t\t\t\t; drop root privs\n"
|
||||
" --uid=uid[:gid]\t\t\t\t; drop root privs\n"
|
||||
" --user=<username>\t\t\t\t; drop root privileges\n"
|
||||
" --uid=uid[:gid]\t\t\t\t; drop root privileges\n"
|
||||
#endif
|
||||
#ifdef __linux__
|
||||
" --bind-fix4\t\t\t\t\t; apply outgoing interface selection fix for generated ipv4 packets\n"
|
||||
" --bind-fix6\t\t\t\t\t; apply outgoing interface selection fix for generated ipv6 packets\n"
|
||||
" --bind-fix4\t\t\t\t\t; apply outgoing interface selection fix for generated IPv4 packets\n"
|
||||
" --bind-fix6\t\t\t\t\t; apply outgoing interface selection fix for generated IPv6 packets\n"
|
||||
#endif
|
||||
" --ctrack-timeouts=S:E:F[:U]\t\t\t; internal conntrack timeouts for TCP SYN, ESTABLISHED, FIN stages, UDP timeout. default %u:%u:%u:%u\n"
|
||||
#ifdef __CYGWIN__
|
||||
@ -835,7 +835,7 @@ static void exithelp(void)
|
||||
" --wf-raw=<filter>|@<filename>\t\t\t; raw windivert filter string or filename\n"
|
||||
" --wf-save=<filename>\t\t\t\t; save windivert filter string to a file and exit\n"
|
||||
"\nLOGICAL NETWORK FILTER:\n"
|
||||
" --ssid-filter=ssid1[,ssid2,ssid3,...]\t\t; enable winws only if any of specified wifi SSIDs connected\n"
|
||||
" --ssid-filter=ssid1[,ssid2,ssid3,...]\t\t; enable winws only if any of specified Wi-Fi SSIDs connected\n"
|
||||
" --nlm-filter=net1[,net2,net3,...]\t\t; enable winws only if any of specified NLM network is connected. names and GUIDs are accepted.\n"
|
||||
" --nlm-list[=all]\t\t\t\t; list Network List Manager (NLM) networks. connected only or all.\n"
|
||||
#endif
|
||||
@ -844,7 +844,7 @@ static void exithelp(void)
|
||||
" --hostlist-exclude=<filename>\t\t\t; do not apply dpi desync to the listed hosts (one host per line, subdomains auto apply, gzip supported, multiple hostlists allowed)\n"
|
||||
" --hostlist-auto=<filename>\t\t\t; detect DPI blocks and build hostlist automatically\n"
|
||||
" --hostlist-auto-fail-threshold=<int>\t\t; how many failed attempts cause hostname to be added to auto hostlist (default : %d)\n"
|
||||
" --hostlist-auto-fail-time=<int>\t\t; all failed attemps must be within these seconds (default : %d)\n"
|
||||
" --hostlist-auto-fail-time=<int>\t\t; all failed attempts must be within these seconds (default : %d)\n"
|
||||
" --hostlist-auto-retrans-threshold=<int>\t; how many request retransmissions cause attempt to fail (default : %d)\n"
|
||||
" --hostlist-auto-debug=<logfile>\t\t; debug auto hostlist positives\n"
|
||||
"\nTAMPER:\n"
|
||||
@ -862,14 +862,14 @@ static void exithelp(void)
|
||||
" --dpi-desync-sockarg=<int|0xHEX>\t\t; override sockarg (SO_USER_COOKIE) for desync packet. default = 0x%08X (%u)\n"
|
||||
#endif
|
||||
" --dpi-desync-ttl=<int>\t\t\t\t; set ttl for desync packet\n"
|
||||
" --dpi-desync-ttl6=<int>\t\t\t; set ipv6 hop limit for desync packet. by default ttl value is used.\n"
|
||||
" --dpi-desync-autottl=[<delta>[:<min>[-<max>]]]\t; auto ttl mode for both ipv4 and ipv6. default: %u:%u-%u\n"
|
||||
" --dpi-desync-autottl6=[<delta>[:<min>[-<max>]]] ; overrides --dpi-desync-autottl for ipv6 only\n"
|
||||
" --dpi-desync-ttl6=<int>\t\t\t; set IPv6 hop limit for desync packet. by default ttl value is used.\n"
|
||||
" --dpi-desync-autottl=[<delta>[:<min>[-<max>]]]\t; auto ttl mode for both IPv4 and IPv6. default: %u:%u-%u\n"
|
||||
" --dpi-desync-autottl6=[<delta>[:<min>[-<max>]]] ; overrides --dpi-desync-autottl for IPv6 only\n"
|
||||
" --dpi-desync-fooling=<mode>[,<mode>]\t\t; can use multiple comma separated values. modes : none md5sig ts badseq badsum datanoack hopbyhop hopbyhop2\n"
|
||||
" --dpi-desync-repeats=<N>\t\t\t; send every desync packet N times\n"
|
||||
" --dpi-desync-skip-nosni=0|1\t\t\t; 1(default)=do not act on ClientHello without SNI (ESNI ?)\n"
|
||||
" --dpi-desync-split-pos=<1..%u>\t\t; data payload split position\n"
|
||||
" --dpi-desync-split-http-req=method|host\t; split at specified logical part of plain http request\n"
|
||||
" --dpi-desync-split-http-req=method|host\t; split at specified logical part of plain HTTP request\n"
|
||||
" --dpi-desync-split-tls=sni|sniext\t\t; split at specified logical part of TLS ClientHello\n"
|
||||
" --dpi-desync-split-seqovl=<int>\t\t; use sequence overlap before first sent original split segment\n"
|
||||
" --dpi-desync-split-seqovl-pattern=<filename>|0xHEX ; pattern for the fake part of overlap\n"
|
||||
@ -877,9 +877,9 @@ static void exithelp(void)
|
||||
" --dpi-desync-ipfrag-pos-udp=<8..%u>\t\t; ip frag position starting from the transport header. multiple of 8, default %u.\n"
|
||||
" --dpi-desync-badseq-increment=<int|0xHEX>\t; badseq fooling seq signed increment. default %d\n"
|
||||
" --dpi-desync-badack-increment=<int|0xHEX>\t; badseq fooling ackseq signed increment. default %d\n"
|
||||
" --dpi-desync-any-protocol=0|1\t\t\t; 0(default)=desync only http and tls 1=desync any nonempty data packet\n"
|
||||
" --dpi-desync-fake-http=<filename>|0xHEX\t; file containing fake http request\n"
|
||||
" --dpi-desync-fake-tls=<filename>|0xHEX\t\t; file containing fake TLS ClientHello (for https)\n"
|
||||
" --dpi-desync-any-protocol=0|1\t\t\t; 0(default)=desync only HTTP and tls 1=desync any nonempty data packet\n"
|
||||
" --dpi-desync-fake-http=<filename>|0xHEX\t; file containing fake HTTP request\n"
|
||||
" --dpi-desync-fake-tls=<filename>|0xHEX\t\t; file containing fake TLS ClientHello (for HTTPS)\n"
|
||||
" --dpi-desync-fake-unknown=<filename>|0xHEX\t; file containing unknown protocol fake payload\n"
|
||||
" --dpi-desync-fake-syndata=<filename>|0xHEX\t; file containing SYN data payload\n"
|
||||
" --dpi-desync-fake-quic=<filename>|0xHEX\t; file containing fake QUIC Initial\n"
|
||||
@ -972,7 +972,7 @@ int main(int argc, char **argv)
|
||||
params.fake_http_size = strlen(fake_http_request_default);
|
||||
memcpy(params.fake_http, fake_http_request_default, params.fake_http_size);
|
||||
params.fake_quic_size = 620; // must be 601+ for TSPU hack
|
||||
params.fake_quic[0] = 0x40; // russian TSPU QUIC short header fake
|
||||
params.fake_quic[0] = 0x40; // Russian TSPU QUIC short header fake
|
||||
params.fake_wg_size = 64;
|
||||
params.fake_dht_size = 64;
|
||||
params.fake_unknown_size = 256;
|
||||
|
@ -797,7 +797,7 @@ bool QUICExtractHostFromInitial(const uint8_t *data, size_t data_len, char *host
|
||||
|
||||
bool IsQUICInitial(const uint8_t *data, size_t len)
|
||||
{
|
||||
// too small packets are not likely to be initials with client hello
|
||||
// too small packets are not likely to be initials with ClientHello
|
||||
// long header, fixed bit
|
||||
if (len < 256 || (data[0] & 0xC0) != 0xC0)
|
||||
return false;
|
||||
|
@ -6,7 +6,7 @@
|
||||
|
||||
int ppoll(struct pollfd *fds, nfds_t nfds, const struct timespec *tmo_p, const sigset_t *sigmask)
|
||||
{
|
||||
// macos does not implement ppoll
|
||||
// macOS does not implement ppoll
|
||||
// this is a hacky ppoll shim. only for tpws which does not require sigmask
|
||||
if (sigmask)
|
||||
{
|
||||
|
@ -212,7 +212,7 @@ bool get_dest_addr(int sockfd, const struct sockaddr *accept_sa, struct sockaddr
|
||||
}
|
||||
#endif
|
||||
if (saconvmapped(orig_dst))
|
||||
DBGPRINT("Original destination : converted ipv6 mapped address to ipv4\n");
|
||||
DBGPRINT("Original destination : converted IPv6 mapped address to IPv4\n");
|
||||
|
||||
if (params.debug)
|
||||
{
|
||||
|
@ -181,7 +181,7 @@ bool resolver_init(int threads, int fd_signal_pipe)
|
||||
resolver.bInit = true;
|
||||
|
||||
#ifdef __APPLE__
|
||||
// MacOS does not support unnamed semaphores
|
||||
// macOS does not support unnamed semaphores
|
||||
|
||||
char sn[64];
|
||||
snprintf(sn, sizeof(sn), "%s_%d", sem_name, getpid());
|
||||
|
@ -58,7 +58,7 @@ void tamper_out(t_ctrack *ctrack, uint8_t *segment, size_t segment_buffer_size,
|
||||
(*size)--;
|
||||
if (pp == (p - 1))
|
||||
{
|
||||
// probably end of http headers
|
||||
// probably end of HTTP headers
|
||||
VPRINT("Found double EOL at pos %td. Stop replacing.\n", pp - segment);
|
||||
break;
|
||||
}
|
||||
@ -360,7 +360,7 @@ void tamper_in(t_ctrack *ctrack, uint8_t *segment, size_t segment_buffer_size, s
|
||||
}
|
||||
else
|
||||
{
|
||||
// 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);
|
||||
}
|
||||
if (bFail)
|
||||
|
30
tpws/tpws.c
30
tpws/tpws.c
@ -129,9 +129,9 @@ static void exithelp(void)
|
||||
{
|
||||
printf(
|
||||
" --bind-addr=<v4_addr>|<v6_addr>\t; for v6 link locals append %%interface_name\n"
|
||||
" --bind-iface4=<interface_name>\t\t; bind to the first ipv4 addr of interface\n"
|
||||
" --bind-iface6=<interface_name>\t\t; bind to the first ipv6 addr of interface\n"
|
||||
" --bind-linklocal=no|unwanted|prefer|force ; prohibit, accept, prefer or force ipv6 link local bind\n"
|
||||
" --bind-iface4=<interface_name>\t\t; bind to the first IPv4 addr of interface\n"
|
||||
" --bind-iface6=<interface_name>\t\t; bind to the first IPv6 addr of interface\n"
|
||||
" --bind-linklocal=no|unwanted|prefer|force ; prohibit, accept, prefer or force IPv6 link local bind\n"
|
||||
" --bind-wait-ifup=<sec>\t\t\t; wait for interface to appear and up\n"
|
||||
" --bind-wait-ip=<sec>\t\t\t; after ifup wait for ip address to appear up to N seconds\n"
|
||||
" --bind-wait-ip-linklocal=<sec>\t\t; (prefer) accept only LL first N seconds then any (unwanted) accept only globals first N seconds then LL\n"
|
||||
@ -140,7 +140,7 @@ static void exithelp(void)
|
||||
" --connect-bind-addr=<v4_addr>|<v6_addr> ; address for outbound connections. for v6 link locals append %%interface_name\n"
|
||||
" --port=<port>\t\t\t\t; only one port number for all binds is supported\n"
|
||||
" --socks\t\t\t\t; implement socks4/5 proxy instead of transparent proxy\n"
|
||||
" --no-resolve\t\t\t\t; disable socks5 remote dns ability\n"
|
||||
" --no-resolve\t\t\t\t; disable socks5 remote DNS ability\n"
|
||||
" --resolver-threads=<int>\t\t; number of resolver worker threads\n"
|
||||
" --local-rcvbuf=<bytes>\n"
|
||||
" --local-sndbuf=<bytes>\n"
|
||||
@ -163,8 +163,8 @@ static void exithelp(void)
|
||||
" --max-orphan-time=<sec>\t\t; if local leg sends something and closes and remote leg is still connecting then cancel connection attempt after N seconds\n"
|
||||
" --daemon\t\t\t\t; daemonize\n"
|
||||
" --pidfile=<filename>\t\t\t; write pid to file\n"
|
||||
" --user=<username>\t\t\t; drop root privs\n"
|
||||
" --uid=uid[:gid]\t\t\t; drop root privs\n"
|
||||
" --user=<username>\t\t\t; drop root privileges\n"
|
||||
" --uid=uid[:gid]\t\t\t; drop root privileges\n"
|
||||
#if defined(__FreeBSD__)
|
||||
" --enable-pf\t\t\t\t; enable PF redirector support. required in FreeBSD when used with PF firewall.\n"
|
||||
#endif
|
||||
@ -175,13 +175,13 @@ static void exithelp(void)
|
||||
" --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-auto=<filename>\t\t; detect DPI blocks and build hostlist automatically\n"
|
||||
" --hostlist-auto-fail-threshold=<int>\t; how many failed attempts cause hostname to be added to auto hostlist (default : %d)\n"
|
||||
" --hostlist-auto-fail-time=<int>\t; all failed attemps must be within these seconds (default : %d)\n"
|
||||
" --hostlist-auto-fail-time=<int>\t; all failed attempts must be within these seconds (default : %d)\n"
|
||||
" --hostlist-auto-debug=<logfile>\t; debug auto hostlist positives\n"
|
||||
"\nTAMPER:\n"
|
||||
" --split-http-req=method|host\t\t; split at specified logical part of plain http request\n"
|
||||
" --split-http-req=method|host\t\t; split at specified logical part of plain HTTP request\n"
|
||||
" --split-tls=sni|sniext\t\t\t; split at specified logical part of TLS ClientHello\n"
|
||||
" --split-pos=<numeric_offset>\t\t; split at specified pos. split-http-req or split-tls take precedence for http.\n"
|
||||
" --split-any-protocol\t\t\t; split not only http and https\n"
|
||||
" --split-pos=<numeric_offset>\t\t; split at specified pos. split-http-req or split-tls take precedence for HTTP.\n"
|
||||
" --split-any-protocol\t\t\t; split not only HTTP and HTTPS\n"
|
||||
#if defined(BSD) && !defined(__APPLE__)
|
||||
" --disorder[=http|tls]\t\t\t; when splitting simulate sending second fragment first (BSD sends entire message instead of first fragment, this is not good)\n"
|
||||
#else
|
||||
@ -303,7 +303,7 @@ void parse_params(int argc, char *argv[])
|
||||
LIST_INIT(¶ms.hostlist_exclude_files);
|
||||
|
||||
#if defined(__OpenBSD__) || defined(__APPLE__)
|
||||
params.pf_enable = true; // OpenBSD and MacOS have no other choice
|
||||
params.pf_enable = true; // OpenBSD and macOS have no other choice
|
||||
#endif
|
||||
if (can_drop_root())
|
||||
{
|
||||
@ -898,7 +898,7 @@ void parse_params(int argc, char *argv[])
|
||||
|
||||
#if defined(__linux__)
|
||||
case 58: /* 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
|
||||
params.mss = atoi(optarg);
|
||||
if (params.mss < 88 || params.mss > 32767)
|
||||
{
|
||||
@ -966,7 +966,7 @@ static bool find_listen_addr(struct sockaddr_storage *salisten, const char *bind
|
||||
if (getifaddrs(&addrs) < 0)
|
||||
return false;
|
||||
|
||||
// for ipv6 preference order
|
||||
// for IPv6 preference order
|
||||
// bind-linklocal-1 : link-local,any
|
||||
// bind-linklocal=0 : private,global,link-local
|
||||
for (int pass = 0; pass < 3; pass++)
|
||||
@ -1312,7 +1312,7 @@ int main(int argc, char *argv[])
|
||||
goto exiterr;
|
||||
if (!params.local_rcvbuf)
|
||||
{
|
||||
// HACK : dont know why but if dont set RCVBUF explicitly RCVBUF of accept()-ed socket can be very large. may be linux bug ?
|
||||
// HACK : don't know why but if don't set RCVBUF explicitly RCVBUF of accept()-ed socket can be very large. may be Linux bug ?
|
||||
int v;
|
||||
socklen_t sz = sizeof(int);
|
||||
if (!getsockopt(listen_fd[i], SOL_SOCKET, SO_RCVBUF, &v, &sz))
|
||||
@ -1326,7 +1326,7 @@ int main(int argc, char *argv[])
|
||||
{
|
||||
if (bind(listen_fd[i], (struct sockaddr *)&list[i].salisten, list[i].salisten_len) == -1)
|
||||
{
|
||||
// in linux strange behaviour was observed
|
||||
// in Linux strange behaviour was observed
|
||||
// just after ifup and address assignment there's short window when bind() can't bind to addresses got from getifaddrs()
|
||||
// it does not happen to transparent sockets because they can bind to any non-existend ip
|
||||
// also only IPv6 seem to be buggy this way
|
||||
|
@ -514,7 +514,7 @@ static tproxy_conn_t *new_conn(int fd, bool remote)
|
||||
conn->remote = remote;
|
||||
|
||||
#ifdef SPLICE_PRESENT
|
||||
// if dont tamper - both legs are spliced, create 2 pipes
|
||||
// if don't tamper - both legs are spliced, create 2 pipes
|
||||
// otherwise create pipe only in local leg
|
||||
if (!params.nosplice && (!remote || !params.tamper || params.tamper_start || params.tamper_cutoff) && pipe2(conn->splice_pipe, O_NONBLOCK) != 0)
|
||||
{
|
||||
@ -817,14 +817,14 @@ bool proxy_mode_connect_remote(const struct sockaddr *sa, tproxy_conn_t *conn, s
|
||||
|
||||
if ((remote_fd = connect_remote(sa, bConnFooling)) < 0)
|
||||
{
|
||||
DLOG_ERR("socks failed to connect (1) errno=%d\n", errno);
|
||||
DLOG_ERR("SOCKS failed to connect (1) errno=%d\n", errno);
|
||||
socks_send_rep_errno(conn->socks_ver, conn->fd, errno);
|
||||
return false;
|
||||
}
|
||||
if (!(conn->partner = new_conn(remote_fd, true)))
|
||||
{
|
||||
close(remote_fd);
|
||||
DLOG_ERR("socks out-of-memory (1)\n");
|
||||
DLOG_ERR("SOCKS out-of-memory (1)\n");
|
||||
socks_send_rep(conn->socks_ver, conn->fd, S5_REP_GENERAL_FAILURE);
|
||||
return false;
|
||||
}
|
||||
@ -832,7 +832,7 @@ bool proxy_mode_connect_remote(const struct sockaddr *sa, tproxy_conn_t *conn, s
|
||||
conn->partner->efd = conn->efd;
|
||||
if (!epoll_set(conn->partner, EPOLLOUT))
|
||||
{
|
||||
DLOG_ERR("socks epoll_set error %d\n", errno);
|
||||
DLOG_ERR("SOCKS epoll_set error %d\n", errno);
|
||||
free_conn(conn->partner);
|
||||
conn->partner = NULL;
|
||||
socks_send_rep(conn->socks_ver, conn->fd, S5_REP_GENERAL_FAILURE);
|
||||
@ -848,7 +848,7 @@ bool proxy_mode_connect_remote(const struct sockaddr *sa, tproxy_conn_t *conn, s
|
||||
|
||||
static bool handle_proxy_mode(tproxy_conn_t *conn, struct tailhead *conn_list)
|
||||
{
|
||||
// To simplify things I dont care about buffering. If message splits, I just hang up
|
||||
// To simplify things I don't care about buffering. If message splits, I just hang up
|
||||
// in proxy mode messages are short. they can be split only intentionally. all normal programs send them in one packet
|
||||
|
||||
ssize_t rd, wr;
|
||||
@ -1175,7 +1175,7 @@ static bool handle_epoll(tproxy_conn_t *conn, struct tailhead *conn_list, uint32
|
||||
{
|
||||
// incoming data from remote leg we splice without touching
|
||||
// pipe is in the local leg, so its in conn->partner->splice_pipe
|
||||
// if we dont tamper - splice both legs
|
||||
// if we don't tamper - splice both legs
|
||||
|
||||
rd = splice(conn->fd, NULL, conn->partner->splice_pipe[1], NULL, SPLICE_LEN, SPLICE_F_MOVE | SPLICE_F_NONBLOCK);
|
||||
DBGPRINT("splice fd=%d remote=%d len=%d rd=%zd err=%d\n", conn->fd, conn->remote, SPLICE_LEN, rd, errno);
|
||||
|
Loading…
Reference in New Issue
Block a user