zapret2 (anti-DPI) Beginner Guide: Install, Intercept, and Apply Strategies Safely

A beginner-friendly zapret2 guide: install it, redirect only the right packets, and apply anti-DPI strategies on Linux/Windows.

2026-04-14 GIGATAP Team #vpn
#vpn#anti-dpi#censorship-circumvention#freebsd#linux#openbsd

zapret is an anti-DPI toolkit for cases where traffic is blocked or shaped by packet inspection rather than by the destination service. It should be deployed carefully: pick the smallest interception scope, test strategies one at a time, and keep a rollback path before routing sensitive apps.

What is zapret2#

zapret2 is a local anti-DPI toolkit (repo: bol-van/zapret2, latest: v0.9.5) designed to interfere with Deep Packet Inspection (DPI) systems that block or slow down traffic based on protocol “fingerprints.” Unlike VPNs or proxy services, zapret2 does not require you to connect to a third-party server. It works by selectively modifying how certain connections look “on the wire” so that brittle DPI classifiers fail to match.

Why this matters for privacy/OPSEC:

  • In many censorship environments, DPI targets the shape of traffic (TLS/QUIC patterns, TCP/UDP behaviors), not just destination IPs.
  • Some networks throttle or disrupt HTTPS, QUIC (UDP/443), or even VPN handshakes using signature-based detection.
  • zapret2 aims to be lightweight enough for routers (especially OpenWrt), while also supporting Linux, FreeBSD/OpenBSD, and Windows.

At a high level, zapret2 has two major parts:

  • A packet interception path (kernel/firewall or a driver) that diverts selected packets into a userspace process.
  • A “strategy” layer (implemented in Lua for nfqws2) that decides how to manipulate traffic to confuse DPI while keeping endpoints functional.

This guide focuses on getting a minimal, safe setup running and avoiding the common performance/locking pitfalls.

Installation#

zapret2 is written in C and is commonly built from source. You’ll need a compiler toolchain and (for the Linux NFQUEUE method) Netfilter queue development headers plus Lua headers.

Debian/Ubuntu example:

sudo apt update
sudo apt install -y git build-essential pkg-config \
  libnetfilter-queue-dev libmnl-dev \
  lua5.4 liblua5.4-dev

Clone and build (example workflow):

git clone https://github.com/bol-van/zapret2.git
cd zapret2
make

Check what binaries were produced and where:

ls -la
find . -maxdepth 3 -type f -name '*nfqws2*' -o -name '*winws2*' 2>/dev/null

If make fails, the fastest path is usually to read the build error and install the missing -dev packages (headers) for your distro.

Windows#

On Windows, zapret2 uses the WinDivert driver via the winws2 engine for packet interception. Typical installation flow:

  1. Download the v0.9.5 release archive from the project’s Releases page.
  2. Extract it somewhere simple, e.g. C:\zapret2\.
  3. Open an elevated terminal (Admin PowerShell or Admin CMD) because packet interception generally requires admin rights.
  4. Run the executable and confirm WinDivert can load.

A quick “does it start” check (run from the extracted folder):

.\winws2.exe --help

If you see driver load errors, your environment may block driver loading (Device Guard / HVCI / endpoint security policies). In that case, you’ll need to adjust your Windows security policy or run zapret2 on a router/Linux host instead.

macOS#

macOS is not a primary target for zapret2. The project relies on OS-specific packet interception mechanisms (NFQUEUE on Linux, ipfw/pf on BSD, WinDivert on Windows), and macOS doesn’t provide the same drop-in equivalents for this workflow.

If you’re on macOS but want to use zapret2 anyway, the practical option is to run it on:

# Option A: a router (OpenWrt)
# Option B: a Linux VM or a small Linux box acting as your gateway

Basic Configuration#

The single most important beginner concept: only intercept what you must. Redirecting “all packets” into userspace will hurt performance and can break networking. A common safe baseline is: intercept only the first few packets of new connections on the ports most often DPI-targeted (TCP/80, TCP/443, UDP/443).

Linux: minimal nftables redirection into NFQUEUE#

The example below creates an inet nftables table and queues the first 12 packets of new connections for:

  • outbound TCP ports 80 and 443
  • outbound UDP port 443 (often QUIC)
  • and also queues the matching reply direction for symmetry

Create rules (NFQUEUE number 200):

sudo nft delete table inet ztest 2>/dev/null || true
sudo nft create table inet ztest
sudo nft add chain inet ztest post '{ type filter hook postrouting priority 101; }'
sudo nft add rule inet ztest post meta mark and 0x40000000 == 0 tcp dport '{80,443}' ct original packets 1-12 queue num 200 bypass
sudo nft add rule inet ztest post meta mark and 0x40000000 == 0 udp dport '{443}' ct original packets 1-12 queue num 200 bypass

Enable a more forgiving TCP conntrack mode (often helpful when doing packet-level tricks):

sudo sysctl -w net.netfilter.nf_conntrack_tcp_be_liberal=1

Queue the early reply packets too:

sudo nft add chain inet ztest pre '{ type filter hook prerouting priority -101; }'
sudo nft add rule inet ztest pre meta mark and 0x40000000 == 0 tcp sport '{80,443}' ct reply packets 1-12 queue num 200 bypass
sudo nft add rule inet ztest pre meta mark and 0x40000000 == 0 udp sport '{443}' ct reply packets 1-12 queue num 200 bypass

Optional: a “pre-defrag” chain that disables conntrack for already-marked flows (reduces overhead in some designs):

sudo nft add chain inet ztest predefrag '{ type filter hook output priority -401; }'
sudo nft add rule inet ztest predefrag 'mark & 0x40000000 != 0x00000000 notrack'

Verify rules exist:

sudo nft list table inet ztest

Linux: start nfqws2 and attach a strategy#

Your nftables rules only redirect packets; you still need the userspace processor (nfqws2) to read from NFQUEUE 200 and apply a Lua strategy.

Because zapret2 is strategy-driven and ships multiple scripts, the exact command depends on how your build outputs binaries and where the Lua strategy files live in your checkout. Use --help to confirm the exact flags on your build:

./nfqws2 --help

A typical pattern is:

# Example pattern: queue number 200 + a Lua strategy script
# Adjust paths/flags to match your build and chosen strategy.
sudo ./nfqws2 --qnum 200 --lua ./strategies/<your-strategy>.lua

If you’re unsure which strategy to begin with, start with a “baseline” strategy shipped by the project (often a default or “nfqws1 compatibility” style strategy), then change only one thing at a time.

Windows: intercept only the ports you need#

On Windows, winws2 can capture traffic by port using built-in options:

# Outgoing web traffic
.\winws2.exe --wf-tcp-out=80,443 --wf-udp-out=443

If you also want to include incoming packets for those flows (common when you want consistent bidirectional handling):

.\winws2.exe --wf-tcp-out=80,443 --wf-udp-out=443 --wf-tcp-in=80,443 --wf-udp-in=443

For more precise selection, you can add raw WinDivert filter fragments (the tool combines them internally). Example (illustrative filter fragments):

.\winws2.exe --wf-raw-part="outbound and tcp.DstPort == 443" --wf-raw-part="outbound and udp.DstPort == 443"

Then consult:

.\winws2.exe --help

…and the project manual to connect interception to a specific zapret2 strategy on Windows (the Windows engine is tightly coupled to WinDivert capabilities and build options).

Common Use Cases#

1) Bypass DPI throttling for HTTPS without touching everything#

Goal: only influence HTTPS and QUIC setup packets, not bulk traffic.

Linux (nftables + NFQUEUE for first packets only):

sudo nft delete table inet ztest 2>/dev/null || true
sudo nft create table inet ztest
sudo nft add chain inet ztest post '{ type filter hook postrouting priority 101; }'
sudo nft add rule inet ztest post tcp dport 443 ct original packets 1-12 queue num 200 bypass
sudo nft add rule inet ztest post udp dport 443 ct original packets 1-12 queue num 200 bypass

Start processor (adjust flags/strategy for your build):

sudo ./nfqws2 --qnum 200 --lua ./strategies/<baseline-https-quic>.lua

Why this is a good beginner baseline: it limits CPU impact and minimizes the chance you break unrelated traffic.

2) Protect only a specific LAN client (router/gateway scenario)#

If zapret2 runs on a gateway, you may want to apply it only to one device you control (e.g., a test laptop), not the entire household.

Example: only queue traffic from 192.168.1.50:

sudo nft delete table inet ztest 2>/dev/null || true
sudo nft create table inet ztest
sudo nft add chain inet ztest post '{ type filter hook postrouting priority 101; }'
sudo nft add rule inet ztest post ip saddr 192.168.1.50 tcp dport '{80,443}' ct original packets 1-12 queue num 200 bypass
sudo nft add rule inet ztest post ip saddr 192.168.1.50 udp dport '{443}' ct original packets 1-12 queue num 200 bypass

Start nfqws2:

sudo ./nfqws2 --qnum 200 --lua ./strategies/<your-strategy>.lua

This is ideal for safe experimentation: if you misconfigure a strategy, only one client is affected.

3) Include non-standard ports (when the censor targets VPN-like traffic)#

Some environments block or fingerprint VPN transports on ports other than 443. If you know you need to cover additional ports, add them explicitly rather than widening to “all UDP” or “all TCP.”

Example: also include UDP/51820 (common WireGuard port) for first packets only:

sudo nft add rule inet ztest post udp dport '{443,51820}' ct original packets 1-12 queue num 200 bypass

Run nfqws2 as usual:

sudo ./nfqws2 --qnum 200 --lua ./strategies/<udp-focused-strategy>.lua

Practical OPSEC note: if you’re using a VPN, changing its port/protocol plus using an anti-DPI layer can reduce simple blocking, but it also increases complexity—test carefully.

Tips and Gotchas#

  • Start small (ports + packet count): Intercepting only ct original packets 1-12 is a common performance-friendly approach; raising it too high increases CPU and latency.
  • Use bypass on NFQUEUE rules: The bypass keyword ensures traffic continues if the userspace queue handler stops; without it you can accidentally “blackhole” connections during testing.
  • Avoid double interception: If you already use NFQUEUE for another tool (IDS/IPS, custom filters), pick a different queue number and ensure rule priorities don’t conflict.
  • Windows limitation awareness: WinDivert-based interception does not offer the same “first N packets only” limiter found in Linux conntrack expressions; be extra strict with filters/ports on Windows.
  • Validate with observation, not guesses: Use counters and captures. Examples:
    sudo nft list table inet ztest
    sudo tcpdump -ni any 'tcp port 443 or udp port 443'
    
  • Upgrade notes: zapret2 v0.9.5 mentions nfqws2 timer changes; if you’re troubleshooting behavior across versions, re-test strategies after upgrades.

Conclusion#

zapret2 is a powerful, local anti-DPI toolkit for users who need censorship circumvention without relying on third-party proxy servers. If you’re technically curious and can test methodically (small scope, clear filters, careful rollout), it’s a strong addition to a privacy/VPN OPSEC toolbox—especially on Linux gateways and routers.

If the symptom looks like a mismatch between payment, entitlement, and provider runtime state, capture the client behavior first and change the protocol or profile only after that baseline is clear.

Definition#

  • zapret - an anti-DPI toolkit that manipulates packet handling and connection behavior to reduce blocking or interference from deep packet inspection systems.

Comparison#

Strategy Use when Watch out for
zapret anti-DPI Filtering targets packet patterns or connection setup. Broad interception rules can break unrelated traffic.
VPN You need encrypted routing through a provider. The VPN protocol may be what the filter blocks.
DNS change Blocking is only domain-resolution based. It will not help when IP, SNI, or packet behavior is filtered.

FAQ#

Is zapret easier than using a VPN?#

zapret can be lighter than a VPN for specific DPI problems, but it is less turnkey. Users need to understand interception scope, platform support, and how to undo a strategy if normal traffic breaks.

What should be tested first?#

Test one target domain or app, one strategy, and one network path first. If it works, expand carefully; if it fails, the small test makes rollback and troubleshooting much safer.