Compare commits

..

98 Commits

Author SHA1 Message Date
remittor
83bf86b2f8 luci: service: Rewrite func serviceActionEx 2026-01-26 16:08:37 +03:00
remittor
e2c6c0552e luci: service: Add method getPackageDict 2026-01-26 13:00:54 +03:00
remittor
1f89151fe5 Bump version to v0.8.20260125 2026-01-25 10:07:30 +03:00
remittor
3ff8c4d746 makefile: Update LUA_VER to 5.5 2026-01-25 10:05:55 +03:00
remittor
db1833e93c makefile: Cleanup custom.d directory 2026-01-25 09:59:59 +03:00
remittor
6a50fb9708 luci: Fix typo 2026-01-25 09:49:35 +03:00
remittor
8eb054f2f9 config: Use --comment option for strategy naming 2026-01-25 09:49:15 +03:00
remittor
26d88c1efc ipset: Update zapret-hosts-user-exclude.txt 2026-01-25 09:48:45 +03:00
remittor
1cef4d7db9 diag: Add sites check 2026-01-19 17:36:15 +03:00
remittor
0aaee0ad36 luci: updater: Fix check result after checkUpdates 2026-01-18 14:22:47 +03:00
remittor
2500109837 Bump version to v0.8.20260118 2026-01-18 13:35:06 +03:00
remittor
05b84183d9 luci: updater: Using 3 buttons and fix execAndRead 2026-01-18 13:34:55 +03:00
remittor
2d32f04071 luci: Fix error "XHR request timed out" into execAndRead 2026-01-18 10:01:27 +03:00
remittor
bf418db17e luci: Fix file permissions for saved configs 2026-01-17 17:36:54 +03:00
remittor
c574e04a2b luci: NFQWS2_OPT: Block enter text with quotes 2026-01-17 15:52:46 +03:00
remittor
1f0d674185 luci: Using dict for arguments of function 2026-01-17 15:52:10 +03:00
remittor
27dab23ed2 Bump version to v0.8.20260117 2026-01-17 11:02:28 +03:00
remittor
5a6c607fee makefile: Cleanup conffiles and install sections 2026-01-16 20:24:27 +03:00
remittor
0309b4b94c updater: Add uninstall oldest mdig and ip2net packages 2026-01-16 20:08:21 +03:00
remittor
13b6e4611a ipset: Update zapret-hosts-user-exclude.txt 2026-01-16 20:01:28 +03:00
remittor
15a6f9e5ae settings: Add new options on "Reset settings" dialog 2026-01-16 19:59:40 +03:00
remittor
4aca2043c1 diag: dwc: Add support resolve ip via specific dns and add recommendations 2026-01-16 19:53:07 +03:00
remittor
84f297492a luci: Fix save very long textareas to file 2026-01-16 11:33:09 +03:00
remittor
685afc1a69 comfunc: Fix recreating crontab log cleaning task on restart
PR: ad6b23f4aa
2026-01-13 21:42:04 +03:00
remittor
a84174e51d luci: Fix show NFQWS2_OPT 2026-01-13 21:36:30 +03:00
remittor
ee8089e1bb Bump version to v0.8.20260113 2026-01-13 14:37:26 +03:00
remittor
4dd7030c60 makefile: Fix conffiles section and other fixes 2026-01-13 14:31:21 +03:00
remittor
00490e3b5d shell: Fix sh-scripts (copilot) 2026-01-13 14:17:07 +03:00
remittor
126e7dea89 Fix uci-def-cfg.sh 2026-01-13 14:15:25 +03:00
remittor
fc85552e4e updater: Fix pkg_mgr_update for opkg 2026-01-13 14:14:57 +03:00
remittor
e15eaafa33 luci: Add description for "Diagnostics" button 2026-01-13 14:11:00 +03:00
remittor
5b331132a1 github: releases: Add step "Wait for GitHub API consistency" 2026-01-12 22:51:52 +03:00
remittor
5711c1f2d4 config: Fix sync for AUTOHOSTLIST_RETRANS_RESET 2026-01-12 21:56:01 +03:00
remittor
0ee7ae325e diag: Fix bugs in dwc.sh 2026-01-11 19:09:07 +03:00
remittor
c4ce5c1aeb diag: Fix load comfunc.sh 2026-01-11 17:30:42 +03:00
remittor
d50aa75e94 makefile: skip init.d.sh 2026-01-11 16:09:35 +03:00
remittor
77f8f94d38 Bump version to v0.8.20260111 2026-01-11 15:31:38 +03:00
remittor
f7e01283e7 diag: Fix DPI checker 2026-01-11 15:30:48 +03:00
remittor
5b997a5eb5 config: Add new option AUTOHOSTLIST_RETRANS_RESET 2026-01-11 14:49:19 +03:00
remittor
0e2940c338 ipset: Update zapret-hosts-user-exclude.txt 2026-01-11 14:21:48 +03:00
remittor
0e31e5d804 Add diagnostic button (DPI checker) 2026-01-11 11:54:19 +03:00
remittor
ab50c2099b luci: updater: Add new func tools.execAndRead 2026-01-10 20:51:11 +03:00
remittor
17afabe150 luci: Fix update text after edit for NFQWS2_OPT 2026-01-10 10:56:58 +03:00
remittor
2ecf3cf5d0 luci: Fix js-files for unification 2026-01-09 22:31:11 +03:00
remittor
9e8046d734 luci: Splitting file tools.js into two parts (add file env.js) 2026-01-09 21:58:12 +03:00
remittor
c68236c8fd Replace "founded" to "found" 2026-01-09 17:36:26 +03:00
remittor
706f92fea7 config: Update default values
src: https://github.com/bol-van/zapret2/commits/master/config.default
2026-01-09 17:10:18 +03:00
remittor
d747201f9b Bump version to v0.8.20260109 2026-01-09 16:55:37 +03:00
remittor
9ead0e1d30 build: Rewrite build script (using OpenWrt SDK from github) 2026-01-09 16:55:24 +03:00
remittor
b37b35db80 updater: Add support install packages on clean OpenWrt
Example: ./update-pkg.sh -u 1
Example: ./update-pkg.sh -u 2
2026-01-08 18:33:51 +03:00
remittor
9737a10e1f Bump version to v0.8.20260107 2026-01-07 23:08:59 +03:00
remittor
bc1af90349 Integrate mdig and ip2net to main package 2026-01-01 20:59:37 +03:00
remittor
11f632259e Remove mdig and ip2net packages 2026-01-01 12:30:10 +03:00
remittor
a215600415 Bump version to v0.8.20251230 2025-12-30 13:38:10 +03:00
remittor
28e6c466cb updater: Change get_actual_release error 1 to 150 2025-12-30 13:36:13 +03:00
remittor
c72921f2fa zapret: Global use of dynamic variables 2025-12-29 21:10:58 +03:00
remittor
55041b3b16 luci: updater: Skip error -32000 2025-12-29 19:36:59 +03:00
remittor
bf012b36bf updater: Fix get_pkg_version for OpenWrt 25 2025-12-29 18:33:58 +03:00
remittor
9717bc8ff7 Bump version to v0.8.20251229 2025-12-29 18:16:24 +03:00
remittor
61e234ab12 build: Rename base directories 2025-12-28 20:17:33 +03:00
remittor
c11ca1ca2e Rename all directories 2025-12-28 20:15:29 +03:00
remittor
dd35b5d50a Bump version to v0.7.20251227 2025-12-27 13:18:59 +03:00
remittor
072b742a13 luci: tools: Fix modal dialog for NFQWS2_OPT 2025-12-27 10:47:53 +03:00
remittor
487d92bda2 updater: Fix files renaming 2025-12-26 15:44:11 +03:00
remittor
71eccc6057 Bump version to v0.7.20251226 2025-12-26 09:00:21 +03:00
remittor
5f92425261 luci: Rename handleSave to handleSaveAdv 2025-12-26 08:58:30 +03:00
remittor
950672426c updater: Update func download_releases_info 2025-12-26 08:56:45 +03:00
remittor
d0c49a8e6f def-cfg: Add new strategy v2_by_Schiz23 2025-12-26 08:03:58 +03:00
remittor
2da0526472 Bump version to v0.7.20251225-r2 2025-12-25 18:06:29 +03:00
remittor
c9823adaae luci: tools: Fix show and close modal dialog for NFQWS_OPT 2025-12-25 18:01:29 +03:00
remittor
d14f26a8cb updater: Fix find base package after ZIP unpack 2025-12-25 14:54:49 +03:00
remittor
ecf49f1be8 Bump version to v0.7.20251225 2025-12-25 09:01:37 +03:00
remittor
3ef469b416 fake: Add TLS 1.3 hello from max.ru 2025-12-25 08:25:52 +03:00
remittor
88665d417a luci: tools: Fix close modal dialog for NFQWS2_OPT 2025-12-24 18:49:41 +03:00
remittor
35fb6e9a43 luci: updater: Fix timer using 2025-12-24 14:38:07 +03:00
remittor
9c7f906b72 Bump version to v0.7.20251224 2025-12-24 10:30:59 +03:00
remittor
bd3d224178 def-cfg: Add new strategy v1_by_Schiz23 2025-12-24 10:27:40 +03:00
remittor
fcf7889a93 luci: tools: Fix close modal dialog for NFQWS_OPT 2025-12-23 14:15:22 +03:00
remittor
76dcf0638d luci: dmnlog: Fix load tools.js 2025-12-20 14:16:47 +03:00
remittor
d20c81b1c1 Bump version to v0.7.20251220 2025-12-20 10:43:48 +03:00
remittor
ea2a39877d Makefile: Fix build with LUA
Source: https://github.com/spvkgn/zapret2-openwrt/blob/main/package/nfqws2/Makefile
2025-12-20 10:24:43 +03:00
remittor
85b7f91767 comfunc: Fix remove debug log 2025-12-20 10:12:25 +03:00
remittor
7cd7293424 luci: settings: Fix NFQWS2_PORTS_UDP_KEEPALIVE 2025-12-20 10:12:14 +03:00
remittor
116ce93c63 Bump version to v0.7.20251219 2025-12-19 17:23:10 +03:00
remittor
4f586e66b0 build: Delete riscv64 arch 2025-12-19 17:22:53 +03:00
remittor
3e19c9c9e2 luci: Fix for show menu Zapret2 2025-12-19 14:23:11 +03:00
remittor
980dd77ba1 def-cfg: Fix DAEMON_LOG_FILE value 2025-12-19 13:58:38 +03:00
remittor
aaef886826 updater: Add check for unzip installed 2025-12-19 11:12:27 +03:00
remittor
c8558cf6c1 updater: Adapt code for new version format 2025-12-19 10:44:49 +03:00
remittor
c6e2e79683 updater: Fix parsing package version (APK) 2025-12-19 10:23:52 +03:00
remittor
08e6776a81 zapret: Add depends from luajit 2025-12-18 18:11:45 +03:00
remittor
509b834729 zapret: Makefile: Fix Package-install section 2025-12-18 17:43:49 +03:00
remittor
003160cb05 build: Fix compile packages 2025-12-18 17:22:18 +03:00
remittor
682d153742 zapret: Add depends from liblua 2025-12-18 17:02:33 +03:00
remittor
e2810bbe98 build: Fix detection tag-version 2025-12-18 16:49:04 +03:00
remittor
7aecaa4ab7 config: Add new options for AutoHostList 2025-12-18 16:42:41 +03:00
remittor
03e8513703 luci: Rename files: zapret -> zapret2 2025-12-18 16:38:57 +03:00
remittor
7a4825a708 Add support Zapret2
Sources: https://github.com/bol-van/zapret2
2025-12-18 16:35:13 +03:00
49 changed files with 1709 additions and 2030 deletions

View File

@@ -1,80 +0,0 @@
---
name: 🐛 Bug Report
description: Report a reproducible bug
title: "[BUG] "
labels: ["bug"]
assignees: []
body:
- type: markdown
attributes:
value: |
Thanks for reporting a bug! Please fill out the form below.
Before sending, please:
- Check [existing issues](https://github.com/remittor/zapret-openwrt/issues)
- Read [documentation](https://github.com/remittor/zapret-openwrt/wiki/)
- type: textarea
id: description
attributes:
label: 📝 Bug description
description: A clear and concise description of what is not working
placeholder: A clear and concise description of the bug
validations:
required: true
- type: textarea
id: reproduction
attributes:
label: Steps to reproduce
description: Steps to reproduce the problem. If you're following a manual, please include a link to it.
placeholder: |
1.
2.
3.
4.
validations:
required: true
- type: textarea
id: expected
attributes:
label: ✅ Expected behavior
description: A clear and concise description of what was to happen
placeholder: Describe the expected behavior
validations:
required: true
- type: textarea
id: environment
attributes:
label: 🖥️ System Information
description: |
Information about your system (fill in all that used)
value: |
- **OpenWrt version**:
- **Zapret version**:
- **Router model**:
render: markdown
validations:
required: true
- type: textarea
id: strategy
attributes:
label: ✅ The NFQWS strategy used
description: All parameters of the NFQWS strategy, or its name
placeholder: If the problem is caused by the NFQWS strategy
- type: textarea
id: config
attributes:
label: ⚙️ System Configurations
description: |
Relevant parts of the configuration (remove sensitive information!)
placeholder: |
For example:
- Contents of /etc/config/zapret
- Firewall configuration (Flow offloading, etc.)
- Additional configurations required for wireless/network/dhcp, etc.
render: shell

View File

@@ -1,80 +0,0 @@
---
name: 🐛 Сообщение об ошибке
description: Сообщить об ошибке
title: "[BUG] "
labels: ["bug"]
assignees: []
body:
- type: markdown
attributes:
value: |
Спасибо за создание отчета об ошибке!
Перед отправкой, пожалуйста:
- Проверьте [существующие issues](https://github.com/remittor/zapret-openwrt/issues)
- Просмотрите [документацию](https://github.com/remittor/zapret-openwrt/wiki/)
- type: textarea
id: description
attributes:
label: 📝 Описание проблемы
description: Четкое и краткое описание того, что не работает
placeholder: Опишите проблему
validations:
required: true
- type: textarea
id: reproduction
attributes:
label: Шаги для воспроизведения
description: Шаги для воспроизведения проблемы. Если вы настраваете что-то по какому либо мануалу, приложите ссылку на него.
placeholder: |
1.
2.
3.
4.
validations:
required: true
- type: textarea
id: expected
attributes:
label: ✅ Ожидаемое поведение
description: Четкое и краткое описание того, что должно было произойти
placeholder: Опишите ожидаемое поведение
validations:
required: true
- type: textarea
id: environment
attributes:
label: 🖥️ Информация о системе
description: |
Информация о вашей системе (заполните всё применяемое)
value: |
- **OpenWrt версия**:
- **Zapret версия**:
- **Роутер модель**:
render: markdown
validations:
required: true
- type: textarea
id: strategy
attributes:
label: ✅ Используемая стратегия NFQWS
description: Все параметры стратегии NFQWS, либо её название
placeholder: Если проблема вызвана стратегией NFQWS
- type: textarea
id: config
attributes:
label: ⚙️ Конфигурация
description: |
Релевантные части конфигурации (удалите чувствительную информацию!)
placeholder: |
Например:
- Содержимое /etc/config/zapret
- Конфигурация файервола (опция Flow offloading и т.п.)
- Дополнительные конфиги, которые потребуются wireless/network/dhcp и т.д.
render: shell

View File

@@ -1,9 +0,0 @@
blank_issues_enabled: false
contact_links:
- name: 💬 Installation instructions / Инструкция по установке
url: https://github.com/remittor/zapret-openwrt/wiki/Installing-zapret%E2%80%90openwrt-package
about: Installation instructions / Инструкция по установке
- name: 📚 Original documetation / Оригинальная документация к zapret'у
url: https://github.com/bol-van/zapret/blob/master/docs/readme.md
about: README zapret

View File

@@ -1,66 +0,0 @@
---
name: ✨ Feature Request
description: Suggest a new feature or improvement
title: "[FEATURE] "
labels: ["enhancement", "needs-discussion"]
assignees: []
body:
- type: markdown
attributes:
value: |
Before sending, please:
- Check [existing requests](https://github.com/remittor/zapret-openwrt/issues?q=is%3Aissue+label%3Aenhancement)
- Make sure the function doesn't exist in [documentation](https://github.com/remittor/zapret-openwrt/wiki/)
- type: textarea
id: summary
attributes:
label: Brief description
description: Brief description of the proposed function
placeholder: In one sentence, describe what you want to add...
validations:
required: true
- type: textarea
id: problem
attributes:
label: The problem it solves
description: |
Description of the problem or inconvenience this feature will solve
placeholder: |
There is no possibility now [...]
validations:
required: true
- type: textarea
id: solution
attributes:
label: 💡 Proposed solution
description: A clear and concise description of what you want to achieve
placeholder: |
I want Zapret to be able to [...]
I suggest adding a feature that [...]
Could be improved [...]
validations:
required: true
- type: textarea
id: alternatives
attributes:
label: Workaround
description: |
Describe any alternative solutions or features you considered.
Are there any workarounds you currently use?
placeholder: |
I'm currently solving this problem by [...]
An alternative would be [...]
I tried using [...], but it doesn't work because [...]
- type: textarea
id: implementation
attributes:
label: Implementation ideas (optional)
description: |
If you have any ideas on how this could be implemented, please share them. Please keep LuCI's limitations in mind.
placeholder: |
This can be achieved using [...]

View File

@@ -1,68 +0,0 @@
---
name: ✨ Запрос новой функции
description: Предложите новую функцию или улучшение для Zapret
title: "[FEATURE] "
labels: ["enhancement", "needs-discussion"]
assignees: []
body:
- type: markdown
attributes:
value: |
Спасибо за предложение новой функции!
Перед отправкой, пожалуйста:
- Проверьте [существующие запросы](https://github.com/remittor/zapret-openwrt/issues?q=is%3Aissue+label%3Aenhancement)
- Убедитесь, что функции не существует в [документации](https://github.com/remittor/zapret-openwrt/wiki/)
- type: textarea
id: summary
attributes:
label: Краткое описание
description: Краткое описание предлагаемой функции
placeholder: В одном предложении опишите, что вы хотите добавить...
validations:
required: true
- type: textarea
id: problem
attributes:
label: Проблема, которую решает
description: |
Описание проблемы или неудобства, которое решит эта функция
placeholder: |
Сейчас нет возможности [...]
validations:
required: true
- type: textarea
id: solution
attributes:
label: 💡 Предлагаемое решение
description: Четкое и краткое описание того, что вы хотите реализовать
placeholder: |
Я хочу, чтобы Zapret мог [...]
Предлагаю добавить функцию, которая [...]
Можно было бы улучшить [...] путем [...]
validations:
required: true
- type: textarea
id: alternatives
attributes:
label: Workaround
description: |
Опишите альтернативные решения или функции, которые вы рассматривали
Есть ли обходные пути, которые вы используете сейчас?
placeholder: |
Сейчас я решаю это проблему путем [...]
Альтернативой могло бы быть [...]
Пробовал использовать [...], но это не подходит потому что [...]
- type: textarea
id: implementation
attributes:
label: Идеи реализации (опционально)
description: |
Если у вас есть идеи о том, как это можно реализовать, поделитесь ими. Помните про ограничения LuCI.
placeholder: |
Это можно реализовать с помощью [...]

View File

@@ -1,78 +0,0 @@
---
name: 🆘 Help wanted
description: Ask for help or propose to help
title: "[HELP] "
labels: ["help wanted"]
assignees: []
body:
- type: markdown
attributes:
value: |
Before sending, please:
- Check [existing issues](https://github.com/remittor/zapret-openwrt/issues)
- Read [documentation](https://github.com/remittor/zapret-openwrt/wiki/)
- type: textarea
id: description
attributes:
label: 📝 Problem description
description: What do you need help with?
placeholder: A clear and concise description of the problem
validations:
required: true
- type: textarea
id: reproduction
attributes:
label: Steps to reproduce
description: Steps to reproduce the problem. If you're following a manual, please include a link to it.
placeholder: |
1.
2.
3.
4.
validations:
required: true
- type: textarea
id: expected
attributes:
label: ✅ Expected behavior
description: A clear and concise description of what was to happen
placeholder: Describe the expected behavior
validations:
required: true
- type: textarea
id: environment
attributes:
label: 🖥️ System Information
description: |
Information about your system (fill in all that used)
value: |
- **OpenWrt version**:
- **Zapret version**:
- **Router model**:
render: markdown
validations:
required: true
- type: textarea
id: strategy
attributes:
label: ✅ The NFQWS strategy used
description: All parameters of the NFQWS strategy, or its name
placeholder: If the problem is caused by the NFQWS strategy
- type: textarea
id: config
attributes:
label: ⚙️ System Configurations
description: |
Relevant parts of the configuration (remove sensitive information!)
placeholder: |
For example:
- Contents of /etc/config/zapret
- Firewall configuration (Flow offloading, etc.)
- Additional configurations required for wireless/network/dhcp, etc.
render: shell

View File

@@ -1,78 +0,0 @@
---
name: 🆘 Нужна помощь
description: Нужна помощь
title: "[HELP] "
labels: ["help wanted"]
assignees: []
body:
- type: markdown
attributes:
value: |
Перед отправкой, пожалуйста:
- Проверьте [существующие issues](https://github.com/remittor/zapret-openwrt/issues)
- Просмотрите [документацию](https://github.com/remittor/zapret-openwrt/wiki/)
- type: textarea
id: description
attributes:
label: 📝 Описание проблемы
description: В чём именно нужна помощь?
placeholder: Опишите проблему
validations:
required: true
- type: textarea
id: reproduction
attributes:
label: Шаги для воспроизведения
description: Шаги для воспроизведения проблемы. Если вы настраваете что-то по какому либо мануалу, приложите ссылку на него.
placeholder: |
1.
2.
3.
4.
validations:
required: true
- type: textarea
id: expected
attributes:
label: ✅ Ожидаемое поведение
description: Четкое и краткое описание того, что должно было произойти
placeholder: Опишите ожидаемое поведение
validations:
required: true
- type: textarea
id: environment
attributes:
label: 🖥️ Информация о системе
description: |
Информация о вашей системе (заполните всё применяемое)
value: |
- **OpenWrt версия**:
- **Zapret версия**:
- **Роутер модель**:
render: markdown
validations:
required: true
- type: textarea
id: strategy
attributes:
label: ✅ Используемая стратегия NFQWS
description: Все параметры стратегии NFQWS, либо её название
placeholder: Если проблема вызвана стратегией NFQWS
- type: textarea
id: config
attributes:
label: ⚙️ Конфигурация
description: |
Релевантные части конфигурации (удалите чувствительную информацию!)
placeholder: |
Например:
- Содержимое /etc/config/zapret
- Конфигурация файервола (опция Flow offloading и т.п.)
- Дополнительные конфиги, которые потребуются wireless/network/dhcp и т.д.
render: shell

View File

@@ -155,8 +155,6 @@ jobs:
- mipsel_24kc_24kf - mipsel_24kc_24kf
- mipsel_74kc - mipsel_74kc
- mipsel_mips32 - mipsel_mips32
- riscv64_riscv64
- riscv64_generic
- x86_64 - x86_64
isTestOrFake: isTestOrFake:
- ${{ needs.check.outputs.test_build == 'true' || needs.check.outputs.fake_build == 'true' }} - ${{ needs.check.outputs.test_build == 'true' || needs.check.outputs.fake_build == 'true' }}
@@ -165,10 +163,6 @@ jobs:
arch: arm_cortex-a9_vfpv3-d16 arch: arm_cortex-a9_vfpv3-d16
- branch: ${{ needs.var.outputs.APK_BRANCH }} - branch: ${{ needs.var.outputs.APK_BRANCH }}
arch: mips_4kec arch: mips_4kec
- branch: ${{ needs.var.outputs.APK_BRANCH }}
arch: riscv64_riscv64
- branch: ${{ needs.var.outputs.IPK_BRANCH }}
arch: riscv64_generic
- { isTestOrFake: true } - { isTestOrFake: true }
include: include:
- branch: ${{ needs.var.outputs.IPK_BRANCH }} - branch: ${{ needs.var.outputs.IPK_BRANCH }}
@@ -290,9 +284,9 @@ jobs:
env: env:
ARCH_TAG: ${{ matrix.arch }} ARCH_TAG: ${{ matrix.arch }}
run: | run: |
PKGLIST="package/zapret-openwrt/zapret/compile" PKGLIST="package/zapret-openwrt/zapret2/compile"
if [ "$ARCH_TAG" = "$LUCI_ARCH" ]; then if [ "$ARCH_TAG" = "$LUCI_ARCH" ]; then
PKGLIST="$PKGLIST package/zapret-openwrt/luci-app-zapret/compile" PKGLIST="$PKGLIST package/zapret-openwrt/luci-app-zapret2/compile"
fi fi
MAKE_JOBS=$(nproc) MAKE_JOBS=$(nproc)
echo "$MAKE_JOBS thread compile" echo "$MAKE_JOBS thread compile"
@@ -312,8 +306,8 @@ jobs:
run: | run: |
OUT_DIR=./bin/packages/dev_x/base OUT_DIR=./bin/packages/dev_x/base
mkdir -p $OUT_DIR mkdir -p $OUT_DIR
touch $OUT_DIR/zapret_$PKGVER-$ARCH_TAG.$PKGTYPE touch $OUT_DIR/zapret2_$PKGVER-$ARCH_TAG.$PKGTYPE
touch $OUT_DIR/luci-app-zapret_$PKGVER-all.$PKGTYPE touch $OUT_DIR/luci-app-zapret2_$PKGVER-all.$PKGTYPE
echo "status=success" >> $GITHUB_OUTPUT echo "status=success" >> $GITHUB_OUTPUT
- name: Install packages - name: Install packages
@@ -324,7 +318,7 @@ jobs:
ARCH_TAG: ${{ matrix.arch }} ARCH_TAG: ${{ matrix.arch }}
SIGN_KEY: ${{ secrets.SIGN_PRIVATE_KEY }} SIGN_KEY: ${{ secrets.SIGN_PRIVATE_KEY }}
run: | run: |
find ./bin/packages/*/base -type f ! -regex ".*\(zapret\).*\.[ai]pk$" -delete find ./bin/packages/*/base -type f ! -regex ".*\(zapret2\).*\.[ai]pk$" -delete
#echo ">>>>>>> build a repository index to make the output directory usable as local OPKG source" #echo ">>>>>>> build a repository index to make the output directory usable as local OPKG source"
#ln -s `which usign` staging_dir/host/bin/usign #ln -s `which usign` staging_dir/host/bin/usign
#echo "$SIGN_KEY" | base64 -d > key-build #echo "$SIGN_KEY" | base64 -d > key-build
@@ -390,7 +384,7 @@ jobs:
find ./sorted -mindepth 1 -maxdepth 1 -type d -exec cp -f "$LUCI_IPK" "{}/" \; find ./sorted -mindepth 1 -maxdepth 1 -type d -exec cp -f "$LUCI_IPK" "{}/" \;
find ./sorted -mindepth 2 -maxdepth 2 -type d -name "apk" -exec cp -f "$LUCI_APK" "{}/" \; find ./sorted -mindepth 2 -maxdepth 2 -type d -name "apk" -exec cp -f "$LUCI_APK" "{}/" \;
mkdir -p public mkdir -p public
find ./sorted -mindepth 1 -maxdepth 1 -type d -exec sh -c '7z a ./public/zapret_v${PKGVER}_$(basename "{}" | cut -d, -f3).zip {}/*' \; find ./sorted -mindepth 1 -maxdepth 1 -type d -exec sh -c '7z a ./public/zapret2_v${PKGVER}_$(basename "{}" | cut -d, -f3).zip {}/*' \;
ls -lh ./public/*.zip ls -lh ./public/*.zip
- name: Upload assets - name: Upload assets
@@ -402,7 +396,7 @@ jobs:
draft: ${{ env.TEST_BUILD == 'true' || env.FAKE_BUILD == 'true' }} draft: ${{ env.TEST_BUILD == 'true' || env.FAKE_BUILD == 'true' }}
prerelease: true prerelease: true
tag_name: v${{ needs.build.outputs.pkgver }}${{ env.TAG_SUFFIX }} tag_name: v${{ needs.build.outputs.pkgver }}${{ env.TAG_SUFFIX }}
name: zapret v${{ needs.build.outputs.pkgver }} name: zapret2 v${{ needs.build.outputs.pkgver }}
body: | body: |
zapret v${{ needs.build.outputs.pkgver }} for OpenWrt zapret2 v${{ needs.build.outputs.pkgver }} for OpenWrt
files: ./public/*.zip files: ./public/*.zip

View File

@@ -2,12 +2,13 @@
[![Github All Releases](https://img.shields.io/github/downloads/remittor/zapret-openwrt/total.svg)](https://github.com/remittor/zapret-openwrt/releases) [![Github All Releases](https://img.shields.io/github/downloads/remittor/zapret-openwrt/total.svg)](https://github.com/remittor/zapret-openwrt/releases)
[![Github Latest Release](https://img.shields.io/github/downloads/remittor/zapret-openwrt/latest/total.svg)](https://github.com/remittor/zapret-openwrt/releases) [![Github Latest Release](https://img.shields.io/github/downloads/remittor/zapret-openwrt/latest/total.svg)](https://github.com/remittor/zapret-openwrt/releases)
[![ViewCount](https://views.whatilearened.today/views/github/remittor/zapret-openwrt.svg)](https://github.com/remittor/zapret-openwrt) [![ViewCount](https://views.whatilearened.today/views/github/remittor/zapret-openwrt.svg)](https://github.com/remittor/zapret-openwrt)
[![Hits](https://hits.seeyoufarm.com/api/count/incr/badge.svg?url=https%3A%2F%2Fgithub.com%2Fremittor%2Fzapret-openwrt&count_bg=%2379C83D&title_bg=%23555555&icon=&icon_color=%23E7E7E7&title=hits&edge_flat=false)](https://github.com/remittor/zapret-openwrt/releases)
[![Donations Page](https://github.com/andry81-cache/gh-content-static-cache/raw/master/common/badges/donate/donate.svg)](https://github.com/remittor/donate) [![Donations Page](https://github.com/andry81-cache/gh-content-static-cache/raw/master/common/badges/donate/donate.svg)](https://github.com/remittor/donate)
# zapret-openwrt # zapret-openwrt
Zapret is not a VPN! Zapret is an Anti-DPI utility! Zapret2 is not a VPN! Zapret2 is an Anti-DPI utility!
[Instructions for installing](https://github.com/remittor/zapret-openwrt/wiki) [Instructions for installing](https://github.com/remittor/zapret-openwrt/wiki/Installing-zapretopenwrt-package)
[Download page](https://github.com/remittor/zapret-openwrt/releases) [Download page](https://github.com/remittor/zapret-openwrt/releases)

View File

@@ -1,96 +0,0 @@
'use strict';
'require baseclass';
'require fs';
'require poll';
'require uci';
'require ui';
'require view';
'require view.zapret.tools as tools';
const btn_style_neutral = 'btn';
const btn_style_action = 'btn cbi-button-action';
const btn_style_positive = 'btn cbi-button-save important';
const btn_style_negative = 'btn cbi-button-reset important';
const btn_style_warning = 'btn cbi-button-negative';
const btn_style_success = 'btn cbi-button-success important';
const fn_dwc_sh = '/opt/'+tools.appName+'/dwc.sh';
return baseclass.extend({
appendLog: function(msg, end = '\n')
{
this.logArea.value += msg + end;
this.logArea.scrollTop = this.logArea.scrollHeight;
},
dpiCheck: async function()
{
this._action = 'dpiCheck';
this.appendLog('DPI check [tcp 16-20]...');
this.appendLog('Original sources: https://github.com/hyperion-cs/dpi-checkers');
this.appendLog('WEB-version: https://hyperion-cs.github.io/dpi-checkers/ru/tcp-16-20/');
let cmd = [ fn_dwc_sh ];
let log = '/tmp/'+tools.appName+'_dwc.log';
let callback = this.execAndReadCallback;
let wnd = this;
return tools.execAndRead({ cmd: cmd, log: log, logArea: this.logArea, callback: callback, cbarg: wnd });
},
execAndReadCallback: function(wnd, rc, txt = '')
{
if (rc == 0 && txt) {
if (wnd._action == 'dpiCheck') {
wnd.appendLog('=========================================================');
return;
}
}
if (rc >= 500) {
if (txt) {
wnd.appendLog(txt.startsWith('ERROR') ? txt : 'ERROR: ' + txt);
} else {
wnd.appendLog('ERROR: ' + wnd._action + ': Terminated with error code = ' + rc);
}
} else {
wnd.appendLog('ERROR: Process finished with retcode = ' + rc);
}
wnd.appendLog('=========================================================');
},
openDiagnostDialog: function(pkg_arch)
{
this.pkg_arch = pkg_arch;
this.logArea = E('textarea', {
'id': 'widget.modal_content',
'readonly': true,
'style': 'width:100% !important; font-family: monospace;',
'rows': 26,
'wrap': 'off',
});
this.btn_cancel = E('button', {
'id': 'btn_cancel',
'name': 'btn_cancel',
'class': btn_style_warning,
}, _('Cancel'));
this.btn_cancel.onclick = ui.hideModal;
this.btn_dpicheck = E('button', {
'id': 'btn_dpicheck',
'name': 'btn_dpicheck',
'class': btn_style_action,
}, _('DPI check [tcp 16-20]'));
this.btn_dpicheck.onclick = ui.createHandlerFn(this, () => { this.dpiCheck() });
ui.showModal(_('Diagnostics'), [
E('div', { 'class': 'cbi-section' }, [
this.logArea,
]),
E('div', { 'class': 'right' }, [
this.btn_dpicheck,
' ',
this.btn_cancel,
])
]);
}
});

View File

@@ -1,53 +0,0 @@
'use strict';
'require baseclass';
return baseclass.extend({
packager : { },
appName : 'zapret',
AppName : 'Zapret',
execPath : '/etc/init.d/zapret',
appDir : '/opt/zapret',
syncCfgPath : '/opt/zapret/sync_config.sh',
defCfgPath : '/opt/zapret/def-cfg.sh',
defaultCfgPath : '/opt/zapret/restore-def-cfg.sh',
hostsGoogleFN : '/opt/zapret/ipset/zapret-hosts-google.txt',
hostsUserFN : '/opt/zapret/ipset/zapret-hosts-user.txt',
hostsUserExcludeFN: '/opt/zapret/ipset/zapret-hosts-user-exclude.txt',
iplstExcludeFN : '/opt/zapret/ipset/zapret-ip-exclude.txt',
iplstUserFN : '/opt/zapret/ipset/zapret-ip-user.txt',
iplstUserExcludeFN: '/opt/zapret/ipset/zapret-ip-user-exclude.txt',
custFileMax : 4,
custFileTemplate : '/opt/zapret/ipset/cust%s.txt',
customdPrefixList : [ 10, 20, 50, 60, 90 ] ,
customdFileFormat : '/opt/zapret/init.d/openwrt/custom.d/%s-script.sh',
discord_num : 50,
discord_url : [ 'https://github.com/bol-van/zapret/blob/4e8e3a9ed9dbeb1156db68dfaa7b353051c13797/init.d/custom.d.examples.linux/50-discord',
'https://github.com/bol-van/zapret/blob/b251ea839cc8f04c45090314ef69fce69f2c00f2/init.d/custom.d.examples.linux/50-discord-media',
'https://github.com/bol-van/zapret/blob/b251ea839cc8f04c45090314ef69fce69f2c00f2/init.d/custom.d.examples.linux/50-stun4all',
'https://github.com/bol-van/zapret/tree/master/init.d/custom.d.examples.linux'
],
nfqws_opt_url : 'https://github.com/remittor/zapret-openwrt/discussions/168',
autoHostListFN : '/opt/zapret/ipset/zapret-hosts-auto.txt',
autoHostListDbgFN : '/opt/zapret/ipset/zapret-hosts-auto-debug.log',
load_env: function(dst_obj) {
let env_proto = Object.getPrototypeOf(this);
Object.getOwnPropertyNames(env_proto).forEach(function(key) {
if (key === 'constructor' || key === 'load_env' || key.startsWith('__'))
return;
dst_obj[key] = env_proto[key];
});
dst_obj.packager = { };
if (L.hasSystemFeature('apk')) {
dst_obj.packager.name = 'apk';
dst_obj.packager.path = '/usr/bin/apk';
dst_obj.packager.args = [ 'list', '-I', '*'+this.appName+'*' ];
} else {
dst_obj.packager.name = 'opkg';
dst_obj.packager.path = '/bin/opkg';
dst_obj.packager.args = [ 'list-installed', '*'+this.appName+'*' ];
}
}
});

View File

@@ -1,46 +0,0 @@
{
"admin/services/zapret": {
"title": "Zapret",
"order": 61,
"action": {
"type": "alias",
"path": "admin/services/zapret/service"
},
"depends": {
"acl": [ "luci-app-zapret" ],
"fs": {
"/opt/zapret/sync_config.sh": "executable",
"/opt/zapret/restore-def-cfg.sh": "executable",
"/etc/init.d/zapret": "executable"
},
"uci": { "zapret": true }
}
},
"admin/services/zapret/service": {
"title": "Service",
"order": 10,
"action": {
"type": "view",
"path": "zapret/service"
}
},
"admin/services/zapret/settings": {
"title": "Settings",
"order": 20,
"action": {
"type": "view",
"path": "zapret/settings"
}
},
"admin/services/zapret/dmnlog": {
"title": "Log Viewer",
"order": 30,
"action": {
"type": "view",
"path": "zapret/dmnlog"
}
}
}

View File

@@ -1,40 +0,0 @@
{
"luci-app-zapret": {
"description": "Grant access to zapret procedures",
"read": {
"cgi-io": [ "exec" ],
"file": {
"/opt/zapret/config": [ "read" ],
"/opt/zapret/ipset/*": [ "read" ],
"/opt/zapret/init.d/openwrt/custom.d/*": [ "read" ],
"/etc/crontabs/root": [ "read" ],
"/tmp/zapret*": [ "read" ],
"/etc/init.d/zapret*": [ "exec" ],
"/bin/ps*": [ "exec" ],
"/bin/cat*": [ "exec" ],
"/bin/busybox*": [ "exec" ],
"/bin/opkg*": [ "exec" ],
"/usr/bin/apk*": [ "exec" ],
"/usr/bin/find*": [ "exec" ],
"/opt/zapret/restore-def-cfg.sh*": [ "exec" ],
"/opt/zapret/script-exec.sh*": [ "exec" ],
"/opt/zapret/update-pkg.sh*": [ "exec" ],
"/opt/zapret/sync_config.sh*": [ "exec" ]
},
"uci": [ "zapret", "network" ],
"ubus": {
"luci": [ "getInitList", "setInitAction" ],
"service": [ "list" ]
}
},
"write": {
"file": {
"/opt/zapret/config": [ "write" ],
"/opt/zapret/ipset/*": [ "write" ],
"/opt/zapret/init.d/openwrt/custom.d/*": [ "write" ],
"/etc/crontabs/root": [ "write" ]
},
"uci": [ "zapret" ]
}
}
}

View File

@@ -4,14 +4,14 @@
include $(TOPDIR)/rules.mk include $(TOPDIR)/rules.mk
PKG_NAME:=luci-app-zapret PKG_NAME:=luci-app-zapret2
PKG_VERSION:=72.20260113 PKG_VERSION:=0.8.20260125
PKG_RELEASE:=1 PKG_RELEASE:=1
PKG_LICENSE:=MIT PKG_LICENSE:=MIT
PKG_MAINTAINER:=remittor <https://github.com/remittor> PKG_MAINTAINER:=remittor <https://github.com/remittor>
LUCI_TITLE:=LuCI support for zapret LUCI_TITLE:=LuCI support for zapret2
LUCI_DEPENDS:=+zapret LUCI_DEPENDS:=+zapret2
LUCI_PKGARCH:=all LUCI_PKGARCH:=all
define Package/$(PKG_NAME)/postinst define Package/$(PKG_NAME)/postinst

View File

@@ -0,0 +1,170 @@
'use strict';
'require baseclass';
'require fs';
'require poll';
'require uci';
'require ui';
'require view';
'require view.zapret2.tools as tools';
const btn_style_neutral = 'btn';
const btn_style_action = 'btn cbi-button-action';
const btn_style_positive = 'btn cbi-button-save important';
const btn_style_negative = 'btn cbi-button-reset important';
const btn_style_warning = 'btn cbi-button-negative';
const btn_style_success = 'btn cbi-button-success important';
const fn_dwc_sh = '/opt/'+tools.appName+'/dwc.sh';
return baseclass.extend({
appendLog: function(msg, end = '\n')
{
this.logArea.value += msg + end;
this.logArea.scrollTop = this.logArea.scrollHeight;
},
setBtnMode: function(check1, check2, cancel)
{
this.btn_dpicheck.disabled = check1 ? false : true;
this.btn_sitescheck.disabled = check2 ? false : true;
this.btn_cancel.disabled = cancel ? false : true;
},
dpiCheck: async function()
{
this._action = 'dpiCheck';
this.setBtnMode(0, 0, 0);
this.appendLog('DPI check [tcp 16-20]...');
this.appendLog('Original sources: https://github.com/hyperion-cs/dpi-checkers');
this.appendLog('WEB-version: https://hyperion-cs.github.io/dpi-checkers/ru/tcp-16-20/');
let cmd = [ fn_dwc_sh ];
let resolve_dns = document.getElementById('cfg_resolve_dns');
let dns_ip = resolve_dns.options[resolve_dns.selectedIndex].text;
if (dns_ip && dns_ip != 'default') {
cmd.push(...[ '-d', dns_ip.trim() ]);
}
cmd.push('-R'); // show recommendations
return tools.execAndRead({
cmd: cmd,
log: '/tmp/'+tools.appName+'_dwc.log',
logArea: this.logArea,
callback: this.execAndReadCallback,
cbarg: this, // wnd
});
},
sitesCheck: async function()
{
this._action = 'dpiCheck';
this.setBtnMode(0, 0, 0);
this.appendLog('Sites check...');
let cmd = [ fn_dwc_sh ];
let resolve_dns = document.getElementById('cfg_resolve_dns');
let dns_ip = resolve_dns.options[resolve_dns.selectedIndex].text;
if (dns_ip && dns_ip != 'default') {
cmd.push(...[ '-d', dns_ip.trim() ]);
}
cmd.push('-s'); // mode: check sites
return tools.execAndRead({
cmd: cmd,
log: '/tmp/'+tools.appName+'_dwc.log',
logArea: this.logArea,
callback: this.execAndReadCallback,
cbarg: this, // wnd
});
},
execAndReadCallback: function(wnd, rc, txt = '')
{
wnd.setBtnMode(1, 1, 1);
if (rc == 0 && txt) {
wnd.appendLog('=========================================================');
return;
}
if (rc >= 500) {
if (txt) {
wnd.appendLog(txt.startsWith('ERROR') ? txt : 'ERROR: ' + txt);
} else {
wnd.appendLog('ERROR: ' + wnd._action + ': Terminated with error code = ' + rc);
}
} else {
wnd.appendLog('ERROR: Process finished with retcode = ' + rc);
}
wnd.appendLog('=========================================================');
},
openDiagnostDialog: function(pkg_arch)
{
this.pkg_arch = pkg_arch;
let DNS_LIST = [
'8.8.8.8', // Google
'8.8.4.4', // Google
'1.1.1.1', // Cloudflare
'1.0.0.1', // Cloudflare
'9.9.9.9', // Quad9
'149.112.112.112', // Quad9
'208.67.222.222', // OpenDNS
'208.67.220.220', // OpenDNS
'8.26.56.26', // Comodo
'8.20.247.20', // Comodo
'64.6.64.6', // Verisign
'64.6.65.6', // Verisign
];
let dns_list = [ ];
dns_list.push( E('option', { value: 'dns_default' }, [ 'default' ] ) );
for (let id = 0; id < DNS_LIST.length; id++) {
let dns_ipaddr = '' + DNS_LIST[id];
let val = 'dns_' + dns_ipaddr.replace(/\./g, "_");
dns_list.push( E('option', { value: val }, [ dns_ipaddr ] ));
}
let resolve_dns = E('label', [
_('Resolve IP-Addr via') + ': ',
E('select', { id: 'cfg_resolve_dns' }, dns_list)
]);
this.logArea = E('textarea', {
'id': 'widget.modal_content',
'readonly': true,
'style': 'width:100% !important; font-family: monospace;',
'rows': 26,
'wrap': 'off',
});
this.btn_cancel = E('button', {
'id': 'btn_cancel',
'name': 'btn_cancel',
'class': btn_style_warning,
}, _('Cancel'));
this.btn_cancel.onclick = ui.hideModal;
this.btn_dpicheck = E('button', {
'id': 'btn_dpicheck',
'name': 'btn_dpicheck',
'class': btn_style_action,
}, _('DPI check'));
this.btn_dpicheck.onclick = ui.createHandlerFn(this, this.dpiCheck);
this.btn_sitescheck = E('button', {
'id': 'btn_sitescheck',
'name': 'btn_sitescheck',
'class': btn_style_action,
}, _('Sites check'));
this.btn_sitescheck.onclick = ui.createHandlerFn(this, this.sitesCheck);
ui.showModal(_('Diagnostics'), [
E('div', { 'class': 'cbi-section' }, [
resolve_dns,
E('br'), E('br'),
this.logArea,
]),
E('div', { 'class': 'right' }, [
this.btn_sitescheck,
' ',
this.btn_dpicheck,
' ',
this.btn_cancel,
])
]);
}
});

View File

@@ -5,7 +5,7 @@
'require poll'; 'require poll';
'require uci'; 'require uci';
'require ui'; 'require ui';
'require view.zapret.tools as tools'; 'require view.zapret2.tools as tools';
return view.extend({ return view.extend({
retrieveLog: async function() { retrieveLog: async function() {

View File

@@ -0,0 +1,52 @@
'use strict';
'require baseclass';
return baseclass.extend({
packager : { },
appName : 'zapret2',
AppName : 'Zapret2',
execPath : '/etc/init.d/zapret2',
appDir : '/opt/zapret2',
syncCfgPath : '/opt/zapret2/sync_config.sh',
defCfgPath : '/opt/zapret2/def-cfg.sh',
defaultCfgPath : '/opt/zapret2/restore-def-cfg.sh',
hostsGoogleFN : '/opt/zapret2/ipset/zapret-hosts-google.txt',
hostsUserFN : '/opt/zapret2/ipset/zapret-hosts-user.txt',
hostsUserExcludeFN: '/opt/zapret2/ipset/zapret-hosts-user-exclude.txt',
iplstExcludeFN : '/opt/zapret2/ipset/zapret-ip-exclude.txt',
iplstUserFN : '/opt/zapret2/ipset/zapret-ip-user.txt',
iplstUserExcludeFN: '/opt/zapret2/ipset/zapret-ip-user-exclude.txt',
custFileMax : 4,
custFileTemplate : '/opt/zapret2/ipset/cust%s.txt',
customdPrefixList : [ 10, 20, 50, 60, 90 ] ,
customdFileFormat : '/opt/zapret2/init.d/openwrt/custom.d/%s-script.sh',
discord_num : 50,
discord_url : [ 'https://github.com/bol-van/zapret2/blob/master/init.d/custom.d.examples.linux/50-discord-media',
'https://github.com/bol-van/zapret2/blob/master/init.d/custom.d.examples.linux/50-stun4all',
'https://github.com/bol-van/zapret2/tree/master/init.d/custom.d.examples.linux'
],
nfqws_opt_url : 'https://github.com/remittor/zapret-openwrt/discussions/',
autoHostListFN : '/opt/zapret2/ipset/zapret-hosts-auto.txt',
autoHostListDbgFN : '/opt/zapret2/ipset/zapret-hosts-auto-debug.log',
load_env: function(dst_obj) {
let env_proto = Object.getPrototypeOf(this);
Object.getOwnPropertyNames(env_proto).forEach(function(key) {
if (key === 'constructor' || key === 'load_env' || key.startsWith('__'))
return;
dst_obj[key] = env_proto[key];
});
dst_obj.packager = { };
if (L.hasSystemFeature('apk')) {
dst_obj.packager.name = 'apk';
dst_obj.packager.path = '/usr/bin/apk';
dst_obj.packager.args = [ 'list', '-I', '*'+this.appName+'*' ];
} else {
dst_obj.packager.name = 'opkg';
dst_obj.packager.path = '/bin/opkg';
dst_obj.packager.args = [ 'list-installed', '*'+this.appName+'*' ];
}
}
});

View File

@@ -4,9 +4,9 @@
'require uci'; 'require uci';
'require ui'; 'require ui';
'require view'; 'require view';
'require view.zapret.tools as tools'; 'require view.zapret2.tools as tools';
'require view.zapret.diagnost as diagnost'; 'require view.zapret2.diagnost as diagnost';
'require view.zapret.updater as updater'; 'require view.zapret2.updater as updater';
const btn_style_neutral = 'btn'; const btn_style_neutral = 'btn';
const btn_style_action = 'btn cbi-button-action'; const btn_style_action = 'btn cbi-button-action';
@@ -18,14 +18,14 @@ const btn_style_success = 'btn cbi-button-success important';
return view.extend({ return view.extend({
get_svc_buttons: function(elems = { }) { get_svc_buttons: function(elems = { }) {
return { return {
enable : elems.btn_enable || document.getElementById('btn_enable'), "enable" : elems.btn_enable || document.getElementById('btn_enable'),
disable : elems.btn_disable || document.getElementById('btn_disable'), "disable" : elems.btn_disable || document.getElementById('btn_disable'),
start : elems.btn_start || document.getElementById('btn_start'), "start" : elems.btn_start || document.getElementById('btn_start'),
restart : elems.btn_restart || document.getElementById('btn_restart'), "restart" : elems.btn_restart || document.getElementById('btn_restart'),
stop : elems.btn_stop || document.getElementById('btn_stop'), "stop" : elems.btn_stop || document.getElementById('btn_stop'),
reset : elems.btn_reset || document.getElementById('btn_reset'), "reset" : elems.btn_reset || document.getElementById('btn_reset'),
diag : elems.btn_diag || document.getElementById('btn_diag'), "diag" : elems.btn_diag || document.getElementById('btn_diag'),
update : elems.btn_update || document.getElementById('btn_update'), "update" : elems.btn_update || document.getElementById('btn_update'),
}; };
}, },
@@ -50,7 +50,7 @@ return view.extend({
fs.exec(tools.execPath, [ 'enabled' ]), // svc_en fs.exec(tools.execPath, [ 'enabled' ]), // svc_en
tools.getSvcInfo(), // svc_info tools.getSvcInfo(), // svc_info
fs.exec('/bin/busybox', [ 'ps' ]), // process list fs.exec('/bin/busybox', [ 'ps' ]), // process list
fs.exec(tools.packager.path, tools.packager.args), // installed packages tools.getPackageDict(), // installed packages
tools.getStratList(), // nfqws strategy list tools.getStratList(), // nfqws strategy list
fs.exec('/bin/cat', [ '/etc/openwrt_release' ]), // CPU arch fs.exec('/bin/cat', [ '/etc/openwrt_release' ]), // CPU arch
uci.load(tools.appName), // config uci.load(tools.appName), // config
@@ -75,7 +75,7 @@ return view.extend({
let svc_en = status_array[1]; // stdout: empty or error text let svc_en = status_array[1]; // stdout: empty or error text
let svc_info = status_array[2]; // stdout: JSON as text let svc_info = status_array[2]; // stdout: JSON as text
let proc_list = status_array[3]; // stdout: multiline text let proc_list = status_array[3]; // stdout: multiline text
let pkg_list = status_array[4]; // stdout: installed packages let pkg_dict = status_array[4]; // stdout: installed packages
let stratlist = status_array[5]; // array of strat names let stratlist = status_array[5]; // array of strat names
let sys_info = status_array[6]; // stdout: openwrt distrib info let sys_info = status_array[6]; // stdout: openwrt distrib info
@@ -95,8 +95,8 @@ return view.extend({
this.disableButtons(true, -1, elems); this.disableButtons(true, -1, elems);
return; return;
} }
if (pkg_list.code != 0) { if (!pkg_dict) {
ui.addNotification(null, E('p', _('Unable to enumerate installed packages') + ': setAppStatus()')); ui.addNotification(null, E('p', _('Unable to enumerate installed packages') + ': getPackageDict()'));
this.disableButtons(true, -1, elems); this.disableButtons(true, -1, elems);
return; return;
} }
@@ -135,89 +135,51 @@ return view.extend({
} }
}, },
serviceAction: function(action, button) { serviceActionEx: async function(action, button, args = [ ], hide_modal = false, btn_dis = true)
if (button) { {
let elem = document.getElementById(button); let btn = document.getElementById(button);
this.disableButtons(true, elem); this.disableButtons(true, btn);
}
poll.stop(); poll.stop();
let errmsg = null;
let _this = this; try {
let exec_cmd = null;
return tools.handleServiceAction(tools.appName, action) let exec_arg = [ ];
.then(() => { if (action == 'start' || action == 'restart') {
return _this.getAppStatus().then( if (tools.checkUnsavedChanges()) {
(status_array) => { ui.changes.apply(true);
_this.setAppStatus(status_array); await new Promise(resolve => setTimeout(resolve, 100));
}
exec_cmd = tools.syncCfgPath;
errmsg = _('Unable to run sync_config.sh script.');
}
if (action == 'reset') {
exec_cmd = tools.defaultCfgPath;
exec_arg = args; // (reset_ipset)(sync) ==> restore all configs + sync config
errmsg = _('Unable to run restore-def-cfg.sh script.');
action = null;
}
if (exec_cmd) {
let res = await fs.exec(exec_cmd, exec_arg);
if (res.code != 0) {
throw Error('res.code = ' + res.code);
} }
);
})
.catch(e => {
ui.addNotification(null, E('p', _('Unable to run service action.') + ' Error: ' + e.message));
});
},
serviceActionEx: function(action, button, args = [ ], hide_modal = false) {
if (button) {
let elem = document.getElementById(button);
this.disableButtons(true, elem);
}
poll.stop();
let _this = this;
let exec_cmd = null;
let exec_arg = [ ];
let errmsg = 'ERROR:';
if (action == 'start' || action == 'restart') {
exec_cmd = tools.syncCfgPath;
errmsg = _('Unable to run sync_config.sh script.');
}
else if (action == 'reset') {
exec_cmd = tools.defaultCfgPath;
exec_arg = args; // (reset_ipset)(sync) ==> restore all configs + sync config
errmsg = _('Unable to run restore-def-cfg.sh script.');
action = null;
} else {
ui.addNotification(null, E('p', 'ERROR: unknown action'));
return null;
}
return fs.exec(exec_cmd, exec_arg)
.then(function(res) {
if (res.code != 0) {
ui.addNotification(null, E('p', errmsg + ' res.code = ' + res.code));
action = null; // return with error
} }
if (hide_modal) { if (hide_modal) {
ui.hideModal(); ui.hideModal();
} }
if (!action) { errmsg = null;
return _this.getAppStatus().then( await tools.handleServiceAction(tools.appName, action);
(status_array) => { } catch(e) {
_this.setAppStatus(status_array); let msg = errmsg ? errmsg : _('Unable to run service action') + ' "' + action + '".';
} ui.addNotification(null, E('p', msg + ' Error: ' + e.message));
); } finally {
if (!poll.active()) {
poll.start();
}
if (btn && btn_dis) {
setTimeout(() => { btn.disabled = true; }, 0);
} }
return _this.serviceAction(action, null);
})
.catch(e => {
ui.addNotification(null, E('p', errmsg + ' Error: ' + e.message));
});
},
appAction: function(action, button) {
if (button) {
let elem = document.getElementById(button);
this.disableButtons(true, elem);
} }
poll.stop();
return fs.exec_direct(tools.execPath, [ action ]).then(res => {
return this.getAppStatus().then(
(status_array) => {
this.setAppStatus(status_array);
ui.hideModal();
}
);
});
}, },
statusPoll: function() { statusPoll: function() {
@@ -226,7 +188,12 @@ return view.extend({
); );
}, },
dialogResetCfg: function(ev) { dialogResetCfg: function(ev)
{
if (tools.checkUnsavedChanges()) {
ui.addNotification(null, E('p', _('You have unapplied changes')));
return;
}
ev.target.blur(); ev.target.blur();
let reset_base = E('label', [ let reset_base = E('label', [
@@ -244,8 +211,18 @@ return view.extend({
' ', _('Set AutoHostList mode') ' ', _('Set AutoHostList mode')
]); ]);
let erase_autohostlist = E('label', [
E('input', { type: 'checkbox', id: 'cfg_erase_autohostlist' }),
' ', _('Erase AutoHostList (ipset)')
]);
let enable_custom_d = E('label', [
E('input', { type: 'checkbox', id: 'cfg_enable_custom_d' }),
' ', _('Enable use custom.d scripts')
]);
let strat_list = [ ]; let strat_list = [ ];
strat_list.push( E('option', { value: 'strat__skip__' }, [ '-' ] ) ); strat_list.push( E('option', { value: 'strat__skip__' }, [ 'not change' ] ) );
for (let id = 0; id < this.nfqws_strat_list.length; id++) { for (let id = 0; id < this.nfqws_strat_list.length; id++) {
let strat = '' + this.nfqws_strat_list[id]; let strat = '' + this.nfqws_strat_list[id];
strat_list.push( E('option', { value: 'strat_' + id }, [ strat ] ) ); strat_list.push( E('option', { value: 'strat_' + id }, [ strat ] ) );
@@ -264,7 +241,7 @@ return view.extend({
let resetcfg_btn = E('button', { let resetcfg_btn = E('button', {
'class': btn_style_action, 'class': btn_style_action,
}, _('Reset settings')); }, _('Reset settings'));
resetcfg_btn.onclick = ui.createHandlerFn(this, () => { resetcfg_btn.onclick = ui.createHandlerFn(this, async () => {
//cancel_button.disabled = true; //cancel_button.disabled = true;
let opt_flags = ''; let opt_flags = '';
if (document.getElementById('cfg_reset_base').checked == false) { if (document.getElementById('cfg_reset_base').checked == false) {
@@ -276,10 +253,19 @@ return view.extend({
if (document.getElementById('cfg_autohostlist').checked) { if (document.getElementById('cfg_autohostlist').checked) {
opt_flags += '(set_mode_autohostlist)'; opt_flags += '(set_mode_autohostlist)';
}; };
if (document.getElementById('cfg_erase_autohostlist').checked) {
opt_flags += '(erase_autohostlist)';
};
if (document.getElementById('cfg_enable_custom_d').checked) {
opt_flags += '(enable_custom_d)';
};
//console.log('RESET: opt_flags = ' + opt_flags); //console.log('RESET: opt_flags = ' + opt_flags);
let sel_strat = document.getElementById('cfg_nfqws_strat'); let sel_strat = document.getElementById('cfg_nfqws_strat');
let opt_strat = sel_strat.options[sel_strat.selectedIndex].text; let opt_strat = sel_strat.options[sel_strat.selectedIndex].text;
//console.log('RESET: strat = ' + opt_strat); //console.log('RESET: strat = ' + opt_strat);
if (opt_strat == 'not change') {
opt_strat = '-';
}
opt_flags += '(sync)'; opt_flags += '(sync)';
let args = [ opt_flags, opt_strat ]; let args = [ opt_flags, opt_strat ];
return this.serviceActionEx('reset', resetcfg_btn, args, true); return this.serviceActionEx('reset', resetcfg_btn, args, true);
@@ -293,6 +279,10 @@ return view.extend({
E('br'), E('br'), E('br'), E('br'),
set_autohostlist, set_autohostlist,
E('br'), E('br'), E('br'), E('br'),
erase_autohostlist,
E('br'), E('br'),
enable_custom_d,
E('br'), E('br'),
nfqws_strat, nfqws_strat,
E('br'), E('br') E('br'), E('br')
]), ]),
@@ -319,9 +309,9 @@ return view.extend({
} }
let cfg = uci.get(tools.appName, 'config'); let cfg = uci.get(tools.appName, 'config');
let pkg_list = status_array[4]; let pkgdict = status_array[4];
if (pkg_list === undefined || typeof(pkg_list) !== 'object' || pkg_list.code != 0) { if (pkgdict == null) {
ui.addNotification(null, E('p', _('Unable to enumerate installed packages') + ': setAppStatus()')); ui.addNotification(null, E('p', _('Unable to enumerate installed packages') + ': render()'));
return; return;
} }
@@ -367,9 +357,9 @@ return view.extend({
}; };
let btn_enable = create_btn('btn_enable', btn_style_success, _('Enable')); let btn_enable = create_btn('btn_enable', btn_style_success, _('Enable'));
btn_enable.onclick = ui.createHandlerFn(this, this.serviceAction, 'enable', 'btn_enable'); btn_enable.onclick = ui.createHandlerFn(this, this.serviceActionEx, 'enable', 'btn_enable');
let btn_disable = create_btn('btn_disable', btn_style_warning, _('Disable')); let btn_disable = create_btn('btn_disable', btn_style_warning, _('Disable'));
btn_disable.onclick = ui.createHandlerFn(this, this.serviceAction, 'disable', 'btn_disable'); btn_disable.onclick = ui.createHandlerFn(this, this.serviceActionEx, 'disable', 'btn_disable');
layout_append(_('Service autorun control'), null, [ btn_enable, btn_disable ] ); layout_append(_('Service autorun control'), null, [ btn_enable, btn_disable ] );
let btn_start = create_btn('btn_start', btn_style_action, _('Start')); let btn_start = create_btn('btn_start', btn_style_action, _('Start'));
@@ -377,7 +367,7 @@ return view.extend({
let btn_restart = create_btn('btn_restart', btn_style_action, _('Restart')); let btn_restart = create_btn('btn_restart', btn_style_action, _('Restart'));
btn_restart.onclick = ui.createHandlerFn(this, this.serviceActionEx, 'restart', 'btn_restart'); btn_restart.onclick = ui.createHandlerFn(this, this.serviceActionEx, 'restart', 'btn_restart');
let btn_stop = create_btn('btn_stop', btn_style_warning, _('Stop')); let btn_stop = create_btn('btn_stop', btn_style_warning, _('Stop'));
btn_stop.onclick = ui.createHandlerFn(this, this.serviceAction, 'stop', 'btn_stop'); btn_stop.onclick = ui.createHandlerFn(this, this.serviceActionEx, 'stop', 'btn_stop');
layout_append(_('Service daemons control'), null, [ btn_start, btn_restart, btn_stop ] ); layout_append(_('Service daemons control'), null, [ btn_start, btn_restart, btn_stop ] );
let btn_reset = create_btn('btn_reset', btn_style_action, _('Reset settings')); let btn_reset = create_btn('btn_reset', btn_style_action, _('Reset settings'));
@@ -405,15 +395,15 @@ return view.extend({
}; };
this.setAppStatus(status_array, elems); this.setAppStatus(status_array, elems);
poll.add(L.bind(this.statusPoll, this)); poll.add(L.bind(this.statusPoll, this), 2); // interval 2 sec
let page_title = tools.AppName; let page_title = tools.AppName;
let pkgdict = tools.decode_pkg_list(pkg_list.stdout, false);
page_title += ' &nbsp '; page_title += ' &nbsp ';
if (pkgdict[tools.appName] === undefined || pkgdict[tools.appName] == '') { if (pkgdict[tools.appName] === undefined || pkgdict[tools.appName] == '') {
page_title += 'unknown version'; page_title += 'unknown version';
} else { } else {
page_title += 'v' + pkgdict[tools.appName]; page_title += 'v' + pkgdict[tools.appName];
page_title = page_title.replace(/-r1$/, '');
} }
let aux1 = E('em'); let aux1 = E('em');
let aux2 = E('em'); let aux2 = E('em');

View File

@@ -5,7 +5,12 @@
'require uci'; 'require uci';
'require ui'; 'require ui';
'require view'; 'require view';
'require view.zapret.tools as tools'; 'require view.zapret2.tools as tools';
document.head.appendChild(E('link', {
rel: 'stylesheet',
href: L.resource('view/zapret2/styles.css')
}));
return view.extend({ return view.extend({
parsers: { }, parsers: { },
@@ -128,8 +133,10 @@ return view.extend({
let btn = sec.taboption(tabname, form.Button, '_' + param + '_btn', locname); let btn = sec.taboption(tabname, form.Button, '_' + param + '_btn', locname);
btn.inputtitle = _('Edit'); btn.inputtitle = _('Edit');
btn.inputstyle = 'edit btn'; btn.inputstyle = 'edit btn';
let val = sec.taboption(tabname, form.DummyValue, '_' + param); let val = sec.taboption(tabname, form.TextValue, '_' + param);
val.rawhtml = multiline ? true : false; val.readonly = true;
val.rows = rows + 5;
val.wrap = false;
val.cfgvalue = function(section_id) { val.cfgvalue = function(section_id) {
let value = uci.get(tools.appName, section_id, param); let value = uci.get(tools.appName, section_id, param);
if (value == null) { if (value == null) {
@@ -141,21 +148,23 @@ return view.extend({
value = value.replace(/\n --/g, "\n--"); value = value.replace(/\n --/g, "\n--");
value = value.replace(/ --/g, "\n--"); value = value.replace(/ --/g, "\n--");
} }
if (val.rawhtml) {
value = value.replace(/</g, '˂');
value = value.replace(/>/g, '˃');
value = value.replace(/\n/g, '<br/>');
}
return value; return value;
}; };
val.validate = function(section_id, value) { val.validate = function(section_id, value) {
return (value) ? value.trim() : ""; return true;
}; };
let desc = locname; let desc = locname;
if (multiline == 2) { if (multiline == 2) {
desc += '<br/>' + _('Example') + ': <a target=_blank href=%s>%s</a>'.format(tools.nfqws_opt_url); desc += '<br/>' + _('Example') + ': <a target=_blank href=%s>%s</a>'.format(tools.nfqws_opt_url);
} }
btn.onclick = () => new tools.longstrEditDialog('config', param, param, desc, rows, multiline).show(); btn.onclick = () => new tools.longstrEditDialog({
cfgsec: 'config',
cfgparam: param,
title: param,
desc: desc,
rows: rows,
multiline: multiline,
}).show();
}; };
if (tools.appName == 'zapret2') { if (tools.appName == 'zapret2') {
@@ -279,6 +288,10 @@ return view.extend({
o = s.taboption(tabname, form.Value, 'AUTOHOSTLIST_RETRANS_MAXSEQ', _('RETRANS_MAXSEQ')); o = s.taboption(tabname, form.Value, 'AUTOHOSTLIST_RETRANS_MAXSEQ', _('RETRANS_MAXSEQ'));
o.rmempty = false; o.rmempty = false;
o.datatype = 'uinteger'; o.datatype = 'uinteger';
o = s.taboption(tabname, form.Value, 'AUTOHOSTLIST_RETRANS_RESET', _('RETRANS_RESET'));
o.rmempty = false;
o.datatype = 'uinteger';
} }
o = s.taboption(tabname, form.Value, 'AUTOHOSTLIST_RETRANS_THRESHOLD', _('RETRANS_THRESHOLD')); o = s.taboption(tabname, form.Value, 'AUTOHOSTLIST_RETRANS_THRESHOLD', _('RETRANS_THRESHOLD'));
@@ -307,13 +320,12 @@ return view.extend({
o.inputtitle = _('Edit'); o.inputtitle = _('Edit');
o.inputstyle = 'edit btn'; o.inputstyle = 'edit btn';
o.description = tools.autoHostListFN; o.description = tools.autoHostListFN;
o.onclick = () => new tools.fileEditDialog( o.onclick = () => new tools.fileEditDialog({
tools.autoHostListFN, file: tools.autoHostListFN,
_('Auto host list'), title: _('Auto host list'),
'', desc: '',
'', rows: 15,
15 }).show();
).show();
o = s.taboption(tabname, form.Flag, 'AUTOHOSTLIST_DEBUGLOG', _('DEBUGLOG')); o = s.taboption(tabname, form.Flag, 'AUTOHOSTLIST_DEBUGLOG', _('DEBUGLOG'));
o.rmempty = false; o.rmempty = false;
@@ -323,13 +335,12 @@ return view.extend({
o.inputtitle = _('Edit'); o.inputtitle = _('Edit');
o.inputstyle = 'edit btn'; o.inputstyle = 'edit btn';
o.description = tools.autoHostListDbgFN; o.description = tools.autoHostListDbgFN;
o.onclick = () => new tools.fileEditDialog( o.onclick = () => new tools.fileEditDialog({
tools.autoHostListDbgFN, file: tools.autoHostListDbgFN,
_('Auto host debug list'), title: _('Auto host debug list'),
'', desc: '',
'', rows: 15,
15 }).show();
).show();
/* HostList settings */ /* HostList settings */
@@ -340,37 +351,37 @@ return view.extend({
o.inputtitle = _('Edit'); o.inputtitle = _('Edit');
o.inputstyle = 'edit btn'; o.inputstyle = 'edit btn';
o.description = tools.hostsGoogleFN; o.description = tools.hostsGoogleFN;
o.onclick = () => new tools.fileEditDialog( o.onclick = () => new tools.fileEditDialog({
tools.hostsGoogleFN, file: tools.hostsGoogleFN,
_('Google hostname entries'), title: _('Google hostname entries'),
_('One hostname per line.<br />Examples:'), desc: _('One hostname per line.<br />Examples:'),
'<code>youtube.com<br />googlevideo.com</code>', aux: '<code>youtube.com<br />googlevideo.com</code>',
15 rows: 15,
).show(); }).show();
o = s.taboption(tabname, form.Button, '_user_entries_btn', _('User hostname entries <HOSTLIST>')); o = s.taboption(tabname, form.Button, '_user_entries_btn', _('User hostname entries <HOSTLIST>'));
o.inputtitle = _('Edit'); o.inputtitle = _('Edit');
o.inputstyle = 'edit btn'; o.inputstyle = 'edit btn';
o.description = tools.hostsUserFN; o.description = tools.hostsUserFN;
o.onclick = () => new tools.fileEditDialog( o.onclick = () => new tools.fileEditDialog({
tools.hostsUserFN, file: tools.hostsUserFN,
_('User entries'), title: _('User entries'),
_('One hostname per line.<br />Examples:'), desc: _('One hostname per line.<br />Examples:'),
'<code>domain.net<br />sub.domain.com<br />facebook.com</code>', aux: '<code>domain.net<br />sub.domain.com<br />facebook.com</code>',
15 rows: 15,
).show(); }).show();
o = s.taboption(tabname, form.Button, '_user_excluded_entries_btn', _('User excluded hostname entries')); o = s.taboption(tabname, form.Button, '_user_excluded_entries_btn', _('User excluded hostname entries'));
o.inputtitle = _('Edit'); o.inputtitle = _('Edit');
o.inputstyle = 'edit btn'; o.inputstyle = 'edit btn';
o.description = tools.hostsUserExcludeFN; o.description = tools.hostsUserExcludeFN;
o.onclick = () => new tools.fileEditDialog( o.onclick = () => new tools.fileEditDialog({
tools.hostsUserExcludeFN, file: tools.hostsUserExcludeFN,
_('User excluded entries'), title: _('User excluded entries'),
_('One hostname per line.<br />Examples:'), desc: _('One hostname per line.<br />Examples:'),
'<code>domain.net<br />sub.domain.com<br />gosuslugi.ru</code>', aux: '<code>domain.net<br />sub.domain.com<br />gosuslugi.ru</code>',
15 rows: 15,
).show(); }).show();
add_delim(s); add_delim(s);
@@ -378,37 +389,37 @@ return view.extend({
o.inputtitle = _('Edit'); o.inputtitle = _('Edit');
o.inputstyle = 'edit btn'; o.inputstyle = 'edit btn';
o.description = tools.iplstExcludeFN; o.description = tools.iplstExcludeFN;
o.onclick = () => new tools.fileEditDialog( o.onclick = () => new tools.fileEditDialog({
tools.iplstExcludeFN, file: tools.iplstExcludeFN,
_('Excluded IP filter'), title: _('Excluded IP filter'),
_('Patterns can be strings or regular expressions. Each pattern in a separate line<br />Examples:'), desc: _('Patterns can be strings or regular expressions. Each pattern in a separate line<br />Examples:'),
'<code>128.199.0.0/16<br />34.217.90.52<br />162.13.190.77</code>', aux: '<code>128.199.0.0/16<br />34.217.90.52<br />162.13.190.77</code>',
15 rows: 15,
).show(); }).show();
o = s.taboption(tabname, form.Button, '_user_ip_filter_btn', _('User IP entries')); o = s.taboption(tabname, form.Button, '_user_ip_filter_btn', _('User IP entries'));
o.inputtitle = _('Edit'); o.inputtitle = _('Edit');
o.inputstyle = 'edit btn'; o.inputstyle = 'edit btn';
o.description = tools.iplstUserFN; o.description = tools.iplstUserFN;
o.onclick = () => new tools.fileEditDialog( o.onclick = () => new tools.fileEditDialog({
tools.iplstUserFN, file: tools.iplstUserFN,
_('User IP filter'), title: _('User IP filter'),
_('Patterns can be strings or regular expressions. Each pattern in a separate line<br />Examples:'), desc: _('Patterns can be strings or regular expressions. Each pattern in a separate line<br />Examples:'),
'<code>128.199.0.0/16<br />34.217.90.52<br />162.13.190.77</code>', aux: '<code>128.199.0.0/16<br />34.217.90.52<br />162.13.190.77</code>',
15 rows: 15,
).show(); }).show();
o = s.taboption(tabname, form.Button, '_user_excluded_ip_filter_btn', _('User excluded IP entries')); o = s.taboption(tabname, form.Button, '_user_excluded_ip_filter_btn', _('User excluded IP entries'));
o.inputtitle = _('Edit'); o.inputtitle = _('Edit');
o.inputstyle = 'edit btn'; o.inputstyle = 'edit btn';
o.description = tools.iplstUserExcludeFN; o.description = tools.iplstUserExcludeFN;
o.onclick = () => new tools.fileEditDialog( o.onclick = () => new tools.fileEditDialog({
tools.iplstUserExcludeFN, file: tools.iplstUserExcludeFN,
_('User excluded IP filter'), title: _('User excluded IP filter'),
_('Patterns can be strings or regular expressions. Each pattern in a separate line<br />Examples:'), desc: _('Patterns can be strings or regular expressions. Each pattern in a separate line<br />Examples:'),
'<code>128.199.0.0/16<br />34.217.90.52<br />162.13.190.77</code>', aux: '<code>128.199.0.0/16<br />34.217.90.52<br />162.13.190.77</code>',
15 rows: 15,
).show(); }).show();
add_delim(s); add_delim(s);
@@ -419,7 +430,7 @@ return view.extend({
o.inputtitle = _('Edit'); o.inputtitle = _('Edit');
o.inputstyle = 'edit btn'; o.inputstyle = 'edit btn';
o.description = fn; o.description = fn;
o.onclick = () => new tools.fileEditDialog(fn, name, '', '', 15).show(); o.onclick = () => new tools.fileEditDialog({ file: fn, title: name, rows: 15}).show();
} }
/* custom.d files */ /* custom.d files */
@@ -461,7 +472,7 @@ return view.extend({
desc += '<a target=_blank href=' + url + '>' + filename + '</a>'; desc += '<a target=_blank href=' + url + '>' + filename + '</a>';
} }
} }
o.onclick = () => new tools.fileEditDialog(fn, name, desc, '', 15).show(); o.onclick = () => new tools.fileEditDialog({ file: fn, title: name, desc: desc, rows: 15}).show();
} }
let map_promise = m.render(); let map_promise = m.render();

View File

@@ -0,0 +1,6 @@
textarea, .cbi-value textarea
{
white-space: pre;
overflow-x: auto;
font-family: monospace;
}

View File

@@ -4,7 +4,7 @@
'require rpc'; 'require rpc';
'require ui'; 'require ui';
'require uci'; 'require uci';
'require view.zapret.env as env_tools'; 'require view.zapret2.env as env_tools';
document.head.append(E('style', {'type': 'text/css'}, document.head.append(E('style', {'type': 'text/css'},
` `
@@ -101,6 +101,30 @@ return baseclass.extend({
}); });
}, },
getPackageDict: function()
{
let ses_var_name = this.appName+'_pkgdict';
let exec_cmd = this.packager.path;
let exec_arg = this.packager.args;
return fs.exec(exec_cmd, exec_arg).then(res => {
let pdict_json = sessionStorage.getItem(ses_var_name);
if (res.code != 0) {
console.log(this.appName + ': Unable to enumerate installed packages. code = ' + res.code);
if (pdict_json != null) {
return JSON.parse(pdict_json); // return cached value
}
return null;
}
let pdict = this.decode_pkg_list(res.stdout);
if (pdict != pdict_json) {
sessionStorage.setItem(ses_var_name, JSON.stringify(pdict)); // renew cache
}
return pdict;
}).catch(e => {
ui.addNotification(null, E('p', _('Unable to enumerate installed packages.') + ' Error: %s'.format(e)));
});
},
getStratList: function() { getStratList: function() {
let exec_cmd = '/bin/busybox'; let exec_cmd = '/bin/busybox';
let exec_arg = [ 'awk', '-F', '"', '/if \\[ "\\$strat" = "/ {print $4}', this.defCfgPath ]; let exec_arg = [ 'awk', '-F', '"', '/if \\[ "\\$strat" = "/ {print $4}', this.defCfgPath ];
@@ -124,6 +148,13 @@ return baseclass.extend({
ui.addNotification(null, E('p', _('Service action failed "%s %s": %s').format(name, action, e))); ui.addNotification(null, E('p', _('Service action failed "%s %s": %s').format(name, action, e)));
}); });
}, },
checkUnsavedChanges: function()
{
if (!ui.changes) return false;
if (!ui.changes.changes) return false;
return ui.changes.changes[this.appName] ? true : false;
},
normalizeValue: function(v) { normalizeValue: function(v) {
return (v && typeof(v) === 'string') ? v.trim().replace(/\r?\n/g, '') : v; return (v && typeof(v) === 'string') ? v.trim().replace(/\r?\n/g, '') : v;
@@ -141,7 +172,7 @@ return baseclass.extend({
return m ? m[2] : defval; return m ? m[2] : defval;
}, },
decode_pkg_list: function(pkg_list, with_suffix_r1 = true) { decode_pkg_list: function(pkg_list) {
let pkg_dict = { }; let pkg_dict = { };
if (!pkg_list) { if (!pkg_list) {
return pkg_dict; return pkg_dict;
@@ -180,11 +211,7 @@ return baseclass.extend({
} }
} }
if (rev >= 0) { if (rev >= 0) {
if (rev == 1 && !with_suffix_r1) { ver += '-r' + rev;
// nothing
} else {
ver += '-r' + rev;
}
} }
pkg_dict[name] = ver; pkg_dict[name] = ver;
} }
@@ -320,14 +347,18 @@ return baseclass.extend({
}, },
fileEditDialog: baseclass.extend({ fileEditDialog: baseclass.extend({
__init__: function(file, title, desc, aux = null, rows = 10, callback, file_exists = false) { __init__: function(opts = {})
this.file = file; {
this.title = title; Object.assign(this, {
this.desc = desc; file: '',
this.aux = aux; title: '',
this.rows = rows, desc: '',
this.callback = callback; aux: '',
this.file_exists = file_exists; rows: 10,
callback: null,
file_exists: false,
setperm: 644,
}, opts);
}, },
load: function() { load: function() {
@@ -370,11 +401,52 @@ return baseclass.extend({
]); ]);
}, },
handleSaveAdv: function(ev) { writeAdv: async function(fileName, data, chunkSize = 8000)
let txt = document.getElementById('widget.modal_content'); {
let value = txt.value.trim().replace(/\r\n/g, '\n') + '\n'; let tmpFile = fileName + '.tmp';
try {
for (let wsize = 0; wsize <= data.length; wsize += chunkSize) {
let chunk = data.slice(wsize, wsize + chunkSize);
if (wsize > 0 && chunk.length == 0) {
break; // EOF
}
chunk = chunk.replace(/'/g, `'\"'\"'`);
let teeArg = (wsize === 0) ? '' : '-a';
let cmd = `printf %s '${chunk}' | tee ${teeArg} '${tmpFile}'`;
let res = await fs.exec('/bin/busybox', [ 'sh', '-c', cmd ]);
if (res.code !== 0) {
throw new Error('tee failed, rc = ' + res.code);
}
}
if (this.setperm) {
let res = await fs.exec('/bin/busybox', [ 'chmod', '' + this.setperm, tmpFile ]);
if (res.code != 0) {
throw new Error('chmod failed, rc = ' + res.code);
}
}
let res = await fs.exec('/bin/busybox', [ 'mv', '-f', tmpFile, fileName ]);
if (res.code != 0) {
throw new Error('mv failed, rc = ' + res.code);
}
} catch(e) {
try {
await fs.exec('/bin/busybox', [ 'rm', '-f', tmpFile ]);
} catch(e2) {
// nothing
}
throw e;
}
return fs.stat(fileName);
},
return fs.write(this.file, value).then(async rc => { handleSaveAdv: async function(ev)
{
let txt = document.getElementById('widget.modal_content');
let value = txt.value.trim().replace(/\r\n/g, '\n');
if (value.length > 0) {
value += '\n';
}
return this.writeAdv(this.file, value).then(async rc => {
txt.value = value; txt.value = value;
ui.addNotification(null, E('p', _('Contents have been saved.')), 'info'); ui.addNotification(null, E('p', _('Contents have been saved.')), 'info');
if (this.callback) { if (this.callback) {
@@ -420,13 +492,16 @@ return baseclass.extend({
}), }),
longstrEditDialog: baseclass.extend({ longstrEditDialog: baseclass.extend({
__init__: function(cfgsec, cfgparam, title, desc, rows = 10, multiline = false) { __init__: function(opts = {})
this.cfgsec = cfgsec; {
this.cfgparam = cfgparam; Object.assign(this, {
this.title = title; cfgsec: '',
this.desc = desc; cfgparam: '',
this.rows = rows; title: '',
this.multiline = multiline; desc: '',
rows: 10,
multiline: false // may be 2
}, opts);
env_tools.load_env(this); env_tools.load_env(this);
}, },
@@ -490,6 +565,10 @@ return baseclass.extend({
if (value != "" && value != "\t") { if (value != "" && value != "\t") {
value = '\n' + value + '\n'; value = '\n' + value + '\n';
if (this.multiline == 2) { if (this.multiline == 2) {
if (value.includes("'") || value.includes('"')) {
alert(_('Unable to save the contents') + ':\n' + _('text cannot contain quotes!'));
return false;
}
value = value.replace(/"/g, ''); value = value.replace(/"/g, '');
value = value.replace(/'/g, ''); value = value.replace(/'/g, '');
} }
@@ -506,24 +585,10 @@ return baseclass.extend({
value = value.replace(/˂/g, '<'); value = value.replace(/˂/g, '<');
value = value.replace(/˃/g, '>'); value = value.replace(/˃/g, '>');
try { try {
let elem = document.getElementById("cbi-" + this.appName + "-" + this.cfgsec + "-_" + this.cfgparam); let elem = document.getElementById("widget.cbid." + this.appName + ".config._" + this.cfgparam);
if (elem) {
if (elem.querySelector('div')) {
elem = elem.querySelector('div');
} else {
elem = elem.querySelector('output');
}
}
if (elem) { if (elem) {
let val = value.trim(); let val = value.trim();
if (this.multiline) { elem.textContent = val;
val = val.replace(/</g, '˂');
val = val.replace(/>/g, '˃');
val = val.replace(/\n/g, '<br/>');
elem.innerHTML = val;
} else {
elem.textContent = val;
}
} }
} catch(e) { } catch(e) {
console.error('ERROR: cannot found elem for ' + this.cfgsec + '.' + this.cfgparam); console.error('ERROR: cannot found elem for ' + this.cfgsec + '.' + this.cfgparam);
@@ -601,54 +666,62 @@ return baseclass.extend({
} }
let lastLen = 0; let lastLen = 0;
let retCode = -1; let retCode = -1;
let timerBusy = false; return await new Promise(async (resolve, reject) => {
let timer = setInterval(async () => { async function poll()
if (timerBusy) {
return; // skip iteration try {
timerBusy = true; let res = await fs.exec('/bin/cat', [ logFile ], null, rpc_opt);
try { if (res.stdout && res.stdout.length > lastLen) {
let res = await fs.exec('/bin/cat', [ logFile ], null, rpc_opt); let log = res.stdout.slice(lastLen);
if (res.stdout && res.stdout.length > lastLen) { hide_rows.forEach(re => {
let log = res.stdout.slice(lastLen); log = log.replace(re, '');
hide_rows.forEach(re => { });
log = log.replace(re, ''); appendLog(log, '');
}); lastLen = res.stdout.length;
appendLog(log, ''); }
lastLen = res.stdout.length; if (retCode < 0) {
} let rc = await fs.exec('/bin/cat', [ rcFile ], null, rpc_opt);
if (retCode < 0) { if (rc.code != 0) {
let rc = await fs.exec('/bin/cat', [ rcFile ], null, rpc_opt); fixLogEnd();
if (rc.code != 0) { resolve(callback(cbarg, 545, 'ERROR: cannot read file "' + rcFile + '"'));
clearInterval(timer); return;
}
if (rc.stdout) {
retCode = parseInt(rc.stdout.trim(), 10);
}
}
if (retCode >= 0) {
fixLogEnd(); fixLogEnd();
return callback(cbarg, 545, 'ERROR: cannot read file "' + rcFile + '"'); if (retCode == 0 && res.stdout) {
resolve(callback(cbarg, 0, res.stdout));
return;
}
resolve(callback(cbarg, retCode, 'ERROR: Process failed with error ' + retCode));
return;
} }
if (rc.stdout) { setTimeout(poll, 500);
retCode = parseInt(rc.stdout.trim(), 10); } catch (e) {
let skip_err = false;
if (e.message?.includes('RPC call to file/exec failed with error -32000: Object not found')) {
skip_err = true;
}
if (e.message?.includes('XHR request timed out')) {
skip_err = true;
}
if (skip_err) {
console.warn('WARN: execAndRead: ' + e.message);
setTimeout(poll, 500);
return; // goto next poll iteration
} }
}
if (retCode >= 0) {
clearInterval(timer);
fixLogEnd(); fixLogEnd();
if (retCode == 0 && res.stdout) { let errtxt = 'ERROR: execAndRead: ' + e.message;
return callback(cbarg, 0, res.stdout); errtxt += 'ERROR: execAndRead: ' + e.stack?.trim().split('\n')[0];
} callback(cbarg, 540, errtxt);
return callback(cbarg, retCode, 'ERROR: Process failed with error ' + retCode); reject(e);
} }
} catch (e) {
if (e.message?.includes('RPC call to file/exec failed with error -32000: Object not found')) {
console.warn('WARN: execAndRead: ' + e.message);
return; // goto next timer iteration
}
clearInterval(timer);
fixLogEnd();
let errtxt = 'ERROR: execAndRead: ' + e.message;
errtxt += 'ERROR: execAndRead: ' + e.stack?.trim().split('\n')[0];
return callback(cbarg, 540, errtxt);
} finally {
timerBusy = false;
} }
}, 500); poll();
});
}, },
}); });

View File

@@ -5,7 +5,7 @@
'require uci'; 'require uci';
'require ui'; 'require ui';
'require view'; 'require view';
'require view.zapret.tools as tools'; 'require view.zapret2.tools as tools';
const btn_style_neutral = 'btn'; const btn_style_neutral = 'btn';
const btn_style_action = 'btn cbi-button-action'; const btn_style_action = 'btn cbi-button-action';
@@ -25,35 +25,28 @@ return baseclass.extend({
this.logArea.scrollTop = this.logArea.scrollHeight; this.logArea.scrollTop = this.logArea.scrollHeight;
}, },
setBtnMode: function(enable) setBtnMode: function(check, install, cancel)
{ {
this.btn_cancel.disabled = enable ? false : true; this.btn_check.disabled = check ? false : true;
this.btn_action.disabled = (enable == 2) ? false : true; this.btn_install.disabled = install ? false : true;
this.btn_cancel.disabled = cancel ? false : true;
}, },
setStage: function(stage, btn_flag = true) setStage: function(stage, btn_flag = true)
{ {
if (stage == 0) { if (stage == 0) this.setBtnMode(1, 0, 1);
this.btn_action.textContent = _('Check for updates'); if (stage == 1) this.setBtnMode(0, 0, 1);
this.btn_action.classList.remove('hidden'); if (stage == 2) this.setBtnMode(1, 1, 1);
} else if (stage == 3) this.setBtnMode(0, 0, 0);
if (stage == 1) { if (stage == 8) this.setBtnMode(0, 0, 1);
this.btn_action.textContent = _('Update packages'); if (stage >= 9) this.setBtnMode(0, 0, 0);
this.btn_action.classList.remove('hidden');
} else {
this.btn_action.classList.add('hidden');
}
if (stage > 1 && typeof(this.btn_action) == 'object') {
this.setBtnMode(1);
}
this.stage = stage; this.stage = stage;
}, },
checkUpdates: async function() checkUpdates: async function(ev)
{ {
this._action = 'checkUpdates'; this._action = 'checkUpdates';
this.setStage(0); this.setStage(1);
this.setBtnMode(0);
this.pkg_url = null; this.pkg_url = null;
this.appendLog(_('Checking for updates...')); this.appendLog(_('Checking for updates...'));
let cmd = [ fn_update_pkg_sh, '-c' ]; // check for updates let cmd = [ fn_update_pkg_sh, '-c' ]; // check for updates
@@ -61,33 +54,38 @@ return baseclass.extend({
cmd.push('-p'); // include prereleases ZIP-files cmd.push('-p'); // include prereleases ZIP-files
} }
this.forced_reinstall = document.getElementById('cfg_forced_reinstall').checked; this.forced_reinstall = document.getElementById('cfg_forced_reinstall').checked;
let log = '/tmp/'+tools.appName+'_pkg_check.log'; return tools.execAndRead({
let callback = this.execAndReadCallback; cmd: cmd,
let wnd = this; log: '/tmp/'+tools.appName+'_pkg_check.log',
return tools.execAndRead({ cmd: cmd, log: log, logArea: this.logArea, callback: callback, cbarg: wnd }); logArea: this.logArea,
callback: this.execAndReadCallback,
cbarg: this, // wnd
});
}, },
installUpdates: async function() installUpdates: async function(ev)
{ {
this._action = 'installUpdates';
this.setStage(1);
this.setBtnMode(0);
if (!this.pkg_url || this.pkg_url.length < 10) { if (!this.pkg_url || this.pkg_url.length < 10) {
this.appendLog('ERROR: pkg_url = null'); this.appendLog('ERROR: pkg_url = null');
this.setStage(999); this.setStage(9);
return; return;
} }
this._action = 'installUpdates';
this.setStage(3);
this.appendLog(_('Install updates...')); this.appendLog(_('Install updates...'));
let cmd = [ fn_update_pkg_sh, '-u', this.pkg_url ]; // update packages let cmd = [ fn_update_pkg_sh, '-u', this.pkg_url ]; // update packages
if (document.getElementById('cfg_forced_reinstall').checked == true) { if (document.getElementById('cfg_forced_reinstall').checked == true) {
cmd.push('-f'); // forced reinstall if same version cmd.push('-f'); // forced reinstall if same version
} }
//this._test = 1; cmd.push('-t'); cmd.push('45'); // only for testing //this._test = 1; cmd.push('-t'); cmd.push('45'); // only for testing
let log = '/tmp/'+tools.appName+'_pkg_install.log'; return tools.execAndRead({
let hiderow = /^ \* resolve_conffiles.*(?:\r?\n|$)/gm; cmd: cmd,
let callback = this.execAndReadCallback; log: '/tmp/'+tools.appName+'_pkg_install.log',
let wnd = this; logArea: this.logArea,
return tools.execAndRead({ cmd: cmd, log: log, logArea: this.logArea, hiderow: hiderow, callback: callback, cbarg: wnd }); hiderow: /^ \* resolve_conffiles.*(?:\r?\n|$)/gm,
callback: this.execAndReadCallback,
cbarg: this, // wnd
});
}, },
execAndReadCallback: function(wnd, rc, txt = '') execAndReadCallback: function(wnd, rc, txt = '')
@@ -96,30 +94,34 @@ return baseclass.extend({
if (rc == 0 && txt) { if (rc == 0 && txt) {
let code = txt.match(/^RESULT:\s*\(([^)]+)\)\s+.+$/m); let code = txt.match(/^RESULT:\s*\(([^)]+)\)\s+.+$/m);
if (wnd._action == 'checkUpdates') { if (wnd._action == 'checkUpdates') {
wnd.appendLog('=========================================================');
if (code && code[1] == 'E') {
wnd.btn_install.textContent = _('Reinstall');
} else {
wnd.btn_install.textContent = _('Install');
}
let pkg_url = txt.match(/^ZAP_PKG_URL\s*=\s*(.+)$/m); let pkg_url = txt.match(/^ZAP_PKG_URL\s*=\s*(.+)$/m);
if (code && pkg_url) { if (code && pkg_url) {
wnd.appendLog('========================================================='); if (!wnd.forced_reinstall) {
wnd.pkg_url = pkg_url[1]; if (code[1] == 'E' || code[1] == 'G') {
code = code[1]; wnd.setStage(0); // install not needed
if (code == 'E' && !wnd.forced_reinstall) { return;
wnd.setStage(999); // install not needed }
return;
} }
wnd.setStage(1); wnd.pkg_url = pkg_url[1];
wnd.setBtnMode(2); // enable all buttons wnd.setStage(2); // enable all buttons
return; // install allowed return; // install allowed
} }
} }
if (wnd._action == 'installUpdates') { if (wnd._action == 'installUpdates') {
if (wnd._test || (code && code[1] == '+')) { if (wnd._test || (code && code[1] == '+')) {
wnd.stage = 999; wnd.setStage(9);
wnd.btn_action.textContent = _('OK'); wnd.appendLog('Please update WEB-page (press F5)');
wnd.btn_action.disabled = false;
wnd.btn_cancel.disabled = true;
return; return;
} }
} }
} }
wnd.setStage(0);
if (rc >= 500) { if (rc >= 500) {
if (txt) { if (txt) {
wnd.appendLog(txt.startsWith('ERROR') ? txt : 'ERROR: ' + txt); wnd.appendLog(txt.startsWith('ERROR') ? txt : 'ERROR: ' + txt);
@@ -129,14 +131,15 @@ return baseclass.extend({
} else { } else {
wnd.appendLog('ERROR: Process finished with retcode = ' + rc); wnd.appendLog('ERROR: Process finished with retcode = ' + rc);
} }
wnd.setStage(999); wnd.appendLog('=========================================================');
if (wnd._action == 'checkUpdates') {
wnd.appendLog('=========================================================');
}
}, },
openUpdateDialog: function(pkg_arch) openUpdateDialog: function(pkg_arch)
{ {
if (tools.checkUnsavedChanges()) {
ui.addNotification(null, E('p', _('You have unapplied changes')));
return;
}
this.stage = 0; this.stage = 0;
this.pkg_arch = pkg_arch; this.pkg_arch = pkg_arch;
this.pkg_url = null; this.pkg_url = null;
@@ -166,25 +169,30 @@ return baseclass.extend({
}, _('Cancel')); }, _('Cancel'));
this.btn_cancel.onclick = ui.hideModal; this.btn_cancel.onclick = ui.hideModal;
this.btn_action = E('button', { this.btn_check = E('button', {
'id': 'btn_action', 'id': 'btn_check',
'name': 'btn_action', 'name': 'btn_check',
'class': btn_style_action, 'class': btn_style_action,
}, 'BUTTON_ACTION'); }, _('Check'));
this.btn_action.onclick = ui.createHandlerFn(this, () => { this.btn_check.onclick = ui.createHandlerFn(this, this.checkUpdates);
if (this.stage == 0) {
return this.checkUpdates(); this.btn_install = E('button', {
'id': 'btn_install',
'name': 'btn_install',
'class': btn_style_positive,
}, _('Install'));
this.btn_install.onclick = ui.createHandlerFn(this, async () => {
let res = await this.installUpdates();
if (true) {
setTimeout(() => {
this.btn_install.disabled = true;
}, 0);
} }
if (this.stage == 1) {
return this.installUpdates();
}
return ui.hideModal();
}); });
this.setStage(0); this.setStage(0);
this.setBtnMode(2);
ui.showModal(_('Package update'), [ ui.showModal(_('Check for updates and install'), [
E('div', { 'class': 'cbi-section' }, [ E('div', { 'class': 'cbi-section' }, [
exclude_prereleases, exclude_prereleases,
E('br'), E('br'), E('br'), E('br'),
@@ -194,9 +202,11 @@ return baseclass.extend({
this.logArea, this.logArea,
]), ]),
E('div', { 'class': 'right' }, [ E('div', { 'class': 'right' }, [
this.btn_cancel, this.btn_check,
' ', ' ',
this.btn_action, this.btn_install,
' ',
this.btn_cancel,
]) ])
]); ]);
} }

View File

@@ -0,0 +1,41 @@
{
"admin/services/zapret2": {
"title": "Zapret2",
"order": 62,
"action": {
"type": "alias",
"path": "admin/services/zapret2/service"
},
"depends": {
"acl": [ "luci-app-zapret2" ],
"uci": { "zapret2": true }
}
},
"admin/services/zapret2/service": {
"title": "Service",
"order": 10,
"action": {
"type": "view",
"path": "zapret2/service"
}
},
"admin/services/zapret2/settings": {
"title": "Settings",
"order": 20,
"action": {
"type": "view",
"path": "zapret2/settings"
}
},
"admin/services/zapret2/dmnlog": {
"title": "Log Viewer",
"order": 30,
"action": {
"type": "view",
"path": "zapret2/dmnlog"
}
}
}

View File

@@ -0,0 +1,40 @@
{
"luci-app-zapret2": {
"description": "Grant access to zapret2 procedures",
"read": {
"cgi-io": [ "exec" ],
"file": {
"/opt/zapret2/config": [ "read" ],
"/opt/zapret2/ipset/*": [ "read" ],
"/opt/zapret2/init.d/openwrt/custom.d/*": [ "read" ],
"/etc/crontabs/root": [ "read" ],
"/tmp/zapret*": [ "read" ],
"/etc/init.d/zapret2*": [ "exec" ],
"/bin/ps*": [ "exec" ],
"/bin/cat*": [ "exec" ],
"/bin/busybox*": [ "exec" ],
"/bin/opkg*": [ "exec" ],
"/usr/bin/apk*": [ "exec" ],
"/usr/bin/find*": [ "exec" ],
"/opt/zapret2/restore-def-cfg.sh*": [ "exec" ],
"/opt/zapret2/script-exec.sh*": [ "exec" ],
"/opt/zapret2/update-pkg.sh*": [ "exec" ],
"/opt/zapret2/sync_config.sh*": [ "exec" ]
},
"uci": [ "zapret2", "network" ],
"ubus": {
"luci": [ "getInitList", "setInitAction" ],
"service": [ "list" ]
}
},
"write": {
"file": {
"/opt/zapret2/config": [ "write" ],
"/opt/zapret2/ipset/*": [ "write" ],
"/opt/zapret2/init.d/openwrt/custom.d/*": [ "write" ],
"/etc/crontabs/root": [ "write" ]
},
"uci": [ "zapret2" ]
}
}
}

View File

@@ -1,319 +0,0 @@
#
# Copyright (c) 2024 remittor
#
include $(TOPDIR)/rules.mk
PKG_NAME:=zapret
PKG_VERSION:=72.20260113
PKG_RELEASE:=1
PKG_MAINTAINER:=bol-van
PKG_LICENSE:=MIT
PKG_LICENSE_FILES:=docs/LICENSE.txt
PKG_SOURCE_URL:=https://github.com/bol-van/zapret.git
PKG_SOURCE_PROTO:=git
PKG_SOURCE_VERSION:=75d2f1195d4beb69eaa614afb117a43e82998518
PKG_SOURCE_DATE:=2026-01-13
#PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
#PKG_SOURCE_URL:=https://github.com/bol-van/zapret/archive/refs/tags/v$(PKG_VERSION).tar.gz?
#PKG_HASH:=skip
include $(INCLUDE_DIR)/package.mk
#TAR_OPTIONS:=--strip-components 1 $(TAR_OPTIONS)
#TAR_CMD=$(HOST_TAR) -C $(1) $(TAR_OPTIONS)
MAKE_PATH:=nfq
define Package/$(PKG_NAME)
SECTION:=net
CATEGORY:=Network
TITLE:=$(PKG_NAME)
SUBMENU:=Zapret
URL:=https://github.com/bol-van/zapret
DEPENDS:= +nftables +curl +gzip
DEPENDS+= +coreutils +coreutils-sort +coreutils-sleep
DEPENDS+= +kmod-nft-nat +kmod-nft-offload +kmod-nft-queue
DEPENDS+= +libnetfilter-queue +libcap +zlib
endef
define Build/Prepare
$(Build/Prepare/Default)
rm -f $(PKG_BUILD_DIR)/$(MAKE_PATH)/nfqws
rm -f $(PKG_BUILD_DIR)/ip2net/ip2net
rm -f $(PKG_BUILD_DIR)/mdig/mdig
endef
#define Build/Configure
#endef
define Build/Compile
$(MAKE) -C $(PKG_BUILD_DIR)/$(MAKE_PATH) $(TARGET_CONFIGURE_OPTS)
$(MAKE) -C $(PKG_BUILD_DIR)/ip2net $(TARGET_CONFIGURE_OPTS)
$(MAKE) -C $(PKG_BUILD_DIR)/mdig $(TARGET_CONFIGURE_OPTS)
endef
define Package/$(PKG_NAME)/conffiles
/opt/zapret/config
/opt/zapret/ipset/zapret-hosts-google.txt
/opt/zapret/ipset/zapret-hosts-user.txt
/opt/zapret/ipset/zapret-hosts-user-exclude.txt
/opt/zapret/ipset/zapret-ip-exclude.txt
/opt/zapret/ipset/zapret-hosts-auto.txt
/opt/zapret/init.d/openwrt/custom.d/10-script.sh
/opt/zapret/init.d/openwrt/custom.d/20-script.sh
/opt/zapret/init.d/openwrt/custom.d/50-script.sh
/opt/zapret/init.d/openwrt/custom.d/60-script.sh
/opt/zapret/init.d/openwrt/custom.d/90-script.sh
endef
define Package/$(PKG_NAME)/install
$(INSTALL_DIR) $(1)/opt/zapret
$(INSTALL_DIR) $(1)/opt/zapret/$(MAKE_PATH)
$(INSTALL_BIN) $(PKG_BUILD_DIR)/$(MAKE_PATH)/nfqws $(1)/opt/zapret/$(MAKE_PATH)/
$(INSTALL_DIR) $(1)/opt/zapret/ip2net
$(INSTALL_BIN) $(PKG_BUILD_DIR)/ip2net/ip2net $(1)/opt/zapret/ip2net/
$(INSTALL_DIR) $(1)/opt/zapret/mdig
$(INSTALL_BIN) $(PKG_BUILD_DIR)/mdig/mdig $(1)/opt/zapret/mdig/
$(INSTALL_DIR) $(1)/opt/zapret/common
$(CP) $(PKG_BUILD_DIR)/common/* $(1)/opt/zapret/common/
#$(INSTALL_DIR) $(1)/opt/zapret/docs
#$(CP) $(PKG_BUILD_DIR)/docs/* $(1)/opt/zapret/docs/
$(INSTALL_DIR) $(1)/opt/zapret/files
$(CP) $(PKG_BUILD_DIR)/files/* $(1)/opt/zapret/files/
$(CP) ./files/* $(1)/opt/zapret/files/
$(INSTALL_DIR) $(1)/opt/zapret/ipset
$(CP) $(PKG_BUILD_DIR)/ipset/* $(1)/opt/zapret/ipset/
$(INSTALL_BIN) $(PKG_BUILD_DIR)/blockcheck.sh $(1)/opt/zapret/blockcheck.sh
#$(INSTALL_DATA) $(PKG_BUILD_DIR)/config.default $(1)/opt/zapret/config.default
$(INSTALL_DIR) $(1)/opt/zapret/tmp
$(INSTALL_DIR) $(1)/opt/zapret/init.d/openwrt
$(CP) $(PKG_BUILD_DIR)/init.d/openwrt/* $(1)/opt/zapret/init.d/openwrt/
$(INSTALL_DIR) $(1)/etc/hotplug.d/iface
$(INSTALL_BIN) $(PKG_BUILD_DIR)/init.d/openwrt/90-zapret $(1)/etc/hotplug.d/iface/90-zapret
$(INSTALL_DIR) $(1)/etc/init.d
$(INSTALL_BIN) ./init.d.sh $(1)/etc/init.d/zapret
$(INSTALL_DATA) ./config.default $(1)/opt/zapret/config.default
$(INSTALL_DATA) ./config.default $(1)/opt/zapret/config
$(INSTALL_DATA) ./ipset/zapret-hosts-google.txt $(1)/opt/zapret/ipset/zapret-hosts-google.txt
$(INSTALL_DATA) ./ipset/zapret-hosts-user.txt $(1)/opt/zapret/ipset/zapret-hosts-user.txt
$(INSTALL_DATA) ./ipset/zapret-hosts-user-exclude.txt $(1)/opt/zapret/ipset/zapret-hosts-user-exclude.txt
$(INSTALL_DATA) ./ipset/zapret-ip-exclude.txt $(1)/opt/zapret/ipset/zapret-ip-exclude.txt
$(INSTALL_DIR) $(1)/opt/zapret/ipset_def
$(INSTALL_DATA) ./ipset/zapret-hosts-google.txt $(1)/opt/zapret/ipset_def/zapret-hosts-google.txt
$(INSTALL_DATA) ./ipset/zapret-hosts-user.txt $(1)/opt/zapret/ipset_def/zapret-hosts-user.txt
$(INSTALL_DATA) ./ipset/zapret-hosts-user-exclude.txt $(1)/opt/zapret/ipset_def/zapret-hosts-user-exclude.txt
$(INSTALL_DATA) ./ipset/zapret-ip-exclude.txt $(1)/opt/zapret/ipset_def/zapret-ip-exclude.txt
$(INSTALL_DIR) $(1)/opt/zapret/init.d
$(INSTALL_DIR) $(1)/opt/zapret/init.d/openwrt
$(INSTALL_DIR) $(1)/opt/zapret/init.d/openwrt/custom.d
$(CP) ./custom.d/* $(1)/opt/zapret/init.d/openwrt/custom.d/
$(INSTALL_DIR) $(1)/etc/uci-defaults
$(INSTALL_BIN) ./uci-def-cfg.sh $(1)/etc/uci-defaults/zapret-uci-def-cfg.sh
# install all sh-scripts
$(CP) ./*.sh $(1)/opt/zapret/
rm -f $(1)/opt/zapret/init.d.sh
# Create empty conf files
$(INSTALL_DATA) /dev/null $(1)/opt/zapret/ipset/zapret-hosts-auto.txt
$(INSTALL_DATA) /dev/null $(1)/opt/zapret/ipset/cust1.txt
$(INSTALL_DATA) /dev/null $(1)/opt/zapret/ipset/cust2.txt
$(INSTALL_DATA) /dev/null $(1)/opt/zapret/ipset/cust3.txt
$(INSTALL_DATA) /dev/null $(1)/opt/zapret/ipset/cust4.txt
$(INSTALL_DATA) /dev/null $(1)/opt/zapret/init.d/openwrt/custom.d/10-script.sh
$(INSTALL_DATA) /dev/null $(1)/opt/zapret/init.d/openwrt/custom.d/20-script.sh
$(INSTALL_DATA) /dev/null $(1)/opt/zapret/init.d/openwrt/custom.d/60-script.sh
$(INSTALL_DATA) /dev/null $(1)/opt/zapret/init.d/openwrt/custom.d/90-script.sh
# Fix permissions
chmod 644 $(1)/opt/zapret/ipset/*.txt
chmod 644 $(1)/opt/zapret/ipset_def/*.txt
chmod 644 $(1)/opt/zapret/init.d/openwrt/custom.d/*.sh
chmod 644 $(1)/opt/zapret/config*
chmod 755 $(1)/opt/zapret/*.sh
chmod 755 $(1)/opt/zapret/$(MAKE_PATH)/*
chmod 755 $(1)/opt/zapret/ip2net/*
chmod 755 $(1)/opt/zapret/mdig/*
# Disable TPWS in blockcheck
grep -q '^SKIP_TPWS=' $(1)/opt/zapret/blockcheck.sh || sed -i '/^NFT_TABLE=blockcheck$$$$/a SKIP_TPWS=$$$${SKIP_TPWS:-1}' $(1)/opt/zapret/blockcheck.sh
endef
define Package/$(PKG_NAME)/preinst
#!/bin/sh
# check if we are on real system
if [ -z "$${IPKG_INSTROOT}" ]; then
ZAPRET_DIR=/opt/zapret
ZAPRET_INITD=/etc/init.d/zapret
ZAPRET_CFG=/etc/config/zapret
if [ -f "$${ZAPRET_INITD}" ]; then
SCRIPT=$$( readlink "$${ZAPRET_INITD}" )
if [ -n "$${SCRIPT}" ]; then
echo "Please uninstall incompatible \"zapret\" service!"
exit 44
fi
fi
if command -v apk >/dev/null; then
PKG_MGR="apk"
PKG_CHECK="apk info -e "
PKG_REMOVE="apk del --force "
else
PKG_MGR="opkg"
PKG_CHECK="opkg status "
PKG_REMOVE="opkg remove --force-remove "
fi
if [ "$${PKG_UPGRADE}" = "1" ]; then
# stop service if PKG_UPGRADE
if [ -x "$${ZAPRET_INITD}" ]; then
$${ZAPRET_INITD} running && $${ZAPRET_INITD} stop >/dev/null 2>&1
fi
fi
if $${PKG_CHECK} zapret >/dev/null 2>&1; then
if [ ! -f "/opt/zapret/sync_config.sh" ]; then
echo "Please uninstall incompatible \"zapret\" package!"
exit 47
fi
if [ -f "$${ZAPRET_CFG}" ] && ! grep -q "run_on_boot" "$${ZAPRET_CFG}"; then
echo "Please uninstall incompatible \"zapret\" package!"
exit 48
fi
fi
if $${PKG_CHECK} luci-app-zapret >/dev/null 2>&1; then
SVC_FILE=/www/luci-static/resources/view/zapret/service.js
if [ ! -f "$${SVC_FILE}" ] || ! grep -Fq "/remittor/zapret-openwrt" "$${SVC_FILE}"; then
echo "Please uninstall incompatible \"luci-app-zapret\" package!"
exit 55
fi
fi
if [ -f "$${ZAPRET_CFG}" ] && ! grep -q "run_on_boot" "$${ZAPRET_CFG}"; then
if [ -x "$${ZAPRET_INITD}" ]; then
$${ZAPRET_INITD} running && $${ZAPRET_INITD} stop >/dev/null 2>&1
fi
rm -f $${ZAPRET_CFG}
rm -f $${ZAPRET_INITD}
[ -d "$${ZAPRET_DIR}" ] && rm -rf $${ZAPRET_DIR}
echo "All files of the previously installed package have been removed!"
fi
if $${PKG_CHECK} zapret-mdig >/dev/null 2>&1; then
$${PKG_REMOVE} zapret-mdig
fi
if $${PKG_CHECK} zapret-ip2net >/dev/null 2>&1; then
$${PKG_REMOVE} zapret-ip2net
fi
if [ ! -d "$${ZAPRET_DIR}" ]; then
mkdir -p $${ZAPRET_DIR}
fi
if [ ! -f "/opt/zapret/ipset/zapret-hosts-google.txt" ]; then
if [ -f "/opt/zapret/ipset/zapret-hosts-user.txt" ]; then
CFGLISTHASH=$$( md5sum "/opt/zapret/ipset/zapret-hosts-user.txt" | awk '{print $$1;}' )
if [ "$${CFGLISTHASH}" = "79e35df62b0d1ae455d0a7e04c4cecac" ]; then
rm -f "/opt/zapret/ipset/zapret-hosts-user.txt"
fi
fi
fi
fi
exit 0
endef
define Package/$(PKG_NAME)/postinst
#!/bin/sh
# check if we are on real system
if [ -z "$${IPKG_INSTROOT}" ]; then
ZAPRET_DIR=/opt/zapret
ZAPRET_INITD=/etc/init.d/zapret
ZAPRET_CFG=/etc/config/zapret
ZAPRET_CONFIG=/opt/zapret/config
ZAPRET_CONFIG_DEF="/opt/zapret/config.default"
# Fix permissions
chmod 644 $${ZAPRET_CFG} >/dev/null 2>&1
chmod 644 $${ZAPRET_DIR}/ipset/*.txt >/dev/null 2>&1
chmod 644 $${ZAPRET_DIR}/ipset_def/*.txt >/dev/null 2>&1
chmod 644 $${ZAPRET_DIR}/init.d/openwrt/custom.d/*.sh >/dev/null 2>&1
chmod 644 $${ZAPRET_DIR}/config* >/dev/null 2>&1
# creating main config if its not exists
if [ ! -f "$${ZAPRET_CONFIG}" ]; then
cp -f "$${ZAPRET_CONFIG_DEF}" "$${ZAPRET_CONFIG}"
fi
# check obsolete format for main config
if grep -qE "^NFQWS_OPT_DESYNC=|^MODE_HTTP=|^MODE_HTTPS=|^MODE_QUIC=|^MODE=" "$${ZAPRET_CONFIG}" ; then
echo "Detect obsolute format for main config!"
ZAPRET_CONFIG_BACKUP="$${ZAPRET_CONFIG}.backup"
cp -f "$${ZAPRET_CONFIG}" "$${ZAPRET_CONFIG_BACKUP}"
echo "Current file $${ZAPRET_CONFIG} backuped to $${ZAPRET_CONFIG_BACKUP}"
cp -f "$${ZAPRET_CONFIG_DEF}" "$${ZAPRET_CONFIG}"
fi
# remove fake uci-config
[ -f "$${ZAPRET_CFG}" ] && [ ! -s "$${ZAPRET_CFG}" ] && rm -f "$${ZAPRET_CFG}"
# check existing uci-config
[ -f "$${ZAPRET_CFG}" ] && ZAPRET_CFG_EXISTS=1 || ZAPRET_CFG_EXISTS=0
# create or merge uci-config
/opt/zapret/uci-def-cfg.sh
[ "$${ZAPRET_CFG_EXISTS}" = "1" ] && echo "Config /etc/config/zapret merged with default uci-config"
# remove uci-default script from system dir (used into /etc/init.d/boot)
rm -f /etc/uci-defaults/zapret-uci-def-cfg.sh
# copy (sync) all params from uci-config to main config
/opt/zapret/sync_config.sh
# check main config
sh -n "$${ZAPRET_CONFIG}" 2>/dev/null || cp -f "$${ZAPRET_CONFIG_DEF}" "$${ZAPRET_CONFIG}"
sh -n "$${ZAPRET_CONFIG}" 2>/dev/null || exit 58
# enable main service
$${ZAPRET_INITD} enable
# stop all
$${ZAPRET_INITD} stop_fw >/dev/null 2>&1
$${ZAPRET_INITD} stop_daemons >/dev/null 2>&1
ps w | grep '/opt/zapret/nfq/nfqws' | grep -v grep | awk '{print $$1}' | xargs -r kill -9
# start main service
$${ZAPRET_INITD} start
# restart firewall
[ -x /sbin/fw4 ] && fw4 -q restart || fw3 -q restart
fi
exit 0
endef
define Package/$(PKG_NAME)/prerm
#!/bin/sh
# check if we are on real system
if [ -z "$${IPKG_INSTROOT}" ]; then
ZAPRET_DIR=/opt/zapret
ZAPRET_BASE=/opt/zapret
ZAPRET_INITD=/etc/init.d/zapret
ZAPRET_CFG=/etc/config/zapret
ZAPRET_CONFIG=/opt/zapret/config
ZAPRET_CONFIG_DEF="/opt/zapret/config.default"
OPENWRT_FW_INCLUDE=/etc/firewall.zapret
# check main config
sh -n "$${ZAPRET_CONFIG}" 2>/dev/null || cp -f "$${ZAPRET_CONFIG_DEF}" "$${ZAPRET_CONFIG}"
if ! sh -n "$${ZAPRET_CONFIG}" 2>/dev/null ; then
ps w | grep '/opt/zapret/nfq/nfqws' | grep -v grep | awk '{print $$1}' | xargs -r kill -9
exit 0
fi
. "$${ZAPRET_CONFIG}"
. "$${ZAPRET_BASE}/common/base.sh"
. "$${ZAPRET_BASE}/common/fwtype.sh"
. "$${ZAPRET_BASE}/common/nft.sh"
. "$${ZAPRET_BASE}/common/installer.sh"
$${ZAPRET_INITD} running && $${ZAPRET_INITD} stop >/dev/null 2>&1
$${ZAPRET_INITD} disable >/dev/null 2>&1
ps w | grep '/opt/zapret/nfq/nfqws' | grep -v grep | awk '{print $$1}' | xargs -r kill -9
remove_openwrt_firewall
nft_del_table
restart_openwrt_firewall
fi
exit 0
endef
define Package/$(PKG_NAME)/postrm
#!/bin/sh
# check if we are on real system
if [ -z "$${IPKG_INSTROOT}" ]; then
rm -f /etc/config/zapret-opkg*
rm -f /etc/config/zapret.opkg*
rm -f /etc/config/zapret.apk*
[ -f "/opt/zapret/config" ] && cp -f /opt/zapret/config "/opt/zapret/config.backup"
#rm -rf /opt/zapret
#echo "Directory /opt/zapret removed!"
fi
exit 0
endef
$(eval $(call BuildPackage,$(PKG_NAME)))

View File

@@ -1,395 +0,0 @@
#!/bin/sh
# Copyright (c) 2024 remittor
function set_cfg_reset_values
{
local cfgname=${1:-$ZAPRET_CFG_NAME}
local TAB="$( printf '\t' )"
uci batch <<-EOF
set $cfgname.config.run_on_boot='0'
# settings for zapret service
set $cfgname.config.FWTYPE='nftables'
set $cfgname.config.POSTNAT='1'
set $cfgname.config.FLOWOFFLOAD='none'
set $cfgname.config.INIT_APPLY_FW='1'
set $cfgname.config.DISABLE_IPV4='0'
set $cfgname.config.DISABLE_IPV6='1'
set $cfgname.config.FILTER_TTL_EXPIRED_ICMP='1'
set $cfgname.config.MODE_FILTER='hostlist'
set $cfgname.config.DISABLE_CUSTOM='1'
set $cfgname.config.WS_USER='daemon'
set $cfgname.config.DAEMON_LOG_ENABLE='0'
set $cfgname.config.DAEMON_LOG_FILE='/tmp/zapret+<DAEMON_NAME>+<DAEMON_IDNUM>+<DAEMON_CFGNAME>.log'
# autohostlist options
set $cfgname.config.AUTOHOSTLIST_RETRANS_THRESHOLD='3'
set $cfgname.config.AUTOHOSTLIST_FAIL_THRESHOLD='3'
set $cfgname.config.AUTOHOSTLIST_FAIL_TIME='60'
set $cfgname.config.AUTOHOSTLIST_DEBUGLOG='0'
# nfqws options
set $cfgname.config.NFQWS_ENABLE='1'
set $cfgname.config.DESYNC_MARK='0x40000000'
set $cfgname.config.DESYNC_MARK_POSTNAT='0x20000000'
set $cfgname.config.FILTER_MARK='$TAB'
set $cfgname.config.NFQWS_PORTS_TCP='80,443'
set $cfgname.config.NFQWS_PORTS_UDP='443'
set $cfgname.config.NFQWS_TCP_PKT_OUT='9'
set $cfgname.config.NFQWS_TCP_PKT_IN='3'
set $cfgname.config.NFQWS_UDP_PKT_OUT='9'
set $cfgname.config.NFQWS_UDP_PKT_IN='0'
set $cfgname.config.NFQWS_PORTS_TCP_KEEPALIVE='0'
set $cfgname.config.NFQWS_PORTS_UDP_KEEPALIVE='0'
# save changes
commit $cfgname
EOF
return 0
}
function clear_nfqws_strat
{
local cfgname=${1:-$ZAPRET_CFG_NAME}
local TAB="$( printf '\t' )"
uci batch <<-EOF
set $cfgname.config.MODE_FILTER='hostlist'
set $cfgname.config.NFQWS_PORTS_TCP='80,443'
set $cfgname.config.NFQWS_PORTS_UDP='443'
set $cfgname.config.NFQWS_OPT='$TAB'
commit $cfgname
EOF
}
function set_cfg_nfqws_strat
{
local strat=${1:--}
local cfgname=${2:-$ZAPRET_CFG_NAME}
local TAB="$( printf '\t' )"
uci batch <<-EOF
set $cfgname.config.MODE_FILTER='hostlist'
commit $cfgname
EOF
if [ "$strat" = "empty" ]; then
clear_nfqws_strat $cfgname
fi
if [ "$strat" = "v1_by_StressOzz" ]; then
uci batch <<-EOF
set $cfgname.config.NFQWS_PORTS_TCP='80,443'
set $cfgname.config.NFQWS_PORTS_UDP='443'
set $cfgname.config.NFQWS_OPT="
# Strategy $strat
--filter-tcp=443 <HOSTLIST>
--hostlist=/opt/zapret/ipset/zapret-hosts-google.txt
--dpi-desync=fake,multidisorder
--dpi-desync-split-seqovl=681
--dpi-desync-split-pos=1
--dpi-desync-fooling=badseq
--dpi-desync-badseq-increment=10000000
--dpi-desync-repeats=2
--dpi-desync-split-seqovl-pattern=/opt/zapret/files/fake/tls_clienthello_www_google_com.bin
--dpi-desync-fake-tls-mod=rnd,dupsid,sni=fonts.google.com
--new
--filter-udp=443
--hostlist=/opt/zapret/ipset/zapret-hosts-google.txt
--hostlist-exclude=/opt/zapret/ipset/zapret-hosts-user-exclude.txt
--dpi-desync=fake
--dpi-desync-repeats=6
--dpi-desync-fake-quic=/opt/zapret/files/fake/quic_initial_www_google_com.bin
"
commit $cfgname
EOF
fi
if [ "$strat" = "v2_by_StressOzz" ]; then
uci batch <<-EOF
set $cfgname.config.NFQWS_PORTS_TCP='80,443'
set $cfgname.config.NFQWS_PORTS_UDP='443'
set $cfgname.config.NFQWS_OPT="
# Strategy $strat
--filter-tcp=443 <HOSTLIST>
--hostlist=/opt/zapret/ipset/zapret-hosts-google.txt
--hostlist-exclude-domains=openwrt.org
--dpi-desync=fake,fakeddisorder
--dpi-desync-split-pos=10,midsld
--dpi-desync-fake-tls=/opt/zapret/files/fake/tls_clienthello_www_google_com.bin
--dpi-desync-fake-tls-mod=rnd,dupsid,sni=fonts.google.com
--dpi-desync-fake-tls=0x0F0F0F0F
--dpi-desync-fake-tls-mod=none
--dpi-desync-fakedsplit-pattern=/opt/zapret/files/fake/tls_clienthello_vk_com.bin
--dpi-desync-split-seqovl=336
--dpi-desync-split-seqovl-pattern=/opt/zapret/files/fake/tls_clienthello_gosuslugi_ru.bin
--dpi-desync-fooling=badseq,badsum
--dpi-desync-badseq-increment=0
--new
--filter-udp=443
--hostlist=/opt/zapret/ipset/zapret-hosts-google.txt
--hostlist-exclude=/opt/zapret/ipset/zapret-hosts-user-exclude.txt
--dpi-desync=fake
--dpi-desync-repeats=6
--dpi-desync-fake-quic=/opt/zapret/files/fake/quic_initial_www_google_com.bin
"
commit $cfgname
EOF
fi
if [ "$strat" = "v3_by_StressOzz" ]; then
uci batch <<-EOF
set $cfgname.config.NFQWS_PORTS_TCP='80,443'
set $cfgname.config.NFQWS_PORTS_UDP='443'
set $cfgname.config.NFQWS_OPT="
# Strategy $strat
--filter-tcp=443 <HOSTLIST>
--hostlist=/opt/zapret/ipset/zapret-hosts-google.txt
--hostlist-exclude-domains=openwrt.org
--dpi-desync=fake,fakeddisorder
--dpi-desync-split-pos=10,midsld
--dpi-desync-fake-tls=/opt/zapret/files/fake/t2.bin
--dpi-desync-fake-tls-mod=rnd,dupsid,sni=m.ok.ru
--dpi-desync-fake-tls=0x0F0F0F0F
--dpi-desync-fake-tls-mod=none
--dpi-desync-fakedsplit-pattern=/opt/zapret/files/fake/tls_clienthello_vk_com.bin
--dpi-desync-split-seqovl=336
--dpi-desync-split-seqovl-pattern=/opt/zapret/files/fake/tls_clienthello_gosuslugi_ru.bin
--dpi-desync-fooling=badseq,badsum
--dpi-desync-badseq-increment=0
--new
--filter-udp=443
--hostlist=/opt/zapret/ipset/zapret-hosts-google.txt
--hostlist-exclude=/opt/zapret/ipset/zapret-hosts-user-exclude.txt
--dpi-desync=fake
--dpi-desync-repeats=6
--dpi-desync-fake-quic=/opt/zapret/files/fake/quic_initial_www_google_com.bin
"
commit $cfgname
EOF
fi
if [ "$strat" = "v4_by_StressOzz" ]; then
uci batch <<-EOF
set $cfgname.config.NFQWS_PORTS_TCP='80,443'
set $cfgname.config.NFQWS_PORTS_UDP='443'
set $cfgname.config.NFQWS_OPT="
# Strategy $strat
--filter-tcp=443
--hostlist=/opt/zapret/ipset/zapret-hosts-google.txt
--hostlist-exclude=/opt/zapret/ipset/zapret-hosts-user-exclude.txt
--hostlist-exclude-domains=openwrt.org
--dpi-desync=fake,multisplit
--dpi-desync-split-pos=2,sld
--dpi-desync-fake-tls=0x0F0F0F0F
--dpi-desync-fake-tls=/opt/zapret/files/fake/tls_clienthello_www_google_com.bin
--dpi-desync-fake-tls-mod=rnd,dupsid,sni=google.com
--dpi-desync-split-seqovl=2108
--dpi-desync-split-seqovl-pattern=/opt/zapret/files/fake/tls_clienthello_www_google_com.bin
--dpi-desync-fooling=badseq
--new
--filter-tcp=443 <HOSTLIST>
--hostlist-exclude-domains=openwrt.org
--dpi-desync-any-protocol=1
--dpi-desync-cutoff=n5
--dpi-desync=multisplit
--dpi-desync-split-seqovl=582
--dpi-desync-split-pos=1
--dpi-desync-split-seqovl-pattern=/opt/zapret/files/fake/4pda.bin
--new
--filter-udp=443
--hostlist=/opt/zapret/ipset/zapret-hosts-google.txt
--hostlist-exclude=/opt/zapret/ipset/zapret-hosts-user-exclude.txt
--dpi-desync=fake
--dpi-desync-repeats=6
--dpi-desync-fake-quic=/opt/zapret/files/fake/quic_initial_www_google_com.bin
"
commit $cfgname
EOF
fi
if [ "$strat" = "v5_by_StressOzz" ]; then
uci batch <<-EOF
set $cfgname.config.NFQWS_PORTS_TCP='80,443'
set $cfgname.config.NFQWS_PORTS_UDP='443'
set $cfgname.config.NFQWS_OPT="
# Strategy $strat
--filter-tcp=443
--hostlist=/opt/zapret/ipset/zapret-hosts-google.txt
--hostlist-exclude=/opt/zapret/ipset/zapret-hosts-user-exclude.txt
--hostlist-exclude-domains=openwrt.org
--ip-id=zero
--dpi-desync=multisplit
--dpi-desync-split-seqovl=681
--dpi-desync-split-pos=1
--dpi-desync-split-seqovl-pattern=/opt/zapret/files/fake/tls_clienthello_www_google_com.bin
--new
--filter-tcp=443 <HOSTLIST>
--hostlist-exclude-domains=openwrt.org
--dpi-desync=fake,fakeddisorder
--dpi-desync-split-pos=10,midsld
--dpi-desync-fake-tls=/opt/zapret/files/fake/max.bin
--dpi-desync-fake-tls-mod=rnd,dupsid
--dpi-desync-fake-tls=0x0F0F0F0F
--dpi-desync-fake-tls-mod=none
--dpi-desync-fakedsplit-pattern=/opt/zapret/files/fake/tls_clienthello_vk_com.bin
--dpi-desync-fooling=badseq,badsum
--dpi-desync-badseq-increment=0
--new
--filter-udp=443
--hostlist=/opt/zapret/ipset/zapret-hosts-google.txt
--hostlist-exclude=/opt/zapret/ipset/zapret-hosts-user-exclude.txt
--dpi-desync=fake
--dpi-desync-repeats=6
--dpi-desync-fake-quic=/opt/zapret/files/fake/quic_initial_www_google_com.bin
"
commit $cfgname
EOF
fi
if [ "$strat" = "v6_by_StressOzz" ]; then
uci batch <<-EOF
set $cfgname.config.NFQWS_PORTS_TCP='80,443,2053,2083,2087,2096,8443'
set $cfgname.config.NFQWS_PORTS_UDP='443,19294-19344,50000-50100'
set $cfgname.config.NFQWS_OPT="
# Strategy $strat
--filter-tcp=443
--hostlist=/opt/zapret/ipset/zapret-hosts-google.txt
--dpi-desync=multisplit
--dpi-desync-split-pos=1,sniext+1
--dpi-desync-split-seqovl=1
--new
--filter-tcp=443 <HOSTLIST>
--dpi-desync=hostfakesplit
--dpi-desync-hostfakesplit-mod=host=rzd.ru
--dpi-desync-hostfakesplit-midhost=host-2
--dpi-desync-split-seqovl=726
--dpi-desync-fooling=badsum,badseq
--dpi-desync-badseq-increment=0
--new
--filter-udp=443 <HOSTLIST_NOAUTO>
--dpi-desync=fake
--dpi-desync-repeats=6
--dpi-desync-fake-quic=/opt/zapret/files/fake/quic_initial_www_google_com.bin
--new
--filter-udp=19294-19344,50000-50100
--filter-l7=discord,stun
--dpi-desync=fake
--dpi-desync-repeats=6
--new
--filter-tcp=2053,2083,2087,2096,8443
--hostlist-domains=discord.media
--dpi-desync=multisplit
--dpi-desync-split-seqovl=652
--dpi-desync-split-pos=2
--dpi-desync-split-seqovl-pattern=/opt/zapret/files/fake/tls_clienthello_www_google_com.bin
"
commit $cfgname
EOF
fi
if [ "$strat" = "ALT7_by_Flowseal" ]; then
uci batch <<-EOF
set $cfgname.config.NFQWS_PORTS_TCP='80,443'
set $cfgname.config.NFQWS_PORTS_UDP='443'
set $cfgname.config.NFQWS_OPT="
# Strategy $strat
--filter-tcp=443
--hostlist=/opt/zapret/ipset/zapret-hosts-google.txt
--hostlist-exclude=/opt/zapret/ipset/zapret-hosts-user-exclude.txt
--hostlist-exclude-domains=openwrt.org
--ip-id=zero
--dpi-desync=multisplit
--dpi-desync-split-pos=2,sniext+1
--dpi-desync-split-seqovl=679
--dpi-desync-split-seqovl-pattern=/opt/zapret/files/fake/tls_clienthello_www_google_com.bin
--new
--filter-tcp=80,443 <HOSTLIST>
--hostlist-exclude-domains=openwrt.org
--dpi-desync=multisplit
--dpi-desync-split-pos=2,sniext+1
--dpi-desync-split-seqovl=679
--dpi-desync-split-seqovl-pattern=/opt/zapret/files/fake/tls_clienthello_www_google_com.bin
--new
--filter-udp=443
--hostlist=/opt/zapret/ipset/zapret-hosts-google.txt
--hostlist-exclude=/opt/zapret/ipset/zapret-hosts-user-exclude.txt
--dpi-desync=fake
--dpi-desync-repeats=6
--dpi-desync-fake-quic=/opt/zapret/files/fake/quic_initial_www_google_com.bin
"
commit $cfgname
EOF
fi
if [ "$strat" = "TLS_AUTO_ALT3_by_Flowseal" ]; then
uci batch <<-EOF
set $cfgname.config.NFQWS_PORTS_TCP='80,443'
set $cfgname.config.NFQWS_PORTS_UDP='443'
set $cfgname.config.NFQWS_OPT="
# Strategy $strat
--filter-tcp=443
--hostlist=/opt/zapret/ipset/zapret-hosts-google.txt
--hostlist-exclude=/opt/zapret/ipset/zapret-hosts-user-exclude.txt
--hostlist-exclude-domains=openwrt.org
--ip-id=zero
--dpi-desync=fake,multisplit
--dpi-desync-split-seqovl=681
--dpi-desync-split-pos=1
--dpi-desync-fooling=ts
--dpi-desync-repeats=8
--dpi-desync-split-seqovl-pattern=/opt/zapret/files/fake/tls_clienthello_www_google_com.bin
--dpi-desync-fake-tls-mod=rnd,dupsid,sni=www.google.com
--new
--filter-tcp=80,443 <HOSTLIST>
--hostlist-exclude-domains=openwrt.org
--dpi-desync=fake,multisplit
--dpi-desync-split-seqovl=681
--dpi-desync-split-pos=1
--dpi-desync-fooling=ts
--dpi-desync-repeats=8
--dpi-desync-split-seqovl-pattern=/opt/zapret/files/fake/tls_clienthello_www_google_com.bin
--dpi-desync-fake-tls-mod=rnd,dupsid,sni=www.google.com
--new
--filter-udp=443
--hostlist=/opt/zapret/ipset/zapret-hosts-google.txt
--hostlist-exclude=/opt/zapret/ipset/zapret-hosts-user-exclude.txt
--dpi-desync=fake
--dpi-desync-repeats=11
--dpi-desync-fake-quic=/opt/zapret/files/fake/quic_initial_www_google_com.bin
"
commit $cfgname
EOF
fi
return 0
}
function set_cfg_default_values
{
local opt_flags=${1:--}
local opt_strat=${2:-v6_by_StressOzz}
local cfgname=${3:-$ZAPRET_CFG_NAME}
if ! echo "$opt_flags" | grep -q "(skip_base)"; then
set_cfg_reset_values $cfgname
fi
if [ "$opt_strat" != "-" ]; then
set_cfg_nfqws_strat "$opt_strat" $cfgname
fi
if echo "$opt_flags" | grep -q "(set_mode_autohostlist)"; then
uci batch <<-EOF
set $cfgname.config.MODE_FILTER='autohostlist'
commit $cfgname
EOF
fi
return 0
}

View File

@@ -1,119 +0,0 @@
#!/bin/sh
# Copyright (c) 2026 remittor
. /opt/zapret/comfunc.sh
ZAP_TMP_DIR=/tmp/zapret_dwc
rm -rf $ZAP_TMP_DIR
CURL_TIMEOUT=5
CURL_RANGETO=65535
if ! command -v curl >/dev/null 2>&1; then
echo "ERROR: package \"curl\" not installed!"
return 10
fi
CURL_INFO=$( curl -V )
if ! echo "$CURL_INFO" | grep -q 'https'; then
echo "------- package curl"
echo "$CURL_INFO"
echo "-------"
echo "ERROR: package \"curl\" not supported HTTPS protocol!"
echo "NOTE: Please install package \"curl-ssl\""
return 11
fi
#echo 'Original sources: https://github.com/hyperion-cs/dpi-checkers'
#echo 'WEB-version: https://hyperion-cs.github.io/dpi-checkers/ru/tcp-16-20/'
TEST_SUITE='[
{ id: "US.CF-01", provider: "🇺🇸 Cloudflare", times: 1, url: "https://img.wzstats.gg/cleaver/gunFullDisplay" },
{ id: "US.CF-02", provider: "🇺🇸 Cloudflare", times: 1, url: "https://genshin.jmp.blue/characters/all#" },
{ id: "US.CF-03", provider: "🇺🇸 Cloudflare", times: 1, url: "https://api.frankfurter.dev/v1/2000-01-01..2002-12-31" },
{ id: "US.CF-04", provider: "🇨🇦 Cloudflare", times: 1, url: "https://www.bigcartel.com/" },
{ id: "US.DO-01", provider: "🇺🇸 DigitalOcean", times: 2, url: "https://genderize.io/" },
{ id: "DE.HE-01", provider: "🇩🇪 Hetzner", times: 1, url: "https://j.dejure.org/jcg/doctrine/doctrine_banner.webp" },
{ id: "DE.HE-02", provider: "🇩🇪 Hetzner", times: 1, url: "https://maps.gnosis.earth/ogcapi/api/swagger-ui/swagger-ui-standalone-preset.js#" },
{ id: "FI.HE-01", provider: "🇫🇮 Hetzner", times: 1, url: "https://251b5cd9.nip.io/1MB.bin" },
{ id: "FI.HE-02", provider: "🇫🇮 Hetzner", times: 1, url: "https://5fd8c176.nip.io/1MB.bin" },
{ id: "FI.HE-03", provider: "🇫🇮 Hetzner", times: 1, url: "https://5fd8bdae.nip.io/1MB.bin" },
{ id: "FI.HE-04", provider: "🇫🇮 Hetzner", times: 1, url: "https://5fd8bca5.nip.io/1MB.bin" },
{ id: "FR.OVH-01", provider: "🇫🇷 OVH", times: 1, url: "https://eu.api.ovh.com/console/rapidoc-min.js" },
{ id: "FR.OVH-02", provider: "🇫🇷 OVH", times: 1, url: "https://ovh.sfx.ovh/10M.bin" },
{ id: "SE.OR-01", provider: "🇸🇪 Oracle", times: 1, url: "https://oracle.sfx.ovh/10M.bin" },
{ id: "DE.AWS-01", provider: "🇩🇪 AWS", times: 1, url: "https://www.getscope.com/assets/fonts/fa-solid-900.woff2" },
{ id: "US.AWS-01", provider: "🇺🇸 AWS", times: 1, url: "https://corp.kaltura.com/wp-content/cache/min/1/wp-content/themes/airfleet/dist/styles/theme.css" },
{ id: "US.GC-01", provider: "🇺🇸 Google Cloud", times: 1, url: "https://api.usercentrics.eu/gvl/v3/en.json" },
{ id: "US.FST-01", provider: "🇺🇸 Fastly", times: 1, url: "https://www.jetblue.com/main.c7b61d59416f714f.js" },
{ id: "CA.FST-01", provider: "🇨🇦 Fastly", times: 1, url: "https://www.cnn10.com/" },
{ id: "US.AKM-01", provider: "🇺🇸 Akamai", times: 1, url: "https://www.roxio.com/static/roxio/images/products/creator/nxt9/call-action-footer-bg.jpg" },
{ id: "PL.AKM-01", provider: "🇵🇱 Akamai", times: 1, url: "https://media-assets.stryker.com/is/image/stryker/gateway_1?$max_width_1410$" },
{ id: "US.CDN77-01", provider: "🇺🇸 CDN77", times: 1, url: "https://cdn.eso.org/images/banner1920/eso2520a.jpg" },
{ id: "FR.CNTB-01", provider: "🇫🇷 Contabo", times: 1, url: "https://airsea.no/images/main_logo.png" },
{ id: "NL.SW-01", provider: "🇳🇱 Scaleway", times: 1, url: "https://www.velivole.fr/img/header.jpg" },
{ id: "US.CNST-01", provider: "🇺🇸 Constant", times: 1, url: "https://cdn.xuansiwei.com/common/lib/font-awesome/4.7.0/fontawesome-webfont.woff2?v=4.7.0" }
]'
function trim
{
echo "$1" | sed 's/^[[:space:]]*//;s/[[:space:]]*$//'
}
mkdir -p $ZAP_TMP_DIR
ID=0
while IFS='|' read -r TAG PROVIDER TIMES URL; do
[ -z "$TAG" ] && continue
ID=$((ID+1))
ID3=$(printf '%03d' "$ID")
COUNTRY="$(echo "$TAG" | cut -d. -f1)"
CNTFLAG="$(echo "$PROVIDER" | awk '{print $1}')"
PROVIDER="$(echo "$PROVIDER" | cut -d' ' -f2-)"
URL_NO_PROTO="${URL#*://}"
DOMAIN="${URL_NO_PROTO%%/*}"
URLPATH="/${URL_NO_PROTO#*/}"
[ "$URLPATH" = "/$URL_NO_PROTO" ] && URLPATH="/"
#echo "TAG=$TAG , COUNTRY=$COUNTRY , PROVIDER=$PROVIDER , TIMES=$TIMES , URL=$URL"
(
DST_IP=$( curl -4 -s -o /dev/null -w '%{remote_ip}\n' $DOMAIN )
if [ -z "$DST_IP" ]; then
DST_IP="$( ping -c1 "$DOMAIN" 2>/dev/null | sed -n '1s/.*(\([0-9.]*\)).*/\1/p')"
fi
curl -k $URL --resolve $DOMAIN:443:$DST_IP -o /dev/null -s -w '%{size_download}\n' --max-time $CURL_TIMEOUT --range 0-$CURL_RANGETO
) >"$ZAP_TMP_DIR/$ID3=$TAG=$PROVIDER.txt" 2>&1 &
done <<EOF
$(printf '%s\n' "$TEST_SUITE" | sed -n '
s/.*id:[[:space:]]*"\([^"]*\)".*provider:[[:space:]]*"\([^"]*\)".*times:[[:space:]]*\([0-9]\+\).*url:[[:space:]]*"\([^"]*\)".*/\1|\2|\3|\4/p
')
EOF
wait
printf '%s\n' "$ZAP_TMP_DIR"/*.txt | sort | while IFS= read -r file; do
[ -f "$file" ] || continue
FNAME="${file##*/}"
ID=$( echo "$FNAME" | cut -d= -f1)
TAG=$( echo "$FNAME" | cut -d= -f2)
PROVIDER=$(echo "$FNAME" | cut -d= -f3 | sed 's/\.txt$//' )
res=$( cat "$file" )
res=$( trim "$res" )
status=
case "$res" in
''|*[!0-9]*)
status="Error (incorrect value)"
;;
esac
if [ -z "$status" ]; then
if [ "$res" = 0 ]; then
status="Possibly detected"
elif [ "$res" -lt $CURL_RANGETO ]; then
status="Failed to complete detection"
else
status="[ OK ]"
fi
fi
printf '%12s / %-13s: %s \n' "$TAG" "$PROVIDER" "$status"
done
return 0

336
zapret2/Makefile Normal file
View File

@@ -0,0 +1,336 @@
#
# Copyright (c) 2025 remittor
#
include $(TOPDIR)/rules.mk
PKG_NAME:=zapret2
PKG_VERSION:=0.8.20260125
PKG_RELEASE:=1
PKG_MAINTAINER:=bol-van
PKG_LICENSE:=MIT
PKG_LICENSE_FILES:=docs/LICENSE.txt
PKG_SOURCE_URL:=https://github.com/bol-van/zapret2.git
PKG_SOURCE_PROTO:=git
PKG_SOURCE_VERSION:=8b11d6c279c737bf78496d04c0261bd3e2c4327f
PKG_SOURCE_DATE:=2026-01-25
#PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
#PKG_SOURCE_URL:=https://github.com/bol-van/zapret2/archive/refs/tags/v$(PKG_VERSION).tar.gz?
#PKG_HASH:=skip
LUA_JIT?=1
ifeq ($(LUA_JIT),1)
LUAJIT_VER?=2.1
LUA_VER?=5.1
LUA_DEPEND:=luajit
LUA_INCLUDE:=-I$(STAGING_DIR)/usr/include/luajit-$(LUAJIT_VER)
LUA_LIBRARY:=-L$(STAGING_DIR)/usr/lib -lluajit-$(LUA_VER)
else
LUA_VER?=5.5
LUA_DEPEND:=lua$(LUA_VER)
LUA_INCLUDE:=-I$(STAGING_DIR)/usr/include/lua$(LUA_VER)
LUA_LIBRARY:=-L$(STAGING_DIR)/usr/lib -llua$(LUA_VER)
endif
include $(INCLUDE_DIR)/package.mk
#TAR_OPTIONS:=--strip-components 1 $(TAR_OPTIONS)
#TAR_CMD=$(HOST_TAR) -C $(1) $(TAR_OPTIONS)
MAKE_PATH:=nfq2
define Package/$(PKG_NAME)
SECTION:=net
CATEGORY:=Network
TITLE:=$(PKG_NAME)
SUBMENU:=Zapret2
URL:=https://github.com/bol-van/zapret2
DEPENDS:= +nftables +curl +gzip +$(LUA_DEPEND)
DEPENDS+= +coreutils +coreutils-sort +coreutils-sleep
DEPENDS+= +kmod-nft-nat +kmod-nft-offload +kmod-nft-queue
DEPENDS+= +libnetfilter-queue +libcap +zlib
endef
define Build/Prepare
$(Build/Prepare/Default)
rm -f $(PKG_BUILD_DIR)/$(MAKE_PATH)/nfqws2
rm -f $(PKG_BUILD_DIR)/ip2net/ip2net
rm -f $(PKG_BUILD_DIR)/mdig/mdig
endef
#define Build/Configure
#endef
define Build/Compile
$(MAKE) -C $(PKG_BUILD_DIR)/$(MAKE_PATH) $(TARGET_CONFIGURE_OPTS) LUA_JIT=$(LUA_JIT) LUA_CFLAGS="$(LUA_INCLUDE)" LUA_LIB="$(LUA_LIBRARY)"
$(MAKE) -C $(PKG_BUILD_DIR)/ip2net $(TARGET_CONFIGURE_OPTS)
$(MAKE) -C $(PKG_BUILD_DIR)/mdig $(TARGET_CONFIGURE_OPTS)
endef
ZAPRET_DIR := /opt/zapret2
define ZAPRET_CONFFILES_LIST
$(ZAPRET_DIR)/config
$(ZAPRET_DIR)/ipset/zapret-hosts-google.txt
$(ZAPRET_DIR)/ipset/zapret-hosts-user.txt
$(ZAPRET_DIR)/ipset/zapret-hosts-user-exclude.txt
$(ZAPRET_DIR)/ipset/zapret-ip-exclude.txt
$(ZAPRET_DIR)/ipset/zapret-hosts-auto.txt
$(ZAPRET_DIR)/ipset/cust1.txt
$(ZAPRET_DIR)/ipset/cust2.txt
$(ZAPRET_DIR)/ipset/cust3.txt
$(ZAPRET_DIR)/ipset/cust4.txt
$(ZAPRET_DIR)/init.d/openwrt/custom.d/10-script.sh
$(ZAPRET_DIR)/init.d/openwrt/custom.d/20-script.sh
$(ZAPRET_DIR)/init.d/openwrt/custom.d/50-script.sh
$(ZAPRET_DIR)/init.d/openwrt/custom.d/60-script.sh
$(ZAPRET_DIR)/init.d/openwrt/custom.d/90-script.sh
endef
$(eval ZAPRET_CONFFILES := $(foreach file,$(ZAPRET_CONFFILES_LIST),$(strip $(file))))
define Package/$(PKG_NAME)/conffiles
$(ZAPRET_CONFFILES_LIST)
endef
define Package/$(PKG_NAME)/install
$(INSTALL_DIR) $(1)$(ZAPRET_DIR)
$(INSTALL_DIR) $(1)$(ZAPRET_DIR)/$(MAKE_PATH)
$(INSTALL_BIN) $(PKG_BUILD_DIR)/$(MAKE_PATH)/nfqws2 $(1)$(ZAPRET_DIR)/$(MAKE_PATH)/
$(INSTALL_DIR) $(1)$(ZAPRET_DIR)/ip2net
$(INSTALL_BIN) $(PKG_BUILD_DIR)/ip2net/ip2net $(1)$(ZAPRET_DIR)/ip2net/
$(INSTALL_DIR) $(1)$(ZAPRET_DIR)/mdig
$(INSTALL_BIN) $(PKG_BUILD_DIR)/mdig/mdig $(1)$(ZAPRET_DIR)/mdig/
$(INSTALL_DIR) $(1)$(ZAPRET_DIR)/common
$(CP) $(PKG_BUILD_DIR)/common/* $(1)$(ZAPRET_DIR)/common/
$(INSTALL_DIR) $(1)$(ZAPRET_DIR)/lua
$(CP) $(PKG_BUILD_DIR)/lua/* $(1)$(ZAPRET_DIR)/lua/
#$(INSTALL_DIR) $(1)$(ZAPRET_DIR)docs
#$(CP) $(PKG_BUILD_DIR)/docs/* $(1)$(ZAPRET_DIR)/docs/
$(INSTALL_DIR) $(1)$(ZAPRET_DIR)/files
$(CP) $(PKG_BUILD_DIR)/files/* $(1)$(ZAPRET_DIR)/files/
$(CP) ./files/* $(1)$(ZAPRET_DIR)/files/
$(INSTALL_DIR) $(1)$(ZAPRET_DIR)/ipset
$(CP) $(PKG_BUILD_DIR)/ipset/* $(1)$(ZAPRET_DIR)/ipset/
$(INSTALL_DIR) $(1)$(ZAPRET_DIR)/blockcheck2.d
$(CP) $(PKG_BUILD_DIR)/blockcheck2.d/* $(1)$(ZAPRET_DIR)/blockcheck2.d/
$(INSTALL_BIN) $(PKG_BUILD_DIR)/blockcheck2.sh $(1)$(ZAPRET_DIR)/blockcheck2.sh
$(INSTALL_DIR) $(1)$(ZAPRET_DIR)/tmp
$(INSTALL_DIR) $(1)$(ZAPRET_DIR)/init.d/openwrt
$(CP) $(PKG_BUILD_DIR)/init.d/openwrt/* $(1)$(ZAPRET_DIR)/init.d/openwrt/
$(INSTALL_DIR) $(1)/etc/hotplug.d/iface
$(INSTALL_BIN) $(PKG_BUILD_DIR)/init.d/openwrt/90-zapret2 $(1)/etc/hotplug.d/iface/90-zapret2
$(INSTALL_DIR) $(1)/etc/init.d
$(INSTALL_BIN) ./init.d.sh $(1)/etc/init.d/zapret2
$(INSTALL_DIR) $(1)$(ZAPRET_DIR)/init.d
$(INSTALL_DIR) $(1)$(ZAPRET_DIR)/init.d/openwrt
$(INSTALL_DIR) $(1)$(ZAPRET_DIR)/init.d/openwrt/custom.d
$(INSTALL_DIR) $(1)/etc/uci-defaults
$(INSTALL_BIN) ./uci-def-cfg.sh $(1)/etc/uci-defaults/zapret2-uci-def-cfg.sh
# install all sh-scripts
$(CP) ./*.sh $(1)$(ZAPRET_DIR)/
rm -f $(1)$(ZAPRET_DIR)/init.d.sh
# Install conf files
$(foreach cfg,$(ZAPRET_CONFFILES), \
rel="$(cfg:$(ZAPRET_DIR)/%=%)"; \
src="./$$$$rel"; \
if echo "$$$$rel" | grep -q "/custom.d/"; then \
src="./custom.d/$$$$(basename $$$$rel)"; \
fi; \
dst="$(1)$(cfg)"; \
mkdir -p "$(1)$(dir $(cfg))"; \
rm -f "$$$${dst}"; \
if [ -f "$$$${src}" ]; then \
$(INSTALL_DATA) "$$$${src}" "$$$${dst}"; \
else \
$(INSTALL_DATA) /dev/null "$$$${dst}"; \
fi; \
)
# Fix main config file
rm -f $(1)$(ZAPRET_DIR)/config
$(INSTALL_DATA) ./config.default $(1)$(ZAPRET_DIR)/config
$(INSTALL_DATA) ./config.default $(1)$(ZAPRET_DIR)/config.default
# Install def conf files
$(INSTALL_DIR) $(1)$(ZAPRET_DIR)/ipset_def
$(CP) ./ipset/zapret*.txt $(1)$(ZAPRET_DIR)/ipset_def/
# Fix permissions
chmod 644 $(1)$(ZAPRET_DIR)/ipset/*.txt
chmod 644 $(1)$(ZAPRET_DIR)/ipset_def/*.txt
chmod 644 $(1)$(ZAPRET_DIR)/init.d/openwrt/custom.d/*.sh
chmod 644 $(1)$(ZAPRET_DIR)/config*
chmod 755 $(1)$(ZAPRET_DIR)/*.sh
chmod 755 $(1)$(ZAPRET_DIR)/$(MAKE_PATH)/*
chmod 755 $(1)$(ZAPRET_DIR)/ip2net/*
chmod 755 $(1)$(ZAPRET_DIR)/mdig/*
endef
define Package/$(PKG_NAME)/preinst
#!/bin/sh
# check if we are on real system
if [ -z "$${IPKG_INSTROOT}" ]; then
ZAPRET_DIR=/opt/zapret2
ZAPRET_INITD=/etc/init.d/zapret2
ZAPRET_CFG=/etc/config/zapret2
if [ -f "$${ZAPRET_INITD}" ]; then
SCRIPT=$$( readlink "$${ZAPRET_INITD}" )
if [ -n "$${SCRIPT}" ]; then
echo "Please uninstall incompatible \"zapret2\" service!"
exit 44
fi
fi
if command -v apk >/dev/null; then
PKG_MGR="apk"
PKG_CHECK="apk info -e "
PKG_REMOVE="apk del --force "
else
PKG_MGR="opkg"
PKG_CHECK="opkg status "
PKG_REMOVE="opkg remove --force-remove "
fi
if [ "$${PKG_UPGRADE}" = "1" ]; then
# stop service if PKG_UPGRADE
if [ -x "$${ZAPRET_INITD}" ]; then
$${ZAPRET_INITD} running && $${ZAPRET_INITD} stop >/dev/null 2>&1
fi
fi
if $${PKG_CHECK} zapret2 >/dev/null 2>&1; then
if [ ! -f "/opt/zapret2/sync_config.sh" ]; then
echo "Please uninstall incompatible \"zapret2\" package!"
exit 47
fi
if [ -f "$${ZAPRET_CFG}" ] && ! grep -q "run_on_boot" "$${ZAPRET_CFG}"; then
echo "Please uninstall incompatible \"zapret2\" package!"
exit 48
fi
fi
if $${PKG_CHECK} luci-app-zapret2 >/dev/null 2>&1; then
SVC_FILE=/www/luci-static/resources/view/zapret2/service.js
if [ ! -f "$${SVC_FILE}" ] || ! grep -Fq "/remittor/zapret-openwrt" "$${SVC_FILE}"; then
echo "Please uninstall incompatible \"luci-app-zapret2\" package!"
exit 55
fi
fi
if [ -f "$${ZAPRET_CFG}" ] && ! grep -q "run_on_boot" "$${ZAPRET_CFG}"; then
if [ -x "$${ZAPRET_INITD}" ]; then
$${ZAPRET_INITD} running && $${ZAPRET_INITD} stop >/dev/null 2>&1
fi
rm -f $${ZAPRET_CFG}
rm -f $${ZAPRET_INITD}
[ -d "$${ZAPRET_DIR}" ] && rm -rf $${ZAPRET_DIR}
echo "All files of the previously installed package have been removed!"
fi
if $${PKG_CHECK} zapret2-mdig >/dev/null 2>&1; then
$${PKG_REMOVE} zapret2-mdig
fi
if $${PKG_CHECK} zapret2-ip2net >/dev/null 2>&1; then
$${PKG_REMOVE} zapret2-ip2net
fi
if [ ! -d "$${ZAPRET_DIR}" ]; then
mkdir -p $${ZAPRET_DIR}
fi
fi
exit 0
endef
define Package/$(PKG_NAME)/postinst
#!/bin/sh
# check if we are on real system
if [ -z "$${IPKG_INSTROOT}" ]; then
ZAPRET_DIR=/opt/zapret2
ZAPRET_INITD=/etc/init.d/zapret2
ZAPRET_CFG=/etc/config/zapret2
ZAPRET_CONFIG=/opt/zapret2/config
ZAPRET_CONFIG_DEF="/opt/zapret2/config.default"
# Fix permissions
chmod 644 $${ZAPRET_CFG} >/dev/null 2>&1
chmod 644 $${ZAPRET_DIR}/ipset/*.txt >/dev/null 2>&1
chmod 644 $${ZAPRET_DIR}/ipset_def/*.txt >/dev/null 2>&1
chmod 644 $${ZAPRET_DIR}/init.d/openwrt/custom.d/*.sh >/dev/null 2>&1
chmod 644 $${ZAPRET_DIR}/config* >/dev/null 2>&1
# cleanup custom.d directory
rm -f $${ZAPRET_DIR}/init.d/openwrt/custom.d/*-opkg*
rm -f $${ZAPRET_DIR}/init.d/openwrt/custom.d/*.opkg*
rm -f $${ZAPRET_DIR}/init.d/openwrt/custom.d/*.apk*
# creating main config if its not exists
if [ ! -f "$${ZAPRET_CONFIG}" ]; then
cp -f "$${ZAPRET_CONFIG_DEF}" "$${ZAPRET_CONFIG}"
fi
# remove fake uci-config
[ -f "$${ZAPRET_CFG}" ] && [ ! -s "$${ZAPRET_CFG}" ] && rm -f "$${ZAPRET_CFG}"
# check existing uci-config
[ -f "$${ZAPRET_CFG}" ] && ZAPRET_CFG_EXISTS=1 || ZAPRET_CFG_EXISTS=0
# create or merge uci-config
/opt/zapret2/uci-def-cfg.sh
[ "$${ZAPRET_CFG_EXISTS}" = "1" ] && echo "Config /etc/config/zapret2 merged with default uci-config"
# remove uci-default script from system dir (used into /etc/init.d/boot)
rm -f /etc/uci-defaults/zapret2-uci-def-cfg.sh
# copy (sync) all params from uci-config to main config
/opt/zapret2/sync_config.sh
# check main config
sh -n "$${ZAPRET_CONFIG}" 2>/dev/null || cp -f "$${ZAPRET_CONFIG_DEF}" "$${ZAPRET_CONFIG}"
sh -n "$${ZAPRET_CONFIG}" 2>/dev/null || exit 58
# enable main service
$${ZAPRET_INITD} enable
# stop all
$${ZAPRET_INITD} stop_fw >/dev/null 2>&1
$${ZAPRET_INITD} stop_daemons >/dev/null 2>&1
ps w | grep '/opt/zapret2/nfq2/nfqws2' | grep -v grep | awk '{print $$1}' | xargs -r kill -9
# start main service
$${ZAPRET_INITD} start
# restart firewall
[ -x /sbin/fw4 ] && fw4 -q restart || fw3 -q restart
fi
exit 0
endef
define Package/$(PKG_NAME)/prerm
#!/bin/sh
# check if we are on real system
if [ -z "$${IPKG_INSTROOT}" ]; then
ZAPRET_DIR=/opt/zapret2
ZAPRET_BASE=/opt/zapret2
ZAPRET_INITD=/etc/init.d/zapret2
ZAPRET_CFG=/etc/config/zapret2
ZAPRET_CONFIG=/opt/zapret2/config
ZAPRET_CONFIG_DEF="/opt/zapret2/config.default"
OPENWRT_FW_INCLUDE=/etc/firewall.zapret2
# check main config
sh -n "$${ZAPRET_CONFIG}" 2>/dev/null || cp -f "$${ZAPRET_CONFIG_DEF}" "$${ZAPRET_CONFIG}"
if ! sh -n "$${ZAPRET_CONFIG}" 2>/dev/null ; then
ps w | grep '/opt/zapret2/nfq2/nfqws2' | grep -v grep | awk '{print $$1}' | xargs -r kill -9
exit 0
fi
. "$${ZAPRET_CONFIG}"
. "$${ZAPRET_BASE}/common/base.sh"
. "$${ZAPRET_BASE}/common/fwtype.sh"
. "$${ZAPRET_BASE}/common/nft.sh"
. "$${ZAPRET_BASE}/common/installer.sh"
$${ZAPRET_INITD} running && $${ZAPRET_INITD} stop >/dev/null 2>&1
$${ZAPRET_INITD} disable >/dev/null 2>&1
ps w | grep '/opt/zapret2/nfq2/nfqws2' | grep -v grep | awk '{print $$1}' | xargs -r kill -9
remove_openwrt_firewall
nft_del_table
restart_openwrt_firewall
fi
exit 0
endef
define Package/$(PKG_NAME)/postrm
#!/bin/sh
# check if we are on real system
if [ -z "$${IPKG_INSTROOT}" ]; then
rm -f /etc/config/zapret2-opkg*
rm -f /etc/config/zapret2.opkg*
rm -f /etc/config/zapret2.apk*
[ -f "/opt/zapret2/config" ] && cp -f /opt/zapret2/config "/opt/zapret2/config.backup"
#rm -rf /opt/zapret2
#echo "Directory /opt/zapret2 removed!"
fi
exit 0
endef
$(eval $(call BuildPackage,$(PKG_NAME)))

View File

@@ -1,20 +1,20 @@
#!/bin/sh #!/bin/sh
# Copyright (c) 2024 remittor # Copyright (c) 2024 remittor
EXEDIR=/opt/zapret EXEDIR=/opt/zapret2
ZAPRET_BASE=/opt/zapret ZAPRET_BASE=/opt/zapret2
ZAPRET_INITD=/etc/init.d/zapret ZAPRET_INITD=/etc/init.d/zapret2
ZAPRET_ORIG_INITD="$ZAPRET_BASE/init.d/openwrt/zapret" ZAPRET_ORIG_INITD="$ZAPRET_BASE/init.d/openwrt/zapret2"
ZAP_LOG_TAG=ZAPRET ZAP_LOG_TAG=ZAPRET2
ZAPRET_CONFIG="$ZAPRET_BASE/config" ZAPRET_CONFIG="$ZAPRET_BASE/config"
ZAPRET_CONFIG_NEW="$ZAPRET_BASE/config.new" ZAPRET_CONFIG_NEW="$ZAPRET_BASE/config.new"
ZAPRET_CONFIG_DEF="$ZAPRET_BASE/config.default" ZAPRET_CONFIG_DEF="$ZAPRET_BASE/config.default"
ZAPRET_CFG=/etc/config/zapret ZAPRET_CFG=/etc/config/zapret2
ZAPRET_CFG_NAME=zapret ZAPRET_CFG_NAME=zapret2
ZAPRET_CFG_SEC=$ZAPRET_CFG_NAME.config ZAPRET_CFG_SEC=$ZAPRET_CFG_NAME.config
ZAPRET_CFG_SEC_NAME="$( uci -q get $ZAPRET_CFG_SEC )" ZAPRET_CFG_SEC_NAME="$( uci -q get $ZAPRET_CFG_SEC )"
@@ -179,7 +179,7 @@ function insert_cron_task_logs
{ {
[ ! -f "$CRONTAB_FILE" ] && touch "$CRONTAB_FILE" [ ! -f "$CRONTAB_FILE" ] && touch "$CRONTAB_FILE"
[ ! -f "$CRONTAB_FILE" ] && return 1 [ ! -f "$CRONTAB_FILE" ] && return 1
if ! grep -q -e "-name '$ZAPRET_CFG_NAME\*\.log' -size \+" "$CRONTAB_FILE"; then if ! grep -q -e "-name '$ZAPRET_CFG_NAME+\*\.log' -size \+" "$CRONTAB_FILE"; then
echo "*/2 * * * * /usr/bin/find /tmp -maxdepth 1 -type f -name '$ZAPRET_CFG_NAME+*.log' -size +2600k -exec rm -f {} \;" >> "$CRONTAB_FILE" echo "*/2 * * * * /usr/bin/find /tmp -maxdepth 1 -type f -name '$ZAPRET_CFG_NAME+*.log' -size +2600k -exec rm -f {} \;" >> "$CRONTAB_FILE"
/etc/init.d/cron restart 2> /dev/null /etc/init.d/cron restart 2> /dev/null
fi fi
@@ -193,6 +193,9 @@ function init_before_start
[ ! -f "$HOSTLIST_FN" ] && touch "$HOSTLIST_FN" [ ! -f "$HOSTLIST_FN" ] && touch "$HOSTLIST_FN"
chmod 644 $ZAPRET_BASE/ipset/*.txt chmod 644 $ZAPRET_BASE/ipset/*.txt
chmod 666 $ZAPRET_BASE/ipset/*.log chmod 666 $ZAPRET_BASE/ipset/*.log
rm -f $ZAPRET_BASE/init.d/openwrt/custom.d/*-opkg*
rm -f $ZAPRET_BASE/init.d/openwrt/custom.d/*.opkg*
rm -f $ZAPRET_BASE/init.d/openwrt/custom.d/*.apk*
rm -f /tmp/$ZAPRET_CFG_NAME+*.log rm -f /tmp/$ZAPRET_CFG_NAME+*.log
#*/ #*/
if [ "$DAEMON_LOG_ENABLE" = "1" ]; then if [ "$DAEMON_LOG_ENABLE" = "1" ]; then

View File

@@ -30,14 +30,25 @@ IP2NET_OPT4="--prefix-length=22-30 --v4-threshold=3/4"
IP2NET_OPT6="--prefix-length=56-64 --v6-threshold=5" IP2NET_OPT6="--prefix-length=56-64 --v6-threshold=5"
# options for auto hostlist # options for auto hostlist
# NOTE : in order for these adjustment to work it's required to redirect enough starting packets
# NOTE : set PKT_IN, PKT_OUT variables appropriately
AUTOHOSTLIST_INCOMING_MAXSEQ=4096
AUTOHOSTLIST_RETRANS_MAXSEQ=32768
AUTOHOSTLIST_RETRANS_RESET=1
AUTOHOSTLIST_RETRANS_THRESHOLD=3 AUTOHOSTLIST_RETRANS_THRESHOLD=3
AUTOHOSTLIST_FAIL_THRESHOLD=3 AUTOHOSTLIST_FAIL_THRESHOLD=3
AUTOHOSTLIST_FAIL_TIME=60 AUTOHOSTLIST_FAIL_TIME=60
AUTOHOSTLIST_UDP_IN=1
AUTOHOSTLIST_UDP_OUT=4
# 1 = debug autohostlist positives to ipset/zapret-hosts-auto-debug.log # 1 = debug autohostlist positives to ipset/zapret-hosts-auto-debug.log
AUTOHOSTLIST_DEBUGLOG=0 AUTOHOSTLIST_DEBUGLOG=0
# number of parallel threads for domain list resolves # number of parallel threads for domain list resolves
MDIG_THREADS=30 MDIG_THREADS=30
# EAI_AGAIN retries
MDIG_EAGAIN=10
# delay between EAI_AGAIN retries (ms)
MDIG_EAGAIN_DELAY=500
# ipset/*.sh can compress large lists # ipset/*.sh can compress large lists
GZIP_LISTS=0 GZIP_LISTS=0
@@ -63,47 +74,30 @@ DESYNC_MARK_POSTNAT=0x20000000
FILTER_MARK="" FILTER_MARK=""
TPWS_SOCKS_ENABLE=0 NFQWS2_ENABLE=1
# tpws socks listens on this port on localhost and LAN interfaces
TPPORT_SOCKS=987
# use <HOSTLIST> and <HOSTLIST_NOAUTO> placeholders to engage standard hostlists and autohostlist in ipset dir
# hostlist markers are replaced to empty string if MODE_FILTER does not satisfy
# <HOSTLIST_NOAUTO> appends ipset/zapret-hosts-auto.txt as normal list
TPWS_SOCKS_OPT="--filter-tcp=80 --methodeol <HOSTLIST> --new --filter-tcp=443 --split-tls=sni --disorder <HOSTLIST>"
TPWS_ENABLE=0
TPWS_PORTS="80,443"
# use <HOSTLIST> and <HOSTLIST_NOAUTO> placeholders to engage standard hostlists and autohostlist in ipset dir
# hostlist markers are replaced to empty string if MODE_FILTER does not satisfy
# <HOSTLIST_NOAUTO> appends ipset/zapret-hosts-auto.txt as normal list
TPWS_OPT="--filter-tcp=80 --methodeol <HOSTLIST> --new --filter-tcp=443 --split-tls=sni --disorder <HOSTLIST>"
NFQWS_ENABLE=1
# redirect outgoing traffic with connbytes limiter applied in both directions. # redirect outgoing traffic with connbytes limiter applied in both directions.
NFQWS_PORTS_TCP="80,443" NFQWS2_PORTS_TCP="80,443"
NFQWS_PORTS_UDP="443" NFQWS2_PORTS_UDP="443"
# PKT_OUT means connbytes dir original # PKT_OUT means connbytes dir original
# PKT_IN means connbytes dir reply # PKT_IN means connbytes dir reply
# this is --dpi-desync-cutoff=nX kernel mode implementation for linux. it saves a lot of CPU. NFQWS2_TCP_PKT_OUT="20"
NFQWS_TCP_PKT_OUT="9" NFQWS2_TCP_PKT_IN="10"
NFQWS_TCP_PKT_IN="3" NFQWS2_UDP_PKT_OUT="5"
NFQWS_UDP_PKT_OUT="9" NFQWS2_UDP_PKT_IN="3"
NFQWS_UDP_PKT_IN="0"
# redirect outgoing traffic without connbytes limiter and incoming with connbytes limiter # redirect outgoing traffic without connbytes limiter and incoming with connbytes limiter
# normally it's needed only for stateless DPI that matches every packet in a single TCP session # normally it's needed only for stateless DPI that matches every packet in a single TCP session
# typical example are plain HTTP keep alives # typical example are plain HTTP keep alives
# this mode can be very CPU consuming. enable with care ! # this mode can be very CPU consuming. enable with care !
NFQWS_PORTS_TCP_KEEPALIVE="" NFQWS2_PORTS_TCP_KEEPALIVE=""
NFQWS_PORTS_UDP_KEEPALIVE="" NFQWS2_PORTS_UDP_KEEPALIVE=""
# use <HOSTLIST> and <HOSTLIST_NOAUTO> placeholders to engage standard hostlists and autohostlist in ipset dir # use <HOSTLIST> and <HOSTLIST_NOAUTO> placeholders to engage standard hostlists and autohostlist in ipset dir
# hostlist markers are replaced to empty string if MODE_FILTER does not satisfy # hostlist markers are replaced to empty string if MODE_FILTER does not satisfy
# <HOSTLIST_NOAUTO> appends ipset/zapret-hosts-auto.txt as normal list # <HOSTLIST_NOAUTO> appends ipset/zapret-hosts-auto.txt as normal list
NFQWS_OPT="--filter-tcp=80 <HOSTLIST> --dpi-desync=fake,fakedsplit --dpi-desync-autottl=2 --dpi-desync-fooling=badsum --new --filter-tcp=443 --hostlist=/opt/zapret/ipset/zapret-hosts-google.txt --dpi-desync=fake,multidisorder --dpi-desync-split-pos=1,midsld --dpi-desync-repeats=11 --dpi-desync-fooling=badsum --dpi-desync-fake-tls-mod=rnd,dupsid,sni=www.google.com --new --filter-udp=443 --hostlist=/opt/zapret/ipset/zapret-hosts-google.txt --dpi-desync=fake --dpi-desync-repeats=11 --dpi-desync-fake-quic=/opt/zapret/files/fake/quic_initial_www_google_com.bin --new --filter-udp=443 <HOSTLIST_NOAUTO> --dpi-desync=fake --dpi-desync-repeats=11 --new --filter-tcp=443 <HOSTLIST> --dpi-desync=multidisorder --dpi-desync-split-pos=1,sniext+1,host+1,midsld-2,midsld,midsld+2,endhost-1" NFQWS2_OPT="--filter-tcp=80 --filter-l7=http <HOSTLIST> --payload=http_req --lua-desync=fake:blob=fake_default_http:tcp_md5 --lua-desync=multisplit:pos=method+2 --new --filter-tcp=443 --filter-l7=tls <HOSTLIST> --payload=tls_client_hello --lua-desync=fake:blob=fake_default_tls:tcp_md5:tcp_seq=-10000 --lua-desync=multidisorder:pos=1,midsld --new --filter-udp=443 --filter-l7=quic <HOSTLIST_NOAUTO> --payload=quic_initial --lua-desync=fake:blob=fake_default_quic:repeats=6"
DISABLE_CUSTOM=1 DISABLE_CUSTOM=1
@@ -121,9 +115,8 @@ FLOWOFFLOAD=none
# for routers based on desktop linux and macos. has no effect in openwrt. # for routers based on desktop linux and macos. has no effect in openwrt.
# CHOOSE LAN and optinally WAN/WAN6 NETWORK INTERFACES # CHOOSE LAN and optinally WAN/WAN6 NETWORK INTERFACES
# or leave them commented if its not router # or leave them commented if its not router
# it's possible to specify multiple interfaces like this : IFACE_LAN="eth0 eth1 eth2" # it's possible to specify multiple interfaces like this : IFACE_WAN="eth0 eth1 eth2"
# if IFACE_WAN6 is not defined it take the value of IFACE_WAN # if IFACE_WAN6 is not defined it take the value of IFACE_WAN
#IFACE_LAN=eth0
#IFACE_WAN=eth1 #IFACE_WAN=eth1
#IFACE_WAN6="ipsec0 wireguard0 he_net" #IFACE_WAN6="ipsec0 wireguard0 he_net"
@@ -132,10 +125,10 @@ FLOWOFFLOAD=none
INIT_APPLY_FW=1 INIT_APPLY_FW=1
# firewall apply hooks # firewall apply hooks
#INIT_FW_PRE_UP_HOOK="/etc/firewall.zapret.hook.pre_up" #INIT_FW_PRE_UP_HOOK="/etc/firewall.zapret2.hook.pre_up"
#INIT_FW_POST_UP_HOOK="/etc/firewall.zapret.hook.post_up" #INIT_FW_POST_UP_HOOK="/etc/firewall.zapret2.hook.post_up"
#INIT_FW_PRE_DOWN_HOOK="/etc/firewall.zapret.hook.pre_down" #INIT_FW_PRE_DOWN_HOOK="/etc/firewall.zapret2.hook.pre_down"
#INIT_FW_POST_DOWN_HOOK="/etc/firewall.zapret.hook.post_down" #INIT_FW_POST_DOWN_HOOK="/etc/firewall.zapret2.hook.post_down"
# do not work with ipv4 # do not work with ipv4
DISABLE_IPV4=0 DISABLE_IPV4=0
@@ -156,4 +149,4 @@ FILTER_TTL_EXPIRED_ICMP=1
DAEMON_LOG_ENABLE=0 DAEMON_LOG_ENABLE=0
DAEMON_LOG_FILE="/tmp/zapret+<DAEMON_NAME>+<DAEMON_IDNUM>+<DAEMON_CFGNAME>.log" DAEMON_LOG_FILE="/tmp/zapret2+<DAEMON_NAME>+<DAEMON_IDNUM>+<DAEMON_CFGNAME>.log"

View File

@@ -3,7 +3,7 @@
# NOTE: @ih requires nft 1.0.1+ and updated kernel version. it's confirmed to work on 5.15 (openwrt 23) and not work on 5.10 (openwrt 22) # NOTE: @ih requires nft 1.0.1+ and updated kernel version. it's confirmed to work on 5.15 (openwrt 23) and not work on 5.10 (openwrt 22)
# can override in config : # can override in config :
NFQWS_OPT_DESYNC_STUN="${NFQWS_OPT_DESYNC_STUN:---dpi-desync=fake --dpi-desync-repeats=2}" NFQWS_OPT_DESYNC_STUN="${NFQWS_OPT_DESYNC_STUN:---payload stun --lua-desync=fake:blob=0x00000000000000000000000000000000:repeats=2}"
alloc_dnum DNUM_STUN4ALL alloc_dnum DNUM_STUN4ALL
alloc_qnum QNUM_STUN4ALL alloc_qnum QNUM_STUN4ALL
@@ -17,14 +17,14 @@ zapret_custom_daemons()
} }
zapret_custom_firewall() zapret_custom_firewall()
{ {
# $1 - 1 - run, 0 - stop # $1 - 1 - run, 0 - stop
local f='-p udp -m u32 --u32' local f='-p udp -m u32 --u32'
fw_nfqws_post $1 "$f 0>>22&0x3C@4>>16=28:65535&&0>>22&0x3C@12=0x2112A442&&0>>22&0x3C@8&0xC0000003=0" "$f 44>>16=28:65535&&52=0x2112A442&&48&0xC0000003=0" $QNUM_STUN4ALL fw_nfqws_post $1 "$f 0>>22&0x3C@4>>16=28:65535&&0>>22&0x3C@12=0x2112A442&&0>>22&0x3C@8&0xC0000003=0" "$f 44>>16=28:65535&&52=0x2112A442&&48&0xC0000003=0" $QNUM_STUN4ALL
} }
zapret_custom_firewall_nft() zapret_custom_firewall_nft()
{ {
# stop logic is not required # stop logic is not required
local f="udp length >= 28 @ih,32,32 0x2112A442 @ih,0,2 0 @ih,30,2 0" local f="udp length >= 28 @ih,32,32 0x2112A442 @ih,0,2 0 @ih,30,2 0"
nft_fw_nfqws_post "$f" "$f" $QNUM_STUN4ALL nft_fw_nfqws_post "$f" "$f" $QNUM_STUN4ALL

197
zapret2/def-cfg.sh Executable file
View File

@@ -0,0 +1,197 @@
#!/bin/sh
# Copyright (c) 2025 remittor
function set_cfg_reset_values
{
local cfgname=${1:-$ZAPRET_CFG_NAME}
local TAB="$( printf '\t' )"
uci batch <<-EOF
set $cfgname.config.run_on_boot='0'
# settings for zapret service
set $cfgname.config.FWTYPE='nftables'
set $cfgname.config.POSTNAT='1'
set $cfgname.config.FLOWOFFLOAD='none'
set $cfgname.config.INIT_APPLY_FW='1'
set $cfgname.config.DISABLE_IPV4='0'
set $cfgname.config.DISABLE_IPV6='1'
set $cfgname.config.FILTER_TTL_EXPIRED_ICMP='1'
set $cfgname.config.MODE_FILTER='hostlist'
set $cfgname.config.DISABLE_CUSTOM='1'
set $cfgname.config.WS_USER='daemon'
set $cfgname.config.DAEMON_LOG_ENABLE='0'
set $cfgname.config.DAEMON_LOG_FILE='/tmp/zapret2+<DAEMON_NAME>+<DAEMON_IDNUM>+<DAEMON_CFGNAME>.log'
# autohostlist options
set $cfgname.config.AUTOHOSTLIST_INCOMING_MAXSEQ='4096'
set $cfgname.config.AUTOHOSTLIST_RETRANS_MAXSEQ='32768'
set $cfgname.config.AUTOHOSTLIST_RETRANS_RESET='1'
set $cfgname.config.AUTOHOSTLIST_RETRANS_THRESHOLD='3'
set $cfgname.config.AUTOHOSTLIST_FAIL_THRESHOLD='3'
set $cfgname.config.AUTOHOSTLIST_FAIL_TIME='60'
set $cfgname.config.AUTOHOSTLIST_UDP_IN='1'
set $cfgname.config.AUTOHOSTLIST_UDP_OUT='4'
set $cfgname.config.AUTOHOSTLIST_DEBUGLOG='0'
# nfqws options
set $cfgname.config.NFQWS2_ENABLE='1'
set $cfgname.config.DESYNC_MARK='0x40000000'
set $cfgname.config.DESYNC_MARK_POSTNAT='0x20000000'
set $cfgname.config.FILTER_MARK='$TAB'
set $cfgname.config.NFQWS2_PORTS_TCP='80,443'
set $cfgname.config.NFQWS2_PORTS_UDP='443'
set $cfgname.config.NFQWS2_TCP_PKT_OUT='20'
set $cfgname.config.NFQWS2_TCP_PKT_IN='10'
set $cfgname.config.NFQWS2_UDP_PKT_OUT='5'
set $cfgname.config.NFQWS2_UDP_PKT_IN='3'
set $cfgname.config.NFQWS2_PORTS_TCP_KEEPALIVE='0'
set $cfgname.config.NFQWS2_PORTS_UDP_KEEPALIVE='0'
# save changes
commit $cfgname
EOF
return 0
}
function clear_nfqws_strat
{
local cfgname=${1:-$ZAPRET_CFG_NAME}
local TAB="$( printf '\t' )"
uci batch <<-EOF
set $cfgname.config.MODE_FILTER='hostlist'
set $cfgname.config.NFQWS2_PORTS_TCP='80,443'
set $cfgname.config.NFQWS2_PORTS_UDP='443'
set $cfgname.config.NFQWS2_OPT='$TAB'
commit $cfgname
EOF
}
function set_cfg_nfqws_strat
{
local strat=${1:--}
local cfgname=${2:-$ZAPRET_CFG_NAME}
local TAB="$( printf '\t' )"
uci batch <<-EOF
set $cfgname.config.MODE_FILTER='hostlist'
commit $cfgname
EOF
if [ "$strat" = "empty" ]; then
clear_nfqws_strat $cfgname
fi
if [ "$strat" = "default" ]; then
uci batch <<-EOF
set $cfgname.config.NFQWS2_PORTS_TCP='80,443'
set $cfgname.config.NFQWS2_PORTS_UDP='443'
set $cfgname.config.NFQWS2_OPT="
--comment=Strategy__$strat
--filter-tcp=80
--filter-l7=http <HOSTLIST>
--payload=http_req
--lua-desync=fake:blob=fake_default_http:tcp_md5
--lua-desync=multisplit:pos=method+2
--new
--filter-tcp=443
--filter-l7=tls <HOSTLIST>
--payload=tls_client_hello
--lua-desync=fake:blob=fake_default_tls:tcp_md5:tcp_seq=-10000
--lua-desync=multidisorder:pos=1,midsld
--new
--filter-udp=443
--filter-l7=quic <HOSTLIST_NOAUTO>
--payload=quic_initial
--lua-desync=fake:blob=fake_default_quic:repeats=6
"
commit $cfgname
EOF
fi
if [ "$strat" = "v1_by_Schiz23" ]; then
uci batch <<-EOF
set $cfgname.config.NFQWS2_PORTS_TCP='80,443'
set $cfgname.config.NFQWS2_PORTS_UDP='443'
set $cfgname.config.NFQWS2_OPT="
--comment=Strategy__$strat
--filter-tcp=80
--filter-l7=http <HOSTLIST>
--payload=http_req
--lua-desync=fake:blob=fake_default_http:tcp_md5
--lua-desync=multisplit:pos=method+2
--new
--filter-tcp=443
--filter-l7=tls <HOSTLIST>
--lua-desync=fake:blob=fake_default_tls:ip_ttl=1:ip6_ttl=1:tls_mod=rnd,rndsni,padencap
--lua-desync=multidisorder:payload=tls_client_hello:pos=3
--new
--filter-udp=443
--filter-l7=quic <HOSTLIST_NOAUTO>
--lua-desync=fake:blob=fake_default_quic:repeats=11:payload=all:out_range=-d10
"
commit $cfgname
EOF
fi
if [ "$strat" = "v2_by_Schiz23" ]; then
uci batch <<-EOF
set $cfgname.config.NFQWS2_PORTS_TCP='80,443'
set $cfgname.config.NFQWS2_PORTS_UDP='443'
set $cfgname.config.NFQWS2_OPT="
--comment=Strategy__$strat
--filter-tcp=80
--filter-l7=http <HOSTLIST>
--payload=http_req
--lua-desync=fake:blob=fake_default_http:tcp_md5
--lua-desync=multisplit:pos=method+2
--new
--filter-tcp=443
--filter-l7=tls <HOSTLIST>
--payload=tls_client_hello
--lua-desync=multidisorder:payload=tls_client_hello:pos=100,midsld,sniext+1,endhost-2,-10
--lua-desync=send:sni=.microsoft
--new
--filter-udp=443
--filter-l7=quic <HOSTLIST_NOAUTO>
--payload=quic_initial
--lua-desync=fake:blob=fake_default_quic:repeats=4
"
commit $cfgname
EOF
fi
return 0
}
function set_cfg_default_values
{
local opt_flags=${1:--}
local opt_strat=${2:-default}
local cfgname=${3:-$ZAPRET_CFG_NAME}
if ! echo "$opt_flags" | grep -q "(skip_base)"; then
set_cfg_reset_values $cfgname
fi
if [ "$opt_strat" != "-" ]; then
set_cfg_nfqws_strat "$opt_strat" $cfgname
fi
if echo "$opt_flags" | grep -q "(set_mode_autohostlist)"; then
uci batch <<-EOF
set $cfgname.config.MODE_FILTER='autohostlist'
commit $cfgname
EOF
fi
if echo "$opt_flags" | grep -q "(enable_custom_d)"; then
uci batch <<-EOF
set $cfgname.config.DISABLE_CUSTOM='0'
commit $cfgname
EOF
fi
if echo "$opt_flags" | grep -q "(disable_custom_d)"; then
uci batch <<-EOF
set $cfgname.config.DISABLE_CUSTOM='1'
commit $cfgname
EOF
fi
return 0
}

308
zapret2/dwc.sh Normal file
View File

@@ -0,0 +1,308 @@
#!/bin/sh
# Copyright (c) 2026 remittor
ZAP_TMP_DIR=/tmp/zapret2_dwc
opt_sites=
opt_dig=
opt_recom=
opt_tmp_dir=
opt_test=
while getopts "sd:RT:t" opt; do
case $opt in
s) opt_sites="true";;
d) opt_dig="$OPTARG";;
R) opt_recom="true";; # Recommendations
T) opt_tmp_dir="$OPTARG";;
t) opt_test="true";;
esac
done
[ "$opt_tmp_dir" != "" ] && ZAP_TMP_DIR="$opt_tmp_dir"
TARGET_LIST_FILE="$ZAP_TMP_DIR/targets"
[ -f "$TARGET_LIST_FILE" ] && rm -rf "$ZAP_TMP_DIR"
[ -f "$TARGET_LIST_FILE" ] && exit 3
CURL_TIMEOUT=5
CURL_MAXBODY=65536
CURL_NOCACHE='cache-control: no-cache'
CURL_NOCACHE2='pragma: no-cache'
CURL_USERAGENT='Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/142.0.0.0 Safari/537.36'
if ! command -v curl >/dev/null 2>&1; then
echo "ERROR: package \"curl\" not installed!"
return 10
fi
CURL_INFO=$( curl -V )
if ! echo "$CURL_INFO" | grep -q 'https'; then
echo "------- package curl"
echo "$CURL_INFO"
echo "-------"
echo "ERROR: package \"curl\" not supported HTTPS protocol!"
echo "NOTE: Please install package \"curl-ssl\""
return 11
fi
if [ "$opt_dig" != "" ]; then
if ! command -v dig >/dev/null 2>&1; then
echo "ERROR: package \"bind-dig\" not installed!"
return 12
fi
OPT_DIG_DNS="@$opt_dig"
[ "$opt_dig" = "@" ] && OPT_DIG_DNS=''
[ "$opt_dig" = "8" ] && OPT_DIG_DNS='@8.8.8.8'
[ "$opt_dig" = "1" ] && OPT_DIG_DNS='@1.1.1.1'
[ "$opt_dig" = "9" ] && OPT_DIG_DNS='@9.9.9.9'
fi
if [ -f /etc/openwrt_release ]; then
CA_CERTS=/etc/ssl/certs/ca-certificates.crt
if [ ! -f $CA_CERTS ]; then
echo "ERROR: package \"ca-bundle\" not installed!"
return 15
fi
fi
#echo 'Original sources: https://github.com/hyperion-cs/dpi-checkers'
#echo 'WEB-version: https://hyperion-cs.github.io/dpi-checkers/ru/tcp-16-20/'
TEST_SUITE='
{ id: "US.CF-01", provider: "🇺🇸 Cloudflare", times: 1, url: "https://img.wzstats.gg/cleaver/gunFullDisplay" },
{ id: "US.CF-02", provider: "🇺🇸 Cloudflare", times: 1, url: "https://genshin.jmp.blue/characters/all#" },
{ id: "US.CF-03", provider: "🇺🇸 Cloudflare", times: 1, url: "https://api.frankfurter.dev/v1/2000-01-01..2002-12-31" },
{ id: "US.CF-04", provider: "🇨🇦 Cloudflare", times: 1, url: "https://www.bigcartel.com/" },
{ id: "US.DO-01", provider: "🇺🇸 DigitalOcean", times: 2, url: "https://genderize.io/" },
{ id: "DE.HE-01", provider: "🇩🇪 Hetzner", times: 1, url: "https://j.dejure.org/jcg/doctrine/doctrine_banner.webp" },
{ id: "DE.HE-02", provider: "🇩🇪 Hetzner", times: 1, url: "https://maps.gnosis.earth/ogcapi/api/swagger-ui/swagger-ui-standalone-preset.js#" },
{ id: "FI.HE-01", provider: "🇫🇮 Hetzner", times: 1, url: "https://251b5cd9.nip.io/1MB.bin" },
{ id: "FI.HE-02", provider: "🇫🇮 Hetzner", times: 1, url: "https://nioges.com/libs/fontawesome/webfonts/fa-solid-900.woff2" },
{ id: "FI.HE-03", provider: "🇫🇮 Hetzner", times: 1, url: "https://5fd8bdae.nip.io/1MB.bin" },
{ id: "FI.HE-04", provider: "🇫🇮 Hetzner", times: 1, url: "https://5fd8bca5.nip.io/1MB.bin" },
{ id: "FR.OVH-01", provider: "🇫🇷 OVH", times: 1, url: "https://eu.api.ovh.com/console/rapidoc-min.js" },
{ id: "FR.OVH-02", provider: "🇫🇷 OVH", times: 1, url: "https://ovh.sfx.ovh/10M.bin" },
{ id: "SE.OR-01", provider: "🇸🇪 Oracle", times: 1, url: "https://oracle.sfx.ovh/10M.bin" },
{ id: "DE.AWS-01", provider: "🇩🇪 AWS", times: 1, url: "https://www.getscope.com/assets/fonts/fa-solid-900.woff2" },
{ id: "US.AWS-01", provider: "🇺🇸 AWS", times: 1, url: "https://corp.kaltura.com/wp-content/cache/min/1/wp-content/themes/airfleet/dist/styles/theme.css" },
{ id: "US.GC-01", provider: "🇺🇸 Google Cloud", times: 1, url: "https://api.usercentrics.eu/gvl/v3/en.json" },
{ id: "US.FST-01", provider: "🇺🇸 Fastly", times: 1, url: "https://www.jetblue.com/footer/footer-element-es2015.js" },
{ id: "CA.FST-01", provider: "🇨🇦 Fastly", times: 1, url: "https://www.cnn10.com/" },
{ id: "US.AKM-01", provider: "🇺🇸 Akamai", times: 1, url: "https://www.roxio.com/static/roxio/images/products/creator/nxt9/call-action-footer-bg.jpg" },
{ id: "PL.AKM-01", provider: "🇵🇱 Akamai", times: 1, url: "https://media-assets.stryker.com/is/image/stryker/gateway_1?$max_width_1410$" },
{ id: "US.CDN77-01", provider: "🇺🇸 CDN77", times: 1, url: "https://cdn.eso.org/images/banner1920/eso2520a.jpg" },
{ id: "FR.CNTB-01", provider: "🇫🇷 Contabo", times: 1, url: "https://airsea.no/images/main_logo.png" },
{ id: "NL.SW-01", provider: "🇳🇱 Scaleway", times: 1, url: "https://www.velivole.fr/img/header.jpg" },
{ id: "US.CNST-01", provider: "🇺🇸 Constant", times: 1, url: "https://cdn.xuansiwei.com/common/lib/font-awesome/4.7.0/fontawesome-webfont.woff2?v=4.7.0" }
'
if [ "$opt_sites" = true ]; then
TEST_SUITE='
gosuslugi.ru | @ | 40000 | https://gosuslugi.ru/__jsch/static/script.js
esia.gosuslugi.ru | @ | 40000 | https://esia.gosuslugi.ru/__jsch/static/script.js
gu-st.ru | | | https://gu-st.ru/portal-st/lib-assets/fonts/Lato-Regular-v3.woff2
nalog.ru | | | https://data.nalog.ru/images/new/buttons/TSET-button.png
lkfl2.nalog.ru | | | https://lkfl2.nalog.ru/lkfl/static/assets/main-desktop-1920-CvJsHANg.jpg
rutube.ru | @ | 40000 | https://static.rutube.ru/static/wdp/fonts/Semibold/OpenSans-Semibold.woff2?20231026
youtube.com | @# | 300000 | https://youtube.com
instagram.com | @# | 300000 | https://instagram.com
rutracker.org | @# | 80000 | https://rutracker.org
nnmclub.to | @# | 120000 | https://nnmclub.to
rutor.info | @# | 110000 | https://rutor.info
epidemz.net.co | @# | 40000 | https://epidemz.net.co
filmix.my | @ | 23000 | https://filmix.my/templates/Filmix/media/fonts/Roboto/roboto-v20-latin_cyrillic-italic.woff2
openwrt.org | + | 60000 | https://openwrt.org/lib/tpl/bootstrap3/assets/bootstrap/default/bootstrap.min.css
ntc.party | @# | 200000 | https://ntc.party
sxyprn.net | @# | 310000 | https://sxyprn.net
pornhub.com | @# | 700000 | https://pornhub.com
spankbang.com | @# | 80000 | https://spankbang.com
discord.com | @# | 120000 | https://discord.com
x.com | @ | 39000 | https://abs.twimg.com/fonts/v1/chirp-extended-heavy-web.woff2
flightradar24.com | @ | 100000 | https://www.flightradar24.com/mobile/airlines?format=2&version=0
cdn77.com | @ | 24000 | https://cdn77.com/fonts/Eina01-Regular.woff2
play.google.com | @# | 100000 | https://gstatic.com/feedback/js/help/prod/service/lazy.min.js
genderize.io | @# | 210000 | https://genderize.io
ottai.com | @ | 70000 | https://seas.static.ottai.com/ottai-website/public/images/new/home/banner/uk/banner.webp
'
CURL_TIMEOUT=7
fi
function trim
{
echo "$1" | sed 's/^[[:space:]]*//;s/[[:space:]]*$//'
}
mkdir -p "$ZAP_TMP_DIR"
: > "$TARGET_LIST_FILE"
IDX=0
while IFS= read -r line; do
if [ "$opt_sites" = true ]; then
echo -n "$line" | grep -q ' | http' || continue
IDX=$((IDX + 1))
TAG=$( printf '%s\n' "$line" | cut -d'|' -f1 | awk '{$1=$1;print}' )
FLAGS=$( printf '%s\n' "$line" | cut -d'|' -f2 | awk '{$1=$1;print}' )
TSIZE=$( printf '%s\n' "$line" | cut -d'|' -f3 | awk '{$1=$1;print}' )
URL=$( printf '%s\n' "$line" | cut -d'|' -f4 | awk '{$1=$1;print}' )
COUNTRY="XX"
echo "${IDX}|${TAG}|${COUNTRY}|${FLAGS}|${TSIZE}|${URL}" >> "$TARGET_LIST_FILE"
continue
fi
case "$line" in
*id:*provider:*url:*)
IDX=$((IDX + 1))
TAG=$( printf '%s\n' "$line" | cut -d'"' -f2 )
COUNTRY="${TAG%%.*}"
PROVIDER_RAW=$( printf '%s\n' "$line" | cut -d'"' -f4 )
PROVIDER="${PROVIDER_RAW#* }"
TIMES=$( printf '%s\n' "$line" | cut -d':' -f4 | cut -d',' -f1 | tr -d ' ')
URL=$( printf '%s\n' "$line" | cut -d'"' -f6 )
echo "${IDX}|${TAG}|${COUNTRY}|${PROVIDER}|${TIMES}|${URL}" >> "$TARGET_LIST_FILE"
;;
esac
done <<EOF
$TEST_SUITE
EOF
CURL_CON_TIMEOUT=$((CURL_TIMEOUT-2))
CURL_SPEED_TIME=$((CURL_TIMEOUT-2))
CURL_SPEED_LIMIT=1
while IFS='|' read -r ID TAG COUNTRY PROVIDER TIMES URL; do
[ -z "$TAG" ] && continue
ID3=$( printf '%03d' "$ID" )
RANGETO=""
REDIRECT=""
USERAGENT="$CURL_USERAGENT"
if [ "$opt_sites" = true ]; then
FLAGS="$PROVIDER"
TSIZE="$TIMES"
[ "$TSIZE" = "" ] && TSIZE=$CURL_MAXBODY
if echo "$FLAGS" | grep -q '@'; then
RANGETO=""
else
RANGETO="--range 0-$((TSIZE - 1))"
fi
PROVIDER="$TSIZE"
if echo "$FLAGS" | grep -q '#'; then
REDIRECT="-L"
fi
if echo "$FLAGS" | grep -q '+'; then
USERAGENT="curl/8.12"
fi
else
RANGETO="--range 0-$((CURL_MAXBODY - 1))"
COUNTRY=$( echo "$TAG" | cut -d. -f1 )
CNTFLAG=$( echo "$PROVIDER" | awk '{print $1}' )
fi
URL_NO_PROTO="${URL#*://}"
DOMAIN="${URL_NO_PROTO%%/*}"
URLPATH="/${URL_NO_PROTO#*/}"
[ "$URLPATH" = "/$URL_NO_PROTO" ] && URLPATH="/"
#echo "TAG=$TAG , COUNTRY=$COUNTRY , PROVIDER=$PROVIDER , DOMAIN=$DOMAIN , URL=$URL"
FNAME="$ZAP_TMP_DIR/$ID3=$TAG=$PROVIDER"
(
DST_IP=
RESOLVE_OPT=
if [ "$opt_dig" != "" ]; then
DST_IP=$( dig +time=2 +retry=1 $OPT_DIG_DNS +short "$DOMAIN" 2>/dev/null | grep -E '^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$' | head -n1 )
else
CURL_TIMEOUTS="--connect-timeout 2 --max-time 3 --speed-time 3 --speed-limit 1"
DST_IP=$( curl -4 -I -s $CURL_TIMEOUTS -o /dev/null -w '%{remote_ip}\n' "$URL" )
if [ -z "$DST_IP" ]; then
DST_IP=$( curl -4 -s $CURL_TIMEOUTS -o /dev/null -r 0-0 -w '%{remote_ip}\n' "$URL" )
fi
fi
if [ "$DST_IP" = "" ]; then
DST_IP=$( ping -c1 "$DOMAIN" 2>/dev/null | sed -n '1s/.*(\([0-9.]*\)).*/\1/p' )
fi
[ "$DST_IP" != "" ] && RESOLVE_OPT="--resolve $DOMAIN:443:$DST_IP"
echo "$DST_IP" > "$FNAME.ip"
echo "$URL" > "$FNAME.url"
curl "$URL" \
$RESOLVE_OPT \
$REDIRECT \
--connect-timeout $CURL_CON_TIMEOUT \
--max-time $CURL_TIMEOUT \
--speed-time $CURL_SPEED_TIME \
--speed-limit $CURL_SPEED_LIMIT \
$RANGETO \
-A "$USERAGENT" \
-D "$FNAME.hdr" \
-o "$FNAME.body"
) > "$FNAME.log" 2>&1 &
done < "$TARGET_LIST_FILE"
wait
FAIL_URL_LIST="$ZAP_TMP_DIR/FAIL_URL_LIST.txt"
rm -f "$FAIL_URL_LIST"
printf '%s\n' "$ZAP_TMP_DIR"/*.log | sort | while IFS= read -r file; do
[ -f "$file" ] || continue
FILENAME="${file##*/}"
FILENAME="${FILENAME%.log}"
ID=$( echo "$FILENAME" | cut -d= -f1)
TAG=$( echo "$FILENAME" | cut -d= -f2)
PROVIDER=$(echo "$FILENAME" | cut -d= -f3 )
FNAME="$ZAP_TMP_DIR/$FILENAME"
REQ_SIZE=$CURL_MAXBODY
[ "$opt_sites" = true ] && REQ_SIZE="$PROVIDER"
BODY_SIZE=0
[ -f "$FNAME.body" ] && BODY_SIZE=$( wc -c < "$FNAME.body" )
IPADDR="x.x.x.x"
[ -s "$FNAME.ip" ] && IPADDR=$( cat "$FNAME.ip" )
res=0
status=
if [ ! -f "$FNAME.hdr" ]; then
status="ERROR: cannot Get Headers"
elif [ ! -s "$FNAME.hdr" ]; then
status="ERROR: cannot get headers"
elif [ ! -f "$FNAME.body" ]; then
status="Possibly detected*"
elif [ ! -s "$FNAME.body" ]; then
status="Possibly detected"
else
if [ $BODY_SIZE -lt $REQ_SIZE ]; then
status="Failed (recv $BODY_SIZE bytes)"
res=5
else
status="[ OK ]"
res=100
fi
fi
if [ "$opt_sites" = true ]; then
printf '%18s / %-15s : %s \n' "$TAG" "$IPADDR" "$status"
else
printf '%12s / %-15s / %-13s: %s \n' "$TAG" "$IPADDR" "$PROVIDER" "$status"
fi
echo "$BODY_SIZE" > "$FNAME.size"
if [ $res != 100 ]; then
URL=$( cat "$FNAME.url" )
echo "$FILENAME : $URL" >> "$FAIL_URL_LIST"
fi
done
if [ "$opt_test" != true ]; then
rm -f "$ZAP_TMP_DIR"/*.body >/dev/null 2>&1
fi
[ "$opt_recom" != "true" ] && return 0
[ ! -f "$FAIL_URL_LIST" ] && return 0
echo "==================================================="
echo "Recommendations:"
echo "Try adding the specified domains to the \"zapret-hosts-user.txt\" file:"
while IFS=' : ' read -r FILENAME URL; do
[ -z "$FILENAME" ] && continue
URL_NO_PROTO="${URL#*://}"
DOMAIN="${URL_NO_PROTO%%/*}"
URLPATH="/${URL_NO_PROTO#*/}"
[ "$URLPATH" = "/$URL_NO_PROTO" ] && URLPATH="/"
echo "$DOMAIN"
done < "$FAIL_URL_LIST"
return 0

View File

@@ -7,7 +7,7 @@ START=21
SCRIPT_FILENAME=$1 SCRIPT_FILENAME=$1
. /opt/zapret/comfunc.sh . /opt/zapret2/comfunc.sh
if ! is_valid_config ; then if ! is_valid_config ; then
logger -p err -t $ZAP_LOG_TAG "Wrong main config: $ZAPRET_CONFIG" logger -p err -t $ZAP_LOG_TAG "Wrong main config: $ZAPRET_CONFIG"

View File

@@ -11,11 +11,14 @@ fe80::/10
nalog.ru nalog.ru
gstatic.com gstatic.com
gosuslugi.ru gosuslugi.ru
mos.ru
mos-gorsud.ru mos-gorsud.ru
gov.ru gov.ru
sudrf.ru sudrf.ru
ottai.com ottai.com
ipstream.one ipstream.one
vkusvill.ru
kinopoisk.ru
#################################### Epicgames #################################### Epicgames
easy.ac easy.ac
fab.com fab.com
@@ -37,45 +40,14 @@ cubicmotion.com
playparagon.com playparagon.com
realityscan.com realityscan.com
epicgamescdn.com epicgamescdn.com
et.epicgames.com
ol.epicgames.com
radgametools.com radgametools.com
unrealengine.com unrealengine.com
api.epicgames.dev
easyanticheat.net easyanticheat.net
shadowcomplex.com shadowcomplex.com
battlebreakers.com battlebreakers.com
store.epicgames.com
capturingreality.com capturingreality.com
unrealtournament.com unrealtournament.com
cdn1.unrealengine.com
cdn2.unrealengine.com
accounts.epicgames.com
download.epicgames.com
tracking.epicgames.com
download2.epicgames.com
download3.epicgames.com
download4.epicgames.com
metrics.ol.epicgames.com
datarouter.ol.epicgames.com
fastly-download.epicgames.com
store-content.ak.epicgames.com
static-assets-prod.epicgames.com
epicgames-download1.akamaized.net epicgames-download1.akamaized.net
launcher-website-prod07.ol.epicgames.com
ut-public-service-prod10.ol.epicgames.com
store-site-backend-static.ak.epicgames.com
library-service.live.use1a.on.epicgames.com
accountportal-website-prod07.ol.epicgames.com
account-public-service-prod03.ol.epicgames.com
catalog-public-service-prod06.ol.epicgames.com
friends-public-service-prod06.ol.epicgames.com
launcher-public-service-prod06.ol.epicgames.com
entitlement-public-service-prod08.ol.epicgames.com
lightswitch-public-service-prod06.ol.epicgames.com
orderprocessor-public-service-ecomprod01.ol.epicgames.com
launcherwaitingroom-public-service-prod06.ol.epicgames.com
datastorage-public-service-liveegs.live.use1a.on.epicgames.com
#################################### Steam #################################### Steam
s.team s.team
steam.tv steam.tv
@@ -103,99 +75,49 @@ valvesoftware.net
steam.cdn.webra.ru steam.cdn.webra.ru
steambroadcast.com steambroadcast.com
steamcommunity.com steamcommunity.com
cdn.steamstatic.com
cs.steampowered.com
dl.steam.clngaa.com dl.steam.clngaa.com
steam.ru.qtlglb.com steam.ru.qtlglb.com
api.steampowered.com
steam.eca.qtlglb.com steam.eca.qtlglb.com
steamusercontent.com steamusercontent.com
help.steampowered.com
steam.apac.qtlglb.com steam.apac.qtlglb.com
steam.naeu.qtlglb.com steam.naeu.qtlglb.com
cdn.steamcommunity.com cdn.steamcommunity.com
gstore.val.manlaxy.com gstore.val.manlaxy.com
login.steampowered.com
media.steampowered.com
partner.steamgames.com partner.steamgames.com
shared.steamstatic.com
steam.cdn.orcon.net.nz steam.cdn.orcon.net.nz
store.steampowered.com
steamcdn-a.akamaihd.net steamcdn-a.akamaihd.net
steampipe.akamaized.net steampipe.akamaized.net
partner.steampowered.com
steamcdn-a.akamaized.net steamcdn-a.akamaized.net
steamdeckusercontent.com steamdeckusercontent.com
support.steampowered.com
checkout.steampowered.com
community.steamstatic.com
steam.cdn.slingshot.co.nz steam.cdn.slingshot.co.nz
steammobile.akamaized.net steammobile.akamaized.net
steamstatic.akamaized.net steamstatic.akamaized.net
steamstore-a.akamaihd.net steamstore-a.akamaihd.net
steamvideo-a.akamaihd.net steamvideo-a.akamaihd.net
workshop.steampowered.com
cdn.akamai.steamstatic.com
cdn.fastly.steamstatic.com
client-update.queniuqe.com client-update.queniuqe.com
community.steampowered.com
steamdeckcdn.akamaized.net steamdeckcdn.akamaized.net
steampipe-kr.akamaized.net steampipe-kr.akamaized.net
clan.fastly.steamstatic.com
steamcontent-a.akamaihd.net steamcontent-a.akamaihd.net
steambroadcast.akamaized.net steambroadcast.akamaized.net
steamcommunity.akamaized.net steamcommunity.akamaized.net
store.akamai.steamstatic.com
store.fastly.steamstatic.com
scontent.steamusercontent.com scontent.steamusercontent.com
shared.fastly.steamstatic.com
steamcommunity-a.akamaihd.net steamcommunity-a.akamaihd.net
avatars.fastly.steamstatic.com
cdn.cloudflare.steamstatic.com
edge.steam-dns.top.comcast.net edge.steam-dns.top.comcast.net
steamcommunity-a.akamaized.net steamcommunity-a.akamaized.net
steamuserimages-a.akamaihd.net steamuserimages-a.akamaihd.net
steampipe-partner.akamaized.net steampipe-partner.akamaized.net
steamusercontent-a.akamaihd.net steamusercontent-a.akamaihd.net
client-download.steampowered.com
community.fastly.steamstatic.com
store.cloudflare.steamstatic.com
community.cloudflare.steamstatic.com
steamcdn-a.akamaihd.net.edgesuite.net steamcdn-a.akamaihd.net.edgesuite.net
steamcloudsweden.blob.core.windows.net steamcloudsweden.blob.core.windows.net
steamcommunity.cloudflare.steamstatic.com
steamcommunity-a.akamaihd.net.edgesuite.net steamcommunity-a.akamaihd.net.edgesuite.net
#################################### OpenWRT #################################### OpenWRT
github.com
openwrt.org openwrt.org
gh.openwrt.org
cdn.openwrt.org
dev.openwrt.org
git.openwrt.org
lede-project.org lede-project.org
wiki.openwrt.org
forum.openwrt.org
lists.openwrt.org
openwrt.gitlab.io
archive.openwrt.org
downloads.openwrt.org
fwdownloads.openwrt.org
mirror-01.infra.openwrt.org
mirror-02.infra.openwrt.org
mirror-03.infra.openwrt.org
mirror-04.infra.openwrt.org
#################################### UbisoftConnect #################################### UbisoftConnect
ubi.com ubi.com
ubisoft.com ubisoft.com
store.ubi.com
ubisoftconnect.com ubisoftconnect.com
connect.ubisoft.com connect.ubisoft.comubisoft-orbit-savegames.s3.amazonaws.com
drops-register.ubi.com
public-ubiservices.ubi.com
ubisoftconnect.cdn.ubi.com
uplaypc-s-ubisoft.cdn.ubi.com
uplaypc-s-ubisoft-ww.cdn.ubi.com
ubisoft-orbit-savegames.s3.amazonaws.com
ubisoft-uplay-savegames.s3.amazonaws.com ubisoft-uplay-savegames.s3.amazonaws.com
#################################### Aliexpress #################################### Aliexpress
ae.com ae.com
@@ -215,55 +137,33 @@ playstation.net
playstation.com playstation.com
account.sony.com account.sony.com
psremoteplay.com psremoteplay.com
ps4.playstation.com
ps5.playstation.com
playstationcloud.com playstationcloud.com
psapi.playstation.net
store.playstation.com
media.playstation.com
auth.np.ac.playstation.net
sonyentertainmentnetwork.com sonyentertainmentnetwork.com
np.community.playstation.net
id.sonyentertainmentnetwork.com
#################################### Twitch #################################### Twitch
twitch.tv twitch.tv
ttvnw.net ttvnw.net
jtvnw.net jtvnw.net
twimg.com
m.twitch.tv
id.twitch.tv
www.twitch.tv
twitchcdn.net twitchcdn.net
ext-twitch.tv ext-twitch.tv
twitchsvc.net twitchsvc.net
api.twitch.tv
gql.twitch.tv
dev.twitch.tv
live-video.net live-video.net
twitch.a2z.com twitch.a2z.com
chat.twitch.tv
help.twitch.tv
assets.twitch.tv
twitch-shadow.net twitch-shadow.net
passport.twitch.tv
irc.chat.twitch.tv
vod-metro.twitch.tv
twitchcdn-shadow.net twitchcdn-shadow.net
static.twitchcdn.net
vod-secure.twitch.tv
irc-ws.chat.twitch.tv
pubsub-edge.twitch.tv
vod-pop-secure.twitch.tv
#################################### Valorant #################################### Valorant
qq.com
pvp.net pvp.net
vivox.com vivox.com
sd-rtn.com sd-rtn.com
adjust.com
riotcdn.net riotcdn.net
adobess.com adobess.com
valorant.com valorant.com
akamaihd.net akamaihd.net
myqcloud.com
riotgames.com riotgames.com
playvalorant.com playvalorant.com
wildrift-na.akamaized.net
#################################### TikTok #################################### TikTok
musical.ly musical.ly
tiktok.com tiktok.com
@@ -359,4 +259,68 @@ xiaomifactory.com
airstarfinance.net airstarfinance.net
dreame-technology.cn dreame-technology.cn
dreame-technology.com dreame-technology.com
#################################### Picooc
picoocru.com
picooc-g.com
picooc-int.com
#################################### Huawei
hc-cdn.cn
huawei.ru
huawei.com
hc-cdn.com
huawei.net
dbankcdn.ru
hicloud.com
dbankcdn.com
dbankcloud.ru
dbankcloud.cn
dbankcloud.com
huaweicloud.com
huaweistatic.com
hwclouds-dns.com
hwclouds-dns.net
myhuaweicloud.cn
myhuaweicloud.com
huaweicloud-dns.cn
huaweicloud-dns.ru
huaweicloud-dns.com
huaweicloud-dns.org
#################################### Okko
okko.tv
playfamily.ru
#################################### Beeline
beeline.ru
beeline.tv
#################################### Delta Force
volces.com
wetest.net
intlgame.com
fleetlogd.com
dgameglobal.com
tdatamaster.com
playdeltaforce.com
quovadisglobal.com
jupiterlauncher.com
anticheatexpert.com
#################################### Microsoft
live.com
lync.com
skype.com
microsoft
msauth.net
office.net
office.com
msocdn.com
mojang.com
windows.net
msftauth.net
xboxlive.com
microsoft.com
office365.com
azureedge.net
skypeassets.com
windowsupdate.com
microsoftonline.com
microsoftonline-p.com
minecraftservices.com
#################################### ####################################

View File

@@ -25,10 +25,10 @@ index 0af19c0..41c0967 100644
done done
} }
} }
diff --git a/init.d/openwrt/zapret b/init.d/openwrt/zapret diff --git a/init.d/openwrt/zapret b/init.d/openwrt/zapret2
index 8d6d3a9..fcb1e91 100755 index 8d6d3a9..fcb1e91 100755
--- a/init.d/openwrt/zapret --- a/init.d/openwrt/zapret2
+++ b/init.d/openwrt/zapret +++ b/init.d/openwrt/zapret2
@@ -58,12 +58,29 @@ run_daemon() @@ -58,12 +58,29 @@ run_daemon()
# use $PIDDIR/$DAEMONBASE$1.pid as pidfile # use $PIDDIR/$DAEMONBASE$1.pid as pidfile
local DAEMONBASE="$(basename "$2")" local DAEMONBASE="$(basename "$2")"
@@ -51,15 +51,15 @@ index 8d6d3a9..fcb1e91 100755
procd_open_instance procd_open_instance
- procd_set_param command $2 $3 - procd_set_param command $2 $3
+ procd_set_param command $DAEMON_PATH $DAEMON_ARGS + procd_set_param command $DAEMON_PATH $DAEMON_ARGS
procd_set_param pidfile $PIDDIR/$DAEMONBASE$1.pid procd_set_param pidfile $PIDDIR/${DAEMONBASE}_$1.pid
procd_close_instance procd_close_instance
} }
+DAEMON_CFGNAME="main" +DAEMON_CFGNAME="main"
+ +
run_tpws() run_nfqws()
{ {
[ "$DISABLE_IPV4" = "1" ] && [ "$DISABLE_IPV6" = "1" ] && return 0 run_daemon $1 "$NFQWS2" "$NFQWS2_OPT_BASE $2"
-- --
2.41.0.windows.3 2.41.0.windows.3

View File

@@ -13,6 +13,11 @@ opt_strat=$2
if echo "$opt_flags" | grep -q "(reset_ipset)"; then if echo "$opt_flags" | grep -q "(reset_ipset)"; then
restore_all_ipset_cfg restore_all_ipset_cfg
fi fi
if echo "$opt_flags" | grep -q "(erase_autohostlist)"; then
: > $ZAPRET_BASE/ipset/zapret-hosts-auto.txt
: > $ZAPRET_BASE/ipset/zapret-hosts-auto-debug.log
fi
create_default_cfg "$opt_flags" "$opt_strat" create_default_cfg "$opt_flags" "$opt_strat"

View File

@@ -1,9 +1,9 @@
#!/bin/sh #!/bin/sh
# Copyright (c) 2024 remittor # Copyright (c) 2024 remittor
[ ! -f /opt/zapret/comfunc.sh ] && exit 0 [ ! -f /opt/zapret2/comfunc.sh ] && exit 0
. /opt/zapret/comfunc.sh . /opt/zapret2/comfunc.sh
mkdir -p $ZAPRET_BASE/ipset mkdir -p $ZAPRET_BASE/ipset

View File

@@ -75,9 +75,13 @@ ZAP_PKG_URL=
if command -v apk >/dev/null; then if command -v apk >/dev/null; then
PKG_MGR=apk PKG_MGR=apk
ZAP_PKG_EXT=apk ZAP_PKG_EXT=apk
PKG_CHECK="apk info -e "
PKG_REMOVE="apk del --force "
elif command -v opkg >/dev/null; then elif command -v opkg >/dev/null; then
PKG_MGR=opkg PKG_MGR=opkg
ZAP_PKG_EXT=ipk ZAP_PKG_EXT=ipk
PKG_CHECK="opkg status "
PKG_REMOVE="opkg remove --force-remove "
else else
echo "ERROR: No package manager found" echo "ERROR: No package manager found"
return 1 return 1
@@ -487,7 +491,7 @@ if [ "$opt_update" != "" ]; then
fi fi
fi fi
if ! command -v unzip >/dev/null 2>&1; then if ! command -v unzip >/dev/null 2>&1; then
echo "ERROR: package \"upzip\" not installed!" echo "ERROR: package \"unzip\" not installed!"
return 218 return 218
fi fi
unzip -q "$ZAP_PKG_FN" -d $ZAP_PKG_DIR unzip -q "$ZAP_PKG_FN" -d $ZAP_PKG_DIR
@@ -525,6 +529,14 @@ if [ "$opt_update" != "" ]; then
if [ "$opt_forced" = true ]; then if [ "$opt_forced" = true ]; then
pkg_mgr_update pkg_mgr_update
fi fi
if ${PKG_CHECK} ${ZAPRET_CFG_NAME}-mdig >/dev/null 2>&1; then
echo "Uninstall mdig..."
${PKG_REMOVE} ${ZAPRET_CFG_NAME}-mdig
fi
if ${PKG_CHECK} ${ZAPRET_CFG_NAME}-ip2net >/dev/null 2>&1; then
echo "Uninstall ip2net..."
${PKG_REMOVE} ${ZAPRET_CFG_NAME}-ip2net
fi
echo "Install downloaded packages..." echo "Install downloaded packages..."
if [ "$PKG_MGR" != "apk" ]; then if [ "$PKG_MGR" != "apk" ]; then
opkg install --force-reinstall "$ZAP_PKG_BASE_FN" opkg install --force-reinstall "$ZAP_PKG_BASE_FN"