Zapret2UI
EN RU

Theory

How it works

What your provider sees in your traffic, why that is enough to block you, and how a few altered bytes take the block away.

You do not have to read this page to use the program. But once you understand what is going on, two things stop being surprising: why there are nine strategies rather than one, and why sometimes "diagnostics is all green but the site will not open".

How the blocking works

When a browser opens an https:// connection, the first thing it sends is a TLS ClientHello packet. Among other things it carries the SNI field (Server Name Indication): the name of the site you are connecting to. It exists so that a server hosting thousands of domains knows whose certificate to present.

The key detail: the connection is not encrypted yet, and the site name travels in plain text. Anyone watching the channel can see it, including the provider's equipment. Operators call this DPI (Deep Packet Inspection); in Russia it is more often TSPU, a "technical countermeasure device" installed on the operator's network.

The rest is simple. The box reads the name, compares it against a list and, if it matches, interferes. There are three ways to interfere, and the symptom usually tells you which one was used:

What the DPI doesWhat it looks like
Reset (a forged TCP RST) The connection drops instantly. The browser says the site closed the connection. The classic Russian signature.
Silent drop The packet carrying the site name is discarded without a word. There is no reply, and the page hangs loading until it times out.
Substitution Instead of the site you get a stub page or a redirect. Less common these days.

There is a fourth mechanism built differently: not blocking but a volume limit. The connection is established, the first few dozen kilobytes get through, and after roughly sixteen or twenty packets in each direction the stream stalls. That is the "the site opens but video buffers and media will not load" case. To check whether this is being applied to you, use the "DPI check" button on the Diagnostics tab.

Why it can be bypassed

The bypass exists thanks to one asymmetry: the DPI is not the recipient of your traffic. It sits to the side, sees a copy of the stream, and has to decide within milliseconds, for millions of connections at once. The real server receives the whole stream and reassembles it by all the rules of TCP, in no hurry at all.

From which the main point follows: the picture of the stream can differ between the DPI and the server. If you can make the box see one thing while the server assembles another, the block does not fire and the site still opens normally. Every bypass strategy does exactly this, and it is called desynchronisation (desync).

It is important to understand the boundary: the bypass does not break into the provider, does not encrypt your traffic and does not hide your address. All it does is stop the automation from recognising the site name in the first packet. The rest of the connection runs as usual, directly.

Three families of techniques

The engine has a couple of dozen specific techniques, but they all boil down to three ideas.

Split the packet

The site name is cut by a TCP segment boundary. The browser sends not one ClientHello but several pieces: for example, so that you goes in one segment and tube.com in the next. The server reassembles them in the right order and sees the whole name, while the DPI, which analyses packets individually and keeps no state for every connection, never sees the whole name.

Verbs: multisplit (just cut), multidisorder (cut and send the pieces in reverse order, to make reassembly even harder). Where exactly to place the cut is set by position markers such as midsld, meaning "the middle of the second-level domain".

Forge a packet

Before the real ClientHello a fake one is sent, with an innocent name inside: for example a ready-made ClientHello from www.google.com or vk.com. The DPI sees that one first, considers the connection allowed and loses interest. The real packet follows behind it without inspection.

This is where the central difficulty of the whole bypass appears. The fake is only meant for the provider's box. If it reaches the server, the server receives two ClientHellos in a row and tears the handshake down. So the fake must die somewhere in the middle: after the DPI but before the server. How that is achieved is covered below.

Verbs: fake (insert a fake only), fakedsplit and fakeddisorder (fake plus splitting), hostfakesplit (a cut exactly on the name marker with a false name of the same length substituted in).

Squeeze the window

The third approach works not on your request but on the server's reply. The client advertises a very small TCP window, and the server is forced to deliver its reply in small portions. The signature the DPI looks for in the reply never assembles. This technique is slower than the others, but sometimes it gets through where nothing else did.

Verbs: wssize, wsize.

How the fake dies on the way

The techniques that make an intermediate packet fail to reach the server are called fooling. The idea is always the same: craft a packet so that the DPI reads and counts it, while the network or the server itself throws it away.

TechniqueHow it kills the fakeCaveats
ip_autottl Lowers the TTL so the packet expires a few hops past the provider's DPI and never reaches the server. Depends on the route. When the network changes, the value that was picked may stop fitting.
badsum Corrupts the checksum. The server discards the packet as damaged. Often useless at home: the home router behind NAT drops such a packet before it even reaches the provider, so the DPI never sees it either.
tcp_md5 Adds a TCP MD5 signature option. An ordinary server does not accept such a packet. Safe behind NAT. The working replacement for badsum on a home network.
tcp_seq Shifts the sequence number outside the window. The server treats the packet as out-of-order junk. Reliable, but some DPIs also check sequence numbers and stop believing the fake.
tcp_ts Gives the fake an older timestamp. The PAWS mechanism in the server's kernel discards the "stale" packet. Only works with TCP timestamps enabled and only with a negative value. See the warning below.

The tcp_ts trap. The value must be negative (tcp_ts=-1000). PAWS discards the packet with the smaller timestamp, that is, the older one. Set a positive value and everything inverts: the fake survives and PAWS discards the real packet instead. The connection then breaks silently, with no error, and looks like "the bypass is on but nothing works".

One more subtlety that makes ts techniques silently do nothing: by default Windows keeps TCP timestamps in the allowed state, which does not guarantee they are present in outgoing packets. Zapret2UI switches them to enabled for the duration of the session and restores the previous value on stop, so there is nothing to configure by hand.

Fooling is not applied to every verb the same way. With fake and the faked* family it affects the fake packets only, so you can put anything there. With multisplit and multidisorder it affects all segments, including the real ones, so destructive fooling there breaks the connection. More in the reference.

Why there is no single strategy for everyone

Operators use different equipment: different vendors, different firmware versions, different inspection depth settings. One DPI looks only at the first packet of a connection, another assembles the first few. One believes any ClientHello, another checks sequence numbers. One cuts QUIC entirely, another ignores it.

So a technique that punches straight through at one provider gives nothing at another. The only honest way to find a working variant is to try. That is what two of the program's features do:

What it finds is tied to a fingerprint of the current network (your router's address) and turns on by itself when you return to that network. The data is stored locally; nothing goes to the internet.

This is zapret2, not the ordinary zapret

Confusion here is constant, so let us be thorough. There are two different engines, both made by the same author, bol-van.

This is not a fork or a competitor: the second continues the first. But there is no compatibility between them: different argument names, a different strategy format, and each has its own driver.

What changed in the second one

The main change is not in the set of techniques but in where their logic lives. In the first zapret every technique was baked into the executable: adding a new one, or peeking at what exactly it does to a packet, was impossible without rebuilding. In the second, the logic is moved out into Lua scripts that sit next to the engine in the lua\ folder and are open to read.

Everything else follows from that.

zapret (the first)zapret2
Engine winws.exe winws2.exe
Techniques are set with --dpi-desync= --lua-desync=
Where a technique's logic lives Baked into the executable. Lua scripts next to the engine. You can read them and add your own.
Fake packets Separate flags for each type, such as --dpi-desync-fake-tls. Named blobs: a file is declared once with --blob=name:path and used by name afterwards.
Several techniques in a row A limited set of pre-baked combinations. As many --lua-desync entries per profile as you like, executed in order.
Control on the fly None. There are orchestrators (circular and others): they switch techniques themselves when they catch a reset from the DPI, without restarting the engine.
Driver Its own. Its own, a different one. Which is why the two versions should not be run at the same time.

How to tell which engine a guide is for

Two things in any config or command you find are enough.

What you see in the textWhat it means
winws.exe, --dpi-desync=, --dpi-desync-ttl The first zapret. Does not apply here.
winws2.exe, --lua-desync=, --blob= zapret2. Most likely applicable, but check the blob names.

A word about the name "Zapret 2 GUI". There are popular builds with the digit 2 in their name that run the first zapret inside, with hand-written Lua scripts bolted on. The digit there is the version of the build, not the generation of the engine. Their strategies are fine as a source of ideas, but you cannot carry lines over directly: some of those verbs and blob names simply do not exist in stock zapret2.

What this means in practice. Configs found in guides for the first zapret will not run here: the engine stops with an "invalid parameter" error. That is not a bug in the program but an incompatibility of formats. If you want to bring someone else's strategy over, check every verb against the list of supported ones and replace any blob names such as tls5 with ones that exist here.

How this differs from a VPN

The bypass and a VPN solve different problems and affect speed differently.

DPI bypassVPN
Where the traffic goes Straight to the site Through somebody else's server
Speed Unchanged: the route is the same Limited by the channel and the server's distance
Hides your address No Yes
Adds extra encryption No Yes
Against blocking by site name Works Works
Against blocking by IP address Powerless Works

What the bypass cannot do

An honest list of limits. All of them follow from the fact that the bypass only touches how the site name in the first packet is recognised.

Three details that decide everything

QUIC and HTTP/3

Modern YouTube and Discord happily use QUIC over UDP instead of the familiar TCP. That is a separate protocol and has to be bypassed separately, with its own profiles. If your provider is cutting or throttling QUIC specifically, the quickest way out is to disable it in Settings. The browser silently falls back to TCP, which the bypass handles better. Hence the classic recipe for "video loads forever".

Discord voice

Voice traffic does not run over port 443 but over UDP on high ports, up to 65535, using the STUN protocol. A profile that only catches 443 never reaches voice at all. That is why every built-in strategy has a separate voice profile covering the 19294-19344, 50000-65535 range. Hence also the classic symptom "text works but the voice channel is stuck connecting".

Bypass scope

By default the program only touches domains from the lists (Discord, YouTube plus your own targets), not all traffic. That is deliberate: bypassing everything means interfering with connections from games, banking apps and everything else, which may well break as a result. An "all sites" mode exists, but turn it on deliberately.