Compare commits

..

82 Commits

Author SHA1 Message Date
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
46 changed files with 2375 additions and 1602 deletions

View File

@@ -27,6 +27,7 @@ on:
options:
- true
- false
push:
tags:
- v[0-9]+*
@@ -36,17 +37,19 @@ env:
FAKE_BUILD: ${{ github.event.inputs.fake_build == 'true' }}
MAX_SPEED: ${{ github.event.inputs.max_speed != 'false' }}
TAG_SUFFIX: ${{ github.event.inputs.fake_build == 'true' && '-fake' || github.event.inputs.test_build == 'true' && '-test' || '' }}
REPO_NAME: zapret-openwrt
REPO_URL: https://github.com/remittor/zapret-openwrt
REPO_LNK: remittor/zapret-openwrt
REPO_BRANCH: master
BUILD_ROOT: ${{ github.workspace }}/builder
PKGDIR: ${{ github.workspace }}/zapret-openwrt
SDKDIR: /builder
BUILD_DATE: unknown
REPO_DATE: unknown
LUCI_ARCH: aarch64_cortex-a53
jobs:
check:
runs-on: ubuntu-latest
runs-on: ubuntu-24.04
outputs:
tag: ${{ steps.gh.outputs.tag }}
date: ${{ steps.gh.outputs.date }}
@@ -103,14 +106,29 @@ jobs:
fi
echo "is_active=$is_active" >> $GITHUB_OUTPUT
var:
runs-on: ubuntu-24.04
outputs:
IPK_BRANCH: ${{ steps.set.outputs.IPK_BRANCH }}
APK_BRANCH: ${{ steps.set.outputs.APK_BRANCH }}
XXX_BRANCH: ${{ steps.set.outputs.XXX_BRANCH }}
steps:
- id: set
run: |
echo "IPK_BRANCH=v24.10.5" >> "$GITHUB_OUTPUT"
echo "APK_BRANCH=v25.12.0-rc2" >> "$GITHUB_OUTPUT"
echo "XXX_BRANCH=SNAPSHOT" >> "$GITHUB_OUTPUT"
build:
needs: check
needs: [ check, var ]
#if: needs.check.outputs.is_active == 'true'
runs-on: ubuntu-latest
runs-on: ubuntu-24.04
strategy:
fail-fast: false
matrix:
branch: [ openwrt-24.10, SNAPSHOT ]
branch:
- ${{ needs.var.outputs.IPK_BRANCH }}
- ${{ needs.var.outputs.APK_BRANCH }}
arch:
- aarch64_cortex-a53
- aarch64_cortex-a72
@@ -137,40 +155,67 @@ 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
- branch: ${{ needs.var.outputs.APK_BRANCH }}
arch: arm_cortex-a9_vfpv3-d16
- branch: ${{ needs.var.outputs.APK_BRANCH }}
arch: mips_4kec
- { isTestOrFake: true }
include:
- branch: openwrt-24.10
- branch: ${{ needs.var.outputs.IPK_BRANCH }}
arch: x86_64
- branch: openwrt-24.10
- branch: ${{ needs.var.outputs.IPK_BRANCH }}
arch: aarch64_cortex-a53
- branch: SNAPSHOT
- branch: ${{ needs.var.outputs.APK_BRANCH }}
arch: aarch64_cortex-a53
container:
image: openwrt/sdk:${{ matrix.arch }}-${{ matrix.branch }}
image: ghcr.io/openwrt/sdk:${{ matrix.arch }}-${{ matrix.branch }}
options: --user root
outputs:
pkgver: ${{ steps.build.outputs.pkgver }}
pkgver: ${{ steps.prepare.outputs.pkgver }}
steps:
- name: Checkout
uses: actions/checkout@v4
with:
repository: ${{ env.REPO_LNK }}
path: zapret-openwrt
path: ${{ env.REPO_NAME }}
- name: Fix SDK paths
run: |
mkdir -p $SDKDIR/shared-workdir
rm -rf $SDKDIR/shared-workdir/build
ln -sf $SDKDIR $SDKDIR/shared-workdir/build
- name: Initialization environment
working-directory: ${{ env.SDKDIR }}
env:
DEBIAN_FRONTEND: noninteractive
ARCH_TAG: ${{ matrix.arch }}
BRANCH: ${{ matrix.branch }}
FAKE_BUILD: ${{ env.FAKE_BUILD == 'true' || ( env.TEST_BUILD == 'true' && matrix.branch == needs.var.outputs.APK_BRANCH ) }}
run: |
if [ "$BRANCH" = "${{ needs.var.outputs.IPK_BRANCH }}" ]; then
echo "PKGTYPE=ipk" >> $GITHUB_ENV
else
echo "PKGTYPE=apk" >> $GITHUB_ENV
fi
mkdir -p ./logs
#echo ============== $SDKDIR ======================
#ls -la $SDKDIR
#echo ----------------------------------------------
echo "FAKE_BUILD=$FAKE_BUILD" >> $GITHUB_ENV
echo "ARCH_TAG=$ARCH_TAG" >> $GITHUB_ENV
echo "BRANCH=$BRANCH" >> $GITHUB_ENV
echo "TZ=UTC" >> $GITHUB_ENV
- name: Setup OpenWrt SDK
working-directory: /builder
env:
BRANCH: ${{ matrix.branch }}
shell: bash
if: false
working-directory: ${{ env.SDKDIR }}
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')
@@ -181,120 +226,120 @@ jobs:
sed -r -i 's/^rm.+//' setup.sh
./setup.sh
ls -lh
if [ "$BRANCH" = "openwrt-24.10" ]; then
echo "PKGTYPE=ipk" >> $GITHUB_ENV
else
echo "PKGTYPE=apk" >> $GITHUB_ENV
fi
- name: Setup ccache
if: false
uses: actions/cache@v4
with:
path: '/builder/.ccache'
path: ${{ env.SDKDIR }}/.ccache
key: ccache-${{ matrix.arch }}-${{ matrix.branch }}-${{ github.run_id }}
restore-keys: |
ccache-${{ matrix.arch }}-${{ matrix.branch }}-
- name: Init packages
id: init
working-directory: '/builder'
env:
FAKE_BUILD: ${{ env.FAKE_BUILD == 'true' || ( env.TEST_BUILD == 'true' && matrix.branch == 'SNAPSHOT' ) }}
BUILD_DATE: ${{ needs.check.outputs.build_date }}
ARCH: ${{ matrix.arch }}
BRANCH: ${{ matrix.branch }}
SIGN_KEY: ${{ secrets.SIGN_PRIVATE_KEY }}
CCACHE_DIR: '/builder/.ccache'
shell: bash
- name: Prepare packages
id: prepare
working-directory: ${{ env.SDKDIR }}
run: |
PKGDIR=$GITHUB_WORKSPACE/zapret-openwrt
MKFN=$PKGDIR/luci-app-zapret/Makefile
MKFN=$( ls -1 $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/
mv feeds.conf.default feeds.conf
sed -i -e 's|base.*\.git|base https://github.com/openwrt/openwrt.git|' feeds.conf
sed -i -e 's|packages.*\.git|packages https://github.com/openwrt/packages.git|' feeds.conf
sed -i -e 's|luci.*\.git|luci https://github.com/openwrt/luci.git|' feeds.conf
mkdir -p ./logs
if [ "$FAKE_BUILD" = "false" ]; then
./scripts/feeds update base packages luci
./scripts/feeds install -a
fi
echo "FAKE_BUILD=$FAKE_BUILD" >> $GITHUB_ENV
cp -vr $PKGDIR ./package/$REPO_NAME/
echo "PKGVER=$PKGVER" >> $GITHUB_ENV
echo "pkgver=$PKGVER" >> $GITHUB_OUTPUT
echo "status=success" >> $GITHUB_OUTPUT
- name: Build packages
id: build
if: steps.init.outputs.status == 'success'
working-directory: '/builder'
env:
BUILD_DATE: ${{ needs.check.outputs.build_date }}
ARCH: ${{ matrix.arch }}
BRANCH: ${{ matrix.branch }}
SIGN_KEY: ${{ secrets.SIGN_PRIVATE_KEY }}
CCACHE_DIR: '/builder/.ccache'
shell: bash
- name: Init packages
id: init
if: steps.prepare.outputs.status == 'success'
working-directory: ${{ env.SDKDIR }}
run: |
MAKE_JOBS=$(($(nproc)+1))
echo "$MAKE_JOBS thread compile"
if [ "$FAKE_BUILD" = "false" ]; then
make defconfig
sed -i 's/CONFIG_LUCI_JSMIN=y/CONFIG_LUCI_JSMIN=n/g' .config
echo "------------- .config BEG -------------------"
cat .config
echo "------------- .config END -------------------"
if [ "$ARCH" = "$LUCI_ARCH" ]; then
PKGLIST=`echo package/zapret-openwrt/{zapret,zapret-tpws,zapret-mdig,zapret-ip2net,luci-app-zapret}/compile`
else
PKGLIST=`echo package/zapret-openwrt/{zapret,zapret-tpws,zapret-mdig,zapret-ip2net}/compile`
fi
if [ "$MAX_SPEED" = "false" ]; then
make $PKGLIST V=s CONFIG_CCACHE=1 BUILD_LOG=1
else
make -j$MAKE_JOBS $PKGLIST CONFIG_CCACHE=1
fi
else
OUT_DIR=./bin/packages/dev_x/base
mkdir -p $OUT_DIR
touch $OUT_DIR/zapret_$PKGVER-$ARCH.$PKGTYPE
touch $OUT_DIR/luci-app-zapret_$PKGVER-all.$PKGTYPE
mv feeds.conf.default feeds.conf
sed -i -e 's|base.*\.git|base https://github.com/openwrt/openwrt.git|' feeds.conf
sed -i -e 's|packages.*\.git|packages https://github.com/openwrt/packages.git|' feeds.conf
sed -i -e 's|luci.*\.git|luci https://github.com/openwrt/luci.git|' feeds.conf
./scripts/feeds update base packages luci
./scripts/feeds install -a
echo "status=success" >> $GITHUB_OUTPUT
- name: Init config
id: config
if: steps.init.outputs.status == 'success'
working-directory: ${{ env.SDKDIR }}
run: |
make defconfig
sed -i 's/CONFIG_LUCI_JSMIN=y/CONFIG_LUCI_JSMIN=n/g' .config
echo "status=success" >> $GITHUB_OUTPUT
- name: Show config
working-directory: ${{ env.SDKDIR }}
run: |
cat .config || echo "File .config not found"
- name: Build packages
id: build
if: steps.config.outputs.status == 'success' && env.FAKE_BUILD != 'true'
working-directory: ${{ env.SDKDIR }}
env:
ARCH_TAG: ${{ matrix.arch }}
run: |
PKGLIST="package/zapret-openwrt/zapret2/compile"
if [ "$ARCH_TAG" = "$LUCI_ARCH" ]; then
PKGLIST="$PKGLIST package/zapret-openwrt/luci-app-zapret2/compile"
fi
find ./bin/packages/*/base -type f ! -regex ".*\(zapret\).*\.[ai]pk$" -delete
MAKE_JOBS=$(nproc)
echo "$MAKE_JOBS thread compile"
if [ "$MAX_SPEED" != "true" ]; then
make $PKGLIST V=sc BUILD_LOG=1
else
make $PKGLIST -j$MAKE_JOBS
fi
echo "status=success" >> $GITHUB_OUTPUT
- name: Build packages (FAKE)
id: build_fake
if: env.FAKE_BUILD == 'true'
working-directory: ${{ env.SDKDIR }}
env:
ARCH_TAG: ${{ matrix.arch }}
run: |
OUT_DIR=./bin/packages/dev_x/base
mkdir -p $OUT_DIR
touch $OUT_DIR/zapret2_$PKGVER-$ARCH_TAG.$PKGTYPE
touch $OUT_DIR/luci-app-zapret2_$PKGVER-all.$PKGTYPE
echo "status=success" >> $GITHUB_OUTPUT
- name: Install packages
id: install
if: steps.build.outputs.status == 'success' || steps.build_fake.outputs.status == 'success'
working-directory: ${{ env.SDKDIR }}
env:
ARCH_TAG: ${{ matrix.arch }}
SIGN_KEY: ${{ secrets.SIGN_PRIVATE_KEY }}
run: |
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"
#ln -s `which usign` staging_dir/host/bin/usign
#echo "$SIGN_KEY" | base64 -d > key-build
#make package/index
OUTDIR=$GITHUB_WORKSPACE/$PKGTYPE-$ARCH
OUTDIR=$GITHUB_WORKSPACE/$PKGTYPE-$ARCH_TAG
mkdir -p $OUTDIR
cp -R ./bin/packages/*/base/. $OUTDIR/
./staging_dir/host/bin/ccache --max-size=10M --show-stats
echo "OUTDIR=$OUTDIR" >> $GITHUB_ENV
echo "pkgver=$PKGVER" >> $GITHUB_OUTPUT
echo "status=success" >> $GITHUB_OUTPUT
- name: Compress build logs
if: always()
env:
ARCH: ${{ matrix.arch }}
ARCH_TAG: ${{ matrix.arch }}
BRANCH: ${{ matrix.branch }}
LOGS_DIR: '/builder/logs'
LOGS_DIR: ${{ env.SDKDIR }}/logs
run: |
tar -cJvf logs-$BRANCH-$ARCH.tar.xz $LOGS_DIR
tar -cJvf logs-$BRANCH-$ARCH_TAG.tar.xz $LOGS_DIR
- name: Upload packages
if: steps.build.outcome == 'success'
if: steps.install.outcome == 'success'
uses: actions/upload-artifact@main
with:
path: ${{ env.OUTDIR }}
@@ -312,7 +357,7 @@ jobs:
needs: [ check, build ]
permissions:
contents: write
runs-on: ubuntu-latest
runs-on: ubuntu-24.04
steps:
- name: Download artifacts
uses: actions/download-artifact@v4
@@ -339,7 +384,7 @@ jobs:
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" "{}/" \;
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
- name: Upload assets
@@ -351,7 +396,7 @@ jobs:
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 }}
name: zapret2 v${{ needs.build.outputs.pkgver }}
body: |
zapret v${{ needs.build.outputs.pkgver }} for OpenWrt
zapret2 v${{ needs.build.outputs.pkgver }} for OpenWrt
files: ./public/*.zip

View File

@@ -5,7 +5,7 @@ on:
workflows: ["build"]
types: [completed]
release:
types: [published, created, edited]
types: [published, unpublished, created, edited, deleted, prereleased]
permissions:
contents: write
@@ -25,6 +25,62 @@ jobs:
ref: gh-pages
continue-on-error: true
- name: Wait for GitHub API consistency (release events)
if: github.event_name == 'release'
env:
REPO: ${{ github.repository }}
ACTION: ${{ github.event.action }}
TARGET_ID: ${{ github.event.release.id }}
TARGET_NAME: ${{ github.event.release.name }}
run: |
set -e
echo "Release action: $ACTION"
echo "Target release id: $TARGET_ID"
max=10
delay=6
check() {
curl -s https://api.github.com/repos/$REPO/releases
}
for iter in $(seq 1 $max); do
case "$ACTION" in
created)
echo "Release created (draft). No API wait needed."
exit 0
;;
published|prereleased)
if check | jq "any(.[]; .id == $TARGET_ID)"; then
echo "Release appeared in API"
exit 0
fi
;;
deleted)
if ! check | jq "any(.[]; .id == $TARGET_ID)"; then
echo "Release disappeared from API"
exit 0
fi
;;
unpublished)
if check | jq "any(.[]; .id == $TARGET_ID and .draft == true)"; then
echo "Release is now draft"
exit 0
fi
;;
edited)
if check | jq "any(.[]; .id == $TARGET_ID and .name == \"$TARGET_NAME\")"; then
echo "Release updated"
exit 0
fi
;;
*)
echo "No consistency wait needed for action: $ACTION"
exit 0
;;
esac
echo "Retry $iter/$max..."
sleep "$delay"
done
echo "WARNING: API consistency timeout for action $ACTION"
- name: Save FULL releases.json
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}

View File

@@ -6,7 +6,7 @@
[![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 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/Installing-zapretopenwrt-package)

View File

@@ -1,238 +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_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 timer = setInterval(async () => {
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.setStage(999);
}
}, 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

@@ -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
PKG_NAME:=luci-app-zapret
PKG_VERSION:=72.20251219
PKG_NAME:=luci-app-zapret2
PKG_VERSION:=0.8.20260117
PKG_RELEASE:=1
PKG_LICENSE:=MIT
PKG_MAINTAINER:=remittor <https://github.com/remittor>
LUCI_TITLE:=LuCI support for zapret
LUCI_DEPENDS:=+zapret
LUCI_TITLE:=LuCI support for zapret2
LUCI_DEPENDS:=+zapret2
LUCI_PKGARCH:=all
define Package/$(PKG_NAME)/postinst

View File

@@ -0,0 +1,130 @@
'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;
},
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 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
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;
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 [tcp 16-20]'));
this.btn_dpicheck.onclick = ui.createHandlerFn(this, () => { this.dpiCheck() });
ui.showModal(_('Diagnostics'), [
E('div', { 'class': 'cbi-section' }, [
resolve_dns,
E('br'), E('br'),
this.logArea,
]),
E('div', { 'class': 'right' }, [
this.btn_dpicheck,
' ',
this.btn_cancel,
])
]);
}
});

View File

@@ -5,13 +5,13 @@
'require poll';
'require uci';
'require ui';
'require view.zapret.tools as tools';
'require view.zapret2.tools as tools';
return view.extend({
retrieveLog: async function() {
return Promise.all([
L.resolveDefault(fs.stat('/bin/cat'), null),
fs.exec('/usr/bin/find', [ '/tmp', '-maxdepth', '1', '-type', 'f', '-name', 'zapret+*.log' ]),
fs.exec('/usr/bin/find', [ '/tmp', '-maxdepth', '1', '-type', 'f', '-name', tools.appName+'+*.log' ]),
uci.load(tools.appName),
]).then(function(status_array) {
var filereader = status_array[0] ? status_array[0].path : null;
@@ -64,7 +64,7 @@ return view.extend({
}).catch(function(e) {
ui.addNotification(null, E('p', _('Unable to execute or read contents')
+ ': %s [ %s | %s | %s ]'.format(
e.message, 'retrieveLogData', 'uci.zapret'
e.message, 'retrieveLogData', 'uci.'+tools.appName
)));
return null;
});
@@ -72,7 +72,7 @@ return view.extend({
const [, lineno, colno] = e.stack.match(/(\d+):(\d+)/);
ui.addNotification(null, E('p', _('Unable to execute or read contents')
+ ': %s [ lineno: %s | %s | %s | %s ]'.format(
e.message, lineno, 'retrieveLog', 'uci.zapret'
e.message, lineno, 'retrieveLog', 'uci.'+tools.appName
)));
return null;
});
@@ -90,21 +90,21 @@ return view.extend({
logdate_len = (Array.isArray(logdata)) ? logdata.length : -1;
}
let elem_name = elem.getAttribute("name");
let founded = false;
let found = false;
if (logdate_len > 0) {
for (let log_num = 0; log_num < logdate_len; log_num++) {
if (logdata[log_num].filename == elem_name) {
if (logdata[log_num].data) {
elem.value = logdata[log_num].data;
elem.rows = logdata[log_num].rows;
founded = true;
found = true;
//console.log('POLL: updated ' + elem_name);
}
break;
}
}
}
if (!founded) {
if (!found) {
elem.value = '';
elem.rows = 0;
}
@@ -130,7 +130,7 @@ return view.extend({
return;
}
var h2 = E('div', {'class' : 'cbi-title-section'}, [
E('h2', {'class': 'cbi-title-field'}, [ _('Zapret') + ' - ' + _('Log Viewer') ]),
E('h2', {'class': 'cbi-title-field'}, [ tools.AppName + ' - ' + _('Log Viewer') ]),
]);
var tabs = E('div', {}, E('div'));
@@ -140,7 +140,11 @@ return view.extend({
var logfn = logdata[log_num].filename;
let filename = logfn.replace(/.*\//, '');
let fname = filename.split('.')[0];
fname = fname.replace(/^(zapret\+)/, '');
if (tools.appName == 'zapret2') {
fname = fname.replace(/^(zapret2\+)/, '');
} else {
fname = fname.replace(/^(zapret\+)/, '');
}
let fn = fname.split('+');
let tabNameText = fname.replace(/\+/g, ' ');

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,8 +4,9 @@
'require uci';
'require ui';
'require view';
'require view.zapret.tools as tools';
'require view.zapret.updater as updater';
'require view.zapret2.tools as tools';
'require view.zapret2.diagnost as diagnost';
'require view.zapret2.updater as updater';
const btn_style_neutral = 'btn';
const btn_style_action = 'btn cbi-button-action';
@@ -23,6 +24,7 @@ return view.extend({
restart : elems.btn_restart || document.getElementById('btn_restart'),
stop : elems.btn_stop || document.getElementById('btn_stop'),
reset : elems.btn_reset || document.getElementById('btn_reset'),
diag : elems.btn_diag || document.getElementById('btn_diag'),
update : elems.btn_update || document.getElementById('btn_update'),
};
},
@@ -55,7 +57,7 @@ return view.extend({
]).catch(e => {
ui.addNotification(null, E('p', _('Unable to execute or read contents')
+ ': %s [ %s | %s | %s ]'.format(
e.message, tools.execPath, 'tools.getInitState', 'uci.zapret'
e.message, tools.execPath, 'tools.getInitState', 'uci.'+tools.appName
)));
});
},
@@ -242,14 +244,25 @@ return view.extend({
' ', _('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 = [ ];
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++) {
let strat = '' + this.nfqws_strat_list[id];
strat_list.push( E('option', { value: 'strat_' + id }, [ strat ] ) );
}
let label_nfqws = (tools.appName == 'zapret2') ? _('NFQWS2_OPT strategy: ') : _('NFQWS_OPT strategy: ');
let nfqws_strat = E('label', [
_('NFQWS_OPT strategy: '),
label_nfqws,
E('select', { id: 'cfg_nfqws_strat' }, strat_list)
]);
@@ -273,10 +286,19 @@ return view.extend({
if (document.getElementById('cfg_autohostlist').checked) {
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);
let sel_strat = document.getElementById('cfg_nfqws_strat');
let opt_strat = sel_strat.options[sel_strat.selectedIndex].text;
//console.log('RESET: strat = ' + opt_strat);
if (opt_strat == 'not change') {
opt_strat = '-';
}
opt_flags += '(sync)';
let args = [ opt_flags, opt_strat ];
return this.serviceActionEx('reset', resetcfg_btn, args, true);
@@ -290,6 +312,10 @@ return view.extend({
E('br'), E('br'),
set_autohostlist,
E('br'), E('br'),
erase_autohostlist,
E('br'), E('br'),
enable_custom_d,
E('br'), E('br'),
nfqws_strat,
E('br'), E('br')
]),
@@ -381,6 +407,10 @@ return view.extend({
btn_reset.onclick = L.bind(this.dialogResetCfg, this);
layout_append(_('Reset settings to default'), null, [ btn_reset ] );
let btn_diag = create_btn('btn_diag', btn_style_action, _('Diagnostics'));
btn_diag.onclick = ui.createHandlerFn(this, () => { diagnost.openDiagnostDialog(this.pkg_arch) });
layout_append('Diagnostic tools', null, [ btn_diag ] );
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 ] );
@@ -393,29 +423,30 @@ return view.extend({
"btn_restart": btn_restart,
"btn_stop": btn_stop,
"btn_reset": btn_reset,
"btn_diag": btn_diag,
"btn_update": btn_update,
};
this.setAppStatus(status_array, elems);
poll.add(L.bind(this.statusPoll, this));
let page_title = _('Zapret');
let page_title = tools.AppName;
let pkgdict = tools.decode_pkg_list(pkg_list.stdout, false);
page_title += ' &nbsp ';
if (pkgdict['zapret'] === undefined || pkgdict['zapret'] == '') {
if (pkgdict[tools.appName] === undefined || pkgdict[tools.appName] == '') {
page_title += 'unknown version';
} else {
page_title += 'v' + pkgdict['zapret'];
page_title += 'v' + pkgdict[tools.appName];
}
let aux1 = E('em');
let aux2 = E('em');
if (pkgdict['zapret'] != pkgdict['luci-app-zapret']) {
let errtxt = 'LuCI APP v' + pkgdict['luci-app-zapret'] + ' [ incorrect version! ]';
if (pkgdict[tools.appName] != pkgdict['luci-app-'+tools.appName]) {
let errtxt = 'LuCI APP v' + pkgdict['luci-app-'+tools.appName] + ' [ incorrect version! ]';
aux1 = E('div', { 'class': 'label-status error' }, errtxt);
aux2 = E('div', { }, '&nbsp');
}
let url1 = 'https://github.com/bol-van/zapret';
let url1 = 'https://github.com/bol-van/'+tools.appName;
let url2 = 'https://github.com/remittor/zapret-openwrt';
return E([

View File

@@ -5,7 +5,12 @@
'require uci';
'require ui';
'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({
parsers: { },
@@ -48,7 +53,7 @@ return view.extend({
let m, s, o, tabname;
m = new form.Map(tools.appName, _('Zapret') + ' - ' + _('Settings'));
m = new form.Map(tools.appName, tools.AppName + ' - ' + _('Settings'));
s = m.section(form.NamedSection, 'config');
s.anonymous = true;
@@ -107,7 +112,11 @@ return view.extend({
/* NFQWS_OPT_DESYNC tab */
tabname = 'nfqws_params';
s.tab(tabname, _('NFQWS options'));
if (tools.appName == 'zapret2') {
s.tab(tabname, _('NFQWS2 options'));
} else {
s.tab(tabname, _('NFQWS options'));
}
let add_delim = function(sec, url = null) {
let o = sec.taboption(tabname, form.DummyValue, '_hr');
@@ -124,8 +133,10 @@ return view.extend({
let btn = sec.taboption(tabname, form.Button, '_' + param + '_btn', locname);
btn.inputtitle = _('Edit');
btn.inputstyle = 'edit btn';
let val = sec.taboption(tabname, form.DummyValue, '_' + param);
val.rawhtml = multiline ? true : false;
let val = sec.taboption(tabname, form.TextValue, '_' + param);
val.readonly = true;
val.rows = rows + 5;
val.wrap = false;
val.cfgvalue = function(section_id) {
let value = uci.get(tools.appName, section_id, param);
if (value == null) {
@@ -137,15 +148,10 @@ return view.extend({
value = value.replace(/\n --/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;
};
val.validate = function(section_id, value) {
return (value) ? value.trim() : "";
return true;
};
let desc = locname;
if (multiline == 2) {
@@ -154,7 +160,11 @@ return view.extend({
btn.onclick = () => new tools.longstrEditDialog('config', param, param, desc, rows, multiline).show();
};
o = s.taboption(tabname, form.Flag, 'NFQWS_ENABLE', _('NFQWS_ENABLE'));
if (tools.appName == 'zapret2') {
o = s.taboption(tabname, form.Flag, 'NFQWS2_ENABLE', _('NFQWS2_ENABLE'));
} else {
o = s.taboption(tabname, form.Flag, 'NFQWS_ENABLE', _('NFQWS_ENABLE'));
}
o.rmempty = false;
o.default = 1;
@@ -173,41 +183,77 @@ return view.extend({
o.validate = function(section_id, value) { return true; };
o.write = function(section_id, value) { return form.Value.prototype.write.call(this, section_id, (value == null || value.trim() == '') ? "\t" : value.trim()); };
o = s.taboption(tabname, form.Value, 'NFQWS_PORTS_TCP', _('NFQWS_PORTS_TCP'));
if (tools.appName == 'zapret2') {
o = s.taboption(tabname, form.Value, 'NFQWS2_PORTS_TCP', _('NFQWS2_PORTS_TCP'));
} else {
o = s.taboption(tabname, form.Value, 'NFQWS_PORTS_TCP', _('NFQWS_PORTS_TCP'));
}
o.rmempty = false;
o.datatype = 'string';
o = s.taboption(tabname, form.Value, 'NFQWS_PORTS_UDP', _('NFQWS_PORTS_UDP'));
if (tools.appName == 'zapret2') {
o = s.taboption(tabname, form.Value, 'NFQWS2_PORTS_UDP', _('NFQWS2_PORTS_UDP'));
} else {
o = s.taboption(tabname, form.Value, 'NFQWS_PORTS_UDP', _('NFQWS_PORTS_UDP'));
}
o.rmempty = false;
o.datatype = 'string';
o = s.taboption(tabname, form.Value, 'NFQWS_TCP_PKT_OUT', _('NFQWS_TCP_PKT_OUT'));
if (tools.appName == 'zapret2') {
o = s.taboption(tabname, form.Value, 'NFQWS2_TCP_PKT_OUT', _('NFQWS2_TCP_PKT_OUT'));
} else {
o = s.taboption(tabname, form.Value, 'NFQWS_TCP_PKT_OUT', _('NFQWS_TCP_PKT_OUT'));
}
o.rmempty = false;
o.datatype = 'string';
o = s.taboption(tabname, form.Value, 'NFQWS_TCP_PKT_IN', _('NFQWS_TCP_PKT_IN'));
if (tools.appName == 'zapret2') {
o = s.taboption(tabname, form.Value, 'NFQWS2_TCP_PKT_IN', _('NFQWS2_TCP_PKT_IN'));
} else {
o = s.taboption(tabname, form.Value, 'NFQWS_TCP_PKT_IN', _('NFQWS_TCP_PKT_IN'));
}
o.rmempty = false;
o.datatype = 'string';
o = s.taboption(tabname, form.Value, 'NFQWS_UDP_PKT_OUT', _('NFQWS_UDP_PKT_OUT'));
if (tools.appName == 'zapret2') {
o = s.taboption(tabname, form.Value, 'NFQWS2_UDP_PKT_OUT', _('NFQWS2_UDP_PKT_OUT'));
} else {
o = s.taboption(tabname, form.Value, 'NFQWS_UDP_PKT_OUT', _('NFQWS_UDP_PKT_OUT'));
}
o.rmempty = false;
o.datatype = 'string';
o = s.taboption(tabname, form.Value, 'NFQWS_UDP_PKT_IN', _('NFQWS_UDP_PKT_IN'));
if (tools.appName == 'zapret2') {
o = s.taboption(tabname, form.Value, 'NFQWS2_UDP_PKT_IN', _('NFQWS2_UDP_PKT_IN'));
} else {
o = s.taboption(tabname, form.Value, 'NFQWS_UDP_PKT_IN', _('NFQWS_UDP_PKT_IN'));
}
o.rmempty = false;
o.datatype = 'string';
o = s.taboption(tabname, form.Value, 'NFQWS_PORTS_TCP_KEEPALIVE', _('NFQWS_PORTS_TCP_KEEPALIVE'));
if (tools.appName == 'zapret2') {
o = s.taboption(tabname, form.Value, 'NFQWS2_PORTS_TCP_KEEPALIVE', _('NFQWS2_PORTS_TCP_KEEPALIVE'));
} else {
o = s.taboption(tabname, form.Value, 'NFQWS_PORTS_TCP_KEEPALIVE', _('NFQWS_PORTS_TCP_KEEPALIVE'));
}
o.rmempty = false;
o.datatype = 'uinteger';
o = s.taboption(tabname, form.Value, 'NFQWS_PORTS_UDP_KEEPALIVE', _('NFQWS_PORTS_UDP_KEEPALIVE'));
if (tools.appName == 'zapret2') {
o = s.taboption(tabname, form.Value, 'NFQWS2_PORTS_UDP_KEEPALIVE', _('NFQWS2_PORTS_UDP_KEEPALIVE'));
} else {
o = s.taboption(tabname, form.Value, 'NFQWS_PORTS_UDP_KEEPALIVE', _('NFQWS_PORTS_UDP_KEEPALIVE'));
}
o.rmempty = false;
o.datatype = 'uinteger';
add_delim(s, tools.nfqws_opt_url);
add_param(s, 'NFQWS_OPT', null, 21, 2);
if (tools.appName == 'zapret2') {
add_param(s, 'NFQWS2_OPT', null, 21, 2);
} else {
add_param(s, 'NFQWS_OPT', null, 21, 2);
}
/* AutoHostList settings */
tabname = 'autohostlist_tab';
@@ -226,6 +272,20 @@ return view.extend({
o.write = function(section_id, value) {
return uci.set(tools.appName, section_id, 'MODE_FILTER', value === '1' ? 'autohostlist' : 'hostlist');
};
if (tools.appName == 'zapret2') {
o = s.taboption(tabname, form.Value, 'AUTOHOSTLIST_INCOMING_MAXSEQ', _('INCOMING_MAXSEQ'));
o.rmempty = false;
o.datatype = 'uinteger';
o = s.taboption(tabname, form.Value, 'AUTOHOSTLIST_RETRANS_MAXSEQ', _('RETRANS_MAXSEQ'));
o.rmempty = false;
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.rmempty = false;
@@ -239,6 +299,16 @@ return view.extend({
o.rmempty = false;
o.datatype = 'uinteger';
if (tools.appName == 'zapret2') {
o = s.taboption(tabname, form.Value, 'AUTOHOSTLIST_UDP_IN', _('UDP_IN'));
o.rmempty = false;
o.datatype = 'uinteger';
o = s.taboption(tabname, form.Value, 'AUTOHOSTLIST_UDP_OUT', _('UDP_OUT'));
o.rmempty = false;
o.datatype = 'uinteger';
}
o = s.taboption(tabname, form.Button, '_auto_host_btn', _('Auto host list entries'));
o.inputtitle = _('Edit');
o.inputstyle = 'edit btn';

View File

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

View File

@@ -4,6 +4,7 @@
'require rpc';
'require ui';
'require uci';
'require view.zapret2.env as env_tools';
document.head.append(E('style', {'type': 'text/css'},
`
@@ -35,33 +36,11 @@ document.head.append(E('style', {'type': 'text/css'},
`));
return baseclass.extend({
packager : null,
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',
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',
__init__() {
env_tools.load_env(this);
//console.log('appName: ' + this.appName);
//console.log('PACKAGER: ' + this.packager.name);
},
infoLabelRunning : '<span class="label-status running">' + _('Running') + '</span>',
infoLabelStarting : '<span class="label-status starting">' + _('Starting') + '</span>',
@@ -100,24 +79,7 @@ return baseclass.extend({
expect: { result: false }
}),
init_consts: function() {
if (!this.packager) {
this.packager = { };
if (L.hasSystemFeature('apk')) {
this.packager.name = 'apk';
this.packager.path = '/usr/bin/apk';
this.packager.args = [ 'list', '-I', '*zapret*' ];
} else {
this.packager.name = 'opkg';
this.packager.path = '/bin/opkg';
this.packager.args = [ 'list-installed', '*zapret*' ];
}
//console.log('PACKAGER: ' + this.packager.name);
}
},
getSvcInfo: function(svc_name = null) {
this.init_consts();
let name = (svc_name) ? svc_name : this.appName;
let verbose = 1;
return this.callServiceList(name, verbose).then(res => {
@@ -128,7 +90,6 @@ return baseclass.extend({
},
getInitState: function(name) {
this.init_consts();
return this.callInitState(name).then(res => {
if (res) {
return res[name].enabled ? true : false;
@@ -141,7 +102,6 @@ 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 => {
@@ -271,9 +231,9 @@ return baseclass.extend({
return -4;
}
let jdata = svc_info;
if (typeof(jdata.zapret) == 'object') {
if (typeof(jdata[this.appName]) == 'object') {
result.dmn.inited = true;
let dmn_list = jdata.zapret.instances;
let dmn_list = jdata[this.appName].instances;
if (typeof(dmn_list) == 'object') {
for (const [dmn_name, daemon] of Object.entries(dmn_list)) {
result.dmn.total += 1;
@@ -404,17 +364,52 @@ return baseclass.extend({
E('button', {
'id': 'btn_save',
'class': 'btn cbi-button-positive important',
'click': ui.createHandlerFn(this, this.handleSave),
'click': ui.createHandlerFn(this, this.handleSaveAdv),
}, _('Save')),
]),
]);
},
handleSave: function(ev) {
let txt = document.getElementById('widget.modal_content');
let value = txt.value.trim().replace(/\r\n/g, '\n') + '\n';
writeAdv: async function(fileName, data, chunkSize = 8000)
{
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);
}
}
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;
ui.addNotification(null, E('p', _('Contents have been saved.')), 'info');
if (this.callback) {
@@ -467,10 +462,11 @@ return baseclass.extend({
this.desc = desc;
this.rows = rows;
this.multiline = multiline;
env_tools.load_env(this);
},
load: function() {
let value = uci.get('zapret', this.cfgsec, this.cfgparam);
let value = uci.get(this.appName, this.cfgsec, this.cfgparam);
if (typeof(value) === 'string') {
value = value.trim();
if (this.multiline == 2) {
@@ -499,7 +495,7 @@ return baseclass.extend({
'class': 'cbi-input-textarea',
'style': 'width:100% !important',
'rows': this.rows,
'wrap': 'on',
'wrap': 'off',
'spellcheck': 'false',
},
content)
@@ -515,13 +511,13 @@ return baseclass.extend({
E('button', {
'id': 'btn_save',
'class': 'btn cbi-button-positive important',
'click': ui.createHandlerFn(this, this.handleSave),
'click': ui.createHandlerFn(this, this.handleSaveAdv),
}, _('Save')),
]),
]);
},
handleSave: function(ev) {
handleSaveAdv: function(ev) {
let txt = document.getElementById('widget.modal_content');
let value = txt.value.trim();
if (this.multiline) {
@@ -544,33 +540,17 @@ 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();
if (this.multiline) {
val = val.replace(/</g, '˂');
val = val.replace(/>/g, '˃');
val = val.replace(/\n/g, '<br/>');
elem.querySelector('div').innerHTML = val;
} else {
elem.querySelector('div').textContent = val;
try {
let elem = document.getElementById("widget.cbid." + this.appName + ".config._" + this.cfgparam);
if (elem) {
let val = value.trim();
elem.textContent = val;
}
} catch(e) {
console.error('ERROR: cannot found elem for ' + this.cfgsec + '.' + this.cfgparam);
}
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(this.appName, this.cfgsec, this.cfgparam, value);
uci.save().then(ui.hideModal);
},
error: function(e) {
@@ -589,14 +569,107 @@ 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);
})
},
}),
execAndRead: async function({ cmd = [ ], log = '', logArea = null, callback = null, cbarg = null, hiderow = [ ], rpc_timeout = 5, rpc_root = false } = {})
{
function appendLog(msg, end = '\n')
{
logArea.value += msg + end;
logArea.scrollTop = logArea.scrollHeight;
}
function fixLogEnd()
{
if (logArea.value && logArea.value.slice(-1) != '\n') {
appendLog('');
}
}
let hide_rows = Array.isArray(hiderow) ? hiderow : [ hiderow ];
let rpc_opt = { "timeout": rpc_timeout*1000 };
if (rpc_root) {
rpc_opt.uid = 0; // run under root
}
const logFile = log; // file for reading: '/tmp/zapret_pkg_install.log'
const rcFile = logFile + '.rc';
try {
await fs.exec('/bin/busybox', [ 'rm', '-f', logFile + '*' ], null, rpc_opt);
appendLog('Output file cleared!');
} catch (e) {
return callback(cbarg, 500, 'ERROR: Failed to clear output file');
}
try {
let opt_list = [ logFile ];
opt_list.push(...cmd);
let res = await fs.exec(this.appDir+'/script-exec.sh', opt_list, null, rpc_opt);
if (res.code != 0) {
return callback(cbarg, 525, 'ERROR: cannot run "' + cmd[0] + '" script! (error = ' + res.code + ')');
}
appendLog('Process started...');
} catch (e) {
return callback(cbarg, 520, 'ERROR: Failed on execute process: ' + e.message);
}
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);
hide_rows.forEach(re => {
log = log.replace(re, '');
});
appendLog(log, '');
lastLen = res.stdout.length;
}
if (retCode < 0) {
let rc = await fs.exec('/bin/cat', [ rcFile ], null, rpc_opt);
if (rc.code != 0) {
clearInterval(timer);
fixLogEnd();
return callback(cbarg, 545, 'ERROR: cannot read file "' + rcFile + '"');
}
if (rc.stdout) {
retCode = parseInt(rc.stdout.trim(), 10);
}
}
if (retCode >= 0) {
clearInterval(timer);
fixLogEnd();
if (retCode == 0 && res.stdout) {
return callback(cbarg, 0, res.stdout);
}
return callback(cbarg, retCode, 'ERROR: Process failed with error ' + retCode);
}
} 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);
},
});

View File

@@ -0,0 +1,203 @@
'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_update_pkg_sh = '/opt/'+tools.appName+'/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: async function()
{
this._action = 'checkUpdates';
this.setStage(0);
this.setBtnMode(0);
this.pkg_url = null;
this.appendLog(_('Checking for updates...'));
let cmd = [ fn_update_pkg_sh, '-c' ]; // check for updates
if (document.getElementById('cfg_exclude_prereleases').checked == false) {
cmd.push('-p'); // include prereleases ZIP-files
}
this.forced_reinstall = document.getElementById('cfg_forced_reinstall').checked;
let log = '/tmp/'+tools.appName+'_pkg_check.log';
let callback = this.execAndReadCallback;
let wnd = this;
return tools.execAndRead({ cmd: cmd, log: log, logArea: this.logArea, callback: callback, cbarg: wnd });
},
installUpdates: async function()
{
this._action = 'installUpdates';
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;
}
this.appendLog(_('Install updates...'));
let cmd = [ fn_update_pkg_sh, '-u', this.pkg_url ]; // update packages
if (document.getElementById('cfg_forced_reinstall').checked == true) {
cmd.push('-f'); // forced reinstall if same version
}
//this._test = 1; cmd.push('-t'); cmd.push('45'); // only for testing
let log = '/tmp/'+tools.appName+'_pkg_install.log';
let hiderow = /^ \* resolve_conffiles.*(?:\r?\n|$)/gm;
let callback = this.execAndReadCallback;
let wnd = this;
return tools.execAndRead({ cmd: cmd, log: log, logArea: this.logArea, hiderow: hiderow, callback: callback, cbarg: wnd });
},
execAndReadCallback: function(wnd, rc, txt = '')
{
//console.log('execAndReadCallback = ' + rc + '; _action = ' + wnd._action);
if (rc == 0 && txt) {
let code = txt.match(/^RESULT:\s*\(([^)]+)\)\s+.+$/m);
if (wnd._action == 'checkUpdates') {
let pkg_url = txt.match(/^ZAP_PKG_URL\s*=\s*(.+)$/m);
if (code && pkg_url) {
wnd.appendLog('=========================================================');
wnd.pkg_url = pkg_url[1];
code = code[1];
if (code == 'E' && !wnd.forced_reinstall) {
wnd.setStage(999); // install not needed
return;
}
wnd.setStage(1);
wnd.setBtnMode(2); // enable all buttons
return; // install allowed
}
}
if (wnd._action == 'installUpdates') {
if (wnd._test || (code && code[1] == '+')) {
wnd.stage = 999;
wnd.btn_action.textContent = _('OK');
wnd.btn_action.disabled = false;
wnd.btn_cancel.disabled = true;
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.setStage(999);
if (wnd._action == 'checkUpdates') {
wnd.appendLog('=========================================================');
}
},
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', {
'id': 'widget.modal_content',
'readonly': true,
'style': 'width:100% !important; font-family: monospace;',
'rows': 20,
'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_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

@@ -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,45 +0,0 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=zapret-ip2net
PKG_VERSION:=72.20251219
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:=994e9c34883ddc95e51c8285f134bd01fd6b6732
PKG_SOURCE_DATE:=2025-12-19
#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:=ip2net
define Package/$(PKG_NAME)
SECTION:=net
CATEGORY:=Network
TITLE:=ip2net
SUBMENU:=Zapret
DEPENDS:=+zlib +zapret
endef
define Build/Prepare
$(Build/Prepare/Default)
rm -f $(PKG_BUILD_DIR)/$(MAKE_PATH)/ip2net
endef
define Package/$(PKG_NAME)/install
$(INSTALL_DIR) $(1)/opt/zapret/ip2net
$(INSTALL_BIN) $(PKG_BUILD_DIR)/$(MAKE_PATH)/ip2net $(1)/opt/zapret/ip2net/
endef
$(eval $(call BuildPackage,$(PKG_NAME)))

View File

@@ -1,45 +0,0 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=zapret-mdig
PKG_VERSION:=72.20251219
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:=994e9c34883ddc95e51c8285f134bd01fd6b6732
PKG_SOURCE_DATE:=2025-12-19
#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:=mdig
define Package/$(PKG_NAME)
SECTION:=net
CATEGORY:=Network
TITLE:=mdig
SUBMENU:=Zapret
DEPENDS:=+zlib +zapret
endef
define Build/Prepare
$(Build/Prepare/Default)
rm -f $(PKG_BUILD_DIR)/$(MAKE_PATH)/mdig
endef
define Package/$(PKG_NAME)/install
$(INSTALL_DIR) $(1)/opt/zapret/mdig
$(INSTALL_BIN) $(PKG_BUILD_DIR)/$(MAKE_PATH)/mdig $(1)/opt/zapret/mdig/
endef
$(eval $(call BuildPackage,$(PKG_NAME)))

View File

@@ -1,45 +0,0 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=zapret-tpws
PKG_VERSION:=72.20251219
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:=994e9c34883ddc95e51c8285f134bd01fd6b6732
PKG_SOURCE_DATE:=2025-12-19
#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:=tpws
define Package/$(PKG_NAME)
SECTION:=net
CATEGORY:=Network
TITLE:=tpws
SUBMENU:=Zapret
DEPENDS:=+zlib +libcap +zapret
endef
define Build/Prepare
$(Build/Prepare/Default)
rm -f $(PKG_BUILD_DIR)/$(MAKE_PATH)/tpws
endef
define Package/$(PKG_NAME)/install
$(INSTALL_DIR) $(1)/opt/zapret/tpws
$(INSTALL_BIN) $(PKG_BUILD_DIR)/$(MAKE_PATH)/tpws $(1)/opt/zapret/tpws/
endef
$(eval $(call BuildPackage,$(PKG_NAME)))

View File

@@ -1,230 +0,0 @@
#
# Copyright (c) 2024 remittor
#
include $(TOPDIR)/rules.mk
PKG_NAME:=zapret
PKG_VERSION:=72.20251219
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:=994e9c34883ddc95e51c8285f134bd01fd6b6732
PKG_SOURCE_DATE:=2025-12-19
#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
endef
#define Build/Configure
#endef
#define Build/Compile
#endef
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
$(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/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) ./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
$(INSTALL_BIN) ./comfunc.sh $(1)/opt/zapret/comfunc.sh
$(INSTALL_BIN) ./def-cfg.sh $(1)/opt/zapret/def-cfg.sh
$(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
define Package/$(PKG_NAME)/preinst
#!/bin/sh
# check if we are on real system
if [ -z "$${IPKG_INSTROOT}" ]; then
if [ -f "/etc/init.d/zapret" ]; then
SCRIPT=$$( readlink /etc/init.d/zapret )
if [ -n "$${SCRIPT}" ]; then
echo "Please uninstall original zapret utility!"
exit 44
fi
fi
if [ "$${PKG_UPGRADE}" = "1" ]; then
# stop service if PKG_UPGRADE
if [ -x "/etc/init.d/zapret" ]; then
/etc/init.d/zapret running && /etc/init.d/zapret stop >/dev/null 2>&1
fi
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_CONFIG=/opt/zapret/config
ZAPRET_CONFIG_DEF="/opt/zapret/config.default"
# 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
# check existing uci-config
[ -f "/etc/config/zapret" ] && 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
/etc/init.d/zapret enable
# stop all
/etc/init.d/zapret stop_fw
/etc/init.d/zapret stop_daemons
ps w | grep '/opt/zapret/nfq/nfqws' | grep -v grep | awk '{print $$1}' | xargs -r kill -9
# start main service
/etc/init.d/zapret 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
EXEDIR=/opt/zapret
ZAPRET_BASE=/opt/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"
/etc/init.d/zapret running && /etc/init.d/zapret stop
/etc/init.d/zapret disable
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
[ -f "/etc/config/zapret-opkg" ] && rm -f "/etc/config/zapret-opkg"
[ -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,272 +0,0 @@
#!/bin/sh
# Copyright (c) 2024 remittor
function set_cfg_reset_values
{
local cfgname=${1:-$ZAPRET_CFG_NAME}
local TAB="$( echo -n -e '\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="$( 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
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
}

View File

@@ -1,256 +0,0 @@
127.0.0.0/8
10.0.0.0/8
172.16.0.0/12
192.168.0.0/16
169.254.0.0/16
100.64.0.0/10
::1
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
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
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
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
s.team
steam.tv
valve.net
steamcdn.com
steamcdn.net
steamstat.us
valvecdn.com
steam-api.com
steamchat.com
steamdeck.com
steam-chat.com
steamgames.com
steamgames.net
underlords.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
github.com
openwrt.org
gh.openwrt.org
cdn.openwrt.org
dev.openwrt.org
git.openwrt.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
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

@@ -1,18 +0,0 @@
#!/bin/sh
# Copyright (c) 2024 remittor
. /opt/zapret/comfunc.sh
# create empty txt files into ipset directory
[ ! -f "/opt/zapret/ipset/zapret-hosts-google.txt" ] && touch "/opt/zapret/ipset/zapret-hosts-google.txt"
#[ ! -f "/opt/zapret/ipset/zapret-hosts-auto.txt" ] && touch "/opt/zapret/ipset/zapret-hosts-auto.txt"
[ ! -f "/opt/zapret/ipset/zapret-hosts-user.txt" ] && touch "/opt/zapret/ipset/zapret-hosts-user.txt"
[ ! -f "/opt/zapret/ipset/zapret-hosts-user-ipban.txt" ] && touch "/opt/zapret/ipset/zapret-hosts-user-ipban.txt"
#[ ! -f "/opt/zapret/ipset/zapret-ip.txt" ] && touch "/opt/zapret/ipset/zapret-ip.txt"
[ ! -f "/opt/zapret/ipset/zapret-ip-user.txt" ] && touch "/opt/zapret/ipset/zapret-ip-user.txt"
[ ! -f "/opt/zapret/ipset/zapret-ip-user-exclude.txt" ] && touch "/opt/zapret/ipset/zapret-ip-user-exclude.txt"
[ ! -f "/opt/zapret/ipset/zapret-ip-user-ipban.txt" ] && touch "/opt/zapret/ipset/zapret-ip-user-ipban.txt"
# create or merge uci-config
$ZAPRET_BASE/renew-cfg.sh

332
zapret2/Makefile Normal file
View File

@@ -0,0 +1,332 @@
#
# Copyright (c) 2025 remittor
#
include $(TOPDIR)/rules.mk
PKG_NAME:=zapret2
PKG_VERSION:=0.8.20260117
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:=5dde1264ce6908fc62561d8bb579d316a00b7ea2
PKG_SOURCE_DATE:=2026-01-17
#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.3
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
# 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,19 +1,22 @@
#!/bin/sh
# Copyright (c) 2024 remittor
EXEDIR=/opt/zapret
ZAPRET_BASE=/opt/zapret
EXEDIR=/opt/zapret2
ZAPRET_BASE=/opt/zapret2
ZAPRET_INITD=/etc/init.d/zapret
ZAPRET_ORIG_INITD="$ZAPRET_BASE/init.d/openwrt/zapret"
ZAPRET_INITD=/etc/init.d/zapret2
ZAPRET_ORIG_INITD="$ZAPRET_BASE/init.d/openwrt/zapret2"
ZAP_LOG_TAG=ZAPRET2
ZAPRET_CONFIG="$ZAPRET_BASE/config"
ZAPRET_CONFIG_NEW="$ZAPRET_BASE/config.new"
ZAPRET_CONFIG_DEF="$ZAPRET_BASE/config.default"
ZAPRET_CFG=/etc/config/zapret
ZAPRET_CFG_NAME=zapret
ZAPRET_CFG_SEC_NAME="$( uci -q get $ZAPRET_CFG_NAME.config )"
ZAPRET_CFG=/etc/config/zapret2
ZAPRET_CFG_NAME=zapret2
ZAPRET_CFG_SEC=$ZAPRET_CFG_NAME.config
ZAPRET_CFG_SEC_NAME="$( uci -q get $ZAPRET_CFG_SEC )"
. $ZAPRET_BASE/def-cfg.sh
@@ -127,7 +130,7 @@ 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
restore_ipset_txt zapret-ip-exclude.txt
}
function create_default_cfg
@@ -148,7 +151,7 @@ function merge_cfg_with_def_values
local cfgname=${1:-$ZAPRET_CFG_NAME}
local force=$2
local cfgfile=/etc/config/$cfgname
local NEWCFGNAME="zapret-default"
local NEWCFGNAME="$ZAPRET_CFG_NAME-default"
local NEWCFGFILE="/etc/config/$NEWCFGNAME"
local cfg_sec_name="$( uci -q get $ZAPRET_CFG_NAME.config )"
@@ -168,7 +171,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_CFG_NAME+\*.log' -size +/d" "$CRONTAB_FILE"
fi
}
@@ -176,8 +179,8 @@ 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"
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"
/etc/init.d/cron restart 2> /dev/null
fi
return 0
@@ -190,7 +193,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_CFG_NAME+*.log
#*/
if [ "$DAEMON_LOG_ENABLE" = "1" ]; then
insert_cron_task_logs

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"
# 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_FAIL_THRESHOLD=3
AUTOHOSTLIST_FAIL_TIME=60
AUTOHOSTLIST_UDP_IN=1
AUTOHOSTLIST_UDP_OUT=4
# 1 = debug autohostlist positives to ipset/zapret-hosts-auto-debug.log
AUTOHOSTLIST_DEBUGLOG=0
# number of parallel threads for domain list resolves
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
GZIP_LISTS=0
@@ -63,47 +74,30 @@ DESYNC_MARK_POSTNAT=0x20000000
FILTER_MARK=""
TPWS_SOCKS_ENABLE=0
# 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
NFQWS2_ENABLE=1
# redirect outgoing traffic with connbytes limiter applied in both directions.
NFQWS_PORTS_TCP="80,443"
NFQWS_PORTS_UDP="443"
NFQWS2_PORTS_TCP="80,443"
NFQWS2_PORTS_UDP="443"
# PKT_OUT means connbytes dir original
# PKT_IN means connbytes dir reply
# this is --dpi-desync-cutoff=nX kernel mode implementation for linux. it saves a lot of CPU.
NFQWS_TCP_PKT_OUT="9"
NFQWS_TCP_PKT_IN="3"
NFQWS_UDP_PKT_OUT="9"
NFQWS_UDP_PKT_IN="0"
NFQWS2_TCP_PKT_OUT="20"
NFQWS2_TCP_PKT_IN="10"
NFQWS2_UDP_PKT_OUT="5"
NFQWS2_UDP_PKT_IN="3"
# 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
# typical example are plain HTTP keep alives
# this mode can be very CPU consuming. enable with care !
NFQWS_PORTS_TCP_KEEPALIVE=""
NFQWS_PORTS_UDP_KEEPALIVE=""
NFQWS2_PORTS_TCP_KEEPALIVE=""
NFQWS2_PORTS_UDP_KEEPALIVE=""
# 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
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
@@ -121,9 +115,8 @@ FLOWOFFLOAD=none
# for routers based on desktop linux and macos. has no effect in openwrt.
# CHOOSE LAN and optinally WAN/WAN6 NETWORK INTERFACES
# 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
#IFACE_LAN=eth0
#IFACE_WAN=eth1
#IFACE_WAN6="ipsec0 wireguard0 he_net"
@@ -132,10 +125,10 @@ FLOWOFFLOAD=none
INIT_APPLY_FW=1
# firewall apply hooks
#INIT_FW_PRE_UP_HOOK="/etc/firewall.zapret.hook.pre_up"
#INIT_FW_POST_UP_HOOK="/etc/firewall.zapret.hook.post_up"
#INIT_FW_PRE_DOWN_HOOK="/etc/firewall.zapret.hook.pre_down"
#INIT_FW_POST_DOWN_HOOK="/etc/firewall.zapret.hook.post_down"
#INIT_FW_PRE_UP_HOOK="/etc/firewall.zapret2.hook.pre_up"
#INIT_FW_POST_UP_HOOK="/etc/firewall.zapret2.hook.post_up"
#INIT_FW_PRE_DOWN_HOOK="/etc/firewall.zapret2.hook.pre_down"
#INIT_FW_POST_DOWN_HOOK="/etc/firewall.zapret2.hook.post_down"
# do not work with ipv4
DISABLE_IPV4=0
@@ -156,4 +149,4 @@ FILTER_TTL_EXPIRED_ICMP=1
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)
# 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_qnum QNUM_STUN4ALL
@@ -17,14 +17,14 @@ zapret_custom_daemons()
}
zapret_custom_firewall()
{
# $1 - 1 - run, 0 - stop
# $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
# 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

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="
# 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="
# 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="
# 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
}

234
zapret2/dwc.sh Normal file
View File

@@ -0,0 +1,234 @@
#!/bin/sh
# Copyright (c) 2026 remittor
ZAP_TMP_DIR=/tmp/zapret2_dwc
opt_dig=
opt_recom=
opt_tmp_dir=
opt_test=
while getopts "d:RT:t" opt; do
case $opt in
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_RANGETO=65535
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://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/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" }
]'
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
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
ID=$((ID+1))
ID3=$( printf '%03d' "$ID" )
COUNTRY=$( echo "$TAG" | cut -d. -f1 )
CNTFLAG=$( echo "$PROVIDER" | awk '{print $1}' )
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 \
--connect-timeout $CURL_CON_TIMEOUT \
--max-time $CURL_TIMEOUT \
--speed-time $CURL_SPEED_TIME \
--speed-limit $CURL_SPEED_LIMIT \
--range 0-$CURL_RANGETO \
-A "$CURL_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"
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" -le $CURL_RANGETO ]; then
status="Failed (recv $BODY_SIZE bytes)"
res=5
else
status="[ OK ]"
res=100
fi
fi
printf '%12s / %-15s / %-13s: %s \n' "$TAG" "$IPADDR" "$PROVIDER" "$status"
echo "$BODY_SIZE" > "$FNAME.size"
if [ $res != 100 ]; then
URL=$( cat "$FNAME.url" )
echo "$FILENAME : $URL" >> "$FAIL_URL_LIST"
fi
done
rm -f "$ZAP_TMP_DIR"/*.body >/dev/null 2>&1
[ "$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

Binary file not shown.

View File

@@ -7,17 +7,17 @@ START=21
SCRIPT_FILENAME=$1
. /opt/zapret/comfunc.sh
. /opt/zapret2/comfunc.sh
if ! is_valid_config ; then
logger -p err -t ZAPRET "Wrong main config: $ZAPRET_CONFIG"
logger -p err -t $ZAP_LOG_TAG "Wrong main config: $ZAPRET_CONFIG"
exit 91
fi
. $ZAPRET_ORIG_INITD
EXEDIR=/opt/zapret
ZAPRET_BASE=/opt/zapret
EXEDIR=/opt/$ZAPRET_CFG_NAME
ZAPRET_BASE=/opt/$ZAPRET_CFG_NAME
is_run_on_boot && IS_RUN_ON_BOOT=1 || IS_RUN_ON_BOOT=0
@@ -30,13 +30,13 @@ function enable
if [ -n "$ZAPRET_CFG_SEC_NAME" ]; then
run_on_boot=$( get_run_on_boot_option )
if [ $run_on_boot != 1 ]; then
logger -p notice -t ZAPRET "Attempt to enable service, but service blocked!"
logger -p notice -t $ZAP_LOG_TAG "Attempt to enable service, but service blocked!"
return 61
fi
fi
fi
if [ -n "$ZAPRET_CFG_SEC_NAME" ]; then
uci set $ZAPRET_CFG_NAME.config.run_on_boot=1
uci set $ZAPRET_CFG_SEC.run_on_boot=1
uci commit
fi
/bin/sh /etc/rc.common $ZAPRET_ORIG_INITD enable
@@ -49,7 +49,7 @@ function enabled
run_on_boot=$( get_run_on_boot_option )
if [ $run_on_boot != 1 ]; then
if [ "$IS_RUN_ON_BOOT" = "1" ]; then
logger -p notice -t ZAPRET "Service is blocked!"
logger -p notice -t $ZAP_LOG_TAG "Service is blocked!"
fi
return 61
fi
@@ -65,7 +65,7 @@ function boot
if [ -n "$ZAPRET_CFG_SEC_NAME" ]; then
run_on_boot=$( get_run_on_boot_option )
if [ $run_on_boot != 1 ]; then
logger -p notice -t ZAPRET "Attempt to run service on boot! Service is blocked!"
logger -p notice -t $ZAP_LOG_TAG "Attempt to run service on boot! Service is blocked!"
return 61
fi
fi

View File

@@ -0,0 +1,287 @@
127.0.0.0/8
10.0.0.0/8
172.16.0.0/12
192.168.0.0/16
169.254.0.0/16
100.64.0.0/10
::1
fc00::/7
fe80::/10
####################################
nalog.ru
gstatic.com
gosuslugi.ru
mos-gorsud.ru
gov.ru
sudrf.ru
ottai.com
ipstream.one
vkusvill.ru
kinopoisk.ru
#################################### Epicgames
easy.ac
fab.com
quixel.se
quixel.com
eac-cdn.com
paragon.com
spyjinx.com
3lateral.com
fortnite.com
epicgames.com
epicgames.dev
hyprsense.com
sketchfab.com
artstation.com
roborecall.com
twinmotion.com
cubicmotion.com
playparagon.com
realityscan.com
epicgamescdn.com
radgametools.com
unrealengine.com
easyanticheat.net
shadowcomplex.com
battlebreakers.com
capturingreality.com
unrealtournament.com
epicgames-download1.akamaized.net
#################################### Steam
s.team
steam.tv
valve.net
steamcdn.com
steamcdn.net
steamstat.us
valvecdn.com
steam-api.com
steamchat.com
steamdeck.com
steam-chat.com
steamgames.com
steamgames.net
underlords.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
dl.steam.clngaa.com
steam.ru.qtlglb.com
steam.eca.qtlglb.com
steamusercontent.com
steam.apac.qtlglb.com
steam.naeu.qtlglb.com
cdn.steamcommunity.com
gstore.val.manlaxy.com
partner.steamgames.com
steam.cdn.orcon.net.nz
steamcdn-a.akamaihd.net
steampipe.akamaized.net
steamcdn-a.akamaized.net
steamdeckusercontent.com
steam.cdn.slingshot.co.nz
steammobile.akamaized.net
steamstatic.akamaized.net
steamstore-a.akamaihd.net
steamvideo-a.akamaihd.net
client-update.queniuqe.com
steamdeckcdn.akamaized.net
steampipe-kr.akamaized.net
steamcontent-a.akamaihd.net
steambroadcast.akamaized.net
steamcommunity.akamaized.net
scontent.steamusercontent.com
steamcommunity-a.akamaihd.net
edge.steam-dns.top.comcast.net
steamcommunity-a.akamaized.net
steamuserimages-a.akamaihd.net
steampipe-partner.akamaized.net
steamusercontent-a.akamaihd.net
steamcdn-a.akamaihd.net.edgesuite.net
steamcloudsweden.blob.core.windows.net
steamcommunity-a.akamaihd.net.edgesuite.net
#################################### OpenWRT
openwrt.org
lede-project.org
#################################### UbisoftConnect
ubi.com
ubisoft.com
ubisoftconnect.com
connect.ubisoft.comubisoft-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
playstationcloud.com
sonyentertainmentnetwork.com
#################################### Twitch
twitch.tv
ttvnw.net
jtvnw.net
twitchcdn.net
ext-twitch.tv
twitchsvc.net
live-video.net
twitch.a2z.com
twitch-shadow.net
twitchcdn-shadow.net
#################################### Valorant
qq.com
pvp.net
vivox.com
sd-rtn.com
adjust.com
riotcdn.net
adobess.com
valorant.com
akamaihd.net
myqcloud.com
riotgames.com
playvalorant.com
wildrift-na.akamaized.net
#################################### TikTok
musical.ly
tiktok.com
tiktokv.eu
tiktokv.us
tiktokw.eu
tiktokw.us
muscdn.com
tiktokd.net
tiktokd.org
tiktokv.com
tiktokcdn.com
ibytedtos.com
ttwstatic.com
tik-tokapi.com
tiktok-row.net
tiktokminis.us
byteoversea.com
tiktok-minis.com
tiktokcdn-eu.com
tiktokcdn-us.com
tiktokeu-cdn.com
tiktokrow-cdn.com
tiktokglobalshopv.com
tiktokcdn.com.akamaized.net
tiktokcdn.com.edgesuite.net
tiktokcdn-us.com.edgesuite.net
#################################### Hoyoverse
hoyo.link
hoyolab.com
yuanshen.com
hoyoverse.com
genshinimpact.com
zenlesszonezero.com
#################################### Xiaomi
mi.com
miui.com
wali.com
c.mi.com
mgslb.com
mifile.cn
xiaomi.cn
mipay.com
youpin.cn
zmifi.com
mi-idc.com
mi-img.com
mijia.tech
mitvos.com
miwifi.com
xiaomi.com
xiaomi.net
duokan.com
saxyit.com
mi-fan.com
mihome.com
xiaomisa.cn
migames.com
miaibox.com
mi-home.com
xiaomicp.com
xiaomidns.cn
xiaomiev.com
xiaomiinc.cn
xiaominr.com
xiaomisa.com
xiaomisa.net
xiaomisa.org
roborock.com
mi-robot.com
yeelight.com
miot-spec.cn
xiaomidns.com
xiaomidns.net
xiaomiinc.com
xiaomiinc.net
duokanbox.com
youpin.com.cn
miot-spec.org
miot-spec.com
xiaomiwear.com
xiaomimimo.com
dreamehome.com
xiaomiprint.com
xiaomidns.com.cn
xiaomiinc.com.cn
xiaomimobile.com
xiaomixiaoai.com
xiaomiyoupin.com
xiaoaiassist.com
xiaomi-mijia.com
xiaomifactory.com
airstarfinance.net
dreame-technology.cn
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
####################################

View File

@@ -25,10 +25,10 @@ index 0af19c0..41c0967 100644
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
--- a/init.d/openwrt/zapret
+++ b/init.d/openwrt/zapret
--- a/init.d/openwrt/zapret2
+++ b/init.d/openwrt/zapret2
@@ -58,12 +58,29 @@ run_daemon()
# use $PIDDIR/$DAEMONBASE$1.pid as pidfile
local DAEMONBASE="$(basename "$2")"
@@ -51,15 +51,15 @@ index 8d6d3a9..fcb1e91 100755
procd_open_instance
- procd_set_param command $2 $3
+ 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
}
+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

View File

@@ -1,7 +1,9 @@
#!/bin/sh
# Copyright (c) 2024 remittor
. /opt/zapret/comfunc.sh
EXE_DIR=$(cd "$(dirname "$0")" 2>/dev/null || exit 1; pwd)
. $EXE_DIR/comfunc.sh
merge_cfg_with_def_values
@@ -12,5 +14,5 @@ CONFIGS_SYNC=0
if [ "$CONFIGS_SYNC" = "1" ]; then
# renew main config
/opt/zapret/sync_config.sh
$ZAPRET_BASE/sync_config.sh
fi

View File

@@ -1,9 +1,11 @@
#!/bin/sh
# Copyright (c) 2024 remittor
. /opt/zapret/comfunc.sh
EXE_DIR=$(cd "$(dirname "$0")" 2>/dev/null || exit 1; pwd)
cfg_run_on_boot="$( uci -q get zapret.config.run_on_boot )"
. $EXE_DIR/comfunc.sh
cfg_run_on_boot="$( uci -q get $ZAPRET_CFG_SEC.run_on_boot )"
opt_flags=${1:--}
opt_strat=$2
@@ -11,11 +13,16 @@ opt_strat=$2
if echo "$opt_flags" | grep -q "(reset_ipset)"; then
restore_all_ipset_cfg
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"
if [ "$cfg_run_on_boot" = "1" ]; then
uci set zapret.config.run_on_boot=1
uci set $ZAPRET_CFG_SEC.run_on_boot=1
uci commit
fi
@@ -29,5 +36,5 @@ fi
if [ "$ZAPRET_SYNC_CONFIG" = "1" ]; then
# renew main config
/opt/zapret/sync_config.sh
$ZAPRET_BASE/sync_config.sh
fi

View File

@@ -1,7 +1,9 @@
#!/bin/sh
# Copyright (c) 2024 remittor
. /opt/zapret/comfunc.sh
EXE_DIR=$(cd "$(dirname "$0")" 2>/dev/null || exit 1; pwd)
. $EXE_DIR/comfunc.sh
function uncomment_param
{
@@ -41,19 +43,25 @@ function sync_param
{
local param=$1
local vtype=$2
local value="$( uci -q get zapret.config.$param )"
local value="$( uci -q get $ZAPRET_CFG_SEC.$param )"
uncomment_param $param
append_param $param
local TAB="$( echo -n -e '\t' )"
local TAB="$( printf '\t' )"
if [ "$value" = "$TAB" ]; then
value=""
fi
if [ "$param" = "NFQWS_PORTS_TCP_KEEPALIVE" -o "$param" = "NFQWS_PORTS_UDP_KEEPALIVE" ]; then
[ "$value" = "0" ] && value=""
fi
if [ "$param" = "NFQWS2_PORTS_TCP_KEEPALIVE" -o "$param" = "NFQWS2_PORTS_UDP_KEEPALIVE" ]; then
[ "$value" = "0" ] && value=""
fi
if [ "$param" = "NFQWS_OPT" -a "$value" != "" ]; then
value=$( echo -n "$value" | sed '/^#/d' )
fi
if [ "$param" = "NFQWS2_OPT" -a "$value" != "" ]; then
value=$( echo -n "$value" | sed '/^#/d' )
fi
if [ "$vtype" = "str" ]; then
set_param_value_str $param "$value"
else
@@ -90,21 +98,43 @@ sync_param DAEMON_LOG_FILE str
sync_param AUTOHOSTLIST_RETRANS_THRESHOLD
sync_param AUTOHOSTLIST_FAIL_THRESHOLD
sync_param AUTOHOSTLIST_FAIL_TIME
if [ $ZAPRET_CFG_NAME = "zapret2" ]; then
sync_param AUTOHOSTLIST_INCOMING_MAXSEQ
sync_param AUTOHOSTLIST_RETRANS_MAXSEQ
sync_param AUTOHOSTLIST_RETRANS_RESET
sync_param AUTOHOSTLIST_UDP_IN
sync_param AUTOHOSTLIST_UDP_OUT
fi
sync_param AUTOHOSTLIST_DEBUGLOG
sync_param NFQWS_ENABLE
sync_param DESYNC_MARK
sync_param DESYNC_MARK_POSTNAT
sync_param FILTER_MARK str
sync_param NFQWS_PORTS_TCP str
sync_param NFQWS_PORTS_UDP str
sync_param NFQWS_TCP_PKT_OUT str
sync_param NFQWS_TCP_PKT_IN str
sync_param NFQWS_UDP_PKT_OUT str
sync_param NFQWS_UDP_PKT_IN str
sync_param NFQWS_PORTS_TCP_KEEPALIVE str
sync_param NFQWS_PORTS_UDP_KEEPALIVE str
sync_param NFQWS_OPT str
if [ $ZAPRET_CFG_NAME = "zapret" ]; then
sync_param NFQWS_ENABLE
sync_param NFQWS_PORTS_TCP str
sync_param NFQWS_PORTS_UDP str
sync_param NFQWS_TCP_PKT_OUT str
sync_param NFQWS_TCP_PKT_IN str
sync_param NFQWS_UDP_PKT_OUT str
sync_param NFQWS_UDP_PKT_IN str
sync_param NFQWS_PORTS_TCP_KEEPALIVE str
sync_param NFQWS_PORTS_UDP_KEEPALIVE str
sync_param NFQWS_OPT str
fi
if [ $ZAPRET_CFG_NAME = "zapret2" ]; then
sync_param NFQWS2_ENABLE
sync_param NFQWS2_PORTS_TCP str
sync_param NFQWS2_PORTS_UDP str
sync_param NFQWS2_TCP_PKT_OUT str
sync_param NFQWS2_TCP_PKT_IN str
sync_param NFQWS2_UDP_PKT_OUT str
sync_param NFQWS2_UDP_PKT_IN str
sync_param NFQWS2_PORTS_TCP_KEEPALIVE str
sync_param NFQWS2_PORTS_UDP_KEEPALIVE str
sync_param NFQWS2_OPT str
fi
ZAPRET_CONFIG="$ZAPRET_CONFIG__SAVED"

23
zapret2/uci-def-cfg.sh Executable file
View File

@@ -0,0 +1,23 @@
#!/bin/sh
# Copyright (c) 2024 remittor
[ ! -f /opt/zapret2/comfunc.sh ] && exit 0
. /opt/zapret2/comfunc.sh
mkdir -p $ZAPRET_BASE/ipset
# create empty txt files into ipset directory
[ ! -f "$ZAPRET_BASE/ipset/zapret-hosts-google.txt" ] && touch "$ZAPRET_BASE/ipset/zapret-hosts-google.txt"
[ ! -f "$ZAPRET_BASE/ipset/zapret-hosts-auto.txt" ] && touch "$ZAPRET_BASE/ipset/zapret-hosts-auto.txt"
[ ! -f "$ZAPRET_BASE/ipset/zapret-hosts-user.txt" ] && touch "$ZAPRET_BASE/ipset/zapret-hosts-user.txt"
[ ! -f "$ZAPRET_BASE/ipset/zapret-hosts-user-ipban.txt" ] && touch "$ZAPRET_BASE/ipset/zapret-hosts-user-ipban.txt"
#[ ! -f "$ZAPRET_BASE/ipset/zapret-ip.txt" ] && touch "$ZAPRET_BASE/ipset/zapret-ip.txt"
[ ! -f "$ZAPRET_BASE/ipset/zapret-ip-user.txt" ] && touch "$ZAPRET_BASE/ipset/zapret-ip-user.txt"
[ ! -f "$ZAPRET_BASE/ipset/zapret-ip-user-exclude.txt" ] && touch "$ZAPRET_BASE/ipset/zapret-ip-user-exclude.txt"
[ ! -f "$ZAPRET_BASE/ipset/zapret-ip-user-ipban.txt" ] && touch "$ZAPRET_BASE/ipset/zapret-ip-user-ipban.txt"
# create or merge uci-config
[ ! -f "$ZAPRET_BASE/renew-cfg.sh" ] && exit 0
$ZAPRET_BASE/renew-cfg.sh

View File

@@ -1,9 +1,7 @@
#!/bin/sh
# Copyright (c) 2025 remittor
. /opt/zapret/comfunc.sh
. /usr/share/libubox/jshn.sh
. /etc/openwrt_release
EXE_DIR=$(cd "$(dirname "$0")" 2>/dev/null || exit 1; pwd)
opt_check=
opt_prerelease=
@@ -14,14 +12,34 @@ opt_test=
while getopts "cu:pft:" opt; do
case $opt in
c) opt_check=true;;
p) opt_prerelease=true;;
p) opt_prerelease="true";;
u) opt_update="$OPTARG";;
f) opt_forced=true;;
f) opt_forced="true";;
t) opt_test="$OPTARG";;
esac
done
ZAP_PKG_DIR=/tmp/zapret_pkg
if [ "$EXE_DIR" = "/tmp" ]; then
ZAPRET_CFG_NAME="zapret"
if [ "$opt_update" = "1" ]; then
ZAPRET_CFG_NAME="zapret"
opt_update="@"
opt_forced="true"
fi
if [ "$opt_update" = "2" ]; then
ZAPRET_CFG_NAME="zapret2"
opt_update="@"
opt_forced="true"
fi
else
[ -f "$EXE_DIR/comfunc.sh" ] || { echo "ERROR: file $EXE_DIR/comfunc.sh not found!"; exit 1; }
. $EXE_DIR/comfunc.sh
fi
. /usr/share/libubox/jshn.sh
. /etc/openwrt_release
ZAP_PKG_DIR=/tmp/$ZAPRET_CFG_NAME-pkg
if [ "$opt_test" != "" ]; then
echo 1; sleep 2;
@@ -33,9 +51,14 @@ if [ "$opt_test" != "" ]; then
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"
ZAP_CPU_ARCH="$DISTRIB_ARCH"
if [ $ZAPRET_CFG_NAME = "zapret" ]; then
ZAP_REL_URL="https://raw.githubusercontent.com/remittor/zapret-openwrt/gh-pages/releases/releases_zap1_$ZAP_CPU_ARCH.json"
fi
if [ $ZAPRET_CFG_NAME = "zapret2" ]; then
ZAP_REL_URL="https://raw.githubusercontent.com/remittor/zapret-openwrt/gh-pages/releases/releases_zap2_$ZAP_CPU_ARCH.json"
fi
CURL_TIMEOUT=5
CURL_HEADER1="Accept: application/json"
CURL_HEADER2="Cache-Control: no-cache"
@@ -52,9 +75,13 @@ ZAP_PKG_URL=
if command -v apk >/dev/null; then
PKG_MGR=apk
ZAP_PKG_EXT=apk
PKG_CHECK="apk info -e "
PKG_REMOVE="apk del --force "
elif command -v opkg >/dev/null; then
PKG_MGR=opkg
ZAP_PKG_EXT=ipk
PKG_CHECK="opkg status "
PKG_REMOVE="opkg remove --force-remove "
else
echo "ERROR: No package manager found"
return 1
@@ -62,11 +89,73 @@ fi
# -------------------------------------------------------------------------------------------------------
function download_json
function get_distrib_param
{
local url="$1"
curl -s -L --max-time $CURL_TIMEOUT -H "$CURL_HEADER1" -H "$CURL_HEADER2" "$url" 2>/dev/null
return $?
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 pkg_mgr_update
{
local forced=$1
if [ "$PKG_MGR" = "opkg" ]; then
PKG_TOTAL=$( opkg list | wc -l )
PKG_INSTALLED=$( opkg list-installed | wc -l )
if [ "$PKG_TOTAL" -le "$PKG_INSTALLED" ] || [[ "$PKG_TOTAL" -le $((PKG_INSTALLED + 100)) ]]; then
echo ">>> OPKG update..."
opkg update
return $?
fi
else
PKG_AVAIL=$( apk list --available 2>/dev/null | wc -l )
if [ "$PKG_AVAIL" -lt 100 ]; then
echo ">>> APK update..."
apk update
return $?
fi
fi
return 0
}
function curl_install
{
if command -v curl >/dev/null 2>&1; then
return 0
fi
pkg_mgr_update || { echo "ERROR: cannot update packages list"; return 1; }
echo ">>> Package curl not found, installing..."
if [ "$PKG_MGR" = "opkg" ]; then
opkg install curl
else
apk add curl
fi
}
function unzip_install
{
if command -v unzip >/dev/null 2>&1; then
return 0
fi
pkg_mgr_update || { echo "ERROR: cannot update packages list"; return 1; }
echo ">>> Package unzip not found, installing..."
if [ "$PKG_MGR" = "opkg" ]; then
opkg install unzip
else
apk add unzip
fi
}
function get_pkg_version
@@ -81,7 +170,7 @@ function get_pkg_version
fi
fi
if [ "$PKG_MGR" = apk ]; then
line=$( apk info -e "$pkg_name" 2>/dev/null || true )
line=$( apk info -s "$pkg_name" 2>/dev/null | head -n 1 | awk '{print $1}' || true )
if [ -n "$line" ]; then
base=${line%-r[0-9]*}
ver=${base##*-}
@@ -104,7 +193,8 @@ function normalize_version
{
local ver="$1"
local base
local major minor rel
local major minor build rel
local old_ifs
case "$ver" in
*-r[0-9]*)
rel="${ver##*-r}"
@@ -115,11 +205,17 @@ function normalize_version
base="$ver"
;;
esac
major="${base%%.*}"
minor="${base#*.}"
[ -z "$minor" ] && minor=0
[ -z "$rel" ] && rel=1
echo "$major.$minor.$rel"
old_ifs="$IFS" ; IFS='.' ; set -- $base ; IFS="$old_ifs"
rel=${rel:-1}
major=${1:-0}
minor=${2:-0}
if [ $ZAPRET_CFG_NAME = "zapret" ]; then
echo "$major.$minor.$rel"
fi
if [ $ZAPRET_CFG_NAME = "zapret2" ]; then
build=${3:-0}
echo "$major.$minor.$build.$rel"
fi
}
function pkg_version_cmp
@@ -137,9 +233,22 @@ function pkg_version_cmp
x2=$( echo "$ver2" | cut -d. -f2 )
[ "$x1" -gt "$x2" ] && { echo -n "G"; return 0; }
[ "$x1" -lt "$x2" ] && { echo -n "L"; return 0; }
if [ $ZAPRET_CFG_NAME = "zapret2" ]; then
# build
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; }
fi
# release
x1=$( echo "$ver1" | cut -d. -f3 )
x2=$( echo "$ver2" | cut -d. -f3 )
if [ $ZAPRET_CFG_NAME = "zapret" ]; then
x1=$( echo "$ver1" | cut -d. -f3 )
x2=$( echo "$ver2" | cut -d. -f3 )
fi
if [ $ZAPRET_CFG_NAME = "zapret2" ]; then
x1=$( echo "$ver1" | cut -d. -f4 )
x2=$( echo "$ver2" | cut -d. -f4 )
fi
[ "$x1" -gt "$x2" ] && { echo -n "G"; return 0; }
[ "$x1" -lt "$x2" ] && { echo -n "L"; return 0; }
echo -n "E"
@@ -147,18 +256,28 @@ function pkg_version_cmp
function download_releases_info
{
local txt txtlen txtlines generated_at
local fname resp hdr txt txtlen txtlines generated_at
REL_JSON=
echo "Download releases info..."
txt=$(download_json $ZAP_REL_URL)
fname="${ZAP_REL_URL##*/}"
resp=$( curl -s -D - --max-time $CURL_TIMEOUT -H "$CURL_HEADER1" -H "$CURL_HEADER2" "$ZAP_REL_URL" 2>/dev/null )
hdr="${resp%%$'\r\n\r\n'*}"
status=$( printf '%s\n' "$hdr" | head -n 1 | awk '{print $2}' )
if [ "$status" != 200 ]; then
echo "ERROR: Cannot download file \"$ZAP_REL_URL\" (status = $status)"
return 103
fi
txtlen=$( printf '%s\n' "$hdr" | awk -F': ' 'BEGIN{IGNORECASE=1} $1=="Content-Length"{print $2}' | tr -d '\r' )
echo "Content-Length: $txtlen bytes"
txt="${resp#*$'\r\n\r\n'}"
txtlen=${#txt}
txtlines=$(printf '%s\n' "$txt" | wc -l)
if [[ $txtlen -lt 64 ]]; then
echo "ERROR: Cannot download releases info!"
echo "ERROR: Cannot download releases info! (size = $txtlen)"
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)
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
@@ -221,8 +340,8 @@ function get_actual_release
return 0
done
json_cleanup
echo "ERROR: latest release for arch \"$ZAP_CPU_ARCH\" not founded!"
return 1 # release not founded
echo "ERROR: latest release for arch \"$ZAP_CPU_ARCH\" not found!"
return 150 # release not found
}
# -------------------------------------------------------------------------------------------------------
@@ -238,11 +357,16 @@ 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)
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!"
if [ "$opt_forced" = true ]; then
curl_install
fi
fi
if ! command -v curl >/dev/null 2>&1; then
echo "ERROR: Required package \"curl\" not installed!"
return 10
fi
CURL_INFO=$( curl -V )
@@ -264,6 +388,11 @@ if [ "$opt_check" = "true" ]; then
fi
get_actual_release
ZAP_ERR=$?
if [ $ZAP_ERR = 150 ] && [ "$opt_prerelease" != true ] && [ "$opt_forced" = true ]; then
opt_prerelease="true"
get_actual_release
ZAP_ERR=$?
fi
if [ $ZAP_ERR -ne 0 ]; then
echo "ERROR: Func get_actual_release return error code: $ZAP_ERR"
return $ZAP_ERR
@@ -279,13 +408,13 @@ ZAP_PKG_FN=
ZAP_PKG_BASE_FN=
ZAP_PKG_LUCI_FN=
ZAP_CUR_PKG_VER=$( get_pkg_version zapret )
ZAP_CUR_PKG_VER=$( get_pkg_version $ZAPRET_CFG_NAME )
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!"
echo "ERROR: actual release not found!"
return 199
fi
else
@@ -294,7 +423,7 @@ else
ZAP_PKG_URL="$REL_ACTUAL_URL"
fi
if [ "$opt_update" = "@" -a "$ZAP_PKG_URL" = "" ]; then
echo "ERROR: actual release not founded!"
echo "ERROR: actual release not found!"
return 199
fi
fi
@@ -334,8 +463,8 @@ if [ "$opt_update" != "" ]; then
return 0
fi
fi
ZAP_PKG_DIR=/tmp/zapret_pkg
rm -rf $ZAP_PKG_DIR
ZAP_PKG_DIR=/tmp/$ZAPRET_CFG_NAME-pkg
rm -rf $ZAP_PKG_DIR 2>/dev/null
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"
@@ -357,37 +486,57 @@ if [ "$opt_update" != "" ]; then
return 216
fi
if ! command -v unzip >/dev/null 2>&1; then
echo "ERROR: package \"upzip\" not installed!"
if [ "$opt_forced" = true ]; then
unzip_install
fi
fi
if ! command -v unzip >/dev/null 2>&1; then
echo "ERROR: package \"unzip\" not installed!"
return 218
fi
unzip -q "$ZAP_PKG_FN" -d $ZAP_PKG_DIR
rm -f "$ZAP_PKG_FN"
rm -f "$ZAP_PKG_FN" 2>/dev/null
if [ "$PKG_MGR" = "apk" ]; then
if [ ! -d "$ZAP_PKG_DIR/apk" ]; then
echo "ERROR: APK-files not founded"
echo "ERROR: APK-files not found"
return 221
fi
rm -f "$ZAP_PKG_DIR/*.ipk"
mv "$ZAP_PKG_DIR/apk/*" "$ZAP_PKG_DIR/"
rm -f $ZAP_PKG_DIR/*.ipk 2>/dev/null
mv $ZAP_PKG_DIR/apk/* $ZAP_PKG_DIR/
else
rm -rf "$ZAP_PKG_DIR/apk"
rm -rf $ZAP_PKG_DIR/apk 2>/dev/null
fi
ZAP_PKG_LIST=$( ls -1 "$ZAP_PKG_DIR" )
echo "------ Downloaded packages:"
echo "$ZAP_PKG_LIST"
echo "------"
ZAP_PKG_BASE_FN=$( find "$ZAP_PKG_DIR" -maxdepth 1 -type f -name "zapret_*.${ZAP_PKG_EXT}" | head -n 1 )
ZAP_PKG_LUCI_FN=$( find "$ZAP_PKG_DIR" -maxdepth 1 -type f -name "luci-app-*.${ZAP_PKG_EXT}" | head -n 1 )
if [ "$PKG_MGR" != "apk" ]; then
ZAP_PKG_BASE_FN=$( find "$ZAP_PKG_DIR" -maxdepth 1 -type f -name "${ZAPRET_CFG_NAME}_*.${ZAP_PKG_EXT}" | head -n 1 )
else
ZAP_PKG_BASE_FN=$( find "$ZAP_PKG_DIR" -maxdepth 1 -type f -name "${ZAPRET_CFG_NAME}-[0-9]*.?*.${ZAP_PKG_EXT}" | head -n 1 )
fi
ZAP_PKG_LUCI_FN=$( find "$ZAP_PKG_DIR" -maxdepth 1 -type f -name "luci-app-${ZAPRET_CFG_NAME}*.${ZAP_PKG_EXT}" | head -n 1 )
if [ ! -f "$ZAP_PKG_BASE_FN" ]; then
echo "ERROR: File \"zapret_*.${ZAP_PKG_EXT}\" not found!"
echo "ERROR: File \"${ZAPRET_CFG_NAME}*.${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-*.${ZAP_PKG_EXT}\" not found!"
echo "ERROR: File \"luci-app-${ZAPRET_CFG_NAME}*.${ZAP_PKG_EXT}\" not found!"
return 232
fi
echo "ZAP_PKG_LUCI_FN = $ZAP_PKG_LUCI_FN"
if [ "$opt_forced" = true ]; then
pkg_mgr_update
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..."
if [ "$PKG_MGR" != "apk" ]; then
opkg install --force-reinstall "$ZAP_PKG_BASE_FN"