mirror of
https://github.com/egor-white/zaprett.git
synced 2025-12-10 05:19:42 +05:00
Compare commits
5 Commits
0f5492a29a
...
192d846a12
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
192d846a12 | ||
|
|
87a6b72aee | ||
|
|
7ea4a516be | ||
|
|
4b9e60336b | ||
|
|
51af644b5f |
67
rust/Cargo.lock
generated
67
rust/Cargo.lock
generated
@@ -266,6 +266,15 @@ version = "0.2.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "460fbee9c2c2f33933d720630a6a0bac33ba7053db5344fac858d4b8952d77d5"
|
||||
|
||||
[[package]]
|
||||
name = "daemonize"
|
||||
version = "0.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ab8bfdaacb3c887a54d41bdf48d3af8873b3f5566469f8ba21b92057509f116e"
|
||||
dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "dlv-list"
|
||||
version = "0.5.2"
|
||||
@@ -293,6 +302,19 @@ dependencies = [
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "env_logger"
|
||||
version = "0.10.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4cd405aab171cb85d6735e5c8d9db038c17d3ca007a4d2c25f337935c3d90580"
|
||||
dependencies = [
|
||||
"humantime",
|
||||
"is-terminal",
|
||||
"log",
|
||||
"regex",
|
||||
"termcolor",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "errno"
|
||||
version = "0.3.14"
|
||||
@@ -348,12 +370,24 @@ version = "0.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea"
|
||||
|
||||
[[package]]
|
||||
name = "hermit-abi"
|
||||
version = "0.5.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fc0fef456e4baa96da950455cd02c081ca953b141298e41db3fc7e36b1da849c"
|
||||
|
||||
[[package]]
|
||||
name = "hex"
|
||||
version = "0.4.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70"
|
||||
|
||||
[[package]]
|
||||
name = "humantime"
|
||||
version = "2.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "135b12329e5e3ce057a9f972339ea52bc954fe1e9358ef27f95e89716fbc5424"
|
||||
|
||||
[[package]]
|
||||
name = "iana-time-zone"
|
||||
version = "0.1.64"
|
||||
@@ -388,6 +422,17 @@ dependencies = [
|
||||
"regex",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "is-terminal"
|
||||
version = "0.4.17"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3640c1c38b8e4e43584d8df18be5fc6b0aa314ce6ebf51b53313d4306cca8e46"
|
||||
dependencies = [
|
||||
"hermit-abi",
|
||||
"libc",
|
||||
"windows-sys 0.61.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "is_terminal_polyfill"
|
||||
version = "1.70.2"
|
||||
@@ -575,6 +620,16 @@ version = "0.2.16"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3b3cff922bd51709b605d9ead9aa71031d81447142d828eb4a6eba76fe619f9b"
|
||||
|
||||
[[package]]
|
||||
name = "pretty_env_logger"
|
||||
version = "0.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "865724d4dbe39d9f3dd3b52b88d859d66bcb2d6a0acfd5ea68a65fb66d4bdc1c"
|
||||
dependencies = [
|
||||
"env_logger",
|
||||
"log",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "prettyplease"
|
||||
version = "0.2.37"
|
||||
@@ -832,6 +887,15 @@ dependencies = [
|
||||
"walkdir",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "termcolor"
|
||||
version = "1.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "06794f8f6c5c898b3275aebefa6b8a1cb24cd2c6c79397ab15774837a0bc5755"
|
||||
dependencies = [
|
||||
"winapi-util",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thiserror"
|
||||
version = "2.0.17"
|
||||
@@ -1119,10 +1183,13 @@ version = "0.0.1"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"clap",
|
||||
"daemonize",
|
||||
"iptables",
|
||||
"libc",
|
||||
"libnfqws",
|
||||
"log",
|
||||
"once_cell",
|
||||
"pretty_env_logger",
|
||||
"procfs",
|
||||
"regex",
|
||||
"rust-ini",
|
||||
|
||||
@@ -20,4 +20,6 @@ serde_json = "1.0.145"
|
||||
sysctl = "0.7.1"
|
||||
tokio = { version = "1.48.0", features = ["full"] }
|
||||
once_cell = "1.21.3"
|
||||
|
||||
daemonize = "0.5.0"
|
||||
log = "0.4.28"
|
||||
pretty_env_logger = "0.5.0"
|
||||
|
||||
@@ -17,4 +17,7 @@ serde_json = { workspace = true }
|
||||
sysctl ={ workspace = true }
|
||||
tokio = { workspace = true }
|
||||
once_cell = { workspace = true }
|
||||
libnfqws = { path = "../libnfqws" }
|
||||
libnfqws = { path = "../libnfqws" }
|
||||
daemonize = { workspace = true }
|
||||
pretty_env_logger = { workspace = true }
|
||||
log = { workspace = true }
|
||||
|
||||
@@ -2,7 +2,10 @@
|
||||
|
||||
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 procfs::process::all_processes;
|
||||
use regex::Regex;
|
||||
use serde::{Deserialize, Serialize};
|
||||
@@ -11,11 +14,11 @@ 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::sync::atomic::{AtomicBool, Ordering};
|
||||
use std::{fs, path::Path};
|
||||
use sysctl::{CtlValue, Sysctl};
|
||||
use tokio::task;
|
||||
use libnfqws::nfqws_main;
|
||||
|
||||
#[derive(Parser)]
|
||||
#[command(version)]
|
||||
@@ -71,11 +74,17 @@ struct Config {
|
||||
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"));
|
||||
|
||||
#[tokio::main]
|
||||
async fn main() {
|
||||
pretty_env_logger::init();
|
||||
|
||||
let cli = Cli::parse();
|
||||
match &cli.cmd {
|
||||
Some(Commands::Start) => start_service(),
|
||||
Some(Commands::Start) => start_service().await,
|
||||
Some(Commands::Stop) => stop_service(),
|
||||
Some(Commands::Restart) => restart_service(),
|
||||
Some(Commands::Status) => service_status(),
|
||||
@@ -83,16 +92,30 @@ async fn main() {
|
||||
Some(Commands::GetAutostart) => get_autostart(),
|
||||
Some(Commands::ModuleVer) => module_version(),
|
||||
Some(Commands::BinVer) => todo!(), //bin_version(),
|
||||
//None => println!("zaprett installed. Join us: t.me/zaprett_module"),
|
||||
None => run_nfqws("--version".to_string()).await.unwrap(),
|
||||
None => println!("zaprett installed. Join us: t.me/zaprett_module"),
|
||||
}
|
||||
tokio::signal::ctrl_c().await.unwrap();
|
||||
}
|
||||
|
||||
fn start_service() {
|
||||
async fn daemonize_nfqws(args: &String) {
|
||||
info!("Starting nfqws as a daemon");
|
||||
let daemonize = Daemonize::new()
|
||||
.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() {
|
||||
println!("Starting zaprett service...");
|
||||
|
||||
let tmp_dir = Path::new("/data/adb/modules/zaprett/tmp");
|
||||
let tmp_dir = MODULE_PATH.join("tmp");
|
||||
if tmp_dir.exists() {
|
||||
fs::remove_dir_all(&tmp_dir).unwrap()
|
||||
}
|
||||
@@ -121,49 +144,63 @@ fn start_service() {
|
||||
let regex_ipsets = Regex::new(r"\$ipset").unwrap();
|
||||
let regex_zaprettdir = Regex::new(r"\$\{?zaprettdir\}?").unwrap();
|
||||
|
||||
let zaprett_dir = String::from("/sdcard/zaprett");
|
||||
let mut strat_modified = String::new();
|
||||
|
||||
if list_type.eq("whitelist") {
|
||||
merge_files(
|
||||
config.active_lists,
|
||||
"/data/adb/modules/zaprett/tmp/hostlist",
|
||||
MODULE_PATH.join("tmp/hostlist").as_path(),
|
||||
)
|
||||
.unwrap();
|
||||
merge_files(config.active_ipsets, "/data/adb/modules/zaprett/tmp/ipset").unwrap();
|
||||
.unwrap();
|
||||
merge_files(
|
||||
config.active_ipsets,
|
||||
MODULE_PATH.join("tmp/ipset").as_path(),
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
let hosts = String::from("--hostlist=/data/adb/modules/zaprett/tmp/hostlist");
|
||||
let ipsets = String::from("--ipset=/data/adb/modules/zaprett/tmp/ipset");
|
||||
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)
|
||||
.replace_all(&strat_modified, &*ZAPRETT_DIR_PATH.to_str().unwrap())
|
||||
.into_owned();
|
||||
} else if list_type.eq("blacklist") {
|
||||
merge_files(
|
||||
config.active_exclude_lists,
|
||||
"/data/adb/modules/zaprett/tmp/hostlist-exclude",
|
||||
MODULE_PATH.join("tmp/hostlist-exclude").as_path(),
|
||||
)
|
||||
.unwrap();
|
||||
.unwrap();
|
||||
merge_files(
|
||||
config.active_exclude_ipsets,
|
||||
"/data/adb/modules/zaprett/tmp/ipset-exclude",
|
||||
MODULE_PATH.join("tmp/ipset-exclude").as_path(),
|
||||
)
|
||||
.unwrap();
|
||||
.unwrap();
|
||||
|
||||
let hosts =
|
||||
String::from("--hostlist-exclude=/data/adb/modules/zaprett/tmp/hostlist-exclude");
|
||||
let ipsets = String::from("--ipset-exclude=/data/adb/modules/zaprett/tmp/ipset-exclude");
|
||||
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)
|
||||
.replace_all(&strat_modified, &*ZAPRETT_DIR_PATH.to_str().unwrap())
|
||||
.into_owned();
|
||||
} else {
|
||||
panic!("no list-type called {}", &list_type)
|
||||
@@ -173,32 +210,36 @@ fn start_service() {
|
||||
ctl.set_value(CtlValue::Int(1)).unwrap();
|
||||
|
||||
setup_iptables_rules();
|
||||
//run_nfqws(&strat_modified);
|
||||
todo!();
|
||||
daemonize_nfqws(&strat_modified).await;
|
||||
println!("zaprett service started!");
|
||||
}
|
||||
|
||||
fn stop_service() {
|
||||
clear_iptables_rules();
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn restart_service() {
|
||||
stop_service();
|
||||
start_service();
|
||||
println!("zaprett service restarted!")
|
||||
}
|
||||
|
||||
fn set_autostart(autostart: &bool) {
|
||||
if *autostart {
|
||||
if let Err(e) = std::fs::File::create("/data/adb/modules/zaprett/autostart") {
|
||||
if let Err(e) = std::fs::File::create(MODULE_PATH.join("autostart")) {
|
||||
eprintln!("autostart: cannot create flag file: {e}");
|
||||
}
|
||||
} else {
|
||||
fs::remove_file("/data/adb/modules/zaprett/autostart").unwrap()
|
||||
fs::remove_file(MODULE_PATH.join("autostart")).unwrap()
|
||||
}
|
||||
}
|
||||
|
||||
fn get_autostart() {
|
||||
let file = Path::new("/data/adb/modules/zaprett/autostart");
|
||||
let file = MODULE_PATH.join("autostart");
|
||||
println!("{}", file.exists());
|
||||
}
|
||||
|
||||
fn service_status() {
|
||||
let running = match all_processes() {
|
||||
Ok(iter) => iter
|
||||
@@ -212,7 +253,7 @@ fn service_status() {
|
||||
}
|
||||
|
||||
fn module_version() {
|
||||
if let Ok(prop) = Ini::load_from_file("/data/adb/modules/zaprett/module.prop") {
|
||||
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);
|
||||
@@ -220,6 +261,7 @@ fn module_version() {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn bin_version() {
|
||||
todo!()
|
||||
/*if let Ok(output) = Command::new("nfqws").arg("--version").output() {
|
||||
@@ -238,7 +280,7 @@ fn bin_version() {
|
||||
}
|
||||
fn merge_files(
|
||||
input_paths: Vec<String>,
|
||||
output_path: &str,
|
||||
output_path: &Path,
|
||||
) -> Result<(), Box<dyn std::error::Error>> {
|
||||
let mut combined_content = String::new();
|
||||
|
||||
@@ -255,6 +297,7 @@ fn merge_files(
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn setup_iptables_rules() {
|
||||
let ipt = iptables::new(false).unwrap();
|
||||
|
||||
@@ -264,21 +307,22 @@ fn setup_iptables_rules() {
|
||||
"-j NFQUEUE --queue-num 200 --queue-bypass",
|
||||
1,
|
||||
)
|
||||
.unwrap();
|
||||
.unwrap();
|
||||
ipt.insert(
|
||||
"mangle",
|
||||
"PREROUTING",
|
||||
"-j NFQUEUE --queue-num 200 --queue-bypass",
|
||||
1,
|
||||
)
|
||||
.unwrap();
|
||||
.unwrap();
|
||||
ipt.append(
|
||||
"filter",
|
||||
"FORWARD",
|
||||
"-j NFQUEUE --queue-num 200 --queue-bypass",
|
||||
)
|
||||
.unwrap();
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
fn clear_iptables_rules() {
|
||||
let ipt = iptables::new(false).unwrap();
|
||||
|
||||
@@ -287,22 +331,22 @@ fn clear_iptables_rules() {
|
||||
"POSTROUTING",
|
||||
"-j NFQUEUE --queue-num 200 --queue-bypass",
|
||||
)
|
||||
.unwrap();
|
||||
.unwrap();
|
||||
ipt.delete(
|
||||
"mangle",
|
||||
"PREROUTING",
|
||||
"-j NFQUEUE --queue-num 200 --queue-bypass",
|
||||
)
|
||||
.unwrap();
|
||||
.unwrap();
|
||||
ipt.delete(
|
||||
"filter",
|
||||
"FORWARD",
|
||||
"-j NFQUEUE --queue-num 200 --queue-bypass",
|
||||
)
|
||||
.unwrap();
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
async fn run_nfqws(args_str: String) -> anyhow::Result<()> {
|
||||
async fn run_nfqws(args_str: &String) -> anyhow::Result<()> {
|
||||
static RUNNING: AtomicBool = AtomicBool::new(false);
|
||||
|
||||
if RUNNING.swap(true, Ordering::SeqCst) {
|
||||
@@ -331,7 +375,8 @@ async fn run_nfqws(args_str: String) -> anyhow::Result<()> {
|
||||
}
|
||||
|
||||
RUNNING.store(false, Ordering::SeqCst);
|
||||
});
|
||||
})
|
||||
.await?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user