mirror of
https://github.com/egor-white/zaprett.git
synced 2025-12-10 05:19:42 +05:00
Compare commits
32 Commits
8542d33af2
...
a581e02ccd
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a581e02ccd | ||
|
|
2e7b943712 | ||
|
|
4f6a80a8ee | ||
|
|
8caa7ff696 | ||
|
|
ef58166767 | ||
|
|
89ecb5e7fe | ||
|
|
26cb5ca046 | ||
|
|
4370ff8867 | ||
|
|
eafb226036 | ||
|
|
0316a4b004 | ||
|
|
3d78a3d0a4 | ||
|
|
d11eb93be6 | ||
|
|
490c8fa685 | ||
|
|
1128168924 | ||
|
|
1b7448afa3 | ||
|
|
636cd47ffa | ||
|
|
ceb27e1ee8 | ||
|
|
fc431f8e88 | ||
|
|
8a3df7b253 | ||
|
|
bb1fe1bc32 | ||
|
|
f5cee6df60 | ||
|
|
930eaf48d2 | ||
|
|
515c946f13 | ||
|
|
bf76e162ee | ||
|
|
2790c8ed62 | ||
|
|
2e9e08fb96 | ||
|
|
17d5e7a8f0 | ||
|
|
aecde98d0d | ||
|
|
d5267997a3 | ||
|
|
57382991ad | ||
|
|
12ceb7a7d1 | ||
|
|
f37c14ef0a |
70
.github/workflows/workflow_without_post.yml
vendored
70
.github/workflows/workflow_without_post.yml
vendored
@@ -1,12 +1,20 @@
|
||||
name: Build module (Without telegram post)
|
||||
name: Build module
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
create_release:
|
||||
description: 'Create GitHub release?'
|
||||
required: false
|
||||
default: 'false'
|
||||
tag:
|
||||
description: "Tag for the release (x.x.x)"
|
||||
required: true
|
||||
type: string
|
||||
zapret-version:
|
||||
description: "Zapret version (x.x)"
|
||||
required: true
|
||||
type: string
|
||||
version:
|
||||
description: "Module version (x.x)"
|
||||
required: true
|
||||
@@ -27,41 +35,31 @@ on:
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
env:
|
||||
ZAPRET_VERSION: ${{ inputs.zapret-version }}
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Setup Git submodules
|
||||
run: git submodule update --init --recursive
|
||||
|
||||
- name: Install dependencies
|
||||
run: sudo apt install build-essential pkg-config just unzip
|
||||
|
||||
- name: Build zaprett
|
||||
run: just -f rust/justfile build-android --release
|
||||
|
||||
- name: Make build dirs
|
||||
run: mkdir -p zaprett/system/bin zaprett-hosts/system/bin zaprett-tv/system/bin zaprett/system/etc/zaprett/lists zapret-latest out lists zapret-hosts/system/etc/zaprett/lists zapret-tv/system/etc/zaprett/lists
|
||||
|
||||
- name: Download latest zapret binaries
|
||||
run: |
|
||||
LATEST_RELEASE=$(curl -s https://api.github.com/repos/bol-van/zapret/releases/latest)
|
||||
DOWNLOAD_URL=$(echo "$LATEST_RELEASE" | grep -o 'browser_download_url.*zapret-v.*\.zip"' | cut -d'"' -f3)
|
||||
wget $DOWNLOAD_URL -O zapret-latest.zip
|
||||
|
||||
- name: Unzip zapret binaries
|
||||
run: |
|
||||
unzip -o zapret-latest.zip
|
||||
ZAPRET_DIR=$(find . -maxdepth 1 -type d -name 'zapret-v*' | head -n 1)
|
||||
if [ "$(ls -A "$ZAPRET_DIR")" ]; then
|
||||
mv "$ZAPRET_DIR"/* zapret-latest/
|
||||
else
|
||||
echo "Warning: $ZAPRET_DIR is empty"
|
||||
fi
|
||||
rm -rf "${ZAPRET_DIR}"
|
||||
rm zapret-latest.zip
|
||||
|
||||
- name: Copy files to dirs
|
||||
run: |
|
||||
#copy nfqws and zaprett
|
||||
cp zapret-latest/binaries/android-arm/nfqws zaprett/system/bin/nfqws_arm32
|
||||
cp zapret-latest/binaries/android-arm64/nfqws zaprett/system/bin/nfqws_arm64
|
||||
cp zapret-latest/binaries/android-x86/nfqws zaprett/system/bin/nfqws_x86
|
||||
cp zapret-latest/binaries/android-x86_64/nfqws zaprett/system/bin/nfqws_x86_64
|
||||
cp zapret-latest/binaries/linux-mips/nfqws zaprett/system/bin/nfqws_mips
|
||||
cp zapret-latest/binaries/linux-mipsel/nfqws zaprett/system/bin/nfqws_mipsel
|
||||
cp rust/target/armv7-linux-androideabi/release/zaprett zaprett/system/bin/zaprett-armv7
|
||||
cp rust/target/aarch64-linux-android/release/zaprett zaprett/system/bin/zaprett-aarch64
|
||||
cp rust/target/x86_64-linux-android/release/zaprett zaprett/system/bin/zaprett-x86_64
|
||||
|
||||
cp -a src-module/* zaprett/
|
||||
cp -a src/* zaprett/
|
||||
|
||||
#copy all files to another distributions
|
||||
cp -r zaprett/* zaprett-hosts/
|
||||
@@ -124,8 +122,9 @@ jobs:
|
||||
mv zaprett.zip out/
|
||||
mv zaprett-hosts.zip out/
|
||||
mv zaprett-tv.zip out/
|
||||
|
||||
|
||||
- name: Create release
|
||||
if: ${{ inputs.create_release == 'true' }}
|
||||
uses: softprops/action-gh-release@v2
|
||||
with:
|
||||
tag_name: ${{ inputs.tag }}
|
||||
@@ -134,10 +133,22 @@ jobs:
|
||||
files: out/*
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Upload artifact
|
||||
if: ${{ inputs.create_release != 'true' }}
|
||||
uses: actions/upload-artifact@v5.0.0
|
||||
with:
|
||||
name: zaprett
|
||||
path: out/*
|
||||
|
||||
|
||||
|
||||
- name: Update changelog
|
||||
run: echo "${{ inputs.release_changes}}" > changelog.md
|
||||
if: ${{ inputs.create_release == 'true' }}
|
||||
run: echo "${{ inputs.release_changes }}" > changelog.md
|
||||
|
||||
- name: Update update.json
|
||||
if: ${{ inputs.create_release == 'true' }}
|
||||
run: |
|
||||
cat > update.json <<EOF
|
||||
{
|
||||
@@ -163,8 +174,11 @@ jobs:
|
||||
"changelog": "https://raw.githubusercontent.com/${{ github.repository }}/refs/heads/main/changelog.md"
|
||||
}
|
||||
EOF
|
||||
|
||||
- name: Commit jsons and changelog
|
||||
if: ${{ inputs.create_release == 'true' }}
|
||||
uses: stefanzweifel/git-auto-commit-action@v5
|
||||
with:
|
||||
commit_message: "Update update's.json and changelog"
|
||||
file_pattern: "update.json update_hosts.json update_tv.json changelog.md"
|
||||
|
||||
|
||||
9
.gitmodules
vendored
9
.gitmodules
vendored
@@ -1,12 +1,3 @@
|
||||
[submodule "rust/libs/zapret"]
|
||||
path = rust/libs/zapret
|
||||
url = https://github.com/bol-van/zapret.git
|
||||
[submodule "rust/crates/libnfqws/libs/zapret"]
|
||||
path = rust/crates/libnfqws/libs/zapret
|
||||
url = https://github.com/bol-van/zapret.git
|
||||
[submodule "rust/crates/libnfqws/zapret"]
|
||||
path = rust/crates/libnfqws/zapret
|
||||
url = https://github.com/bol-van/zapret.git
|
||||
[submodule "rust/crates/iptables"]
|
||||
path = rust/crates/iptables
|
||||
url = https://github.com/yaa110/rust-iptables
|
||||
|
||||
@@ -1 +1 @@
|
||||
Список изменений: ● Обновление бинарников zapret до версии 72.1 ● Добавлена поддержка ipset ● Исправление автозапуска
|
||||
1
|
||||
|
||||
220
rust/Cargo.lock
generated
220
rust/Cargo.lock
generated
@@ -285,6 +285,18 @@ dependencies = [
|
||||
"wasi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "getset"
|
||||
version = "0.1.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9cf0fc11e47561d47397154977bc219f4cf809b2974facc3ccb3b89e2436f912"
|
||||
dependencies = [
|
||||
"proc-macro-error2",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "glob"
|
||||
version = "0.3.3"
|
||||
@@ -318,6 +330,7 @@ checksum = "135b12329e5e3ce057a9f972339ea52bc954fe1e9358ef27f95e89716fbc5424"
|
||||
[[package]]
|
||||
name = "iptables"
|
||||
version = "0.6.0"
|
||||
source = "git+https://github.com/sqlerrorthing/rust-iptables.git?branch=feat%2Fadd-android#c56ec40f30d61becc66024061d2461851acf5d19"
|
||||
dependencies = [
|
||||
"lazy_static",
|
||||
"regex",
|
||||
@@ -374,7 +387,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d7c4b02199fee7c5d21a5ae7d8cfa79a6ef5bb2fc834d6e9058e89c825efdc55"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"windows-link",
|
||||
"windows-link 0.2.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -447,6 +460,34 @@ dependencies = [
|
||||
"minimal-lexical",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ntapi"
|
||||
version = "0.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e8a3895c6391c39d7fe7ebc444a87eb2991b2a0bc718fdabd071eec617fc68e4"
|
||||
dependencies = [
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "objc2-core-foundation"
|
||||
version = "0.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2a180dd8642fa45cdb7dd721cd4c11b1cadd4929ce112ebd8b9f5803cc79d536"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "objc2-io-kit"
|
||||
version = "0.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "33fafba39597d6dc1fb709123dfa8289d39406734be322956a69f0931c73bb15"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"objc2-core-foundation",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "once_cell"
|
||||
version = "1.21.3"
|
||||
@@ -489,7 +530,7 @@ dependencies = [
|
||||
"libc",
|
||||
"redox_syscall",
|
||||
"smallvec",
|
||||
"windows-link",
|
||||
"windows-link 0.2.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -518,6 +559,28 @@ dependencies = [
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro-error-attr2"
|
||||
version = "2.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "96de42df36bb9bba5542fe9f1a054b8cc87e172759a1868aa05c1f3acc89dfc5"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro-error2"
|
||||
version = "2.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "11ec05c52be0a07b08061f7dd003e7d7092e0472bc731b4af7bb1ef876109802"
|
||||
dependencies = [
|
||||
"proc-macro-error-attr2",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.103"
|
||||
@@ -716,6 +779,20 @@ dependencies = [
|
||||
"walkdir",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sysinfo"
|
||||
version = "0.37.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "16607d5caffd1c07ce073528f9ed972d88db15dd44023fa57142963be3feb11f"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"memchr",
|
||||
"ntapi",
|
||||
"objc2-core-foundation",
|
||||
"objc2-io-kit",
|
||||
"windows",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "termcolor"
|
||||
version = "1.4.1"
|
||||
@@ -810,6 +887,22 @@ version = "0.11.1+wasi-snapshot-preview1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b"
|
||||
|
||||
[[package]]
|
||||
name = "winapi"
|
||||
version = "0.3.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
|
||||
dependencies = [
|
||||
"winapi-i686-pc-windows-gnu",
|
||||
"winapi-x86_64-pc-windows-gnu",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "winapi-i686-pc-windows-gnu"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
|
||||
|
||||
[[package]]
|
||||
name = "winapi-util"
|
||||
version = "0.1.11"
|
||||
@@ -819,12 +912,120 @@ dependencies = [
|
||||
"windows-sys 0.61.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "winapi-x86_64-pc-windows-gnu"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
|
||||
|
||||
[[package]]
|
||||
name = "windows"
|
||||
version = "0.61.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9babd3a767a4c1aef6900409f85f5d53ce2544ccdfaa86dad48c91782c6d6893"
|
||||
dependencies = [
|
||||
"windows-collections",
|
||||
"windows-core",
|
||||
"windows-future",
|
||||
"windows-link 0.1.3",
|
||||
"windows-numerics",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-collections"
|
||||
version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3beeceb5e5cfd9eb1d76b381630e82c4241ccd0d27f1a39ed41b2760b255c5e8"
|
||||
dependencies = [
|
||||
"windows-core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-core"
|
||||
version = "0.61.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c0fdd3ddb90610c7638aa2b3a3ab2904fb9e5cdbecc643ddb3647212781c4ae3"
|
||||
dependencies = [
|
||||
"windows-implement",
|
||||
"windows-interface",
|
||||
"windows-link 0.1.3",
|
||||
"windows-result",
|
||||
"windows-strings",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-future"
|
||||
version = "0.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fc6a41e98427b19fe4b73c550f060b59fa592d7d686537eebf9385621bfbad8e"
|
||||
dependencies = [
|
||||
"windows-core",
|
||||
"windows-link 0.1.3",
|
||||
"windows-threading",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-implement"
|
||||
version = "0.60.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "053e2e040ab57b9dc951b72c264860db7eb3b0200ba345b4e4c3b14f67855ddf"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-interface"
|
||||
version = "0.59.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3f316c4a2570ba26bbec722032c4099d8c8bc095efccdc15688708623367e358"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-link"
|
||||
version = "0.1.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5e6ad25900d524eaabdbbb96d20b4311e1e7ae1699af4fb28c17ae66c80d798a"
|
||||
|
||||
[[package]]
|
||||
name = "windows-link"
|
||||
version = "0.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5"
|
||||
|
||||
[[package]]
|
||||
name = "windows-numerics"
|
||||
version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9150af68066c4c5c07ddc0ce30421554771e528bde427614c61038bc2c92c2b1"
|
||||
dependencies = [
|
||||
"windows-core",
|
||||
"windows-link 0.1.3",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-result"
|
||||
version = "0.3.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "56f42bd332cc6c8eac5af113fc0c1fd6a8fd2aa08a0119358686e5160d0586c6"
|
||||
dependencies = [
|
||||
"windows-link 0.1.3",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-strings"
|
||||
version = "0.4.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "56e6c93f3a0c3b36176cb1327a4958a0353d5d166c2a35cb268ace15e91d3b57"
|
||||
dependencies = [
|
||||
"windows-link 0.1.3",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-sys"
|
||||
version = "0.60.2"
|
||||
@@ -840,7 +1041,7 @@ version = "0.61.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fc"
|
||||
dependencies = [
|
||||
"windows-link",
|
||||
"windows-link 0.2.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -849,7 +1050,7 @@ version = "0.53.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4945f9f551b88e0d65f3db0bc25c33b8acea4d9e41163edf90dcd0b19f9069f3"
|
||||
dependencies = [
|
||||
"windows-link",
|
||||
"windows-link 0.2.1",
|
||||
"windows_aarch64_gnullvm",
|
||||
"windows_aarch64_msvc",
|
||||
"windows_i686_gnu",
|
||||
@@ -860,6 +1061,15 @@ dependencies = [
|
||||
"windows_x86_64_msvc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-threading"
|
||||
version = "0.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b66463ad2e0ea3bbf808b7f1d371311c80e115c0b71d60efc142cafbcfb057a6"
|
||||
dependencies = [
|
||||
"windows-link 0.1.3",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_gnullvm"
|
||||
version = "0.53.1"
|
||||
@@ -915,6 +1125,7 @@ dependencies = [
|
||||
"anyhow",
|
||||
"clap",
|
||||
"daemonize",
|
||||
"getset",
|
||||
"iptables",
|
||||
"libc",
|
||||
"libnfqws",
|
||||
@@ -926,5 +1137,6 @@ dependencies = [
|
||||
"serde",
|
||||
"serde_json",
|
||||
"sysctl",
|
||||
"sysinfo",
|
||||
"tokio",
|
||||
]
|
||||
|
||||
@@ -22,3 +22,6 @@ daemonize = "0.5.0"
|
||||
log = "0.4.28"
|
||||
pretty_env_logger = "0.5.0"
|
||||
nix = { version = "0.30.1", features = ["signal"] }
|
||||
iptables = { git = "https://github.com/sqlerrorthing/rust-iptables.git", branch = "feat/add-android" }
|
||||
getset = "0.1.6"
|
||||
sysinfo = "0.37.2"
|
||||
|
||||
Submodule rust/crates/iptables deleted from e0e1f5dcc0
@@ -16,12 +16,16 @@ rel_manifest_path!(NFQ_CRYPTO, "zapret/nfq/crypto");
|
||||
|
||||
fn main() {
|
||||
cc::Build::new()
|
||||
.files(glob::glob(&format!("{}/*.c", NFQ.display()))
|
||||
.unwrap()
|
||||
.filter_map(Result::ok))
|
||||
.files(glob::glob(&format!("{}/*.c", NFQ_CRYPTO.display()))
|
||||
.unwrap()
|
||||
.filter_map(Result::ok))
|
||||
.files(
|
||||
glob::glob(&format!("{}/*.c", NFQ.display()))
|
||||
.unwrap()
|
||||
.filter_map(Result::ok),
|
||||
)
|
||||
.files(
|
||||
glob::glob(&format!("{}/*.c", NFQ_CRYPTO.display()))
|
||||
.unwrap()
|
||||
.filter_map(Result::ok),
|
||||
)
|
||||
.include(&*NFQ)
|
||||
.include(&*NFQ_CRYPTO)
|
||||
.flag("-w")
|
||||
@@ -33,9 +37,13 @@ fn main() {
|
||||
println!("cargo:rustc-link-lib=nfnetlink");
|
||||
println!("cargo:rustc-link-lib=mnl");
|
||||
|
||||
let _ = env::var("NETFILTER_LIBS")
|
||||
.map(|libs| println!("cargo:rustc-link-search=native={libs}/lib"));
|
||||
|
||||
println!("cargo:rustc-link-lib=static=nfqws");
|
||||
println!("cargo:rerun-if-changed={}", NFQ.display());
|
||||
println!("cargo:rerun-if-changed={}", NFQ_CRYPTO.display());
|
||||
println!("cargo:rerun-if-changed=build.rs");
|
||||
|
||||
let mut builder = bindgen::Builder::default();
|
||||
|
||||
|
||||
@@ -7,7 +7,6 @@ repository.workspace = true
|
||||
[dependencies]
|
||||
anyhow = { workspace = true }
|
||||
clap = { workspace = true }
|
||||
iptables = { path = "../iptables" }
|
||||
libc = { workspace = true }
|
||||
regex = { workspace = true }
|
||||
rust-ini = { workspace = true }
|
||||
@@ -20,3 +19,6 @@ daemonize = { workspace = true }
|
||||
pretty_env_logger = { workspace = true }
|
||||
log = { workspace = true }
|
||||
nix = { workspace = true, features = ["user"] }
|
||||
iptables = { workspace = true }
|
||||
getset = { workspace = true }
|
||||
sysinfo = { workspace = true }
|
||||
|
||||
13
rust/crates/zaprett/src/cli.rs
Normal file
13
rust/crates/zaprett/src/cli.rs
Normal file
@@ -0,0 +1,13 @@
|
||||
pub mod commands;
|
||||
|
||||
use clap::Parser;
|
||||
use getset::Getters;
|
||||
use commands::Command;
|
||||
|
||||
#[derive(Parser, Getters)]
|
||||
#[command(version)]
|
||||
#[getset(get = "pub")]
|
||||
pub struct CliApp {
|
||||
#[command(subcommand)]
|
||||
cmd: Option<Command>,
|
||||
}
|
||||
67
rust/crates/zaprett/src/cli/commands.rs
Normal file
67
rust/crates/zaprett/src/cli/commands.rs
Normal file
@@ -0,0 +1,67 @@
|
||||
use crate::service::{restart_service, service_status, start_service, stop_service};
|
||||
use crate::{bin_version, get_autostart, module_version, set_autostart};
|
||||
use clap::Subcommand;
|
||||
use log::error;
|
||||
|
||||
#[derive(Subcommand)]
|
||||
pub enum Command {
|
||||
/// Start the service
|
||||
Start,
|
||||
|
||||
/// Stop the service
|
||||
Stop,
|
||||
|
||||
/// Restart the service
|
||||
Restart,
|
||||
|
||||
/// Show the current service status
|
||||
Status,
|
||||
|
||||
/// Enable or disable automatic restart
|
||||
SetAutostart {
|
||||
/// Whether to enable (true) or disable (false) autostart
|
||||
#[arg(value_parser = clap::value_parser!(bool))]
|
||||
autostart: bool,
|
||||
},
|
||||
|
||||
/// Show whether autostart is enabled
|
||||
GetAutostart,
|
||||
|
||||
/// Show the module version
|
||||
ModuleVersion,
|
||||
|
||||
/// Show the nfqws binary version
|
||||
BinaryVersion,
|
||||
}
|
||||
|
||||
impl Command {
|
||||
pub async fn exec(&self) -> anyhow::Result<()> {
|
||||
match self {
|
||||
Command::Start => return start_service().await,
|
||||
Command::Stop => {
|
||||
let _ = stop_service().await;
|
||||
}
|
||||
Command::Restart => return restart_service().await,
|
||||
Command::Status => {
|
||||
println!(
|
||||
"zaprett is {}",
|
||||
if service_status().await? {
|
||||
"working"
|
||||
} else {
|
||||
"stopped"
|
||||
}
|
||||
);
|
||||
}
|
||||
Command::SetAutostart { autostart } => {
|
||||
if let Err(err) = set_autostart(autostart).await {
|
||||
error!("Failed to set auto start: {err}")
|
||||
}
|
||||
}
|
||||
Command::GetAutostart => get_autostart(),
|
||||
Command::ModuleVersion => module_version(),
|
||||
Command::BinaryVersion => bin_version(),
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
61
rust/crates/zaprett/src/config.rs
Normal file
61
rust/crates/zaprett/src/config.rs
Normal file
@@ -0,0 +1,61 @@
|
||||
use getset::Getters;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use crate::{merge_files, MODULE_PATH};
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
#[serde(rename_all = "lowercase")]
|
||||
pub enum ListType {
|
||||
Whitelist,
|
||||
Blacklist,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Getters)]
|
||||
#[getset(get = "pub")]
|
||||
pub struct Config {
|
||||
active_lists: Vec<String>,
|
||||
active_ipsets: Vec<String>,
|
||||
active_exclude_lists: Vec<String>,
|
||||
active_exclude_ipsets: Vec<String>,
|
||||
list_type: ListType,
|
||||
strategy: String,
|
||||
app_list: String,
|
||||
whitelist: Vec<String>,
|
||||
blacklist: Vec<String>,
|
||||
}
|
||||
|
||||
impl ListType {
|
||||
/// # Returns
|
||||
///
|
||||
/// (hostlist arg, ipset arg)
|
||||
pub async fn merge(&self, config: &Config) -> (String, String) {
|
||||
let module_path_str = MODULE_PATH.to_str().unwrap();
|
||||
|
||||
let (host_files, ipset_files, host_suffix, ipset_suffix, exclude_flag) = match self {
|
||||
ListType::Whitelist => (
|
||||
&config.active_lists,
|
||||
&config.active_ipsets,
|
||||
"hostlist",
|
||||
"ipset",
|
||||
""
|
||||
),
|
||||
ListType::Blacklist => (
|
||||
&config.active_exclude_lists,
|
||||
&config.active_exclude_ipsets,
|
||||
"hostlist-exclude",
|
||||
"ipset-exclude",
|
||||
"-exclude"
|
||||
),
|
||||
};
|
||||
|
||||
let host_path = MODULE_PATH.join(format!("tmp/{host_suffix}"));
|
||||
let ipset_path = MODULE_PATH.join(format!("tmp/{ipset_suffix}"));
|
||||
|
||||
merge_files(host_files, host_path).await.unwrap();
|
||||
merge_files(ipset_files, ipset_path).await.unwrap();
|
||||
|
||||
(
|
||||
format!("--hostlist{exclude_flag}={module_path_str}/tmp/{host_suffix}"),
|
||||
format!("--ipset{exclude_flag}={module_path_str}/tmp/{ipset_suffix}"),
|
||||
)
|
||||
}
|
||||
}
|
||||
20
rust/crates/zaprett/src/daemon.rs
Normal file
20
rust/crates/zaprett/src/daemon.rs
Normal file
@@ -0,0 +1,20 @@
|
||||
use log::{error, info};
|
||||
use daemonize::Daemonize;
|
||||
use crate::{run_nfqws, MODULE_PATH};
|
||||
|
||||
pub async fn daemonize_nfqws(args: &str) {
|
||||
info!("Starting nfqws as a daemon");
|
||||
let daemonize = Daemonize::new()
|
||||
.pid_file(MODULE_PATH.join("tmp/pid.lock").as_path())
|
||||
.working_directory("/tmp")
|
||||
.group("daemon")
|
||||
.privileged_action(|| "Executed before drop privileges");
|
||||
|
||||
match daemonize.start() {
|
||||
Ok(_) => {
|
||||
info!("Success, daemonized");
|
||||
run_nfqws(args).await.unwrap()
|
||||
}
|
||||
Err(e) => error!("Error while starting nfqws daemon: {e}"),
|
||||
}
|
||||
}
|
||||
51
rust/crates/zaprett/src/iptables_rust.rs
Normal file
51
rust/crates/zaprett/src/iptables_rust.rs
Normal file
@@ -0,0 +1,51 @@
|
||||
use std::error;
|
||||
|
||||
pub fn setup_iptables_rules() -> Result<(), Box<dyn error::Error>> {
|
||||
let ipt = iptables::new(false)?;
|
||||
|
||||
ipt.insert(
|
||||
"mangle",
|
||||
"POSTROUTING",
|
||||
"-j NFQUEUE --queue-num 200 --queue-bypass",
|
||||
1,
|
||||
)?;
|
||||
|
||||
ipt.insert(
|
||||
"mangle",
|
||||
"PREROUTING",
|
||||
"-j NFQUEUE --queue-num 200 --queue-bypass",
|
||||
1,
|
||||
)?;
|
||||
|
||||
ipt.append(
|
||||
"filter",
|
||||
"FORWARD",
|
||||
"-j NFQUEUE --queue-num 200 --queue-bypass",
|
||||
)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn clear_iptables_rules() -> Result<(), Box<dyn error::Error>> {
|
||||
let ipt = iptables::new(false)?;
|
||||
|
||||
ipt.delete(
|
||||
"mangle",
|
||||
"POSTROUTING",
|
||||
"-j NFQUEUE --queue-num 200 --queue-bypass",
|
||||
)?;
|
||||
|
||||
ipt.delete(
|
||||
"mangle",
|
||||
"PREROUTING",
|
||||
"-j NFQUEUE --queue-num 200 --queue-bypass",
|
||||
)?;
|
||||
|
||||
ipt.delete(
|
||||
"filter",
|
||||
"FORWARD",
|
||||
"-j NFQUEUE --queue-num 200 --queue-bypass",
|
||||
)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
116
rust/crates/zaprett/src/lib.rs
Normal file
116
rust/crates/zaprett/src/lib.rs
Normal file
@@ -0,0 +1,116 @@
|
||||
pub mod cli;
|
||||
pub mod config;
|
||||
mod daemon;
|
||||
pub mod iptables_rust;
|
||||
mod service;
|
||||
|
||||
use anyhow::bail;
|
||||
use ini::Ini;
|
||||
use libnfqws::nfqws_main;
|
||||
use std::error;
|
||||
use std::ffi::CString;
|
||||
use std::os::raw::c_char;
|
||||
use std::path::Path;
|
||||
use std::sync::LazyLock;
|
||||
use tokio::fs::File;
|
||||
use tokio::io::{AsyncWriteExt, copy};
|
||||
use tokio::{fs, task};
|
||||
|
||||
pub static MODULE_PATH: LazyLock<&Path> = LazyLock::new(|| Path::new("/data/adb/modules/zaprett"));
|
||||
pub static ZAPRETT_DIR_PATH: LazyLock<&Path> =
|
||||
LazyLock::new(|| Path::new("/storage/emulated/0/zaprett"));
|
||||
|
||||
pub static DEFAULT_START: &str = "
|
||||
--filter-tcp=80 --dpi-desync=fake,split2 --dpi-desync-autottl=2 --dpi-desync-fooling=md5sig,badsum $hostlist --new
|
||||
--filter-tcp=443 $hostlist --dpi-desync=fake,split2 --dpi-desync-repeats=6 --dpi-desync-fooling=md5sig,badsum --dpi-desync-fake-tls=${zaprettdir}/bin/tls_clienthello_www_google_com.bin --new
|
||||
--filter-tcp=80,443 --dpi-desync=fake,disorder2 --dpi-desync-repeats=6 --dpi-desync-autottl=2 --dpi-desync-fooling=md5sig,badsum $hostlist --new
|
||||
--filter-udp=50000-50100 --dpi-desync=fake --dpi-desync-any-protocol --dpi-desync-fake-quic=0xC30000000108 --new
|
||||
--filter-udp=443 $hostlist --dpi-desync=fake --dpi-desync-repeats=6 --dpi-desync-fake-quic=${zaprettdir}/bin/quic_initial_www_google_com.bin --new
|
||||
--filter-udp=443 --dpi-desync=fake --dpi-desync-repeats=6 $hostlist
|
||||
";
|
||||
|
||||
async fn set_autostart(autostart: &bool) -> Result<(), anyhow::Error> {
|
||||
let autostart_path = MODULE_PATH.join("autostart");
|
||||
|
||||
if *autostart {
|
||||
File::create(autostart_path).await?;
|
||||
} else {
|
||||
fs::remove_file(autostart_path).await?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn get_autostart() {
|
||||
let file = MODULE_PATH.join("autostart");
|
||||
println!("{}", file.exists());
|
||||
}
|
||||
|
||||
fn module_version() {
|
||||
if let Ok(prop) = Ini::load_from_file(MODULE_PATH.join("module.prop"))
|
||||
&& let Some(props) = prop.section::<String>(None)
|
||||
&& let Some(version) = props.get("version")
|
||||
{
|
||||
println!("{version}");
|
||||
}
|
||||
}
|
||||
|
||||
fn bin_version() {
|
||||
println!("{}", env!("ZAPRET_VERSION"));
|
||||
}
|
||||
|
||||
pub async fn merge_files(
|
||||
input_paths: &[impl AsRef<Path>],
|
||||
output_path: impl AsRef<Path>,
|
||||
) -> Result<(), Box<dyn error::Error>> {
|
||||
let output_path = output_path.as_ref();
|
||||
let mut output_file = File::create(output_path).await?;
|
||||
|
||||
for input in input_paths {
|
||||
let input_path = input.as_ref();
|
||||
let mut input_file = File::open(input_path)
|
||||
.await
|
||||
.map_err(|e| format!("Failed to open {}: {}", input_path.display(), e))?;
|
||||
|
||||
copy(&mut input_file, &mut output_file).await.map_err(|e| {
|
||||
format!(
|
||||
"Failed to write contents of {}: {}",
|
||||
input_path.display(),
|
||||
e
|
||||
)
|
||||
})?;
|
||||
}
|
||||
|
||||
output_file.flush().await?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn run_nfqws(args_str: &str) -> anyhow::Result<()> {
|
||||
if service::service_status().await? {
|
||||
bail!("nfqws already started!");
|
||||
}
|
||||
|
||||
let mut args = vec!["nfqws".to_string()];
|
||||
|
||||
if args_str.trim().is_empty() {
|
||||
args.push("-v".to_string());
|
||||
} else {
|
||||
args.extend(args_str.split_whitespace().map(String::from));
|
||||
}
|
||||
|
||||
task::spawn_blocking(move || {
|
||||
let c_args: Vec<CString> = args
|
||||
.into_iter()
|
||||
.map(|arg| CString::new(arg).unwrap())
|
||||
.collect();
|
||||
|
||||
let mut ptrs: Vec<*const c_char> = c_args.iter().map(|arg| arg.as_ptr()).collect();
|
||||
|
||||
unsafe {
|
||||
nfqws_main(c_args.len() as libc::c_int, ptrs.as_mut_ptr() as *mut _);
|
||||
}
|
||||
})
|
||||
.await?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
@@ -1,433 +1,15 @@
|
||||
use anyhow::bail;
|
||||
use clap::{ArgAction, Parser, Subcommand, builder::BoolishValueParser};
|
||||
use daemonize::Daemonize;
|
||||
use ini::Ini;
|
||||
use libnfqws::nfqws_main;
|
||||
use log::{error, info};
|
||||
use nix::sys::signal::{Signal, kill};
|
||||
use nix::unistd::{Pid, Uid};
|
||||
use regex::Regex;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::ffi::CString;
|
||||
use std::fs::File;
|
||||
use std::io::BufReader;
|
||||
use std::io::{Read, Write};
|
||||
use std::os::raw::c_char;
|
||||
use std::sync::LazyLock;
|
||||
use std::{fs, path::Path};
|
||||
use sysctl::Sysctl;
|
||||
use tokio::task;
|
||||
|
||||
#[derive(Parser)]
|
||||
#[command(version)]
|
||||
struct Cli {
|
||||
#[command(subcommand)]
|
||||
cmd: Option<Commands>,
|
||||
}
|
||||
|
||||
#[derive(Subcommand)]
|
||||
enum Commands {
|
||||
#[clap(about = "Start service")]
|
||||
Start,
|
||||
|
||||
#[clap(about = "Stop service")]
|
||||
Stop,
|
||||
|
||||
#[clap(about = "Restart service")]
|
||||
Restart,
|
||||
|
||||
#[clap(about = "Show service status")]
|
||||
Status,
|
||||
|
||||
#[clap(about = "Enable/disable autorestart")]
|
||||
SetAutostart {
|
||||
#[arg(
|
||||
value_name = "boolean",
|
||||
action = ArgAction::Set,
|
||||
value_parser = BoolishValueParser::new()
|
||||
)]
|
||||
autostart: bool,
|
||||
},
|
||||
|
||||
#[clap(about = "Get autorestart state")]
|
||||
GetAutostart,
|
||||
|
||||
#[clap(about = "Get module version")]
|
||||
ModuleVer,
|
||||
|
||||
#[clap(about = "Get nfqws binary version")]
|
||||
BinVer,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
struct Config {
|
||||
active_lists: Vec<String>,
|
||||
active_ipsets: Vec<String>,
|
||||
active_exclude_lists: Vec<String>,
|
||||
active_exclude_ipsets: Vec<String>,
|
||||
list_type: String,
|
||||
strategy: String,
|
||||
app_list: String,
|
||||
whitelist: Vec<String>,
|
||||
blacklist: Vec<String>,
|
||||
}
|
||||
|
||||
pub static MODULE_PATH: LazyLock<&Path> = LazyLock::new(|| Path::new("/data/adb/modules/zaprett"));
|
||||
pub static ZAPRETT_DIR_PATH: LazyLock<&Path> =
|
||||
LazyLock::new(|| Path::new("/storage/emulated/0/zaprett"));
|
||||
use clap::Parser;
|
||||
use zaprett::cli::CliApp;
|
||||
|
||||
#[tokio::main]
|
||||
async fn main() -> anyhow::Result<()> {
|
||||
pretty_env_logger::init();
|
||||
|
||||
let cli = Cli::parse();
|
||||
match &cli.cmd {
|
||||
Some(Commands::Start) => start_service().await,
|
||||
Some(Commands::Stop) => {
|
||||
let _ = stop_service().await;
|
||||
Ok(())
|
||||
}
|
||||
Some(Commands::Restart) => {
|
||||
restart_service().await;
|
||||
Ok(())
|
||||
}
|
||||
Some(Commands::Status) => {
|
||||
println!(
|
||||
"zaprett is {}",
|
||||
if service_status() {
|
||||
"working"
|
||||
} else {
|
||||
"stopped"
|
||||
}
|
||||
);
|
||||
Ok(())
|
||||
}
|
||||
Some(Commands::SetAutostart { autostart }) => {
|
||||
set_autostart(autostart);
|
||||
Ok(())
|
||||
}
|
||||
Some(Commands::GetAutostart) => {
|
||||
get_autostart();
|
||||
Ok(())
|
||||
}
|
||||
Some(Commands::ModuleVer) => {
|
||||
module_version();
|
||||
Ok(())
|
||||
}
|
||||
Some(Commands::BinVer) => {
|
||||
bin_version();
|
||||
Ok(())
|
||||
}
|
||||
None => {
|
||||
println!("zaprett installed. Join us: t.me/zaprett_module");
|
||||
Ok(())
|
||||
}
|
||||
let cli = CliApp::parse();
|
||||
match &cli.cmd() {
|
||||
Some(cmd) => cmd.exec().await?,
|
||||
None => println!("zaprett installed. Join us: t.me/zaprett_module"),
|
||||
}
|
||||
}
|
||||
|
||||
async fn daemonize_nfqws(args: &String) {
|
||||
info!("Starting nfqws as a daemon");
|
||||
let daemonize = Daemonize::new()
|
||||
.pid_file(MODULE_PATH.join("tmp/pid.lock").as_path())
|
||||
.working_directory("/tmp")
|
||||
.group("daemon")
|
||||
.privileged_action(|| "Executed before drop privileges");
|
||||
|
||||
match daemonize.start() {
|
||||
Ok(_) => {
|
||||
info!("Success, daemonized");
|
||||
run_nfqws(args).await.unwrap()
|
||||
}
|
||||
Err(e) => error!("Error while starting nfqws daemon: {e}"),
|
||||
}
|
||||
}
|
||||
|
||||
async fn start_service() -> anyhow::Result<()> {
|
||||
if !Uid::effective().is_root() {
|
||||
bail!("Running not from root, exiting");
|
||||
};
|
||||
|
||||
println!("Starting zaprett service...");
|
||||
|
||||
let tmp_dir = MODULE_PATH.join("/tmp");
|
||||
if tmp_dir.exists() {
|
||||
fs::remove_dir_all(&tmp_dir).unwrap();
|
||||
fs::create_dir_all(&tmp_dir).unwrap();
|
||||
}
|
||||
|
||||
let reader = BufReader::new(
|
||||
File::open(ZAPRETT_DIR_PATH.join("config.json")).expect("cannot open config.json"),
|
||||
);
|
||||
let config: Config = serde_json::from_reader(reader).expect("invalid json");
|
||||
|
||||
let list_type: &String = &config.list_type;
|
||||
|
||||
let def_strat: String = String::from("
|
||||
--filter-tcp=80 --dpi-desync=fake,split2 --dpi-desync-autottl=2 --dpi-desync-fooling=md5sig,badsum $hostlist --new
|
||||
--filter-tcp=443 $hostlist --dpi-desync=fake,split2 --dpi-desync-repeats=6 --dpi-desync-fooling=md5sig,badsum --dpi-desync-fake-tls=${zaprettdir}/bin/tls_clienthello_www_google_com.bin --new
|
||||
--filter-tcp=80,443 --dpi-desync=fake,disorder2 --dpi-desync-repeats=6 --dpi-desync-autottl=2 --dpi-desync-fooling=md5sig,badsum $hostlist --new
|
||||
--filter-udp=50000-50100 --dpi-desync=fake --dpi-desync-any-protocol --dpi-desync-fake-quic=0xC30000000108 --new
|
||||
--filter-udp=443 $hostlist --dpi-desync=fake --dpi-desync-repeats=6 --dpi-desync-fake-quic=${zaprettdir}/bin/quic_initial_www_google_com.bin --new
|
||||
--filter-udp=443 --dpi-desync=fake --dpi-desync-repeats=6 $hostlist
|
||||
");
|
||||
let strat = if Path::new(&config.strategy).exists() {
|
||||
fs::read_to_string(&config.strategy).unwrap_or_else(|_| def_strat)
|
||||
} else {
|
||||
def_strat
|
||||
};
|
||||
|
||||
let regex_hostlist = Regex::new(r"\$hostlist").unwrap();
|
||||
let regex_ipsets = Regex::new(r"\$ipset").unwrap();
|
||||
let regex_zaprettdir = Regex::new(r"\$\{?zaprettdir\}?").unwrap();
|
||||
|
||||
let mut strat_modified;
|
||||
|
||||
if list_type.eq("whitelist") {
|
||||
merge_files(
|
||||
config.active_lists,
|
||||
MODULE_PATH.join("tmp/hostlist").as_path(),
|
||||
)
|
||||
.unwrap();
|
||||
merge_files(
|
||||
config.active_ipsets,
|
||||
MODULE_PATH.join("tmp/ipset").as_path(),
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
let hosts = String::from(format!(
|
||||
"--hostlist={}/tmp/hostlist",
|
||||
MODULE_PATH.to_str().unwrap()
|
||||
));
|
||||
let ipsets = String::from(format!(
|
||||
"--ipset={}tmp/ipset",
|
||||
MODULE_PATH.to_str().unwrap()
|
||||
));
|
||||
|
||||
strat_modified = regex_hostlist.replace_all(&strat, &hosts).into_owned();
|
||||
strat_modified = regex_ipsets
|
||||
.replace_all(&strat_modified, &ipsets)
|
||||
.into_owned();
|
||||
strat_modified = regex_zaprettdir
|
||||
.replace_all(&strat_modified, &*ZAPRETT_DIR_PATH.to_str().unwrap())
|
||||
.into_owned();
|
||||
} else if list_type.eq("blacklist") {
|
||||
merge_files(
|
||||
config.active_exclude_lists,
|
||||
MODULE_PATH.join("tmp/hostlist-exclude").as_path(),
|
||||
)
|
||||
.unwrap();
|
||||
merge_files(
|
||||
config.active_exclude_ipsets,
|
||||
MODULE_PATH.join("tmp/ipset-exclude").as_path(),
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
let hosts = String::from(format!(
|
||||
"--hostlist-exclude={}/tmp/hostlist-exclude",
|
||||
MODULE_PATH.to_str().unwrap()
|
||||
));
|
||||
let ipsets = String::from(format!(
|
||||
"--ipset-exclude={}/tmp/ipset-exclude",
|
||||
MODULE_PATH.to_str().unwrap()
|
||||
));
|
||||
|
||||
strat_modified = regex_hostlist.replace_all(&strat, &hosts).into_owned();
|
||||
strat_modified = regex_ipsets
|
||||
.replace_all(&strat_modified, &ipsets)
|
||||
.into_owned();
|
||||
strat_modified = regex_zaprettdir
|
||||
.replace_all(&strat_modified, &*ZAPRETT_DIR_PATH.to_str().unwrap())
|
||||
.into_owned();
|
||||
} else {
|
||||
panic!("no list-type called {}", &list_type)
|
||||
}
|
||||
|
||||
let ctl = sysctl::Ctl::new("net.netfilter.nf_conntrack_tcp_be_liberal").unwrap();
|
||||
ctl.set_value(sysctl::CtlValue::String("1".into())).unwrap();
|
||||
|
||||
setup_iptables_rules();
|
||||
daemonize_nfqws(&strat_modified).await;
|
||||
println!("zaprett service started!");
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn stop_service() -> anyhow::Result<()> {
|
||||
if !Uid::effective().is_root() {
|
||||
bail!("Running not from root, exiting");
|
||||
};
|
||||
|
||||
clear_iptables_rules();
|
||||
|
||||
let pid_str = fs::read_to_string(MODULE_PATH.join("tmp/pid.lock").as_path())?;
|
||||
let pid = pid_str.trim().parse::<i32>()?;
|
||||
|
||||
kill(Pid::from_raw(pid), Signal::SIGKILL).unwrap();
|
||||
|
||||
/*for proc in all_processes().unwrap() {
|
||||
if let Ok(p) = proc {
|
||||
if let Ok(stat) = p.stat() {
|
||||
if stat.comm == "zaprett" {
|
||||
let pid = Pid::from_raw(p.pid as i32);
|
||||
if let Err(_) = kill(pid, Signal::SIGTERM) {
|
||||
println!("failed to stop zaprett service")
|
||||
} else {
|
||||
println!("zaprett service stopped!")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}*/
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn restart_service() {
|
||||
stop_service().await.unwrap();
|
||||
start_service().await.unwrap();
|
||||
println!("zaprett service restarted!")
|
||||
}
|
||||
|
||||
fn set_autostart(autostart: &bool) {
|
||||
if *autostart {
|
||||
if let Err(e) = std::fs::File::create(MODULE_PATH.join("autostart")) {
|
||||
eprintln!("autostart: cannot create flag file: {e}");
|
||||
}
|
||||
} else {
|
||||
fs::remove_file(MODULE_PATH.join("autostart")).unwrap()
|
||||
}
|
||||
}
|
||||
|
||||
fn get_autostart() {
|
||||
let file = MODULE_PATH.join("autostart");
|
||||
println!("{}", file.exists());
|
||||
}
|
||||
|
||||
fn service_status() -> bool {
|
||||
let pid_str = match fs::read_to_string(MODULE_PATH.join("tmp/pid.lock")) {
|
||||
Ok(s) => s,
|
||||
Err(_) => return false,
|
||||
};
|
||||
let pid = match pid_str.trim().parse::<i32>() {
|
||||
Ok(p) => p,
|
||||
Err(_) => return false,
|
||||
};
|
||||
return true
|
||||
/*match all_processes() {
|
||||
Ok(iter) => iter
|
||||
.filter_map(|rp| rp.ok())
|
||||
.filter_map(|p| p.stat().ok())
|
||||
.any(|st| st.pid == pid),
|
||||
Err(_) => false,
|
||||
}*/
|
||||
}
|
||||
|
||||
fn module_version() {
|
||||
if let Ok(prop) = Ini::load_from_file(MODULE_PATH.join("module.prop")) {
|
||||
if let Some(props) = prop.section::<String>(None) {
|
||||
if let Some(v) = props.get("version") {
|
||||
println!("{}", v);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn bin_version() {
|
||||
println!("{}", env!("ZAPRET_VERSION"));
|
||||
}
|
||||
fn merge_files(
|
||||
input_paths: Vec<String>,
|
||||
output_path: &Path,
|
||||
) -> Result<(), Box<dyn std::error::Error>> {
|
||||
let mut combined_content = String::new();
|
||||
|
||||
for path_str in input_paths {
|
||||
let path = Path::new(&path_str);
|
||||
let mut file = File::open(path)?;
|
||||
let mut content = String::new();
|
||||
file.read_to_string(&mut content)?;
|
||||
combined_content.push_str(&content);
|
||||
}
|
||||
|
||||
let mut output_file = File::create(output_path)?;
|
||||
output_file.write_all(combined_content.as_bytes())?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn setup_iptables_rules() {
|
||||
let ipt = iptables::new(false).unwrap();
|
||||
|
||||
ipt.insert(
|
||||
"mangle",
|
||||
"POSTROUTING",
|
||||
"-j NFQUEUE --queue-num 200 --queue-bypass",
|
||||
1,
|
||||
)
|
||||
.unwrap();
|
||||
ipt.insert(
|
||||
"mangle",
|
||||
"PREROUTING",
|
||||
"-j NFQUEUE --queue-num 200 --queue-bypass",
|
||||
1,
|
||||
)
|
||||
.unwrap();
|
||||
ipt.append(
|
||||
"filter",
|
||||
"FORWARD",
|
||||
"-j NFQUEUE --queue-num 200 --queue-bypass",
|
||||
)
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
fn clear_iptables_rules() {
|
||||
let ipt = iptables::new(false).unwrap();
|
||||
|
||||
ipt.delete(
|
||||
"mangle",
|
||||
"POSTROUTING",
|
||||
"-j NFQUEUE --queue-num 200 --queue-bypass",
|
||||
)
|
||||
.unwrap();
|
||||
ipt.delete(
|
||||
"mangle",
|
||||
"PREROUTING",
|
||||
"-j NFQUEUE --queue-num 200 --queue-bypass",
|
||||
)
|
||||
.unwrap();
|
||||
ipt.delete(
|
||||
"filter",
|
||||
"FORWARD",
|
||||
"-j NFQUEUE --queue-num 200 --queue-bypass",
|
||||
)
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
async fn run_nfqws(args_str: &String) -> anyhow::Result<()> {
|
||||
if service_status() {
|
||||
bail!("nfqws already started!");
|
||||
}
|
||||
|
||||
let mut args = vec!["nfqws".to_string()];
|
||||
|
||||
if args_str.trim().is_empty() {
|
||||
args.push("-v".to_string());
|
||||
} else {
|
||||
args.extend(args_str.trim().split_whitespace().map(String::from));
|
||||
}
|
||||
|
||||
// fire-and-forget
|
||||
let _ = task::spawn_blocking(move || {
|
||||
let c_args: Vec<CString> = args
|
||||
.into_iter()
|
||||
.map(|arg| CString::new(arg).unwrap())
|
||||
.collect();
|
||||
|
||||
let mut ptrs: Vec<*const c_char> = c_args.iter().map(|arg| arg.as_ptr()).collect();
|
||||
|
||||
unsafe {
|
||||
nfqws_main(c_args.len() as libc::c_int, ptrs.as_mut_ptr() as *mut _);
|
||||
}
|
||||
})
|
||||
.await?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
116
rust/crates/zaprett/src/service.rs
Normal file
116
rust/crates/zaprett/src/service.rs
Normal file
@@ -0,0 +1,116 @@
|
||||
use crate::config::Config;
|
||||
use crate::daemon::daemonize_nfqws;
|
||||
use crate::iptables_rust::{clear_iptables_rules, setup_iptables_rules};
|
||||
use crate::{DEFAULT_START, MODULE_PATH, ZAPRETT_DIR_PATH};
|
||||
use anyhow::bail;
|
||||
use log::info;
|
||||
use nix::sys::signal::{Signal, kill};
|
||||
use nix::unistd::{Pid, Uid};
|
||||
use regex::Regex;
|
||||
use std::borrow::Cow;
|
||||
use std::path::Path;
|
||||
use sysctl::Sysctl;
|
||||
use sysinfo::{Pid as SysPid, System};
|
||||
use tokio::fs;
|
||||
use tokio::fs::File;
|
||||
use tokio::io::AsyncReadExt;
|
||||
|
||||
pub async fn start_service() -> anyhow::Result<()> {
|
||||
if !Uid::effective().is_root() {
|
||||
bail!("Running not from root, exiting");
|
||||
};
|
||||
|
||||
println!("Starting zaprett service...");
|
||||
|
||||
let tmp_dir = MODULE_PATH.join("tmp");
|
||||
if tmp_dir.exists() {
|
||||
fs::remove_dir_all(&tmp_dir).await?;
|
||||
fs::create_dir_all(&tmp_dir).await?;
|
||||
}
|
||||
|
||||
let mut config_contents = String::new();
|
||||
File::open(ZAPRETT_DIR_PATH.join("config.json"))
|
||||
.await
|
||||
.expect("cannot open config.json")
|
||||
.read_to_string(&mut config_contents)
|
||||
.await?;
|
||||
|
||||
let config: Config = serde_json::from_str(&config_contents).expect("invalid json");
|
||||
|
||||
let start = fs::read_to_string(config.strategy())
|
||||
.await
|
||||
.map(Cow::Owned)
|
||||
.unwrap_or(Cow::Borrowed(DEFAULT_START));
|
||||
|
||||
let regex_hostlist = Regex::new(r"\$hostlist")?;
|
||||
let regex_ipsets = Regex::new(r"\$ipset")?;
|
||||
let regex_zaprettdir = Regex::new(r"\$\{?zaprettdir}?")?;
|
||||
|
||||
let mut strat_modified;
|
||||
let (hosts, ipsets) = config.list_type().merge(&config).await;
|
||||
|
||||
strat_modified = regex_hostlist.replace_all(&start, &hosts).into_owned();
|
||||
strat_modified = regex_ipsets
|
||||
.replace_all(&strat_modified, &ipsets)
|
||||
.into_owned();
|
||||
|
||||
strat_modified = regex_zaprettdir
|
||||
.replace_all(&strat_modified, ZAPRETT_DIR_PATH.to_str().unwrap())
|
||||
.into_owned();
|
||||
|
||||
let ctl = sysctl::Ctl::new("net.netfilter.nf_conntrack_tcp_be_liberal")?;
|
||||
ctl.set_value(sysctl::CtlValue::String("1".into()))?;
|
||||
|
||||
setup_iptables_rules().expect("setup iptables rules");
|
||||
|
||||
daemonize_nfqws(&strat_modified).await;
|
||||
println!("zaprett service started!");
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub async fn stop_service() -> anyhow::Result<()> {
|
||||
if !Uid::effective().is_root() {
|
||||
bail!("Running not from root, exiting");
|
||||
};
|
||||
|
||||
clear_iptables_rules().expect("clear iptables rules");
|
||||
|
||||
let pid_str = fs::read_to_string(MODULE_PATH.join("tmp/pid.lock")).await?;
|
||||
let pid = pid_str.trim().parse::<i32>()?;
|
||||
|
||||
kill(Pid::from_raw(pid), Signal::SIGKILL)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub async fn restart_service() -> anyhow::Result<()> {
|
||||
if !Uid::effective().is_root() {
|
||||
bail!("Running not from root, exiting");
|
||||
};
|
||||
stop_service().await?;
|
||||
start_service().await?;
|
||||
info!("zaprett service restarted!");
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub async fn service_status() -> anyhow::Result<bool> {
|
||||
if !Uid::effective().is_root() {
|
||||
bail!("Running not from root, exiting");
|
||||
};
|
||||
|
||||
let pid_i32 = match fs::read_to_string(Path::new(*MODULE_PATH).join("tmp/pid.lock")).await {
|
||||
Ok(s) => match s.trim().parse::<i32>() {
|
||||
Ok(pid) => pid,
|
||||
Err(_) => return Ok(false),
|
||||
},
|
||||
Err(_) => return Ok(false),
|
||||
};
|
||||
let pid = SysPid::from(pid_i32 as usize);
|
||||
let system = System::new_all();
|
||||
if let Some(process) = system.process(pid) {
|
||||
if process.name() == "zaprett" {
|
||||
return Ok(true);
|
||||
}
|
||||
}
|
||||
Ok(false)
|
||||
}
|
||||
109
rust/justfile
Normal file
109
rust/justfile
Normal file
@@ -0,0 +1,109 @@
|
||||
set shell := ["bash", "-eu", "-c"]
|
||||
|
||||
export ANDROID_API := "21"
|
||||
export ANDROID_NDK_VERSION := "r27d-linux"
|
||||
|
||||
TARGET := `pwd` + "/target"
|
||||
|
||||
export NETFILTER_LIBS := TARGET + "/netfilter"
|
||||
|
||||
export NDK_HOME := TARGET + "/android-ndk-" + ANDROID_NDK_VERSION
|
||||
|
||||
_download_android_ndk:
|
||||
#!/usr/bin/env bash
|
||||
if [ ! -d "{{NDK_HOME}}" ]; then
|
||||
echo "Downloading ndk {{ANDROID_NDK_VERSION}} to {{NDK_HOME}}"
|
||||
TMPFILE="{{NDK_HOME}}.tmp"
|
||||
TMPDIR="{{NDK_HOME}}.extracted.tmp"
|
||||
|
||||
mkdir -p "$(dirname "$TMPFILE")"
|
||||
|
||||
curl -L -C - -o "$TMPFILE" "https://dl.google.com/android/repository/android-ndk-{{ANDROID_NDK_VERSION}}.zip"
|
||||
|
||||
unzip "$TMPFILE" -d "$TMPDIR"
|
||||
|
||||
inner_folder=$(find "$TMPDIR" -mindepth 1 -maxdepth 1 -type d | head -n 1)
|
||||
mv -T "$inner_folder" "$NDK_HOME"
|
||||
|
||||
rm -rf "$TMPFILE" "$TMPDIR"
|
||||
|
||||
echo "Android ndk {{ANDROID_NDK_VERSION}} successfully installed in {{NDK_HOME}}"
|
||||
else
|
||||
echo "Android ndk {{ANDROID_NDK_VERSION}} already installed in {{NDK_HOME}}"
|
||||
fi
|
||||
|
||||
_build_netfilter_libs target_arch:
|
||||
#!/usr/bin/env bash
|
||||
|
||||
if [ ! -d "{{NETFILTER_LIBS}}-{{target_arch}}" ]; then
|
||||
export PATCH="$(pwd)/libnetfilter_queue-android.patch"
|
||||
cd "{{TARGET}}"
|
||||
|
||||
export TOOLCHAIN=$NDK_HOME/toolchains/llvm/prebuilt/linux-x86_64
|
||||
export CC="$TOOLCHAIN/bin/clang --target={{target_arch}}$ANDROID_API"
|
||||
export AR=$TOOLCHAIN/bin/llvm-ar
|
||||
export AS=$CC
|
||||
export LD=$TOOLCHAIN/bin/ld
|
||||
export RANLIB=$TOOLCHAIN/bin/llvm-ranlib
|
||||
export STRIP=$TOOLCHAIN/bin/llvm-strip
|
||||
export PKG_CONFIG_PATH=$NETFILTER_LIBS-{{target_arch}}/lib/pkgconfig
|
||||
|
||||
if [ ! -d "libnfnetlink-1.0.2" ]; then
|
||||
wget -O- https://www.netfilter.org/pub/libnfnetlink/libnfnetlink-1.0.2.tar.bz2 | tar -xj
|
||||
fi
|
||||
|
||||
if [ ! -d "libmnl-1.0.5" ]; then
|
||||
wget -O- https://www.netfilter.org/pub/libmnl/libmnl-1.0.5.tar.bz2 | tar -xj
|
||||
fi
|
||||
|
||||
if [ ! -d "libnetfilter_queue-1.0.5" ]; then
|
||||
wget -O- https://www.netfilter.org/pub/libnetfilter_queue/libnetfilter_queue-1.0.5.tar.bz2 | tar -xj
|
||||
patch -p1 -d libnetfilter_queue-* -i $PATCH
|
||||
fi
|
||||
|
||||
for i in libmnl libnfnetlink libnetfilter_queue ; do
|
||||
(
|
||||
cd $i-*
|
||||
make clean
|
||||
CFLAGS="-Os -flto=auto -Wno-implicit-function-declaration" \
|
||||
./configure --prefix= --host={{target_arch}} --enable-static --disable-shared --disable-dependency-tracking
|
||||
make -j$(nproc)
|
||||
make install DESTDIR=$NETFILTER_LIBS-{{target_arch}}
|
||||
)
|
||||
sed -i "s|^prefix=.*|prefix=$NETFILTER_LIBS-{{target_arch}}|g" $NETFILTER_LIBS-{{target_arch}}/lib/pkgconfig/$i.pc
|
||||
done
|
||||
else
|
||||
echo "Netfilter libs for {{target_arch}} already built"
|
||||
fi
|
||||
|
||||
_instal_rust_target target:
|
||||
#!/usr/bin/env bash
|
||||
if ! rustup target list --installed | grep -q "{{target}}"; then
|
||||
echo "Installing missing target: {{target}}"
|
||||
rustup target add "{{target}}"
|
||||
else
|
||||
echo "Target already installed: {{target}}"
|
||||
fi
|
||||
|
||||
prepare-android: _download_android_ndk
|
||||
#!/usr/bin/env bash
|
||||
cargo install cargo-ndk
|
||||
|
||||
build-android *args: prepare-android
|
||||
#!/usr/bin/env bash
|
||||
|
||||
targets=("armv7-linux-androideabi" "aarch64-linux-android" "x86_64-linux-android")
|
||||
|
||||
for i in "${!targets[@]}"; do
|
||||
t=${targets[$i]}
|
||||
(
|
||||
echo "Building target $t"
|
||||
export CFLAGS="-I$NETFILTER_LIBS-$t/include"
|
||||
export LDFLAGS="-L$NETFILTER_LIBS-$t/lib"
|
||||
export CXXFLAGS="$CFLAGS"
|
||||
|
||||
just _build_netfilter_libs $t
|
||||
just _instal_rust_target $t
|
||||
NETFILTER_LIBS=$NETFILTER_LIBS-$t cargo ndk -t $t --platform $ANDROID_API build {{args}}
|
||||
)
|
||||
done
|
||||
41
rust/libnetfilter_queue-android.patch
Normal file
41
rust/libnetfilter_queue-android.patch
Normal file
@@ -0,0 +1,41 @@
|
||||
--- a/src/extra/pktbuff.c
|
||||
+++ b/src/extra/pktbuff.c
|
||||
@@ -14,7 +14,7 @@
|
||||
#include <string.h> /* for memcpy */
|
||||
#include <stdbool.h>
|
||||
|
||||
-#include <netinet/if_ether.h>
|
||||
+#include <linux/if_ether.h>
|
||||
#include <netinet/ip.h>
|
||||
#include <netinet/tcp.h>
|
||||
|
||||
--- a/src/nlmsg.c
|
||||
+++ b/src/nlmsg.c
|
||||
@@ -21,7 +21,7 @@
|
||||
|
||||
#include <linux/netfilter/nfnetlink_queue.h>
|
||||
|
||||
-#include <libnetfilter_queue/libnetfilter_queue.h>
|
||||
+// #include <libnetfilter_queue/libnetfilter_queue.h>
|
||||
|
||||
#include "internal.h"
|
||||
|
||||
--- a/src/extra/tcp.c
|
||||
+++ b/src/extra/tcp.c
|
||||
@@ -139,12 +139,16 @@ void nfq_tcp_compute_checksum_ipv6(struc
|
||||
* (union is compatible to any of its members)
|
||||
* This means this part of the code is -fstrict-aliasing safe now.
|
||||
*/
|
||||
+#ifndef __ANDROID__
|
||||
union tcp_word_hdr {
|
||||
struct tcphdr hdr;
|
||||
uint32_t words[5];
|
||||
};
|
||||
+#endif
|
||||
|
||||
+#ifndef tcp_flag_word
|
||||
#define tcp_flag_word(tp) ( ((union tcp_word_hdr *)(tp))->words[3])
|
||||
+#endif
|
||||
|
||||
/**
|
||||
* nfq_pkt_snprintf_tcp_hdr - print tcp header into one buffer in a humnan
|
||||
@@ -1,19 +0,0 @@
|
||||
diff --git a/crates/iptables/src/lib.rs b/crates/iptables/src/lib.rs
|
||||
index 4a4d6dc..e7d15fc 100644
|
||||
--- a/src/lib.rs
|
||||
+++ b/src/lib.rs
|
||||
@@ -92,14 +92,6 @@ pub struct IPTables {
|
||||
pub is_numeric: bool,
|
||||
}
|
||||
|
||||
-/// Returns `None` because iptables only works on linux
|
||||
-#[cfg(not(target_os = "linux"))]
|
||||
-pub fn new(is_ipv6: bool) -> Result<IPTables, Box<dyn Error>> {
|
||||
- Err(error_from_str("iptables only works on Linux"))
|
||||
-}
|
||||
-
|
||||
-/// Creates a new `IPTables` Result with the command of 'iptables' if `is_ipv6` is `false`, otherwise the command is 'ip6tables'.
|
||||
-#[cfg(target_os = "linux")]
|
||||
pub fn new(is_ipv6: bool) -> Result<IPTables, Box<dyn Error>> {
|
||||
let cmd = if is_ipv6 { "ip6tables" } else { "iptables" };
|
||||
|
||||
@@ -33,30 +33,21 @@ ui_print "Copying files to /bin"
|
||||
arch=$(uname -m)
|
||||
case "$arch" in
|
||||
"x86_64")
|
||||
nfqws="nfqws_x86_64"
|
||||
;;
|
||||
"i386"|"i686")
|
||||
nfqws="nfqws_x86"
|
||||
zaprett_bin="zaprett-x86_64"
|
||||
;;
|
||||
"armv7l"|"arm")
|
||||
nfqws="nfqws_arm32"
|
||||
zaprett_bin="zaprett-armv7"
|
||||
;;
|
||||
"aarch64"|"armv8l")
|
||||
nfqws="nfqws_arm64"
|
||||
;;
|
||||
"mips")
|
||||
nfqws="nfqws_mips"
|
||||
;;
|
||||
"mipsel")
|
||||
nfqws="nfqws_mipsel"
|
||||
zaprett_bin="zaprett-aarch64"
|
||||
;;
|
||||
*)
|
||||
ui_print "Unknown arch: $arch"
|
||||
abort
|
||||
;;
|
||||
esac
|
||||
mv $MODPATH/system/bin/$nfqws $MODPATH/system/bin/nfqws
|
||||
rm $MODPATH/system/bin/nfqws_*
|
||||
mv $MODPATH/system/bin/$zaprett_bin $MODPATH/system/bin/zaprett
|
||||
rm $MODPATH/system/bin/zaprett-*
|
||||
mkdir $MODPATH/tmp
|
||||
|
||||
ui_print "Setting permissions..."
|
||||
|
||||
@@ -1,150 +0,0 @@
|
||||
#!/system/bin/sh
|
||||
source /sdcard/zaprett/config
|
||||
|
||||
clear_iptables_rules() {
|
||||
iptables -t mangle -D POSTROUTING -j NFQUEUE --queue-num 200 --queue-bypass 2>/dev/null
|
||||
iptables -t mangle -D PREROUTING -j NFQUEUE --queue-num 200 --queue-bypass 2>/dev/null
|
||||
iptables -t filter -D FORWARD -j NFQUEUE --queue-num 200 --queue-bypass 2>/dev/null
|
||||
}
|
||||
|
||||
start_service() {
|
||||
rm -f /data/adb/modules/zaprett/tmp/*
|
||||
echo "Starting zaprett..."
|
||||
|
||||
hostlist=""
|
||||
ipset=""
|
||||
|
||||
case "$list_type" in
|
||||
whitelist)
|
||||
lists="$active_lists"
|
||||
ipsets="$active_ipsets"
|
||||
opt="--hostlist"
|
||||
ipopt="--ipset"
|
||||
;;
|
||||
blacklist)
|
||||
lists="$active_exclude_lists"
|
||||
ipsets="$active_exclude_ipsets"
|
||||
opt="--hostlist-exclude"
|
||||
ipopt="--ipset-exclude"
|
||||
;;
|
||||
*)
|
||||
echo "Unknown list-type: $list_type" >&2
|
||||
lists=""
|
||||
ipsets=""
|
||||
opt=""
|
||||
ipopt=""
|
||||
;;
|
||||
esac
|
||||
|
||||
|
||||
if [ -n "$lists" ] && [ -n "$opt" ]; then
|
||||
for itm in $(echo "$lists" | tr ',' ' ' | sort -u); do
|
||||
if [ -f "$itm" ]; then
|
||||
dst="/data/adb/modules/zaprett/tmp/$(basename "$itm")"
|
||||
cp "$itm" "$dst"
|
||||
case "$hostlist" in
|
||||
*"$opt=$dst"*) ;;
|
||||
*) hostlist="$hostlist $opt=$dst" ;;
|
||||
esac
|
||||
fi
|
||||
done
|
||||
fi
|
||||
|
||||
if [ -n "$ipsets" ] && [ -n "$ipopt" ]; then
|
||||
for ipt in $(echo "$ipsets" | tr ',' ' ' | sort -u); do
|
||||
if [ -f "$ipt" ]; then
|
||||
dst="/data/adb/modules/zaprett/tmp/$(basename "$ipt")"
|
||||
cp "$ipt" "$dst"
|
||||
case "$ipset" in
|
||||
*"$ipopt=$dst"*) ;;
|
||||
*) ipset="$ipset $ipopt=$dst" ;;
|
||||
esac
|
||||
fi
|
||||
done
|
||||
fi
|
||||
|
||||
config=""
|
||||
if [[ -n "$strategy" && -f "$strategy" ]]; then
|
||||
config="$(eval "echo \"$(<"$strategy")\"")"
|
||||
fi
|
||||
|
||||
if [[ -z "$config" ]]; then
|
||||
config="--filter-tcp=80 --dpi-desync=fake,split2 --dpi-desync-autottl=2 --dpi-desync-fooling=md5sig,badsum $hostlist --new"
|
||||
config="$config --filter-tcp=443 $hostlist --dpi-desync=fake,split2 --dpi-desync-repeats=6 --dpi-desync-fooling=md5sig,badsum --dpi-desync-fake-tls=${zaprettdir}/bin/tls_clienthello_www_google_com.bin --new"
|
||||
config="$config --filter-tcp=80,443 --dpi-desync=fake,disorder2 --dpi-desync-repeats=6 --dpi-desync-autottl=2 --dpi-desync-fooling=md5sig,badsum $hostlist --new"
|
||||
config="$config --filter-udp=50000-50100 --dpi-desync=fake --dpi-desync-any-protocol --dpi-desync-fake-quic=0xC30000000108 --new"
|
||||
config="$config --filter-udp=443 $hostlist --dpi-desync=fake --dpi-desync-repeats=6 --dpi-desync-fake-quic=${zaprettdir}/bin/quic_initial_www_google_com.bin --new"
|
||||
config="$config --filter-udp=443 --dpi-desync=fake --dpi-desync-repeats=6 $hostlist"
|
||||
fi
|
||||
|
||||
sysctl net.netfilter.nf_conntrack_tcp_be_liberal=1 > /dev/null
|
||||
|
||||
iptables -t mangle -I POSTROUTING -j NFQUEUE --queue-num 200 --queue-bypass
|
||||
iptables -t mangle -I PREROUTING -j NFQUEUE --queue-num 200 --queue-bypass
|
||||
iptables -t filter -A FORWARD -j NFQUEUE --queue-num 200 --queue-bypass
|
||||
|
||||
nfqws --uid=0:0 --qnum=200 $config > /dev/null &
|
||||
echo "zaprett service started!"
|
||||
}
|
||||
|
||||
stop_service() {
|
||||
echo "Stopping zaprett..."
|
||||
clear_iptables_rules
|
||||
kill "$(pidof nfqws)" 2>/dev/null
|
||||
rm -f /data/adb/modules/zaprett/tmp/*
|
||||
echo "zaprett service stopped!"
|
||||
}
|
||||
|
||||
if [ "$1" == "start" ]; then
|
||||
start_service
|
||||
fi
|
||||
|
||||
if [ "$1" == "stop" ]; then
|
||||
stop_service
|
||||
fi
|
||||
|
||||
if [ "$1" == "status" ]; then
|
||||
pidof "nfqws" > /dev/null && echo "zaprett is working" || echo "zaprett is stopped"
|
||||
fi
|
||||
|
||||
if [ "$1" == "restart" ]; then
|
||||
stop_service
|
||||
start_service
|
||||
echo "zaprett service restarted!"
|
||||
fi
|
||||
|
||||
if [ "$1" == "help" ]; then
|
||||
echo -e "Помощь по модулю zaprett:\nzaprett start - запуск сервиса\nzaprett stop - остановка сервиса\nzaprett restart - перезапуск сервиса\nzaprett status - статус сервиса\nzaprett module-ver - версия модуля\nzaprett bin-ver - версия бинарных файлов\nzaprett autostart - переключение автозапуска модуля\nzaprett get-autostart - получить активен ли автозапуск"
|
||||
fi
|
||||
|
||||
if [ "$1" == "module-ver" ]; then
|
||||
grep 'version=' /data/adb/modules/zaprett/module.prop | sed 's/version=//'
|
||||
fi
|
||||
|
||||
if [ "$1" == "bin-ver" ]; then
|
||||
nfqws --version | grep -o 'version v[0-9.]*' | head -n1 | cut -d' ' -f2
|
||||
fi
|
||||
|
||||
if [ "$1" == "autostart" ]; then
|
||||
FILE="/data/adb/modules/zaprett/autostart"
|
||||
if [ -f "$FILE" ]; then
|
||||
rm "$FILE"
|
||||
echo "false"
|
||||
else
|
||||
touch "$FILE"
|
||||
echo "true"
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ "$1" == "get-autostart" ]; then
|
||||
FILE="/data/adb/modules/zaprett/autostart"
|
||||
if [ -f "$FILE" ]; then
|
||||
echo "true"
|
||||
else
|
||||
echo "false"
|
||||
fi
|
||||
fi
|
||||
|
||||
if [[ -z $1 ]]; then
|
||||
echo "zaprett installed. Telegram: t.me/zaprett_module"
|
||||
fi
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"version": "5.1",
|
||||
"versionCode": 51,
|
||||
"zipUrl": "https://github.com/egor-white/zaprett/releases/download/5.1.0/zaprett.zip",
|
||||
"version": "1",
|
||||
"versionCode": 1,
|
||||
"zipUrl": "https://github.com/egor-white/zaprett/releases/download/1/zaprett.zip",
|
||||
"changelog": "https://raw.githubusercontent.com/egor-white/zaprett/refs/heads/main/changelog.md"
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"version": "5.1",
|
||||
"versionCode": 51,
|
||||
"zipUrl": "https://github.com/egor-white/zaprett/releases/download/5.1.0/zaprett-hosts.zip",
|
||||
"version": "1",
|
||||
"versionCode": 1,
|
||||
"zipUrl": "https://github.com/egor-white/zaprett/releases/download/1/zaprett-hosts.zip",
|
||||
"changelog": "https://raw.githubusercontent.com/egor-white/zaprett/refs/heads/main/changelog.md"
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"version": "5.1",
|
||||
"versionCode": 51,
|
||||
"zipUrl": "https://github.com/egor-white/zaprett/releases/download/5.1.0/zaprett-tv.zip",
|
||||
"version": "1",
|
||||
"versionCode": 1,
|
||||
"zipUrl": "https://github.com/egor-white/zaprett/releases/download/1/zaprett-tv.zip",
|
||||
"changelog": "https://raw.githubusercontent.com/egor-white/zaprett/refs/heads/main/changelog.md"
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user