diff --git a/common/nft.sh b/common/nft.sh index ac5c137..aa23177 100644 --- a/common/nft.sh +++ b/common/nft.sh @@ -63,6 +63,10 @@ nft_del_all_chains_from_table() nft_create_chains() { + # NOTE : postrouting hook has priority 101 to hook packets already processed by nat + # NOTE : this is the only way to implement ipfrag for forwarded packets if nat is present + # NOTE : to avoid retracking and sport changing use notrack for nfqws generated packets + # NOTE : this also prevents defragmentation of ipv6 fragmented frames in kernels 4.16+ cat << EOF | nft -f - add chain inet $ZAPRET_NFT_TABLE dnat_output { type nat hook output priority -101; } flush chain inet $ZAPRET_NFT_TABLE dnat_output @@ -79,7 +83,9 @@ cat << EOF | nft -f - add rule inet $ZAPRET_NFT_TABLE localnet_protect ip daddr $TPWS_LOCALHOST4 return comment "route_localnet allow access to tpws" add rule inet $ZAPRET_NFT_TABLE localnet_protect ip daddr 127.0.0.0/8 drop comment "route_localnet remote access protection" add rule inet $ZAPRET_NFT_TABLE input iif != lo jump localnet_protect - add chain inet $ZAPRET_NFT_TABLE postrouting { type filter hook postrouting priority -151; } + add chain inet $ZAPRET_NFT_TABLE postrouting { type filter hook postrouting priority 101; } + add chain inet $ZAPRET_NFT_TABLE predefrag { type filter hook output priority -401; } + add rule inet $ZAPRET_NFT_TABLE predefrag mark and $DESYNC_MARK !=0 notrack comment "do not track nfqws generated packets to avoid nat tampering and defragmentation" flush chain inet $ZAPRET_NFT_TABLE postrouting add set inet $ZAPRET_NFT_TABLE lanif { type ifname; } add set inet $ZAPRET_NFT_TABLE wanif { type ifname; } @@ -98,6 +104,7 @@ cat << EOF | nft -f - 2>/dev/null delete chain inet $ZAPRET_NFT_TABLE forward delete chain inet $ZAPRET_NFT_TABLE input delete chain inet $ZAPRET_NFT_TABLE postrouting + delete chain inet $ZAPRET_NFT_TABLE predefrag delete chain inet $ZAPRET_NFT_TABLE flow_offload delete chain inet $ZAPRET_NFT_TABLE localnet_protect EOF diff --git a/docs/readme.eng.md b/docs/readme.eng.md index 026c32f..ee4c781 100644 --- a/docs/readme.eng.md +++ b/docs/readme.eng.md @@ -478,6 +478,13 @@ It must be done manually, `blockcheck.sh` cannot auto fix this for you. Or just move to `nftables`. You can create hooks with any priority there. +Looks like there's no way to do ipfrag using iptables for forwarded traffic if NAT is present. +`MASQUERADE` is terminating target, after it `NFQUEUE` does not work. +nfqws sees packets with internal network source address. If fragmented NAT does not process them. +This results in attempt to send packets to internet with internal IP address. +You need to use nftables instead with hook priority 101 or higher. + + ## tpws tpws is transparent proxy. diff --git a/docs/readme.txt b/docs/readme.txt index 4c8f669..6567a83 100644 --- a/docs/readme.txt +++ b/docs/readme.txt @@ -507,6 +507,13 @@ options ip6table_raw raw_before_defrag=1 Либо можно раз и навсегда избавиться от этой проблемы, используя nftables. Там можно создать netfilter hook с любым приоритетом. Используйте приоритет -401 и ниже. +При использовании iptables и NAT, похоже, что нет способа прицепить обработчик очереди после NAT. +MASQUERADE является финальным таргетом, после него NFQUEUE не срабатывает. +Пакет попадает в nfqws с source адресом внутренней сети, затем фрагментируется и уже не обрабатывается NAT. +Так и уходит во внешюю сеть с src ip 192.168.x.x. Следовательно, метод не срабатывает. +Видимо единственный рабочий метод - отказаться от iptables и использовать nftables. +Хук должен быть с приоритетом 101 или выше. + tpws -----