Compare commits

...

53 Commits

Author SHA1 Message Date
remittor
5550820fdc Bump version to v72.20251225-r2 2025-12-25 18:04:53 +03:00
remittor
0e8366f7d1 luci: tools: Fix show and close modal dialog for NFQWS_OPT 2025-12-25 18:02:11 +03:00
remittor
ea3c774537 updater: Fix find base package after ZIP unpack 2025-12-25 14:57:36 +03:00
remittor
57b7e65532 github: Fix bug_report.yml 2025-12-25 12:01:27 +03:00
remittor
eeacc486f9 Add ISSUE_TEMPLATE 2025-12-25 11:52:35 +03:00
remittor
101382faf7 Bump version to v72.20251225 2025-12-25 08:58:38 +03:00
remittor
21229ef152 def-cfg: Add strategies by Flowseal (ALT7 + TLS_AUTO_ALT3) 2025-12-25 08:54:40 +03:00
remittor
9aaf2b29e3 fake: Add TLS 1.3 hello from max.ru 2025-12-25 08:25:26 +03:00
remittor
246f4a08a0 luci: tools: Fix close modal dialog for NFQWS_OPT 2025-12-24 18:50:48 +03:00
remittor
3d3eb82b7b luci: updater: Fix timer using 2025-12-24 14:39:52 +03:00
remittor
8aff441b88 luci: tools: Fix close modal dialog for NFQWS_OPT 2025-12-23 14:14:07 +03:00
remittor
1c866d5de1 comfunc: Fix remove debug log 2025-12-20 10:11:18 +03:00
remittor
57d5ab5060 Bump version to v72.20251219 2025-12-19 11:17:04 +03:00
remittor
5a685cfa27 updater: Add check for unzip installed 2025-12-19 11:11:47 +03:00
remittor
21017047a8 updater: Fix parsing package version (APK) 2025-12-19 10:22:54 +03:00
remittor
9298388a12 build: Fix build package for riscv64 arch 2025-12-18 13:34:24 +03:00
remittor
0972ce0889 Bump version to v72.20251218 2025-12-18 11:32:56 +03:00
remittor
40084f0762 luci: Show package version with release number (exclude r1) 2025-12-18 11:30:16 +03:00
remittor
a616c6fa4e updater: Added retcode file (pid-file deleted) 2025-12-18 10:46:29 +03:00
remittor
06f45e3fbb updater: Replace wget to curl and other fixes 2025-12-18 09:19:08 +03:00
remittor
252a7eab9d Bump version to v72.20251217 2025-12-17 11:38:50 +03:00
remittor
73104ca3ca zapret: Fix makefile for install new sh-files 2025-12-17 11:33:59 +03:00
remittor
a5156e0d0c Add support check and install updates from GitHub 2025-12-17 11:31:13 +03:00
remittor
565ef66299 luci: Fix getting CPU arch info 2025-12-17 10:10:18 +03:00
remittor
1364bcbf1a ipset: Update zapret-hosts-user-exclude.txt 2025-12-16 08:23:47 +03:00
remittor
57ba961b07 github: releases: Remove draft releases 2025-12-16 08:14:32 +03:00
remittor
3a37ec9172 build: Add release number to pkg version string 2025-12-16 08:02:18 +03:00
remittor
e0ecbf5145 github: releases: Fix auto run 2025-12-15 23:15:05 +03:00
remittor
cc7ae8a91c build: Fix creation draft release 2025-12-15 23:05:32 +03:00
remittor
50ce130e1c build: Create releases.yml and auto mark all releases as prereleases 2025-12-15 20:55:20 +03:00
remittor
ac97bfae89 luci: Add showing CPU arch 2025-12-15 12:19:35 +03:00
remittor
058b3af2b3 build: releases: Create directory for releases 2025-12-14 15:11:05 +03:00
remittor
029923bac7 build: releases: Create releases for each ARCH 2025-12-14 14:25:28 +03:00
remittor
6aa114e87f build: releases: Add support second branch 2025-12-14 13:09:18 +03:00
remittor
ebd13f65c3 build: Add releases.yml to gh-pages 2025-12-14 12:42:20 +03:00
remittor
a95c938c78 build: Add arch riscv64 2025-12-14 12:42:20 +03:00
remittor
98dcd66524 luci: settings: Rename checkbox DISABLE_CUSTOM 2025-12-14 12:41:32 +03:00
remittor
1e2a9f48a2 luci: Remove unused controls from service-page 2025-12-14 12:41:03 +03:00
remittor
f63ce9d1e2 Bump version to v72.20251213 2025-12-13 10:33:20 +03:00
remittor
3f17898289 luci: Show option MODE_FILTER as checkbox: hostlist/autohostlist 2025-12-13 10:31:44 +03:00
remittor
52bd72079c install: Fix copy fake-files into distributive 2025-12-13 10:08:53 +03:00
remittor
6627678827 custom.d: Mark files into custom.d as configs 2025-12-13 10:06:56 +03:00
remittor
5691882d5e config: Fix using autohostlist option into NFQWS_OPT 2025-12-13 10:04:08 +03:00
remittor
fee8b480b0 Bump version to v72.20251212 2025-12-12 13:23:21 +03:00
remittor
2fb3ac3cc1 build: Return arm_cortex-a7_neon-vfpv4 for SNAPSHOT 2025-12-12 13:23:03 +03:00
remittor
f443195a44 build: fix gpg import
PR: https://github.com/remittor/zapret-openwrt/pull/443
2025-12-12 12:56:31 +03:00
remittor
5b65e2078f luci: Improved display of logs
PR: https://github.com/remittor/zapret-openwrt/pull/526
2025-12-12 12:53:51 +03:00
remittor
18b9394679 config: Add new options to reset settings dialog (choice of NFQWS strategy) 2025-12-12 12:27:18 +03:00
remittor
6ea3432d0c config: set DISABLE_CUSTOM=1 by default 2025-12-12 09:24:55 +03:00
remittor
5b28626ac0 custom.d: Add Stun4ALL script (50-script.sh) 2025-12-12 09:24:55 +03:00
remittor
6cbf1e3c47 ipset: Add ability for restore default ipset configs 2025-12-12 09:24:54 +03:00
remittor
2b04a6f37a fake: Added new TLS HELLO fakes 2025-12-09 14:57:25 +03:00
remittor
8ed3a6e3ae ipset: Update zapret-hosts-user-exclude.txt 2025-12-09 14:55:42 +03:00
30 changed files with 1959 additions and 275 deletions

View File

@@ -0,0 +1,80 @@
---
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

@@ -0,0 +1,80 @@
---
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

9
.github/ISSUE_TEMPLATE/config.yml vendored Normal file
View File

@@ -0,0 +1,9 @@
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

@@ -0,0 +1,66 @@
---
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

@@ -0,0 +1,68 @@
---
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

@@ -137,14 +137,15 @@ jobs:
- mipsel_24kc_24kf
- mipsel_74kc
- mipsel_mips32
- riscv64_generic
- x86_64
isTestOrFake:
- ${{ needs.check.outputs.test_build == 'true' || needs.check.outputs.fake_build == 'true' }}
exclude:
- branch: openwrt-24.10
arch: riscv64_generic
- branch: SNAPSHOT
arch: arm_cortex-a9_vfpv3-d16
- branch: SNAPSHOT
arch: arm_cortex-a7_neon-vfpv4
- { isTestOrFake: true }
include:
- branch: openwrt-24.10
@@ -172,7 +173,8 @@ jobs:
shell: bash
run: |
# gpg --verbose --recv-keys 0x1D53D1877742E911
gpg --verbose --import <(wget -qO- 'https://git.openwrt.org/?p=keyring.git;a=blob_plain;f=gpg/0x1D53D1877742E911.asc')
# gpg --verbose --import <(wget -qO- 'https://git.openwrt.org/?p=keyring.git;a=blob_plain;f=gpg/0x1D53D1877742E911.asc')
gpg --verbose --import <(wget -qO- 'https://raw.githubusercontent.com/openwrt/keyring/refs/heads/master/gpg/0x1D53D1877742E911.asc')
# disable check signatures
sed -i 's/gpg --/#gpg --/g' setup.sh
# disable cleanup keys
@@ -208,6 +210,8 @@ jobs:
PKGDIR=$GITHUB_WORKSPACE/zapret-openwrt
MKFN=$PKGDIR/luci-app-zapret/Makefile
PKGVER=$( grep -s '^PKG_VERSION:=.*' $MKFN | cut -d'=' -f2 )
PKGREL=$( grep -s '^PKG_RELEASE:=.*' $MKFN | cut -d'=' -f2 )
[ "$PKGREL" != "1" ] && PKGVER=$PKGVER-r$PKGREL
echo "PKG_VERSION = $PKGVER"
cp -vr $PKGDIR ./package/zapret-openwrt/
@@ -339,12 +343,13 @@ jobs:
ls -lh ./public/*.zip
- name: Upload assets
uses: andelf/nightly-release@main
uses: softprops/action-gh-release@v2
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
TAG: ${{ needs.check.outputs.tag }}
with:
prerelease: ${{ env.TEST_BUILD == 'true' || env.FAKE_BUILD == 'true' }}
draft: ${{ env.TEST_BUILD == 'true' || env.FAKE_BUILD == 'true' }}
prerelease: true
tag_name: v${{ needs.build.outputs.pkgver }}${{ env.TAG_SUFFIX }}
name: zapret v${{ needs.build.outputs.pkgver }}
body: |

140
.github/workflows/releases.yml vendored Normal file
View File

@@ -0,0 +1,140 @@
name: Update releases.json
on:
workflow_run:
workflows: ["build"]
types: [completed]
release:
types: [published, created, edited]
permissions:
contents: write
jobs:
update-json:
if: |
github.event_name != 'workflow_run' ||
github.event.workflow_run.conclusion == 'success'
runs-on: ubuntu-latest
steps:
- name: Checkout gh-pages
uses: actions/checkout@v4
with:
ref: gh-pages
continue-on-error: true
- name: Save FULL releases.json
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
OWNER: ${{ github.repository_owner }}
REPO: ${{ github.event.repository.name }}
run: |
curl -s \
-H "Authorization: Bearer $GH_TOKEN" \
-H "Accept: application/vnd.github+json" \
https://api.github.com/repos/$OWNER/$REPO/releases \
> releases.json
- name: Generate releases_BRANCH.json
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
OWNER: ${{ github.repository_owner }}
REPO: ${{ github.event.repository.name }}
run: |
curl -s \
-H "Authorization: Bearer $GH_TOKEN" \
-H "Accept: application/vnd.github+json" \
https://api.github.com/repos/$OWNER/$REPO/releases \
| jq '
def normalize_release:
{
id: .id,
version: (.tag_name | sub("^v"; "")),
tag: .tag_name,
name: .name,
draft: .draft,
prerelease: .prerelease,
created_at: .created_at,
published_at: .published_at,
url: .html_url,
assets: (
.assets | map({
id: .id,
name: .name,
size: .size,
content_type: .content_type,
browser_download_url: .browser_download_url
})
)
};
sort_by(.created_at) | reverse
| {
zap1: (
map(select(.draft == false))
| map(select(.name | startswith("zapret ")))
| .[0:20]
| {
generated_at: (now | todate),
releases: map(normalize_release)
}
),
zap2: (
map(select(.draft == false))
| map(select(.name | startswith("zapret2 ")))
| .[0:20]
| {
generated_at: (now | todate),
releases: map(normalize_release)
}
)
}
' \
| tee \
>(jq '.zap1' > releases_zap1.json) \
>(jq '.zap2' > releases_zap2.json)
- name: Generate releases_BRANCH_ARCH.json
run: |
BRANCHES=("zap1" "zap2")
for ARCH in $(jq -r '.[] | .assets[].name | capture("^[^_]+_[^_]+_(?<arch>.+)\\.zip$").arch' releases.json | sort -u); do
for BRANCH in "${BRANCHES[@]}"; do
if [ "$BRANCH" == "zap1" ]; then
PREFIX="zapret "
else
PREFIX="zapret2 "
fi
jq --arg prefix "$PREFIX" --arg arch "$ARCH" '
sort_by(.created_at) | reverse
| map(select(.draft == false))
| map(select(.name | startswith($prefix)))
| .[0:20]
| map(
. as $release
| {
tag: $release.tag_name,
name: $release.name,
prerelease: $release.prerelease,
created_at: $release.created_at,
updated_at: $release.updated_at,
published_at: $release.published_at,
url: $release.html_url,
assets: ($release.assets | map(select(.name | test("_\($arch)\\.zip$"))))
}
)
| { generated_at: (now | todate), releases: . }
' releases.json > "releases_${BRANCH}_${ARCH}.json"
done
done
- name: Commit and push ALL releases.json
run: |
mkdir -p releases
mv releases*.json releases/
git config user.name "github-actions"
git config user.email "github-actions@github.com"
git checkout -B gh-pages
git add releases/*
git commit -m "Update releases" || exit 0
git push origin gh-pages

View File

@@ -5,7 +5,8 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=luci-app-zapret
PKG_VERSION:=72.20251122
PKG_VERSION:=72.20251225
PKG_RELEASE:=2
PKG_LICENSE:=MIT
PKG_MAINTAINER:=remittor <https://github.com/remittor>

View File

@@ -173,16 +173,16 @@ return view.extend({
let tab = E('div', { 'data-tab': tabname, 'data-tab-title': tabNameText }, [
E('div', { 'id': 'content_dmnlog_' + log_num }, [
E('div', {'style': 'padding-bottom: 20px'}, [ scrollDownButton ]),
E('div', {'style': 'margin-bottom: 20px; '}, [ scrollDownButton ]),
E('textarea', {
'id': log_id,
'name': log_name,
'style': 'font-size:12px',
'style': 'font-size:12px; width: 100%; max-height: 50vh;',
'readonly': 'readonly',
'wrap': 'off',
'rows': logdata[log_num].rows,
}, [ log_text ]),
E('div', {'style': 'padding-bottom: 20px'}, [ scrollUpButton ]),
E('div', {'style': 'margin-top: 20px'}, [ scrollUpButton ]),
]),
]);

View File

@@ -5,6 +5,7 @@
'require ui';
'require view';
'require view.zapret.tools as tools';
'require view.zapret.updater as updater';
const btn_style_neutral = 'btn';
const btn_style_action = 'btn cbi-button-action';
@@ -21,8 +22,8 @@ return view.extend({
start : elems.btn_start || document.getElementById('btn_start'),
restart : elems.btn_restart || document.getElementById('btn_restart'),
stop : elems.btn_stop || document.getElementById('btn_stop'),
reset : elems.btn_reset || document.getElementById('btn_reset'),
update : elems.btn_update || document.getElementById('btn_update'),
reset : elems.btn_update || document.getElementById('btn_reset'),
};
},
@@ -37,8 +38,8 @@ return view.extend({
btn.start.disabled = flag;
btn.restart.disabled = flag;
btn.stop.disabled = flag;
btn.update.disabled = true; // TODO
btn.reset.disabled = (error_code == 0) ? flag : false;
btn.update.disabled = (error_code == 0) ? flag : false;
},
getAppStatus: function() {
@@ -48,6 +49,8 @@ return view.extend({
tools.getSvcInfo(), // svc_info
fs.exec('/bin/busybox', [ 'ps' ]), // process list
fs.exec(tools.packager.path, tools.packager.args), // installed packages
tools.getStratList(), // nfqws strategy list
fs.exec('/bin/cat', [ '/etc/openwrt_release' ]), // CPU arch
uci.load(tools.appName), // config
]).catch(e => {
ui.addNotification(null, E('p', _('Unable to execute or read contents')
@@ -61,7 +64,7 @@ return view.extend({
let cfg = uci.get(tools.appName, 'config');
if (!status_array || cfg == null || typeof(cfg) !== 'object') {
let elem_status = elems.status || document.getElementById("status");
elem_status.innerHTML = tools.makeStatusString(null);
elem_status.innerHTML = tools.makeStatusString(null, '', '');
ui.addNotification(null, E('p', _('Unable to read the contents') + ': setAppStatus()'));
this.disableButtons(true, -1, elems);
return;
@@ -71,6 +74,11 @@ return view.extend({
let svc_info = status_array[2]; // stdout: JSON as text
let proc_list = status_array[3]; // stdout: multiline text
let pkg_list = status_array[4]; // stdout: installed packages
let stratlist = status_array[5]; // array of strat names
let sys_info = status_array[6]; // stdout: openwrt distrib info
this.nfqws_strat_list = stratlist;
this.pkg_arch = tools.getConfigPar(sys_info.stdout, 'DISTRIB_ARCH', 'unknown');
//console.log('svc_en: ' + svc_en.code);
svc_en = (svc_en.code == 0) ? true : false;
@@ -97,8 +105,8 @@ return view.extend({
svcinfo = tools.decode_svc_info(svc_en, svc_info, proc_list, cfg);
}
let btn = this.get_svc_buttons(elems);
btn.update.disabled = true; // TODO
btn.reset.disabled = false;
btn.update.disabled = false;
if (Number.isInteger(svcinfo)) {
ui.addNotification(null, E('p', _('Error')
@@ -118,7 +126,7 @@ return view.extend({
}
}
let elem_status = elems.status || document.getElementById("status");
elem_status.innerHTML = tools.makeStatusString(svcinfo, cfg.FWTYPE, 'user_only');
elem_status.innerHTML = tools.makeStatusString(svcinfo, this.pkg_arch, '');
if (!poll.active()) {
poll.start();
@@ -147,7 +155,7 @@ return view.extend({
});
},
serviceActionEx: function(action, button, hide_modal = false) {
serviceActionEx: function(action, button, args = [ ], hide_modal = false) {
if (button) {
let elem = document.getElementById(button);
this.disableButtons(true, elem);
@@ -164,7 +172,7 @@ return view.extend({
}
else if (action == 'reset') {
exec_cmd = tools.defaultCfgPath;
exec_arg = [ 'sync' ]; // restore config + sync configs
exec_arg = args; // (reset_ipset)(sync) ==> restore all configs + sync config
errmsg = _('Unable to run restore-def-cfg.sh script.');
action = null;
} else {
@@ -199,17 +207,7 @@ return view.extend({
let elem = document.getElementById(button);
this.disableButtons(true, elem);
}
poll.stop();
if (action === 'update') {
this.getAppStatus().then(
(status_array) => {
this.setAppStatus(status_array, [], 4);
}
);
}
return fs.exec_direct(tools.execPath, [ action ]).then(res => {
return this.getAppStatus().then(
(status_array) => {
@@ -228,6 +226,33 @@ return view.extend({
dialogResetCfg: function(ev) {
ev.target.blur();
let reset_base = E('label', [
E('input', { type: 'checkbox', id: 'cfg_reset_base', checked: true }),
' ', _('Restore all base settings')
]);
let reset_ipset = E('label', [
E('input', { type: 'checkbox', id: 'cfg_reset_ipset', checked: true }),
' ', _('Restore ipset configs')
]);
let set_autohostlist = E('label', [
E('input', { type: 'checkbox', id: 'cfg_autohostlist', checked: true }),
' ', _('Set AutoHostList mode')
]);
let strat_list = [ ];
strat_list.push( E('option', { value: 'strat__skip__' }, [ '-' ] ) );
for (let id = 0; id < this.nfqws_strat_list.length; id++) {
let strat = '' + this.nfqws_strat_list[id];
strat_list.push( E('option', { value: 'strat_' + id }, [ strat ] ) );
}
let nfqws_strat = E('label', [
_('NFQWS_OPT strategy: '),
E('select', { id: 'cfg_nfqws_strat' }, strat_list)
]);
let cancel_button = E('button', {
'class': btn_style_neutral,
'click': ui.hideModal,
@@ -238,12 +263,35 @@ return view.extend({
}, _('Reset settings'));
resetcfg_btn.onclick = ui.createHandlerFn(this, () => {
//cancel_button.disabled = true;
return this.serviceActionEx('reset', resetcfg_btn, true);
let opt_flags = '';
if (document.getElementById('cfg_reset_base').checked == false) {
opt_flags += '(skip_base)';
};
if (document.getElementById('cfg_reset_ipset').checked) {
opt_flags += '(reset_ipset)';
};
if (document.getElementById('cfg_autohostlist').checked) {
opt_flags += '(set_mode_autohostlist)';
};
//console.log('RESET: opt_flags = ' + opt_flags);
let sel_strat = document.getElementById('cfg_nfqws_strat');
let opt_strat = sel_strat.options[sel_strat.selectedIndex].text;
//console.log('RESET: strat = ' + opt_strat);
opt_flags += '(sync)';
let args = [ opt_flags, opt_strat ];
return this.serviceActionEx('reset', resetcfg_btn, args, true);
});
ui.showModal(_('Reset settings to default'), [
E('div', { 'class': 'cbi-section' }, [
E('p', _('All settings will be reset to default. Continue?')),
reset_base,
E('br'), E('br'),
reset_ipset,
E('br'), E('br'),
set_autohostlist,
E('br'), E('br'),
nfqws_strat,
E('br'), E('br')
]),
E('div', { 'class': 'right' }, [
cancel_button,
@@ -329,14 +377,14 @@ return view.extend({
btn_stop.onclick = ui.createHandlerFn(this, this.serviceAction, 'stop', 'btn_stop');
layout_append(_('Service daemons control'), null, [ btn_start, btn_restart, btn_stop ] );
let btn_update = create_btn('btn_update', btn_style_action, _('Update'));
btn_update.onclick = ui.createHandlerFn(this, () => { this.appAction('update', 'btn_update') });
layout_append(_('Update HostLists'), null, [ btn_update ] );
let btn_reset = create_btn('btn_reset', btn_style_action, _('Reset settings'));
btn_reset.onclick = L.bind(this.dialogResetCfg, this);
layout_append(_('Reset settings to default'), null, [ btn_reset ] );
let btn_update = create_btn('btn_update', btn_style_action, _('Update'));
btn_update.onclick = ui.createHandlerFn(this, () => { updater.openUpdateDialog(this.pkg_arch) });
layout_append(_('Update package'), null, [ btn_update ] );
let elems = {
"status": status_string,
"btn_enable": btn_enable,
@@ -344,15 +392,15 @@ return view.extend({
"btn_start": btn_start,
"btn_restart": btn_restart,
"btn_stop": btn_stop,
"btn_update": btn_update,
"btn_reset": btn_reset,
"btn_update": btn_update,
};
this.setAppStatus(status_array, elems);
poll.add(L.bind(this.statusPoll, this));
let page_title = _('Zapret');
let pkgdict = tools.decode_pkg_list(pkg_list.stdout);
let pkgdict = tools.decode_pkg_list(pkg_list.stdout, false);
page_title += ' &nbsp ';
if (pkgdict['zapret'] === undefined || pkgdict['zapret'] == '') {
page_title += 'unknown version';

View File

@@ -90,11 +90,11 @@ return view.extend({
o.rmempty = false;
o.default = 1;
o = s.taboption(tabname, form.ListValue, 'MODE_FILTER', _('MODE_FILTER'));
//o = s.taboption(tabname, form.ListValue, 'MODE_FILTER', _('MODE_FILTER'));
//o.value('none', 'none');
//o.value('ipset', 'ipset');
o.value('hostlist', 'hostlist');
o.value('autohostlist', 'autohostlist');
//o.value('hostlist', 'hostlist');
//o.value('autohostlist', 'autohostlist');
o = s.taboption(tabname, form.Value, 'WS_USER', _('WS_USER'));
o.rmempty = false;
@@ -212,6 +212,20 @@ return view.extend({
tabname = 'autohostlist_tab';
s.tab(tabname, _('AutoHostList'));
o = s.taboption(tabname, form.Flag, 'MODE_FILTER', _('Use AutoHostList mode'));
o.rmempty = false;
o.default = '0';
o.validate = function(section_id, value) { return true; };
o.load = function(section_id) {
return uci.load(tools.appName).then(L.bind(function() {
var v = uci.get(tools.appName, section_id, 'MODE_FILTER');
return (v === 'autohostlist') ? '1' : '0';
}, this));
};
o.write = function(section_id, value) {
return uci.set(tools.appName, section_id, 'MODE_FILTER', value === '1' ? 'autohostlist' : 'hostlist');
};
o = s.taboption(tabname, form.Value, 'AUTOHOSTLIST_RETRANS_THRESHOLD', _('RETRANS_THRESHOLD'));
o.rmempty = false;
@@ -349,9 +363,19 @@ return view.extend({
tabname = 'custom_d_tab';
s.tab(tabname, 'custom.d');
o = s.taboption(tabname, form.Flag, 'DISABLE_CUSTOM', _('DISABLE_CUSTOM'));
o = s.taboption(tabname, form.Flag, 'DISABLE_CUSTOM', _('Use custom.d scripts'));
o.rmempty = false;
o.default = 0;
o.default = '0';
o.validate = function(section_id, value) { return true; };
o.load = function(section_id) {
return uci.load(tools.appName).then(L.bind(function() {
var v = uci.get(tools.appName, section_id, 'DISABLE_CUSTOM');
return (v === '1') ? '0' : '1';
}, this));
};
o.write = function(section_id, value) {
return uci.set(tools.appName, section_id, 'DISABLE_CUSTOM', value === '1' ? '0' : '1');
};
add_delim(s);

View File

@@ -39,6 +39,7 @@ return baseclass.extend({
appName : 'zapret',
execPath : '/etc/init.d/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',
@@ -139,6 +140,20 @@ return baseclass.extend({
});
},
getStratList: function() {
this.init_consts();
let exec_cmd = '/bin/busybox';
let exec_arg = [ 'awk', '-F', '"', '/if \\[ "\\$strat" = "/ {print $4}', this.defCfgPath ];
return fs.exec(exec_cmd, exec_arg).then(res => {
if (res.code == 0) {
return this.getWordsArray(res.stdout);
}
return [ ];
}).catch(e => {
ui.addNotification(null, E('p', _('Failed to get strat list: %s').format(e)));
});
},
handleServiceAction: function(name, action) {
return this.callInitAction(name, action).then(success => {
if (!success) {
@@ -154,40 +169,61 @@ return baseclass.extend({
return (v && typeof(v) === 'string') ? v.trim().replace(/\r?\n/g, '') : v;
},
decode_pkg_list: function(pkg_list) {
getWordsArray: function (text, { trim = true, removeEmpty = true } = {}) {
const rawLines = text.split(/\n/);
const processed = trim ? rawLines.map(line => line.trim()) : rawLines.slice();
return removeEmpty ? processed.filter(line => line.length > 0) : processed;
},
getConfigPar: function(txt, key, defval = null) {
const re = new RegExp(`^${key}\\s*=\\s*(['"])(.*?)\\1`, 'm');
const m = txt.match(re);
return m ? m[2] : defval;
},
decode_pkg_list: function(pkg_list, with_suffix_r1 = true) {
let pkg_dict = { };
if (!pkg_list) {
return pkg_dict;
}
let lines = pkg_list.trim().split('\n');
for (let i = 0; i < lines.length; i++) {
let line = lines[i].trim();
let name;
let ver;
let rev = -1;
if (this.packager.name == 'apk') {
let fullname = line.split(' ')[0];
let mpos = fullname.lastIndexOf("-");
if (mpos <= 0)
continue;
if (fullname.substring(mpos+1, mpos+2) == 'r') {
// release number
fullname = fullname.substring(0, mpos);
let match = fullname.match(/^(.*)-r(\d+)$/);
if (match) {
fullname = match[1];
rev = parseInt(match[2], 10);
}
mpos = fullname.lastIndexOf("-");
let mpos = fullname.lastIndexOf('-');
if (mpos <= 0)
continue;
name = fullname.substring(0, mpos).trim();
ver = fullname.substring(mpos+1).trim();
continue; // incorrect format
name = fullname.slice(0, mpos).trim();
ver = fullname.slice(mpos + 1).trim();
} else {
if (!line.includes(' - '))
continue;
continue; // incorrect format
name = line.split(' - ')[0].trim();
ver = line.split(' - ')[1].trim();
let spos = ver.indexOf(" ");
if (spos > 0) {
ver = ver.substring(0, spos);
}
let mpos = ver.lastIndexOf("-");
if (mpos > 0 && ver.substring(mpos+1, mpos+2) == 'r') {
// release number
ver = ver.substring(0, mpos);
let match = ver.match(/^(.*)-r(\d+)$/);
if (match) {
ver = match[1];
rev = parseInt(match[2], 10);
}
}
if (rev >= 0) {
if (rev == 1 && !with_suffix_r1) {
// nothing
} else {
ver += '-r' + rev;
}
}
pkg_dict[name] = ver;
@@ -261,7 +297,7 @@ return baseclass.extend({
return result;
},
makeStatusString: function(svcinfo, fwtype, bllist_preset) {
makeStatusString: function(svcinfo, pkg_arch, bllist_preset) {
let svc_autorun = _('Unknown');
let svc_daemons = _('Unknown');
@@ -274,12 +310,18 @@ return baseclass.extend({
svc_daemons += ' [' + svcinfo.dmn.working + '/' + svcinfo.dmn.total + ']';
}
}
let update_mode = _('user entries only');
let td_name_width = 40;
let td_name_style = `style="width: ${td_name_width}%; min-width:${td_name_width}%; max-width:${td_name_width}%;"`;
let out = `
<table class="table">
<tr class="tr">
<td class="td left" ${td_name_style}>
${_('CPU architecture')}:
</td>
<td class="td left">
${pkg_arch}
</td>
</tr>
<tr class="tr">
<td class="td left" ${td_name_style}>
${_('Service autorun status')}:
@@ -296,22 +338,6 @@ return baseclass.extend({
${svc_daemons}
</td>
</tr>
<tr class="tr">
<td class="td left" ${td_name_style}>
${_('FW type')}:
</td>
<td class="td left">
${fwtype}
</td>
</tr>
<tr class="tr">
<td class="td left" ${td_name_style}>
${_('HostLists update mode')}:
</td>
<td class="td left">
${update_mode}
</td>
</tr>
<tr class="tr">
<td class="td left" ${td_name_style}>
</td>
@@ -448,9 +474,12 @@ return baseclass.extend({
if (typeof(value) === 'string') {
value = value.trim();
if (this.multiline == 2) {
value = value.replace(/\n\t\t\t--/g, "\n--");
value = value.replace(/\n\t\t--/g, "\n--");
value = value.replace(/\n\t--/g, "\n--");
value = value.replace(/\n\t/g, "\n");
value = value.replace(/\n\t/g, "\n");
value = value.replace(/\n\t/g, "\n");
value = value.replace(/\n\t/g, "\n");
value = value.replace(/\n\t/g, "\n");
value = value.replace(/\n\t/g, "\n");
value = value.replace(/\n --/g, "\n--");
value = value.replace(/\n --/g, "\n--");
value = value.replace(/ --/g, "\n--");
@@ -515,8 +544,6 @@ return baseclass.extend({
}
value = value.replace(/˂/g, '<');
value = value.replace(/˃/g, '>');
uci.set('zapret', this.cfgsec, this.cfgparam, value);
uci.save();
let elem = document.getElementById("cbi-zapret-" + this.cfgsec + "-_" + this.cfgparam);
if (elem) {
let val = value.trim();
@@ -529,19 +556,8 @@ return baseclass.extend({
elem.querySelector('div').textContent = val;
}
}
ui.hideModal();
/*
return uci.save()
.then(L.bind(ui.changes.init, ui.changes))
.then(L.bind(ui.changes.displayChanges, ui.changes))
//.then(L.bind(ui.changes.apply, ui.changes))
.then(ui.addNotification(null, E('p', _('Contents have been saved.')), 'info'))
.catch(e => {
ui.addNotification(null, E('p', _('Unable to save the contents') + ': %s'.format(e.message)));
}).finally(() => {
ui.hideModal();
});
*/
uci.set('zapret2', this.cfgsec, this.cfgparam, value);
uci.save().then(ui.hideModal);
},
error: function(e) {
@@ -560,13 +576,17 @@ return baseclass.extend({
},
show: function() {
//ui.showModal(null, E('p', { 'class': 'spinning' }, _('Loading')) );
let content = this.load();
//ui.hideModal();
if (content === null) {
return this.error('Cannot load parameter');
}
return this.render(content);
ui.showModal(null,
E('p', { 'class': 'spinning' }, _('Loading'))
);
L.resolveDefault(this.load(), null)
.then(content => {
ui.hideModal();
return this.render(content);
}).catch(e => {
ui.hideModal();
return this.error(e);
})
},
}),

View File

@@ -0,0 +1,245 @@
'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_update_pkg_sh = '/opt/zapret/update-pkg.sh';
return baseclass.extend({
releasesUrlPrefix : 'https://raw.githubusercontent.com/remittor/zapret-openwrt/gh-pages/releases/',
appendLog: function(msg, end = '\n') {
this.logArea.value += msg + end;
this.logArea.scrollTop = this.logArea.scrollHeight;
},
setBtnMode: function(enable) {
this.btn_cancel.disabled = enable ? false : true;
this.btn_action.disabled = (enable == 2) ? false : true;
},
setStage: function(stage, btn_flag = true) {
if (stage == 0) {
this.btn_action.textContent = _('Check for updates');
this.btn_action.classList.remove('hidden');
} else
if (stage == 1) {
this.btn_action.textContent = _('Update packages');
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;
},
checkUpdates: function() {
this.setStage(0);
this.setBtnMode(0);
this.pkg_url = null;
this.appendLog(_('Checking for updates...'));
let opt_list = [ '-c' ]; // check for updates
if (document.getElementById('cfg_exclude_prereleases').checked == false) {
opt_list.push('-p'); // include prereleases ZIP-files
}
let forced_reinstall = document.getElementById('cfg_forced_reinstall').checked;
let rpc_opt = { timeout: 20*1000 }
//rpc_opt.uid = 0; // run under root
let res = fs.exec(fn_update_pkg_sh, opt_list, null, rpc_opt).then(res => {
let log = res.stdout.trim();
this.appendLog(log);
let code = log.match(/^RESULT:\s*\(([^)]+)\)\s+.+$/m);
let pkg_url = log.match(/^ZAP_PKG_URL\s*=\s*(.+)$/m);
if (res.code == 0 && code && pkg_url) {
this.pkg_url = pkg_url[1];
code = code[1];
if (code == 'E' && !forced_reinstall) {
this.setStage(999);
return 0;
}
this.setStage(1);
this.setBtnMode(2); // enable all buttons
} else {
if (res.code != 0) {
this.appendLog('ERROR: Check for updates failed with error ' + res.code);
}
this.setStage(999);
}
return res.code;
}).catch(e => {
this.appendLog('ERROR: ' + _('Updates checking failed'));
this.appendLog('ERROR: ' + e);
this.setStage(999);
return 1;
}).finally(() => {
this.appendLog('=========================================================');
});
},
installUpdates: async function() {
this.setStage(1);
this.setBtnMode(0);
if (!this.pkg_url || this.pkg_url.length < 10) {
this.appendLog('ERROR: pkg_url = null');
this.setStage(999);
return 1;
}
this.appendLog(_('Install updates...'));
let opt_list = [ '-u', this.pkg_url ]; // update packages
if (document.getElementById('cfg_forced_reinstall').checked == true) {
opt_list.push('-f'); // forced reinstall if same version
}
let rpc_opt = { timeout: 5*1000 }
//rpc_opt.uid = 0; // run under root
const logFile = '/tmp/zapret_pkg_install.log';
const rcFile = logFile + '.rc';
try {
await fs.exec('/bin/busybox', [ 'rm', '-f', logFile + '*' ], null, rpc_opt);
this.appendLog('Install log cleared.');
} catch (e) {
this.appendLog('ERROR: Failed to clear log file');
this.setStage(999);
return 1;
}
try {
let opt = [ logFile, fn_update_pkg_sh ];
//opt.push('-t'); opt.push('0'); // only for testing
opt.push(...opt_list);
let res = await fs.exec('/opt/zapret/script-exec.sh', opt, null, rpc_opt);
if (res.code == 0) {
this.appendLog('Process started...');
} else {
this.appendLog('ERROR: cannot run ' + fn_update_pkg_sh + ' script! (error = ' + res.code + ')');
throw new Error('cannot run script');
}
} catch (e) {
this.appendLog('ERROR: Failed to start process: ' + e.message);
this.setStage(999);
return 1;
}
let lastLen = 0;
let retCode = -1;
let timerBusy = false;
let timer = setInterval(async () => {
if (timerBusy)
return; // skip iteration
timerBusy = true;
try {
let res = await fs.exec('/bin/cat', [ logFile ], null, rpc_opt);
if (res.stdout && res.stdout.length > lastLen) {
let log = res.stdout.slice(lastLen);
log = log.replace(/^ \* resolve_conffiles.*(?:\r?\n|$)/gm, '');
this.appendLog(log, '');
lastLen = res.stdout.length;
}
if (retCode < 0) {
let rc = await fs.exec('/bin/cat', [ rcFile ], null, rpc_opt);
if (rc.code != 0) {
throw new Error('cannot read file "' + rcFile + '"');
}
if (rc.stdout) {
retCode = parseInt(rc.stdout.trim(), 10);
}
}
if (retCode >= 0) {
clearInterval(timer);
this.appendLog('\n' + 'Process finished.');
if (res.stdout) {
let code = res.stdout.match(/^RESULT:\s*\(([^)]+)\)\s+.+$/m);
if (retCode == 0 && code && code[1] == '+') {
this.stage = 999;
this.btn_action.textContent = _('OK');
this.btn_action.disabled = false;
this.btn_cancel.disabled = true;
return 0;
}
}
this.appendLog('ERROR: Install updates failed with error ' + retCode);
this.setStage(999);
}
} catch (e) {
clearInterval(timer);
this.appendLog('ERROR: installUpdates: ' + e.message);
this.appendLog('ERROR: installUpdates: ' + e.stack?.trim().split('\n').pop());
this.setStage(999);
} finally {
timerBusy = false;
}
}, 500);
},
openUpdateDialog: function(pkg_arch) {
this.stage = 0;
this.pkg_arch = pkg_arch;
this.pkg_url = null;
let exclude_prereleases = E('label', [
E('input', { type: 'checkbox', id: 'cfg_exclude_prereleases', checked: true }),
' ', _('Exclude PreReleases')
]);
let forced_reinstall = E('label', [
E('input', { type: 'checkbox', id: 'cfg_forced_reinstall'}),
' ', _('Forced reinstall packages')
]);
this.logArea = E('textarea', {
'readonly': true,
'style': 'width:100%; height:400px; font-family: monospace;'
});
this.btn_cancel = E('button', {
'id': 'btn_cancel',
'name': 'btn_cancel',
'class': btn_style_warning,
}, _('Cancel'));
this.btn_cancel.onclick = ui.hideModal;
this.btn_action = E('button', {
'id': 'btn_action',
'name': 'btn_action',
'class': btn_style_action,
}, 'BUTTON_ACTION');
this.btn_action.onclick = ui.createHandlerFn(this, () => {
if (this.stage == 0) {
return this.checkUpdates();
}
if (this.stage == 1) {
return this.installUpdates();
}
return ui.hideModal();
});
this.setStage(0);
this.setBtnMode(2);
ui.showModal(_('Package update'), [
E('div', { 'class': 'cbi-section' }, [
exclude_prereleases,
E('br'), E('br'),
forced_reinstall,
E('br'), E('br'),
E('hr'),
this.logArea,
]),
E('div', { 'class': 'right' }, [
this.btn_cancel,
' ',
this.btn_action,
])
]);
}
});

View File

@@ -17,6 +17,8 @@
"/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" ],

View File

@@ -1,7 +1,8 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=zapret-ip2net
PKG_VERSION:=72.20251122
PKG_VERSION:=72.20251225
PKG_RELEASE:=2
PKG_MAINTAINER:=bol-van
PKG_LICENSE:=MIT
@@ -9,8 +10,8 @@ PKG_LICENSE_FILES:=docs/LICENSE.txt
PKG_SOURCE_URL:=https://github.com/bol-van/zapret.git
PKG_SOURCE_PROTO:=git
PKG_SOURCE_VERSION:=97cefbace9eee57c5f3799743df9d755690dac4c
PKG_SOURCE_DATE:=2025-11-22
PKG_SOURCE_VERSION:=e95a06c7eeff87e166a5f9ca71547b169c9852e0
PKG_SOURCE_DATE:=2025-12-25
#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?

View File

@@ -1,7 +1,8 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=zapret-mdig
PKG_VERSION:=72.20251122
PKG_VERSION:=72.20251225
PKG_RELEASE:=2
PKG_MAINTAINER:=bol-van
PKG_LICENSE:=MIT
@@ -9,8 +10,8 @@ PKG_LICENSE_FILES:=docs/LICENSE.txt
PKG_SOURCE_URL:=https://github.com/bol-van/zapret.git
PKG_SOURCE_PROTO:=git
PKG_SOURCE_VERSION:=97cefbace9eee57c5f3799743df9d755690dac4c
PKG_SOURCE_DATE:=2025-11-22
PKG_SOURCE_VERSION:=e95a06c7eeff87e166a5f9ca71547b169c9852e0
PKG_SOURCE_DATE:=2025-12-25
#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?

View File

@@ -1,7 +1,8 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=zapret-tpws
PKG_VERSION:=72.20251122
PKG_VERSION:=72.20251225
PKG_RELEASE:=2
PKG_MAINTAINER:=bol-van
PKG_LICENSE:=MIT
@@ -9,8 +10,8 @@ PKG_LICENSE_FILES:=docs/LICENSE.txt
PKG_SOURCE_URL:=https://github.com/bol-van/zapret.git
PKG_SOURCE_PROTO:=git
PKG_SOURCE_VERSION:=97cefbace9eee57c5f3799743df9d755690dac4c
PKG_SOURCE_DATE:=2025-11-22
PKG_SOURCE_VERSION:=e95a06c7eeff87e166a5f9ca71547b169c9852e0
PKG_SOURCE_DATE:=2025-12-25
#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?

View File

@@ -5,7 +5,8 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=zapret
PKG_VERSION:=72.20251122
PKG_VERSION:=72.20251225
PKG_RELEASE:=2
PKG_MAINTAINER:=bol-van
PKG_LICENSE:=MIT
@@ -13,8 +14,8 @@ PKG_LICENSE_FILES:=docs/LICENSE.txt
PKG_SOURCE_URL:=https://github.com/bol-van/zapret.git
PKG_SOURCE_PROTO:=git
PKG_SOURCE_VERSION:=97cefbace9eee57c5f3799743df9d755690dac4c
PKG_SOURCE_DATE:=2025-11-22
PKG_SOURCE_VERSION:=e95a06c7eeff87e166a5f9ca71547b169c9852e0
PKG_SOURCE_DATE:=2025-12-25
#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?
@@ -54,6 +55,7 @@ define Package/$(PKG_NAME)/conffiles
/etc/config/zapret
/opt/zapret/config
/opt/zapret/ipset/
/opt/zapret/init.d/openwrt/custom.d/
endef
define Package/$(PKG_NAME)/install
@@ -66,6 +68,7 @@ define Package/$(PKG_NAME)/install
#$(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
@@ -79,8 +82,18 @@ define Package/$(PKG_NAME)/install
$(INSTALL_BIN) ./init.d.sh $(1)/etc/init.d/zapret
$(INSTALL_DATA) ./config.default $(1)/opt/zapret/config.default
$(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_BIN) ./uci-def-cfg.sh $(1)/opt/zapret/uci-def-cfg.sh
@@ -89,8 +102,12 @@ define Package/$(PKG_NAME)/install
$(INSTALL_BIN) ./renew-cfg.sh $(1)/opt/zapret/renew-cfg.sh
$(INSTALL_BIN) ./restore-def-cfg.sh $(1)/opt/zapret/restore-def-cfg.sh
$(INSTALL_BIN) ./sync_config.sh $(1)/opt/zapret/sync_config.sh
$(INSTALL_BIN) ./script-exec.sh $(1)/opt/zapret/script-exec.sh
$(INSTALL_BIN) ./update-pkg.sh $(1)/opt/zapret/update-pkg.sh
# Fix permisions
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.default
chmod 755 $(1)/opt/zapret/*.sh
endef

View File

@@ -90,14 +90,56 @@ function get_run_on_boot_option
fi
}
function get_distrib_param
{
local parname=$1
local value="__unknown__"
if [ -f /etc/openwrt_release ]; then
while IFS='=' read -r key val; do
val="${val#\'}"
val="${val%\'}"
val="${val#\"}"
val="${val%\"}"
if [ "$key" = "$parname" ]; then
value="$val"
break
fi
done < /etc/openwrt_release
fi
printf '%s' "$value"
}
function get_cpu_arch
{
get_distrib_param DISTRIB_ARCH
}
function restore_ipset_txt
{
local cfgname=$1
if [ -f "$ZAPRET_BASE/ipset_def/$cfgname" ]; then
cp -f "$ZAPRET_BASE/ipset_def/$cfgname" "$ZAPRET_BASE/ipset/$cfgname"
fi
}
function restore_all_ipset_cfg
{
restore_ipset_txt zapret-hosts-google.txt
restore_ipset_txt zapret-hosts-user.txt
restore_ipset_txt zapret-hosts-user-exclude.txt
restore_ipset_txt zapret-ip-exclude.txt.txt
}
function create_default_cfg
{
local cfgname=${1:-$ZAPRET_CFG_NAME}
local opt_flags=${1:--}
local opt_strat=$2
local cfgname=${3:-$ZAPRET_CFG_NAME}
local cfgfile=/etc/config/$cfgname
rm -f $cfgfile
touch $cfgfile
uci set $cfgname.config=main
set_cfg_default_values $cfgname
set_cfg_default_values "$opt_flags" "$opt_strat" $cfgname
return 0
}
@@ -112,7 +154,7 @@ function merge_cfg_with_def_values
local cfg_sec_name="$( uci -q get $ZAPRET_CFG_NAME.config )"
[ -z "$cfg_sec_name" ] && create_default_cfg
create_default_cfg "$NEWCFGNAME"
create_default_cfg "-" "" "$NEWCFGNAME"
[ ! -f "$NEWCFGFILE" ] && return 1
uci -m -f $cfgfile import "$NEWCFGNAME"
@@ -126,7 +168,7 @@ function merge_cfg_with_def_values
function remove_cron_task_logs
{
if [ -f "$CRONTAB_FILE" ]; then
sed -i "/-name 'zapret\*.log' -size +/d" "$CRONTAB_FILE"
sed -i "/-name 'zapret+\*.log' -size +/d" "$CRONTAB_FILE"
fi
}
@@ -135,7 +177,7 @@ function insert_cron_task_logs
[ ! -f "$CRONTAB_FILE" ] && touch "$CRONTAB_FILE"
[ ! -f "$CRONTAB_FILE" ] && return 1
if ! grep -q -e "-name 'zapret\*\.log' -size \+" "$CRONTAB_FILE"; then
echo "*/2 * * * * /usr/bin/find /tmp -maxdepth 1 -type f -name 'zapret*.log' -size +2600k -exec rm -f {} \;" >> "$CRONTAB_FILE"
echo "*/2 * * * * /usr/bin/find /tmp -maxdepth 1 -type f -name 'zapret+*.log' -size +2600k -exec rm -f {} \;" >> "$CRONTAB_FILE"
/etc/init.d/cron restart 2> /dev/null
fi
return 0
@@ -148,7 +190,7 @@ function init_before_start
[ ! -f "$HOSTLIST_FN" ] && touch "$HOSTLIST_FN"
chmod 644 $ZAPRET_BASE/ipset/*.txt
chmod 666 $ZAPRET_BASE/ipset/*.log
rm -f /tmp/zapret*.log
rm -f /tmp/zapret+*.log
#*/
if [ "$DAEMON_LOG_ENABLE" = "1" ]; then
insert_cron_task_logs

View File

@@ -106,7 +106,7 @@ NFQWS_PORTS_UDP_KEEPALIVE=""
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"
DISABLE_CUSTOM=0
DISABLE_CUSTOM=1
# FlowOffload mode : donttouch,none,software,hardware
FLOWOFFLOAD=none

View File

@@ -0,0 +1,31 @@
# Stun4ALL (discord audio, discord video, telegram call, etc)
# this custom script runs desync to all stun packets
# 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 :
NFQWS_OPT_DESYNC_STUN="${NFQWS_OPT_DESYNC_STUN:---dpi-desync=fake --dpi-desync-repeats=2}"
alloc_dnum DNUM_STUN4ALL
alloc_qnum QNUM_STUN4ALL
zapret_custom_daemons()
{
# $1 - 1 - add, 0 - stop
local opt="--qnum=$QNUM_STUN4ALL $NFQWS_OPT_DESYNC_STUN"
do_nfqws $1 $DNUM_STUN4ALL "$opt"
}
zapret_custom_firewall()
{
# $1 - 1 - run, 0 - stop
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
}
zapret_custom_firewall_nft()
{
# stop logic is not required
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
}

View File

@@ -1,7 +1,7 @@
#!/bin/sh
# Copyright (c) 2024 remittor
function set_cfg_default_values
function set_cfg_reset_values
{
local cfgname=${1:-$ZAPRET_CFG_NAME}
local TAB="$( echo -n -e '\t' )"
@@ -16,7 +16,7 @@ function set_cfg_default_values
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='0'
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'
@@ -38,31 +38,313 @@ function set_cfg_default_values
set $cfgname.config.NFQWS_UDP_PKT_IN='0'
set $cfgname.config.NFQWS_PORTS_TCP_KEEPALIVE='0'
set $cfgname.config.NFQWS_PORTS_UDP_KEEPALIVE='0'
set $cfgname.config.NFQWS_OPT="
--filter-tcp=443
--hostlist=/opt/zapret/ipset/zapret-hosts-google.txt
--hostlist=/opt/zapret/ipset/zapret-hosts-user.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
--dpi-desync=fake
--dpi-desync-repeats=6
--dpi-desync-fake-quic=/opt/zapret/files/fake/quic_initial_www_google_com.bin
"
# save changes
commit $cfgname
EOF
return 0
}
function clear_nfqws_strat
{
local cfgname=${1:-$ZAPRET_CFG_NAME}
local TAB="$( echo -n -e '\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="$( echo -n -e '\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" = "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:-v2_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
}

BIN
zapret/files/fake/4pda.bin Normal file

Binary file not shown.

BIN
zapret/files/fake/max.bin Normal file

Binary file not shown.

BIN
zapret/files/fake/t2.bin Normal file

Binary file not shown.

Binary file not shown.

View File

@@ -8,173 +8,249 @@
fc00::/7
fe80::/10
####################################
nalog.ru
gstatic.com
gosuslugi.ru
mos-gorsud.ru
gov.ru
sudrf.ru
ipstream.one
#################################### Epicgames
easy.ac
fab.com
quixel.se
quixel.com
eac-cdn.com
paragon.com
spyjinx.com
3lateral.com
accountportal-website-prod07.ol.epicgames.com
account-public-service-prod03.ol.epicgames.com
accounts.epicgames.com
api.epicgames.dev
fortnite.com
epicgames.com
epicgames.dev
hyprsense.com
sketchfab.com
artstation.com
roborecall.com
twinmotion.com
cubicmotion.com
playparagon.com
realityscan.com
epicgamescdn.com
et.epicgames.com
ol.epicgames.com
radgametools.com
unrealengine.com
api.epicgames.dev
easyanticheat.net
shadowcomplex.com
battlebreakers.com
store.epicgames.com
capturingreality.com
catalog-public-service-prod06.ol.epicgames.com
unrealtournament.com
cdn1.unrealengine.com
cdn2.unrealengine.com
cubicmotion.com
datarouter.ol.epicgames.com
datastorage-public-service-liveegs.live.use1a.on.epicgames.com
accounts.epicgames.com
download.epicgames.com
tracking.epicgames.com
download2.epicgames.com
download3.epicgames.com
download4.epicgames.com
eac-cdn.com
easy.ac
easyanticheat.net
entitlement-public-service-prod08.ol.epicgames.com
epicgames.com
epicgames.dev
epicgamescdn.com
epicgames-download1.akamaized.net
et.epicgames.com
fab.com
fastly-download.epicgames.com
fortnite.com
friends-public-service-prod06.ol.epicgames.com
hyprsense.com
launcher-public-service-prod06.ol.epicgames.com
launcherwaitingroom-public-service-prod06.ol.epicgames.com
launcher-website-prod07.ol.epicgames.com
library-service.live.use1a.on.epicgames.com
lightswitch-public-service-prod06.ol.epicgames.com
metrics.ol.epicgames.com
ol.epicgames.com
orderprocessor-public-service-ecomprod01.ol.epicgames.com
paragon.com
playparagon.com
quixel.com
quixel.se
radgametools.com
realityscan.com
roborecall.com
shadowcomplex.com
sketchfab.com
spyjinx.com
static-assets-prod.epicgames.com
store.epicgames.com
datarouter.ol.epicgames.com
fastly-download.epicgames.com
store-content.ak.epicgames.com
store-site-backend-static.ak.epicgames.com
tracking.epicgames.com
twinmotion.com
unrealengine.com
unrealtournament.com
static-assets-prod.epicgames.com
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
api.steampowered.com
avatars.fastly.steamstatic.com
cdn.akamai.steamstatic.com
cdn.cloudflare.steamstatic.com
cdn.fastly.steamstatic.com
cdn.steamcommunity.com
cdn.steamstatic.com
checkout.steampowered.com
clan.fastly.steamstatic.com
client-download.steampowered.com
client-update.queniuqe.com
community.cloudflare.steamstatic.com
community.fastly.steamstatic.com
community.steampowered.com
community.steamstatic.com
cs.steampowered.com
dl.steam.clngaa.com
edge.steam-dns.top.comcast.net
gstore.val.manlaxy.com
help.steampowered.com
login.steampowered.com
media.steampowered.com
partner.steamgames.com
partner.steampowered.com
playartifact.com
s.team
scontent.steamusercontent.com
shared.fastly.steamstatic.com
shared.steamstatic.com
steam.apac.qtlglb.com
steam.cdn.on.net
steam.cdn.orcon.net.nz
steam.cdn.slingshot.co.nz
steam.cdn.webra.ru
steam.eca.qtlglb.com
steam.naeu.qtlglb.com
steam.ru.qtlglb.com
steam.tv
steam-api.com
steambroadcast.akamaized.net
steambroadcast.com
valve.net
steamcdn.com
steamcdn.net
steamcdn-a.akamaihd.net
steamcdn-a.akamaihd.net.edgesuite.net
steamcdn-a.akamaized.net
steamstat.us
valvecdn.com
steam-api.com
steamchat.com
steam-chat.com
steamcloudsweden.blob.core.windows.net
steamcommunity.akamaized.net
steamcommunity.cloudflare.steamstatic.com
steamcommunity.com
steamcommunity-a.akamaihd.net
steamcommunity-a.akamaihd.net.edgesuite.net
steamcommunity-a.akamaized.net
steamcontent.com
steamcontent-a.akamaihd.net
steamdeck.com
steamdeckcdn.akamaized.net
steamdeckusercontent.com
steam-chat.com
steamgames.com
steamgames.net
steammobile.akamaized.net
steampipe.akamaized.net
steampipe-kr.akamaized.net
steampipe-partner.akamaized.net
steampowered.com
steamserver.net
steamstat.us
steamstatic.akamaized.net
steamstatic.com
steamstore-a.akamaihd.net
steamusercontent.com
steamusercontent-a.akamaihd.net
steamuserimages-a.akamaihd.net
steamvideo-a.akamaihd.net
store.akamai.steamstatic.com
store.cloudflare.steamstatic.com
store.fastly.steamstatic.com
store.steampowered.com
support.steampowered.com
underlords.com
valve.net
valvecdn.com
steamserver.net
steamstatic.com
playartifact.com
steam.cdn.on.net
steamcontent.com
steampowered.com
valvecontent.com
valvesoftware.com
valvesoftware.net
steam.cdn.webra.ru
steambroadcast.com
steamcommunity.com
cdn.steamstatic.com
cs.steampowered.com
dl.steam.clngaa.com
steam.ru.qtlglb.com
api.steampowered.com
steam.eca.qtlglb.com
steamusercontent.com
help.steampowered.com
steam.apac.qtlglb.com
steam.naeu.qtlglb.com
cdn.steamcommunity.com
gstore.val.manlaxy.com
login.steampowered.com
media.steampowered.com
partner.steamgames.com
shared.steamstatic.com
steam.cdn.orcon.net.nz
store.steampowered.com
steamcdn-a.akamaihd.net
steampipe.akamaized.net
partner.steampowered.com
steamcdn-a.akamaized.net
steamdeckusercontent.com
support.steampowered.com
checkout.steampowered.com
community.steamstatic.com
steam.cdn.slingshot.co.nz
steammobile.akamaized.net
steamstatic.akamaized.net
steamstore-a.akamaihd.net
steamvideo-a.akamaihd.net
workshop.steampowered.com
cdn.akamai.steamstatic.com
cdn.fastly.steamstatic.com
client-update.queniuqe.com
community.steampowered.com
steamdeckcdn.akamaized.net
steampipe-kr.akamaized.net
clan.fastly.steamstatic.com
steamcontent-a.akamaihd.net
steambroadcast.akamaized.net
steamcommunity.akamaized.net
store.akamai.steamstatic.com
store.fastly.steamstatic.com
scontent.steamusercontent.com
shared.fastly.steamstatic.com
steamcommunity-a.akamaihd.net
avatars.fastly.steamstatic.com
cdn.cloudflare.steamstatic.com
edge.steam-dns.top.comcast.net
steamcommunity-a.akamaized.net
steamuserimages-a.akamaihd.net
steampipe-partner.akamaized.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
steamcloudsweden.blob.core.windows.net
steamcommunity.cloudflare.steamstatic.com
steamcommunity-a.akamaihd.net.edgesuite.net
#################################### OpenWRT
archive.openwrt.org
github.com
openwrt.org
gh.openwrt.org
cdn.openwrt.org
dev.openwrt.org
downloads.openwrt.org
forum.openwrt.org
fwdownloads.openwrt.org
gh.openwrt.org
git.openwrt.org
github.com
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
openwrt.gitlab.io
openwrt.org
wiki.openwrt.org
#################################### UbisoftConnect
ubi.com
ubisoft.com
store.ubi.com
ubisoftconnect.com
connect.ubisoft.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
#################################### Aliexpress
ae.com
ae-rus.net
alicdn.com
aestatic.net
aliexpress.ru
aliexpress.us
aliexpress.com
aliexpress-media.com
#################################### PSN
scea.com
np.scea.com
ps5update.com
psdownload.com
playstation.net
playstation.com
account.sony.com
psremoteplay.com
ps4.playstation.com
ps5.playstation.com
playstationcloud.com
psapi.playstation.net
store.playstation.com
media.playstation.com
auth.np.ac.playstation.net
sonyentertainmentnetwork.com
np.community.playstation.net
id.sonyentertainmentnetwork.com
#################################### Twitch
twitch.tv
ttvnw.net
jtvnw.net
twimg.com
m.twitch.tv
id.twitch.tv
www.twitch.tv
twitchcdn.net
ext-twitch.tv
twitchsvc.net
api.twitch.tv
gql.twitch.tv
dev.twitch.tv
live-video.net
twitch.a2z.com
chat.twitch.tv
help.twitch.tv
assets.twitch.tv
twitch-shadow.net
passport.twitch.tv
irc.chat.twitch.tv
vod-metro.twitch.tv
twitchcdn-shadow.net
static.twitchcdn.net
vod-secure.twitch.tv
irc-ws.chat.twitch.tv
pubsub-edge.twitch.tv
vod-pop-secure.twitch.tv
####################################

View File

@@ -5,14 +5,29 @@
cfg_run_on_boot="$( uci -q get zapret.config.run_on_boot )"
create_default_cfg
opt_flags=${1:--}
opt_strat=$2
if echo "$opt_flags" | grep -q "(reset_ipset)"; then
restore_all_ipset_cfg
fi
create_default_cfg "$opt_flags" "$opt_strat"
if [ "$cfg_run_on_boot" = "1" ]; then
uci set zapret.config.run_on_boot=1
uci commit
fi
if [ "$1" = "sync" ]; then
ZAPRET_SYNC_CONFIG=0
if [ "$opt_flags" = "sync" ]; then
ZAPRET_SYNC_CONFIG=1
fi
if echo "$opt_flags" | grep -q "(sync)"; then
ZAPRET_SYNC_CONFIG=1
fi
if [ "$ZAPRET_SYNC_CONFIG" = "1" ]; then
# renew main config
/opt/zapret/sync_config.sh
fi

15
zapret/script-exec.sh Executable file
View File

@@ -0,0 +1,15 @@
#!/bin/sh
# Copyright (c) 2024 remittor
LOG_FILE=$1
RC_FILE=$1.rc
shift 1
: > $LOG_FILE
: > $RC_FILE
(
exec </dev/null >/dev/null 2>&1
"$@" >> $LOG_FILE 2>&1
RETCODE=$?
sleep 1
echo $RETCODE > $RC_FILE
) &
exit 0

415
zapret/update-pkg.sh Executable file
View File

@@ -0,0 +1,415 @@
#!/bin/sh
# Copyright (c) 2025 remittor
. /opt/zapret/comfunc.sh
. /usr/share/libubox/jshn.sh
. /etc/openwrt_release
opt_check=
opt_prerelease=
opt_update=
opt_forced=
opt_test=
while getopts "cu:pft:" opt; do
case $opt in
c) opt_check=true;;
p) opt_prerelease=true;;
u) opt_update="$OPTARG";;
f) opt_forced=true;;
t) opt_test="$OPTARG";;
esac
done
ZAP_PKG_DIR=/tmp/zapret_pkg
if [ "$opt_test" != "" ]; then
echo 1; sleep 2;
echo 2; sleep 2;
echo 3; sleep 2;
echo ' * resolve_conffiles 123456'; sleep 1;
echo 4; sleep 2;
echo END
return "$opt_test"
fi
ZAP_CPU_ARCH=$(get_cpu_arch)
ZAP_REL_URL="https://raw.githubusercontent.com/remittor/zapret-openwrt/gh-pages/releases/releases_zap1_$ZAP_CPU_ARCH.json"
CURL_TIMEOUT=5
CURL_HEADER1="Accept: application/json"
CURL_HEADER2="Cache-Control: no-cache"
REL_JSON=
REL_ACTUAL_TAG=
REL_ACTUAL_PRE=
REL_ACTUAL_URL=
ZAP_OUT=
ZAP_ERR=
ZAP_PKG_URL=
if command -v apk >/dev/null; then
PKG_MGR=apk
ZAP_PKG_EXT=apk
elif command -v opkg >/dev/null; then
PKG_MGR=opkg
ZAP_PKG_EXT=ipk
else
echo "ERROR: No package manager found"
return 1
fi
# -------------------------------------------------------------------------------------------------------
function download_json
{
local url="$1"
curl -s -L --max-time $CURL_TIMEOUT -H "$CURL_HEADER1" -H "$CURL_HEADER2" "$url" 2>/dev/null
return $?
}
function get_pkg_version
{
local pkg_name="$1"
local ver line base
if [ "$PKG_MGR" = opkg ]; then
ver=$( opkg list-installed "$pkg_name" 2>/dev/null | awk -F' - ' '{print $2}' | tr -d '\r' )
if [ -n "$ver" ]; then
echo -n "$ver"
return 0
fi
fi
if [ "$PKG_MGR" = apk ]; then
line=$( apk info -e "$pkg_name" 2>/dev/null || true )
if [ -n "$line" ]; then
base=${line%-r[0-9]*}
ver=${base##*-}
case "$line" in
*-r[0-9]*)
echo -n "$ver${line#$base}"
;;
*)
echo -n "$ver"
;;
esac
return 0
fi
fi
echo ""
return 1
}
function normalize_version
{
local ver="$1"
local base
local major minor rel
case "$ver" in
*-r[0-9]*)
rel="${ver##*-r}"
base="${ver%-r*}"
;;
*)
rel=1
base="$ver"
;;
esac
major="${base%%.*}"
minor="${base#*.}"
[ -z "$minor" ] && minor=0
[ -z "$rel" ] && rel=1
echo "$major.$minor.$rel"
}
function pkg_version_cmp
{
local ver1=$( normalize_version "$1" )
local ver2=$( normalize_version "$2" )
local x1 x2
# major
x1=$( echo "$ver1" | cut -d. -f1 )
x2=$( echo "$ver2" | cut -d. -f1 )
[ "$x1" -gt "$x2" ] && { echo -n "G"; return 0; }
[ "$x1" -lt "$x2" ] && { echo -n "L"; return 0; }
# minor
x1=$( echo "$ver1" | cut -d. -f2 )
x2=$( echo "$ver2" | cut -d. -f2 )
[ "$x1" -gt "$x2" ] && { echo -n "G"; return 0; }
[ "$x1" -lt "$x2" ] && { echo -n "L"; return 0; }
# release
x1=$( echo "$ver1" | cut -d. -f3 )
x2=$( echo "$ver2" | cut -d. -f3 )
[ "$x1" -gt "$x2" ] && { echo -n "G"; return 0; }
[ "$x1" -lt "$x2" ] && { echo -n "L"; return 0; }
echo -n "E"
}
function download_releases_info
{
local txt txtlen txtlines generated_at
REL_JSON=
echo "Download releases info..."
txt=$(download_json $ZAP_REL_URL)
txtlen=${#txt}
txtlines=$(printf '%s\n' "$txt" | wc -l)
if [[ $txtlen -lt 64 ]]; then
echo "ERROR: Cannot download releases info!"
return 104
fi
echo "Releases info downloaded! Size = $txtlen, Lines = $txtlines"
generated_at=$(printf '%s\n' "$txt" | grep -m1 -o '"generated_at"[[:space:]]*:[[:space:]]*".*"' | cut -d'"' -f4)
if [[ "$generated_at" = "" ]]; then
echo "ERROR: Cannot download releases info! (incorrect generated_at)"
return 105
fi
echo "Releases info generated_at = $generated_at"
REL_JSON="$txt"
return 0
}
function get_actual_release
{
local tag url pre idx_list
REL_ACTUAL_TAG=
REL_ACTUAL_PRE=
REL_ACTUAL_URL=
json_load "$(printf '%s' "$REL_JSON")"
if [ $? -ne 0 ]; then
echo "ERROR: incorrect format of ${ZAP_REL_URL##*/}"
json_cleanup
return 151
fi
json_select releases
if [ $? -ne 0 ]; then
echo "ERROR: incorrect format of ${ZAP_REL_URL##*/}"
json_cleanup
return 157
fi
json_get_keys idx_list
# array already sorted by created_at => take first elem
for rel_id in $idx_list; do
json_select "$rel_id" # enter into releases[rel_id]
json_get_var tag tag
json_get_var pre prerelease
#echo "rel_id = $rel_id opt_prerelease = $opt_prerelease pre = $pre"
if [ "$opt_prerelease" != "true" ] && [ "$pre" = "1" ]; then
json_select .. # exit from releases[rel_id]
continue
fi
json_select assets
if [ $? -ne 0 ]; then
echo "ERROR: release[$rel_id] has not include 'assets'"
json_cleanup
return 160
fi
json_select 0 > /dev/null
if [ $? -ne 0 ]; then
json_select 1 > /dev/null
if [ $? -ne 0 ]; then
echo "ERROR: release[$rel_id] include incorrect 'assets'"
json_cleanup
return 162
fi
fi
json_get_var url browser_download_url
json_select .. .. .. # assets-elem -> assets -> releases[rel_id] -> releases
json_cleanup
REL_ACTUAL_TAG="$tag"
REL_ACTUAL_PRE="$pre"
REL_ACTUAL_URL="$url"
return 0
done
json_cleanup
echo "ERROR: latest release for arch \"$ZAP_CPU_ARCH\" not founded!"
return 1 # release not founded
}
# -------------------------------------------------------------------------------------------------------
if [ "$opt_check" != "true" -a "$opt_update" = "" ]; then
echo 'ERROR: Incorrect arguments'
return 4
fi
if [ "$opt_update" = "@" ]; then
opt_check="true"
fi
#echo "DISTRIB_ID: $DISTRIB_ID"
echo "DISTRIB_RELEASE: $DISTRIB_RELEASE"
echo "DISTRIB_DESCRIPTION:" $(get_distrib_param DISTRIB_DESCRIPTION)
echo "DISTRIB_ARCH:" $(get_distrib_param DISTRIB_ARCH)
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_check" = "true" ]; then
download_releases_info
ZAP_ERR=$?
if [ $ZAP_ERR -ne 0 ]; then
echo "ERROR: Func download_releases_info return error code: $ZAP_ERR"
return $ZAP_ERR
fi
get_actual_release
ZAP_ERR=$?
if [ $ZAP_ERR -ne 0 ]; then
echo "ERROR: Func get_actual_release return error code: $ZAP_ERR"
return $ZAP_ERR
fi
echo "Latest package version: $REL_ACTUAL_TAG"
echo "Latest package url: $REL_ACTUAL_URL"
fi
ZAP_PKG_SIZE=
ZAP_PKG_SZ=
ZAP_PKG_ZIP_NAME=
ZAP_PKG_FN=
ZAP_PKG_BASE_FN=
ZAP_PKG_LUCI_FN=
ZAP_CUR_PKG_VER=$( get_pkg_version zapret )
echo "Current installed version: $ZAP_CUR_PKG_VER"
if [ "$opt_update" = "" ]; then
ZAP_PKG_URL="$REL_ACTUAL_URL"
if [ "$ZAP_PKG_URL" = "" ]; then
echo "ERROR: actual release not founded!"
return 199
fi
else
ZAP_PKG_URL="$opt_update"
if [ "$opt_update" = "@" ]; then
ZAP_PKG_URL="$REL_ACTUAL_URL"
fi
if [ "$opt_update" = "@" -a "$ZAP_PKG_URL" = "" ]; then
echo "ERROR: actual release not founded!"
return 199
fi
fi
ZAP_PKG_ZIP_NAME=${ZAP_PKG_URL##*/}
ZAP_PKG_ZIP_VER=${ZAP_PKG_ZIP_NAME#*_v}
ZAP_PKG_ZIP_VER=${ZAP_PKG_ZIP_VER%%_*}
if [ "$opt_update" != "" ]; then
if [ "$opt_update" = "@" ]; then
echo "Latest available version: $ZAP_PKG_ZIP_VER"
else
echo "Target requested version: $ZAP_PKG_ZIP_VER"
fi
fi
echo "ZAP_PKG_URL = $ZAP_PKG_URL"
ZAP_VER_CMP=$( pkg_version_cmp "$ZAP_CUR_PKG_VER" "$ZAP_PKG_ZIP_VER" )
if [ "$opt_update" = "" ]; then
if [ "$ZAP_VER_CMP" = "E" ]; then
echo "RESULT: (E) No update required for this package!"
elif [ "$ZAP_VER_CMP" = "G" ]; then
echo "RESULT: (G) You have a newer version installed than the one on GitHub!"
elif [ "$ZAP_VER_CMP" = "L" ]; then
echo "RESULT: (L) You have an older version installed than the one on GitHub!"
else
echo "ERROR: ZAP_PKG_ZIP_VER='$ZAP_PKG_ZIP_VER' ZAP_VER_CMP='$ZAP_VER_CMP'"
return 199
fi
return 0
fi
if [ "$opt_update" != "" ]; then
if [ "$opt_forced" != "true" ]; then
if [ "$ZAP_VER_CMP" = "E" ]; then
echo "RESULT: (E) No update required for this package!"
return 0
fi
fi
ZAP_PKG_DIR=/tmp/zapret_pkg
rm -rf $ZAP_PKG_DIR
ZAP_PKG_HDRS=$( curl -s -I -L --max-time $CURL_TIMEOUT -H "$CURL_HEADER2" "$ZAP_PKG_URL" )
ZAP_PKG_SIZE=$( echo "$ZAP_PKG_HDRS" | grep -i 'content-length: ' | tail -n1 | awk '{print $2}' | tr -d '\r' )
echo "Downloded ZIP-file size = $ZAP_PKG_SIZE bytes"
[ "$ZAP_PKG_SIZE" = "" ] || [[ $ZAP_PKG_SIZE -lt 256 ]] && {
echo "ERROR: incorrect package size!"
return 210
}
mkdir $ZAP_PKG_DIR
ZAP_PKG_FN="$ZAP_PKG_DIR/${ZAP_PKG_URL##*/}"
echo "Download ZIP-file..."
curl -s -L --max-time 15 -H "$CURL_HEADER2" "$ZAP_PKG_URL" -o "$ZAP_PKG_FN"
if [ $? -ne 0 ]; then
echo "ERROR: cannot download package!"
return 215
fi
ZAP_PKG_SZ=$( wc -c < "$ZAP_PKG_FN" )
if [ "$ZAP_PKG_SZ" != "$ZAP_PKG_SIZE" ]; then
echo "ERROR: downloaded package is incorrect! (size = $ZAP_PKG_SZ)"
return 216
fi
if ! command -v unzip >/dev/null 2>&1; then
echo "ERROR: package \"upzip\" not installed!"
return 218
fi
unzip -q "$ZAP_PKG_FN" -d $ZAP_PKG_DIR
rm -f "$ZAP_PKG_FN"
if [ "$PKG_MGR" = "apk" ]; then
if [ ! -d "$ZAP_PKG_DIR/apk" ]; then
echo "ERROR: APK-files not founded"
return 221
fi
rm -f "$ZAP_PKG_DIR/*.ipk"
mv "$ZAP_PKG_DIR/apk/*" "$ZAP_PKG_DIR/"
else
rm -rf "$ZAP_PKG_DIR/apk"
fi
ZAP_PKG_LIST=$( ls -1 "$ZAP_PKG_DIR" )
echo "------ Downloaded packages:"
echo "$ZAP_PKG_LIST"
echo "------"
if [ "$PKG_MGR" != "apk" ]; then
ZAP_PKG_BASE_FN=$( find "$ZAP_PKG_DIR" -maxdepth 1 -type f -name "zapret_*.${ZAP_PKG_EXT}" | head -n 1 )
else
ZAP_PKG_BASE_FN=$( find "$ZAP_PKG_DIR" -maxdepth 1 -type f -name "zapret-[0-9]*.?*.${ZAP_PKG_EXT}" | head -n 1 )
fi
ZAP_PKG_LUCI_FN=$( find "$ZAP_PKG_DIR" -maxdepth 1 -type f -name "luci-app-zapret2*.${ZAP_PKG_EXT}" | head -n 1 )
if [ ! -f "$ZAP_PKG_BASE_FN" ]; then
echo "ERROR: File \"zapret*.${ZAP_PKG_EXT}\" not found!"
return 231
fi
echo "ZAP_PKG_BASE_FN = $ZAP_PKG_BASE_FN"
if [ ! -f "$ZAP_PKG_LUCI_FN" ]; then
echo "ERROR: File \"luci-app-zapret*.${ZAP_PKG_EXT}\" not found!"
return 232
fi
echo "ZAP_PKG_LUCI_FN = $ZAP_PKG_LUCI_FN"
echo "Install downloaded packages..."
if [ "$PKG_MGR" != "apk" ]; then
opkg install --force-reinstall "$ZAP_PKG_BASE_FN"
else
apk add --allow-untrusted --upgrade "$ZAP_PKG_BASE_FN"
fi
if [ $? -ne 0 ]; then
echo "ERROR: Failed to install package $ZAP_PKG_BASE_FN"
return 245
fi
if [ "$PKG_MGR" != "apk" ]; then
opkg install --force-reinstall "$ZAP_PKG_LUCI_FN"
else
apk add --allow-untrusted --upgrade "$ZAP_PKG_LUCI_FN"
fi
if [ $? -ne 0 ]; then
echo "ERROR: Failed to install package $ZAP_PKG_LUCI_FN"
return 247
fi
echo "RESULT: (+) Packages from $ZAP_PKG_ZIP_NAME successfully installed!"
fi