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.
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
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.
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`.
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.
This limits techniques that break NAT.
## When it will not work
## When it will not work
* If DNS server returns false responses. ISP can return false IP addresses or not return anything
- 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.
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 blocking is done by IP.
* If a connection passes through a filter capable of reconstructing a TCP connection, and which
- 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.
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`
## `nfqws`
@ -193,10 +191,10 @@ nfqws takes the following parameters:
--dpi-desync-udplen-increment=<int> ; increase or decrease udp packet length by N bytes (default 2). negative values decrease length.
--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-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-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
--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=<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-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=<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-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-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-retrans-threshold=<int> ; how many request retransmissions cause attempt to fail (default: 3)
--hostlist-auto-debug=<logfile>; debug auto hostlist positives
--hostlist-auto-debug=<logfile>; debug auto hostlist positives
```
```
The manipulation parameters can be combined in any way.
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
### 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 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`).
split into 2 segments original packet with fake segment in the middle (`split`).
`fakeknown` sends fake only in response to known application protocol.
`fakeknown` sends fake only in response to known application protocol.
In articles these attack have names **TCB desynchronization** and **TCB teardown**.
In articles these attack have names **TCB desynchronization** and **TCB teardown**.
Fake packet must reach DPI, but do not reach the destination server.
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,
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
- md5sig does not work on all servers
* badsum doesn't work if your device is behind NAT which does not pass invalid packets.
- 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 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.
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.
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.
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.
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.
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.
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.
But usually ISPs pass badsum.
Some adapters/switches/drivers enable hardware filtering of rx badsum not allowing it to pass to the OS.
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.
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.
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.
- 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.
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.
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
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
- 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.
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.
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`.
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.
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.
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.
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.
ISP drops them or because there are two same headers.
DPIs may still anaylize packets with one or two hop-by-hop headers.
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.
- `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.
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).
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.
-`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),
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)
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.
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.
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.
Can fail if inbound and outbound paths are not symmetric.
@ -389,7 +387,7 @@ packet ordering can be changed breaking the whole idea of desync attack.
### DPI desync combos
### DPI desync combos
dpi-desync parameter takes up to 3 comma separated arguments.
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.
Hostlist filter is not applicable to the zero phase.
Next phases work on packets with data payload.
Next phases work on packets with data payload.
1st phase mode can be `fake`,`rst`,`rstack`, 2nd phase mode - `disorder`,`disorder2`,`split`,`split2`,`ipfrag2`.
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 !
!!! 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,
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`
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
config zone
option name 'wan'
option name 'wan'
.........
.........
option masq_allow_invalid '1'
option masq_allow_invalid '1'
```
```
Unfortunately there's no OUTPUT only switch. It's not desired to remove the rule from the FORWARD chain.
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` :
Add the following lines to `/etc/firewall.user` :
@ -433,7 +433,7 @@ Without extra parameter payload is 16 zero bytes.
### Virtual Machines
### Virtual Machines
Most of nfqws packet magic does not work from VMs powered by virtualbox and vmware when network is NATed.
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.
Set up bridge networking.
### CONNTRACK
### 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.
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
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).
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.
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.
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.
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).
'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`.
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
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.
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.
nfqws will dump current conntrack table to stdout.
Typically, in a SYN packet, client sends TCP extension **scaling factor** in addition to window size.
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.
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.
Then they go through desync using fully reassembled message.
On any error reassemble is cancelled and all delayed packets are sent immediately without desync.
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
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 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.
and the last splitted segment. 3 segments total.
### UDP support
### UDP support
UDP attacks are limited. Its not possible to fragment UDP on transport level, only on network (ip) level.
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`,`hopbyhop`,`destopt` can be used in combo with `ipfrag2`.
`fake` can be used in combo with `udplen` and `tamper`.
`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.
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.
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`.
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`.
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
### IP fragmentation
Modern network can be very hostile to IP fragmentation. Fragmented packets are often not delivered or refragmented/reassembled on the way.
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.
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.
Offset starts from the transport header.
tcp fragments are almost always filtered. It's absolutely not suitable for arbitrary websites.
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%.
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.
Likely more with your VPS. Sometimes filtered by DDoS protection.
There are important nuances when working with fragments in Linux.
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.
Sometimes it works, sometimes system defragments packets.
Looks like kernels <4.16havenosimplewaytosolvethisproblem.Unloadingof`nf_conntrack`module
Looks like kernels <4.16havenosimplewaytosolvethisproblem.Unloadingof`nf_conntrack`module
and its dependency `nf_defrag_ipv6` helps but this severely impacts functionality.
and its dependency `nf_defrag_ipv6` helps but this severely impacts functionality.
Sometimes it's required to load `ip6table_raw` kernel module with parameter `raw_before_defrag=1`.
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 :
`/etc/modprobe.d/ip6table_raw.conf` with the following content :
```sh
```sh
options ip6table_raw raw_before_defrag=1
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.
If you want to stay with `nftables-nft` you need to patch and recompile your version.
In `nft.c` find :
In `nft.c` find :
@ -594,6 +594,7 @@ In `nft.c` find :
.hook = NF_INET_LOCAL_OUT,
.hook = NF_INET_LOCAL_OUT,
},
},
```
```
and replace -300 to -450.
and replace -300 to -450.
It must be done manually, `blockcheck.sh` cannot auto fix this for you.
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=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>
--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-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-iface4=<interface_name> ; bind to the first IPv4 addr of interface
--bind-iface6=<interface_name> ; bind to the first ipv6 addr of interface
--bind-iface6=<interface_name> ; bind to the first IPv6 addr of interface
--bind-linklocal=no|unwanted|prefer|force
--bind-linklocal=no|unwanted|prefer|force
; no : bind only to global ipv6
; no: bind only to global IPv6
; unwanted (default) : prefer global address, then LL
; unwanted (default): prefer global address, then LL
; prefer : prefer LL, then global
; prefer: prefer LL, then global
; force : LL only
; force: LL only
--bind-wait-ifup=<sec> ; wait for interface to appear and up
--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=<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-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
--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
--port=<port>; port number to listen on
--socks; implement socks4/5 proxy instead of transparent proxy
--socks; implement socks4/5 proxy instead of transparent proxy
--local-rcvbuf=<bytes>; SO_RCVBUF for local legs
--local-rcvbuf=<bytes>; SO_RCVBUF for local legs
--local-sndbuf=<bytes>; SO_SNDBUF for local legs
--local-sndbuf=<bytes>; SO_SNDBUF for local legs
--remote-rcvbuf=<bytes> ; SO_RCVBUF for remote 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
--nosplice ; do not use splice to transfer data between sockets
--skip-nodelay; do not set TCP_NODELAY for outgoing connections. incompatible with split.
--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)
--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)
--remote-tcp-user-timeout=<seconds> ; set TCP user timeout for remote leg (default: 20, 0 = system default)
--no-resolve ; disable socks5 remote dns
--no-resolve ; disable socks5 remote DNS
--resolver-threads=<int> ; number of resolver worker threads
--resolver-threads=<int> ; number of resolver worker threads
--maxconn=<max_connections>; max number of local legs
--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.
--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
; 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
--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=<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-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=<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-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-fail-time=<int> ; all failed attempts must be within these seconds (default: 60)
--hostlist-auto-debug=<logfile>; debug auto hostlist positives
--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-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-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
--split-any-protocol ; split not only HTTP and HTTPS
--disorder[=http|tls] ; when splitting simulate sending second fragment first
--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[=http|tls] ; when splitting send out of band byte. default is HEX 0x00.
--hostpad=<bytes>; add dummy padding headers before Host:
--hostpad=<bytes>; add dummy padding headers before Host:
--domcase ; mix domain case after Host: like this : TeSt.cOm
--domcase ; mix domain case after Host: like this: TeSt.cOm
--methodspace ; add extra space after method
--methodspace ; add extra space after method
--methodeol ; add end-of-line before method
--methodeol ; add end-of-line before method
--unixeol ; replace 0D0A to 0A
--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.
--tamper-cutoff=[n]<pos> ; do not tamper anymore after specified outbound stream position. byte pos or block number ('n'). default is unlimited.
--daemon ; daemonize
--daemon ; daemonize
--pidfile=<filename> ; write pid to file
--pidfile=<filename> ; write pid to file
--user=<username> ; drop root privs
--user=<username> ; drop root privileges
--uid=uid[:gid] ; drop root privs
--uid=uid[:gid] ; drop root privileges
```
```
The manipulation parameters can be combined in any way.
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).
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.
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=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=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=prefer: first selects LL, then private address fc00::/7, then global address
--bind-iface6 --bind-linklocal=force: select only LL
--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
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.
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."
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.
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 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.
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.
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.
To disable hostname resolve use `--no-resolve` option.
`--disorder` is an additional flag to any split 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.
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).
(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.
`--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
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.
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.
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.
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.
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
## 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.
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`
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.
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.
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.
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
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.
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`
`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`.
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.
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.
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.
LISTS_RELOAD config parameter defines a custom lists reloading command.
Its useful on BSD systems with PF.
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.
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.
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.
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.
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 `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 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" .
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.
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.
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.
1) [nfqws] Multiple retransmissions of the first request inside a TCP session having host.
2) [nfqws,tpws] RST in response to the first request.
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.
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 reponse from server, timeout).
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
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.
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.
All processes must run with the same uid.
If zapret scripts are used then autohostlist is `ipset/zapret-hosts-auto.txt`
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`.
includes hostlist mode. You can use `ipset/zapret-hosts-user.txt`.
## Choosing parameters
## Choosing parameters
The file `/opt/zapret/config` is used by various components of the system and contains basic settings.
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.
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 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`
`FWTYPE=iptables`
@ -909,8 +909,8 @@ Main mode :
```
```
tpws - tpws transparent mode
tpws - tpws transparent mode
tpws-socks - tpws socks mode
tpws-socks - tpws SOCKS mode
binds to localhost and LAN interface (if IFACE_LAN is specified or the system is OpenWRT). port 988
binds to localhost and LAN interface (if IFACE_LAN is specified or the system is OpenWrt). port 988
nfqws - nfqws
nfqws - nfqws
filter - only fill ipset or load hostlist
filter - only fill ipset or load hostlist
custom - use custom script for running daemons and establishing firewall rules
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`
`MODE=tpws`
Enable http fooling :
Enable HTTP fooling :
`MODE_HTTP=1`
`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.
Not enabling this can save CPU time.
`MODE_HTTP_KEEPALIVE=0`
`MODE_HTTP_KEEPALIVE=0`
Enable https fooling :
Enable HTTPS fooling :
`MODE_HTTPS=1`
`MODE_HTTPS=1`
Enable quic fooling :
Enable QUIC fooling :
`MODE_QUIC=1`
`MODE_QUIC=1`
Host filtering mode :
Host filtering mode :
```
```
none - apply fooling to all hosts
none - apply fooling to all hosts
ipset - limit fooling to hosts from ipset zapret/zapret6
ipset - limit fooling to hosts from ipset zapret/zapret6
If `NFQWS_OPT_DESYNC_QUIC6` is not specified `NFQWS_OPT_DESYNC_QUIC` is taken.
If `NFQWS_OPT_DESYNC_QUIC6` is not specified `NFQWS_OPT_DESYNC_QUIC` is taken.
flow offloading control (if supported)
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
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 dont 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
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
hardware: always disable system flow offloading setting and configure selective hardware flow offloading
```
```
`FLOWOFFLOAD=donttouch`
`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.
Put here the name of the script that you will use to update the lists.
If not, then the parameter should be commented out.
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",
Hooks are extremely useful if you need nftables sets populated by zapret scripts.
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
## 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.
ISP returns single ip for all blocked domains to redirect you to their "access denied" page.
`blockcheck.sh` works in Linux and FreeBSD.
`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.
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.
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.
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.
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.
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
### 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.
Use numeric uids in `--uid` option.
Its recommended to use gid 3003 (AID_INET), otherwise tpws will not have inet access.
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.
Write your own shell script with iptables and tpws, run it using your root manager.
Autorun scripts are here :
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.
How to run tpws on root-less android.
You can't write to `/system`, `/data`, can't run from sd card.
You can't write to `/system`, `/data`, can't run from sd card.
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.
`--oob`, `--mss` and `--disorder` do not work.
RST detection in autohostlist scheme may 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.
`--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.
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.
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.
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-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".
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`.
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.
`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` :
echo flow offloading can greatly increase speed on slow devices and high speed links \(usually 150+ mbits\)
echo flow offloading can greatly increase speed on slow devices and high speed links \(usually 150+ mbits\)
if["$SYSTEM"= openwrt ];then
if["$SYSTEM"= openwrt ];then
echo unfortuantely its not compatible with most nfqws options. nfqws traffic must be exempted from flow offloading.
echo unfortuantely its not compatible with most nfqws options. nfqws traffic must be exempted from flow offloading.
echodonttouch= disable system flow offloading setting if nfqws mode was selected, dont touch it otherwise 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"
echonone= always disable system flow offloading setting and dont configure selective flow offloading
echo"none = always disable system flow offloading setting and don't configure selective flow offloading"
echosoftware= always disable system flow offloading setting and configure selective software flow offloading
echosoftware= always disable system flow offloading setting and configure selective software flow offloading
echohardware= always disable system flow offloading setting and configure selective hardware flow offloading
echohardware= always disable system flow offloading setting and configure selective hardware flow offloading
else
else
@ -249,7 +249,7 @@ ask_config_tmpdir() {
# ask tmpdir change for low ram systems with enough free disk space
# ask tmpdir change for low ram systems with enough free disk space
" --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"
" --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__
#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-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"
" --wf-save=<filename>\t\t\t\t; save windivert filter string to a file and exit\n"
"\nLOGICAL NETWORK FILTER:\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-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"
" --nlm-list[=all]\t\t\t\t; list Network List Manager (NLM) networks. connected only or all.\n"
#endif
#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-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=<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-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-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"
" --hostlist-auto-debug=<logfile>\t\t; debug auto hostlist positives\n"
" --bind-addr=<v4_addr>|<v6_addr>\t; for v6 link locals append %%interface_name\n"
" --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-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-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-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-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=<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"
" --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"
" --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"
" --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"
" --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"
" --resolver-threads=<int>\t\t; number of resolver worker threads\n"
" --local-rcvbuf=<bytes>\n"
" --local-rcvbuf=<bytes>\n"
" --local-sndbuf=<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"
" --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"
" --daemon\t\t\t\t; daemonize\n"
" --pidfile=<filename>\t\t\t; write pid to file\n"
" --pidfile=<filename>\t\t\t; write pid to file\n"
" --user=<username>\t\t\t; drop root privs\n"
" --user=<username>\t\t\t; drop root privileges\n"
" --uid=uid[:gid]\t\t\t; drop root privs\n"
" --uid=uid[:gid]\t\t\t; drop root privileges\n"
#if defined(__FreeBSD__)
#if defined(__FreeBSD__)
" --enable-pf\t\t\t\t; enable PF redirector support. required in FreeBSD when used with PF firewall.\n"
" --enable-pf\t\t\t\t; enable PF redirector support. required in FreeBSD when used with PF firewall.\n"
#endif
#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-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=<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-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"
" --hostlist-auto-debug=<logfile>\t; debug auto hostlist positives\n"
"\nTAMPER:\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-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-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-any-protocol\t\t\t; split not only HTTP and HTTPS\n"
#if defined(BSD) && !defined(__APPLE__)
#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"
" --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"