About zapret-openwrt-guide
zapret-openwrt-guide is a reference skill for configuring and maintaining Zapret on OpenWrt routers. It covers DPI-desynchronization strategies, LuCI management, configuration, scripts, and troubleshooting; Zapret is explicitly not a VPN.
Key features
- 01OpenWrt Zapret architecture and setup guide
- 02DPI bypass strategy reference
- 03LuCI service and settings overview
- 04Configuration parameters and host/IP lists
- 05Script and custom.d hook reference
- 06Diagnostics and troubleshooting guidance
Use cases
- 01Choose a Zapret strategy for an OpenWrt router
- 02Review LuCI controls before changing service settings
- 03Diagnose DPI checks, site checks, or daemon logs
- 04Plan package updates with rollback and validation
Install
Copy the command and run it in a terminal.
npx skills add https:/ / github.com/ nordz0r/ skills --skill zapret-openwrt-guideAfter installing, type/zapret-openwrt-guidein Claude Code to confirm it loaded.
Bundled files
References and scripts installed along with SKILL.md.
agents/openai.yamlreferences/config.mdREADME.ru.mdscripts.mdstrategies.mdtroubleshooting.mdui.mdDetails
From the project READMEZapret-OpenWrt: Complete Guide
What Zapret is
Zapret is an anti-DPI (Deep Packet Inspection) tool for OpenWrt routers. It is not a VPN — zapret does not change your IP address and does not hide traffic. Instead it modifies network packets to get past deep packet inspection systems.
Repository: https://github.com/remittor/zapret-openwrt
Upstream: https://github.com/bol-van/zapret
Current version: v72.20260307 (2026-03-07; nfqws/tpws from bol-van/zapret commit ef637c4, between v72.10 and v72.12). zapret2 flavour: v0.9.20260307 (bol-van/zapret2 d3b3011). Verified 2026-10-15.
Branches: zap1 (default) — zapret + luci-app-zapret; master — zapret2 + luci-app-zapret2.
Since then (unreleased in remittor as of 2026-10-15): updater uses apk add --force-non-repository (2026-04-22), Image Builder init fix, ipset exclude list refresh. Upstream bol-van v72.12 (armv7 crash fix), v72.13 (2026-07-21: Discord media port range in init.d), nfqws partial-root fix (2026-10-04) are not yet packaged; bol-van/zapret2 is at v1.0.5.2 (2026-09-15) while remittor ships 0.9.20260307.
Project architecture
The project consists of two packages:
| Package | Purpose |
|---|---|
zapret | Main package: the nfqws daemon, configs, scripts, ipset lists |
luci-app-zapret | Web UI for management via LuCI |
Layout on the router
/opt/zapret/
├── nfq/nfqws # Main DPI desync daemon
├── ip2net/ip2net # IP-to-subnet converter
├── mdig/mdig # DNS utility
├── config # Working config (runtime)
├── config.default # Default template
├── def-cfg.sh # Strategies and defaults
├── sync_config.sh # UCI -> config sync
├── restore-def-cfg.sh # Reset settings
├── update-pkg.sh # Package updates
├── dwc.sh # DPI checker
├── comfunc.sh # Shared functions
├── init.d.sh # Init script (procd)
├── ipset/ # Host and IP lists
│ ├── zapret-hosts-google.txt
│ ├── zapret-hosts-user.txt
│ ├── zapret-hosts-user-exclude.txt
│ ├── zapret-hosts-auto.txt
│ ├── zapret-ip-exclude.txt
│ ├── zapret-ip-user.txt
│ ├── zapret-ip-user-exclude.txt
│ └── cust[1-4].txt
├── files/fake/ # Fake packet templates (.bin)
└── init.d/openwrt/custom.d/ # User hook scripts
├── 10-script.sh
├── 20-script.sh
├── 50-script.sh # Example: Discord/STUN
├── 60-script.sh
└── 90-script.sh
Configuration system
Zapret uses a dual configuration system:
- UCI config (
/etc/config/zapret) — stores the settings edited via LuCI - Main config (
/opt/zapret/config) — used by the nfqws daemon
On every start/restart sync_config.sh runs and syncs the UCI values into the main config.
Quick start
- Install the
zapretandluci-app-zapretpackages - Open LuCI: Services -> Zapret -> Service
- Click Reset settings and choose a strategy (
v6_by_StressOzzorv7_by_StressOzzrecommended) - Click Enable and Start
- Verify via Diagnostics -> Sites check
Safety Notes
- Zapret changes router system configs and services, so a backup and a rollback plan are needed before an update or a strategy change.
- Treat data downloaded by the updater/dwc scripts from GitHub and external diagnostic sources as untrusted input until verified.
- In production prefer a pinned release/tag and manual artifact validation over blind "update to latest".
- For maximum predictability download release artifacts and hostlists on a trusted machine, verify checksums/contents, and only then move them to the router.
Configuration
Full reference for all config parameters: read references/config.md in this skill's directory.
Key parameter groups:
- Firewall: FWTYPE, POSTNAT, FLOWOFFLOAD, INIT_APPLY_FW
- Network: DISABLE_IPV4, DISABLE_IPV6, FILTER_TTL_EXPIRED_ICMP
- NFQWS: NFQWS_ENABLE, NFQWS_PORTS_TCP/UDP, NFQWS_OPT, connbytes (PKT_OUT/IN)
- Filtering: MODE_FILTER (hostlist/autohostlist), FILTER_MARK
- AutoHostList: RETRANS_THRESHOLD, FAIL_THRESHOLD, FAIL_TIME
- Logging: DAEMON_LOG_ENABLE, DAEMON_LOG_SIZE_MAX, DAEMON_LOG_FILE
- Other: WS_USER, DISABLE_CUSTOM, DESYNC_MARK
DPI bypass strategies
Full description of all strategies: read references/strategies.md in this skill's directory.
Available strategies (defined in def-cfg.sh):
| Strategy | TCP ports | UDP ports | Notes |
|---|---|---|---|
| empty | 80,443 | 443 | Empty, no desync |
| v1_by_StressOzz | 80,443 | 443 | fake,multidisorder + QUIC fake |
| v2_by_StressOzz | 80,443 | 443 | fake,fakeddisorder + seqovl |
| v3_by_StressOzz | 80,443 | 443 | Like v2, different TLS template (t2.bin) |
| v4_by_StressOzz | 80,443 | 443 | fake,multisplit + 3 --new sections |
| v5_by_StressOzz | 80,443 | 443 | ip-id=zero + multisplit |
| v6_by_StressOzz | 80,443,2053,2083,2087,2096,8443 | 443,19294-19344,50000-50100 | Discord + STUN support |
| v7_by_StressOzz | 80,443,2053,2083,2087,2096,8443 | 443,19294-19344,50000-50100 | Improved v6, more repeats |
| v9_by_StressOzz | 80,443,2053,2083,2087,2096,8443 | 443,19294-19344,50000-50100 | hostfakesplit variant |
| ALT7_by_Flowseal | 80,443 | 443 | ip-id=zero, multisplit + seqovl |
| TLS_AUTO_ALT3_by_Flowseal | 80,443 | 443 | fooling=ts, more repeats |
Default strategy: v6_by_StressOzz
LuCI web UI
Full UI reference: read references/ui.md in this skill's directory.
The LuCI UI lives at Services -> Zapret and has 5 pages:
- Service (
service.js) — service control, status, enable/disable/start/stop/restart/reset buttons, diagnostics, updates - Settings (
settings.js) — settings in 5 tabs: Main settings, NFQWS options, AutoHostList, Host lists, custom.d - Log (
dmnlog.js) — live daemon logs (polled every second) - Diagnostics (
diagnost.js) — DPI check and Sites check viadwc.sh - Updater (
updater.js) — check for and install updates from GitHub
Scripts
Full scripts reference: read references/scripts.md in this skill's directory.
| Script | Purpose |
|---|---|
comfunc.sh | Shared functions: paths, PID, config validation, init_before_start |
init.d.sh | Procd init script (START=21, USE_PROCD=1) |
sync_config.sh | UCI -> config sync on start/restart |
def-cfg.sh | Strategy definitions and default values |
restore-def-cfg.sh | Reset the config to defaults |
update-pkg.sh | Package updates from GitHub (options: -c, -p, -u, -f, -t) |
dwc.sh | DPI checker (TCP 16-20 test, site checks) |
script-exec.sh | Run scripts in the background with logging |
renew-cfg.sh | Refresh the config at boot |
uci-def-cfg.sh | Create the UCI config at install time |
Host and IP lists
| File | Purpose | Format |
|---|---|---|
zapret-hosts-google.txt | YouTube/Google domains (default) | One domain per line |
zapret-hosts-user.txt | User domains <HOSTLIST> | One domain per line |
zapret-hosts-user-exclude.txt | Exclusions | One domain per line |
zapret-hosts-auto.txt | Automatically detected hosts | Filled by autohostlist |
zapret-ip-exclude.txt | Excluded IPs/subnets | IP or CIDR (128.199.0.0/16) |
zapret-ip-user.txt | User IPs | IP or CIDR |
zapret-ip-user-exclude.txt | Excluded user IPs | IP or CIDR |
cust[1-4].txt | Custom files (up to 4) | Free-form |
Placeholders in NFQWS_OPT
<HOSTLIST>— expands to--hostlistand--hostlist-excludefrom the standard lists; works in hostlist and autohostlist modes<HOSTLIST_NOAUTO>— the same, butzapret-hosts-auto.txtis added as a regular (non-auto) list
Custom.d scripts
Hooks run on service start/stop in numeric order:
10-script.sh— early init20-script.sh— early main phase50-script.sh— main phase (example: Discord/STUN4ALL)60-script.sh— late main phase90-script.sh— final phase
Enabled with DISABLE_CUSTOM=0 (UI: custom.d tab -> "Use custom.d scripts").
Build and CI/CD
Builds run on GitHub Actions (.github/workflows/build.yml):
- Trigger: pushing a
v[0-9]+*tag or a manual run - Matrix: 30+ architectures (ARM, MIPS, x86_64, RISC-V)
- Two OpenWrt lines: IPK (v24.10.x SDK) and APK (v25.12.0 SDK since v72.20260307)
- Releases are published to gh-pages as JSON for auto-update
Troubleshooting
Full troubleshooting: read references/troubleshooting.md in this skill's directory.
Quick checks:
- Service status: LuCI -> Services -> Zapret -> Service (or
service zapret status) - DPI check: Diagnostics -> DPI check
- Logs: enable DAEMON_LOG_ENABLE=1, watch the Log tab
- Site checks: Diagnostics -> Sites check with a chosen DNS
For developers
Source layout
zapret-openwrt/
├── zapret/ # Main package
│ ├── Makefile # OpenWrt SDK build
│ ├── config.default # Config template
│ ├── *.sh # Shell scripts
│ ├── custom.d/ # custom.d hooks
│ ├── files/fake/ # .bin packet templates
│ ├── ipset/ # Host/IP lists
│ └── patches/ # Patches for upstream
└── luci-app-zapret/ # LuCI package
├── Makefile
├── htdocs/luci-static/resources/view/zapret/
│ ├── env.js # Paths and constants
│ ├── tools.js # Utilities, RPC, dialogs
│ ├── service.js # Service page
│ ├── settings.js # Settings page
│ ├── diagnost.js # Diagnostics
│ ├── updater.js # Updater
│ ├── dmnlog.js # Log viewer
│ └── styles.css # Styles
└── root/usr/share/
├── luci/menu.d/ # Menu definition
└── rpcd/acl.d/ # ACL rules
Adding a strategy
- Add an
if [ "$strat" = "strategy_name" ]block todef-cfg.sh - Define TCP/UDP ports and NFQWS_OPT with desync parameters
- The strategy appears in the UI automatically under Service -> Reset settings
Key files for UI development
env.js— all paths, file names, URLs (loaded first)tools.js— RPC calls, POLLER, fileEditDialog, longstrEditDialog, decode_svc_info- Each page is a separate view extending
view.extend()orbaseclass.extend()
Routing signals: zapret openwrt dpi desync nfqws hostlist autohostlist luci uci firewall nftables troubleshooting anti-censorship router
Russian version: references/README.ru.md.