From 05ef0cd339bd43c067ce2cadc2ba4bd40466b94c Mon Sep 17 00:00:00 2001 From: Paul Lecuq Date: Fri, 3 Nov 2023 09:17:24 +0100 Subject: [PATCH 1/3] feat: update monitoring and config reload * monitoring: added read of current config * config: get config by single url --- src/config.rs | 118 +++++++++++++--------------------------------- src/monitoring.rs | 47 +++++++++++------- 2 files changed, 63 insertions(+), 102 deletions(-) diff --git a/src/config.rs b/src/config.rs index 3610071..b400703 100644 --- a/src/config.rs +++ b/src/config.rs @@ -28,6 +28,7 @@ pub struct Context { pub flags: Flags, pub sas: HashMap, pub hashwd: HashMap, + pub reloadinterval: isize, } #[derive(Debug, Clone)] @@ -35,7 +36,7 @@ pub struct SetMap { pub filename: String, pub fullpath: String, pub regex: Regex, - pub set: Set, + pub set: SetCfg, pub watchedfiles: HashMap, pub wd: WatchDescriptor, } @@ -64,6 +65,7 @@ impl Context { sas: HashMap::new(), blocklist: HashMap::new(), hashwd: HashMap::new(), + reloadinterval: 5, }; print!("Loading config ... "); @@ -282,7 +284,7 @@ impl Context { #[derive(Debug, Deserialize, Serialize, Clone)] pub struct Config { - pub sets: HashMap, + pub sets: HashMap, #[serde(skip_serializing)] pub trustnets: Vec, pub ws: HashMap, @@ -294,7 +296,7 @@ impl Config { Self { sets: HashMap::from([ ("smtp".to_string(), - Set { + SetCfg { src: "smtp".to_string(), filename: "mail.log".to_string(), regex: "(SASL LOGIN authentication failed)".to_string(), @@ -303,7 +305,7 @@ impl Config { tryfail: 5, }), ("ssh".to_string(), - Set { + SetCfg { src: "ssh".to_string(), filename: "auth.log".to_string(), regex: "(Invalid user|BREAK|not allowed because|no matching key exchange method found)".to_string(), @@ -312,7 +314,7 @@ impl Config { tryfail: 5, },), ("http".to_string(), - Set { + SetCfg { src: "http".to_string(), filename: "".to_string(), regex: "(anonymousfox.co)".to_string(), @@ -321,7 +323,7 @@ impl Config { tryfail: 5, },), ("openvpn".to_string(), - Set { + SetCfg { src: "openvpn".to_string(), filename: "status".to_string(), regex: "(UNDEF)".to_string(), @@ -350,96 +352,40 @@ impl Config { } pub async fn load(&mut self, server: &String) -> Result<(), ReqError> { - self.get_global_config(server).await?; - self.get_trustnets(server).await?; - self.get_sets(server).await?; - self.get_ws_config(server).await?; + self.get_config(server).await?; Ok(()) } - async fn get_global_config(&mut self, server: &String) -> Result<(), ReqError> { - let resp: Result = - httpclient().get(format!("{server}/config")).send().await; - let req = match resp { - Ok(re) => re, - Err(err) => return Err(err), - }; - let data: HashMap = match req.json::>().await { - Ok(res) => { - let mut out: HashMap = HashMap::new(); - res.into_iter().map(|x| x).for_each(|x| { - out.insert(x.key.to_string(), x); - }); - out - } - Err(err) => return Err(err), - }; - let key = "".to_string(); - self.api = data - .get(&key.to_string()) - .unwrap_or(&GlobalConfig { - key: "api".to_string(), - value: "127.0.0.1:8060".to_string(), - }) - .value - .clone(); - Ok(()) - } - - async fn get_trustnets(&mut self, server: &String) -> Result<(), ReqError> { + async fn get_config(&mut self, server: &String) -> Result<(), ReqError> { let resp: Result = httpclient() - .get(format!("{server}/config/trustlist")) + .get(format!("{server}/config?v=2")) .send() .await; let req = match resp { Ok(re) => re, Err(err) => return Err(err), }; - let data: Vec = match req.json::>().await { + let data: GlobalConfigV2 = match req.json::().await { Ok(res) => res, Err(err) => return Err(err), }; - self.trustnets = data; - Ok(()) - } - async fn get_sets(&mut self, server: &String) -> Result<(), ReqError> { - let resp: Result = httpclient() - .get(format!("{server}/config/sets")) - .send() - .await; - let req = match resp { - Ok(re) => re, - Err(err) => return Err(err), - }; - let data: Vec = match req.json::>().await { - Ok(res) => res, - Err(err) => return Err(err), - }; - for d in data { + for d in data.sets { self.sets.insert(d.src.clone(), d); } - Ok(()) - } - async fn get_ws_config(&mut self, server: &String) -> Result<(), ReqError> { - let resp: Result = - httpclient().get(format!("{server}/config/ws")).send().await; - let req = match resp { - Ok(re) => re, - Err(err) => return Err(err), - }; - let data: HashMap = match req.json::>().await { - Ok(res) => { - let mut out: HashMap = HashMap::new(); - res.into_iter().map(|x| x).for_each(|x| { - out.insert(x.t.to_string(), x); - }); - out - } - Err(err) => return Err(err), - }; - self.ws = data; + self.trustnets = data.trustlists; + + data.ws.into_iter().map(|x| x).for_each(|x| { + self.ws.insert(x.t.to_string(), x); + }); + + self.api = data + .cfg + .get(&"api".to_string()) + .unwrap_or(&self.api) + .clone(); + Ok(()) } @@ -508,13 +454,15 @@ pub fn httpclient() -> Client { } #[derive(Debug, Deserialize, Serialize, Clone)] -pub struct GlobalConfig { - pub key: String, - pub value: String, +pub struct GlobalConfigV2 { + pub cfg: HashMap, + pub sets: Vec, + pub trustlists: Vec, + pub ws: Vec, } #[derive(Debug, Deserialize, Serialize, Clone)] -pub struct Set { +pub struct SetCfg { pub src: String, pub filename: String, pub regex: String, @@ -543,13 +491,13 @@ pub struct URL { pub path: String, } -impl PartialEq for Set { +impl PartialEq for SetCfg { fn eq(&self, other: &Self) -> bool { self.src == other.src } } -impl Hash for Set { +impl Hash for SetCfg { fn hash(&self, state: &mut H) { self.src.hash(state); } diff --git a/src/monitoring.rs b/src/monitoring.rs index 456691a..583a6c2 100644 --- a/src/monitoring.rs +++ b/src/monitoring.rs @@ -24,33 +24,46 @@ pub async fn apiserver(ctxarc: &Arc>) -> io::Result<()> { loop { match listener.accept().await { Ok((stream, _addr)) => { - //let mut buf = [0; 1024]; - let data; - { - let ctx = ctxarc.read().await; - data = serde_json::to_string(&ctx.blocklist); - } + stream.readable().await.unwrap(); + let (reader, mut writer) = stream.into_split(); + let mut buf: [u8; 16] = [0; 16]; - match data { - Ok(dt) => { - let (_reader, mut writer) = stream.into_split(); - match writer.write_all(format!("{dt}").as_bytes()).await { - Ok(_) => {} - Err(err) => { - println!("{err}"); - } - } + match reader.try_read(&mut buf) { + Ok(_) => {} + Err(e) => { + println!("error: {}", e); } + }; + let msg = match String::from_utf8(buf.to_vec()) { + Ok(o) => o.trim_matches(char::from(0)).trim().to_string(), + Err(_) => "".to_string(), + }; + + let res = format_result(&ctxarc, msg.as_str()).await; + + match writer.write_all(format!("{res}").as_bytes()).await { + Ok(_) => {} Err(err) => { - println!("unable to serialize data: {err}"); + println!("ee {err}"); } } } Err(err) => { - println!("couldn't get client: {}", err) + println!("unable to serialize data: {err}"); } } } }); Ok(()) } + +async fn format_result(ctxarc: &Arc>, mode: &str) -> String { + let data; + let ctx = ctxarc.read().await; + match mode { + "cfg" => data = serde_json::to_string(&ctx.cfg).unwrap(), + "blocklist" => data = serde_json::to_string(&ctx.blocklist).unwrap(), + _ => data = serde_json::to_string(&ctx.blocklist).unwrap(), + }; + data +} -- 2.39.5 From a65488926300334313b005296dc99bde0f3a41f5 Mon Sep 17 00:00:00 2001 From: Paul Lecuq Date: Fri, 10 Nov 2023 23:14:13 +0100 Subject: [PATCH 2/3] more simple code * use of some simple macros * simplified code blocks in ctx read/write access --- Cargo.lock | 52 ++++++++++---------- Cargo.toml | 4 +- README.md | 1 + src/fw.rs | 119 +++++++++++++++++++++------------------------- src/ip.rs | 37 ++++++++------ src/ipblc.rs | 38 ++++++--------- src/monitoring.rs | 16 ++++--- src/old.rs | 28 +++++++++++ src/utils.rs | 36 -------------- 9 files changed, 157 insertions(+), 174 deletions(-) create mode 100644 src/old.rs diff --git a/Cargo.lock b/Cargo.lock index 3a3b6a4..be8a143 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -358,9 +358,9 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.2.10" +version = "0.2.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be4136b2a15dd319360be1c07d9933517ccf0be8f16bf62a3bee4f0d618df427" +checksum = "fe9006bed769170c11f845cf00c7c1e9092aeb3f268e007c3e760ac68008070f" dependencies = [ "cfg-if", "libc", @@ -428,9 +428,9 @@ checksum = "d77f7ec81a6d05a3abb01ab6eb7590f6083d08449fe5a1c8b1e620283546ccb7" [[package]] name = "http" -version = "0.2.9" +version = "0.2.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd6effc99afb63425aff9b05836f029929e345a6148a14b7ecd5ab67af944482" +checksum = "f95b9abcae896730d42b78e09c155ed4ddf82c07b4de772c64aee5b2d8b7c150" dependencies = [ "bytes", "fnv", @@ -543,7 +543,7 @@ dependencies = [ [[package]] name = "ipblc" -version = "1.5.0" +version = "1.5.2" dependencies = [ "chrono", "clap", @@ -590,9 +590,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" [[package]] name = "libc" -version = "0.2.149" +version = "0.2.150" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a08173bc88b7955d1b3145aa561539096c421ac8debde8cbc3612ec635fee29b" +checksum = "89d92a4743f9a61002fae18374ed11e7973f530cb3a3255fb354818118b2203c" [[package]] name = "lock_api" @@ -992,9 +992,9 @@ dependencies = [ [[package]] name = "rustls-pemfile" -version = "1.0.3" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d3987094b1d07b653b7dfdc3f70ce9a1da9c51ac18c1b06b662e4f9a0e9f4b2" +checksum = "1c74cae0a4cf6ccbbf5f359f08efdf8ee7e1dc532573bf0db71968cb56b1448c" dependencies = [ "base64", ] @@ -1071,22 +1071,22 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.190" +version = "1.0.192" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91d3c334ca1ee894a2c6f6ad698fe8c435b76d504b13d436f0685d648d6d96f7" +checksum = "bca2a08484b285dcb282d0f67b26cadc0df8b19f8c12502c13d966bf9482f001" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.190" +version = "1.0.192" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67c5609f394e5c2bd7fc51efda478004ea80ef42fee983d5c67a65e34f32c0e3" +checksum = "d6c7207fbec9faa48073f3e3074cbe553af6ea512d7c21ba46e434e70ea9fbc1" dependencies = [ "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.39", ] [[package]] @@ -1143,9 +1143,9 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.11.1" +version = "1.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "942b4a808e05215192e39f4ab80813e599068285906cc91aa64f923db842bd5a" +checksum = "4dccd0940a2dcdf68d092b8cbab7dc0ad8fa938bf95787e1b916b0e3d0e8e970" [[package]] name = "socket2" @@ -1192,9 +1192,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.38" +version = "2.0.39" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e96b79aaa137db8f61e26363a0c9b47d8b4ec75da28b7d1d614c2303e232408b" +checksum = "23e78b90f2fcf45d3e842032ce32e3f2d1545ba6636271dcbf24fa306d87be7a" dependencies = [ "proc-macro2", "quote", @@ -1251,7 +1251,7 @@ checksum = "266b2e40bc00e5a6c09c3584011e08b06f123c00362c92b975ba9843aaaa14b8" dependencies = [ "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.39", ] [[package]] @@ -1271,9 +1271,9 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.33.0" +version = "1.34.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4f38200e3ef7995e5ef13baec2f432a6da0aa9ac495b2c0e8f3b7eec2c92d653" +checksum = "d0c014766411e834f7af5b8f4cf46257aab4036ca95e9d2c144a10f59ad6f5b9" dependencies = [ "backtrace", "bytes", @@ -1290,13 +1290,13 @@ dependencies = [ [[package]] name = "tokio-macros" -version = "2.1.0" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "630bdcf245f78637c13ec01ffae6187cca34625e8c63150d424b59e55af2675e" +checksum = "5b8a1e28f2deaa14e508979454cb3a223b10b938b45af148bc0986de36f1923b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.39", ] [[package]] @@ -1479,7 +1479,7 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.39", "wasm-bindgen-shared", ] @@ -1513,7 +1513,7 @@ checksum = "c5353b8dab669f5e10f5bd76df26a9360c748f054f862ff5f3f8aae0c7fb3907" dependencies = [ "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.39", "wasm-bindgen-backend", "wasm-bindgen-shared", ] diff --git a/Cargo.toml b/Cargo.toml index e972a91..970f33b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "ipblc" -version = "1.5.0" +version = "1.5.2" edition = "2021" authors = ["PaulBSD "] description = "ipblc is a tool that search and send attacking ip addresses to ipbl" @@ -21,7 +21,7 @@ regex = "1.10" reqwest = { version = "0.11", default-features = false, features = ["json", "rustls-tls"] } serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" -tokio = { version = "1.33", features = ["full", "sync"] } +tokio = { version = "1.34", features = ["full", "sync"] } tungstenite = { version = "0.20", features = ["handshake", "rustls-tls-native-roots"] } ## to optimize binary size (slow compile time) diff --git a/README.md b/README.md index 0422a55..cb226f8 100644 --- a/README.md +++ b/README.md @@ -48,6 +48,7 @@ Options: - ✅ Local bound tcp api socket - ✅ ZMQ -> Websocket - ✅ Bug in RwLocks (agent often give up) +- ❌ Create memory friendly structs for ipdata ### Notes diff --git a/src/fw.rs b/src/fw.rs index 8eba965..5e34afd 100644 --- a/src/fw.rs +++ b/src/fw.rs @@ -19,6 +19,57 @@ pub fn fwglobalinit<'a>() -> ((Batch, Table), (Batch, Table)) { ((batch4, table4), (batch6, table6)) } +macro_rules! initrules { + ($batch:expr, $table:expr, $chain:ident) => { + let mut $chain = Chain::new(&CString::new(PKG_NAME).unwrap(), &$table); + $chain.set_hook(nftnl::Hook::In, 1); + $chain.set_policy(nftnl::Policy::Accept); + + $batch.add(&$chain, nftnl::MsgType::Add); + + $batch.add(&Rule::new(&$chain), nftnl::MsgType::Del); + + let mut rule = Rule::new(&$chain); + + rule.add_expr(&nft_expr!(ct state)); + rule.add_expr(&nft_expr!(bitwise mask 4u32, xor 0u32)); + rule.add_expr(&nft_expr!(cmp != 0u32)); + rule.add_expr(&nft_expr!(counter)); + rule.add_expr(&nft_expr!(verdict accept)); + + $batch.add(&rule, nftnl::MsgType::Add); + };} +macro_rules! createrules { + ($ipdata:ident, $chain:ident, $batch:ident) => { + let mut rule = Rule::new(&$chain); + match $ipdata.t { + 4 => { + let ip = $ipdata.ip.parse::().unwrap(); + rule.add_expr(&nft_expr!(payload ipv4 saddr)); + rule.add_expr(&nft_expr!(cmp == ip)); + }, + 6 => { + let ip = $ipdata.ip.parse::().unwrap(); + rule.add_expr(&nft_expr!(payload ipv6 saddr)); + rule.add_expr(&nft_expr!(cmp == ip)); + }, + _ => { + let ip = $ipdata.ip.parse::().unwrap(); + rule.add_expr(&nft_expr!(payload ipv4 saddr)); + rule.add_expr(&nft_expr!(cmp == ip)); + }, + }; + + rule.add_expr(&nft_expr!(ct state)); + rule.add_expr(&nft_expr!(bitwise mask 10u32, xor 0u32)); + rule.add_expr(&nft_expr!(cmp != 0u32)); + rule.add_expr(&nft_expr!(counter)); + rule.add_expr(&nft_expr!(verdict drop)); + + $batch.add(&rule, nftnl::MsgType::Add); + } +} + fn fwinit(t: FwTableType) -> (Batch, Table) { let table_name: String; let table: Table; @@ -54,73 +105,13 @@ pub fn fwblock( ) -> std::result::Result<(), Error> { let ((mut batch4, table4), (mut batch6, table6)) = fwglobalinit(); - // build chain for ipv4 - let mut chain4 = Chain::new(&CString::new(PKG_NAME).unwrap(), &table4); - chain4.set_hook(nftnl::Hook::In, 1); - chain4.set_policy(nftnl::Policy::Accept); - - // add chain - batch4.add(&chain4, nftnl::MsgType::Add); - - batch4.add(&Rule::new(&chain4), nftnl::MsgType::Del); - - let mut rule4 = Rule::new(&chain4); - rule4.add_expr(&nft_expr!(ct state)); - rule4.add_expr(&nft_expr!(bitwise mask 4u32, xor 0u32)); - rule4.add_expr(&nft_expr!(cmp != 0u32)); - rule4.add_expr(&nft_expr!(counter)); - rule4.add_expr(&nft_expr!(verdict accept)); - batch4.add(&rule4, nftnl::MsgType::Add); - - // build chain for ipv6 - let mut chain6 = Chain::new(&CString::new(PKG_NAME).unwrap(), &table6); - chain6.set_hook(nftnl::Hook::In, 1); - chain6.set_policy(nftnl::Policy::Accept); - - // add chain - batch6.add(&chain6, nftnl::MsgType::Add); - - batch6.add(&Rule::new(&chain6), nftnl::MsgType::Del); - - let mut rule6 = Rule::new(&chain6); - rule6.add_expr(&nft_expr!(ct state)); - rule6.add_expr(&nft_expr!(bitwise mask 4u32, xor 0u32)); - rule6.add_expr(&nft_expr!(cmp != 0u32)); - rule6.add_expr(&nft_expr!(counter)); - rule6.add_expr(&nft_expr!(verdict accept)); - batch6.add(&rule6, nftnl::MsgType::Add); + initrules!(batch4, table4, chain4); + initrules!(batch6, table6, chain6); // build and add rules for ipdata in ips_add.clone() { - match ipdata.t { - 4 => { - let ip = ipdata.ip.parse::().unwrap(); - let mut rule = Rule::new(&chain4); - rule.add_expr(&nft_expr!(payload ipv4 saddr)); - rule.add_expr(&nft_expr!(cmp == ip)); - rule.add_expr(&nft_expr!(ct state)); - rule.add_expr(&nft_expr!(bitwise mask 10u32, xor 0u32)); - rule.add_expr(&nft_expr!(cmp != 0u32)); - rule.add_expr(&nft_expr!(counter)); - rule.add_expr(&nft_expr!(verdict drop)); - batch4.add(&rule, nftnl::MsgType::Add); - } - 6 => { - let ip = ipdata.ip.parse::().unwrap(); - let mut rule = Rule::new(&chain6); - rule.add_expr(&nft_expr!(payload ipv6 saddr)); - rule.add_expr(&nft_expr!(cmp == ip)); - rule.add_expr(&nft_expr!(ct state)); - rule.add_expr(&nft_expr!(bitwise mask 10u32, xor 0u32)); - rule.add_expr(&nft_expr!(cmp != 0u32)); - rule.add_expr(&nft_expr!(counter)); - rule.add_expr(&nft_expr!(verdict drop)); - batch6.add(&rule, nftnl::MsgType::Add); - } - _ => { - todo!() - } - } + createrules!(ipdata, chain4, batch4); + createrules!(ipdata, chain6, batch6); } // validate and send batch diff --git a/src/ip.rs b/src/ip.rs index b1f55a6..5d5afa3 100644 --- a/src/ip.rs +++ b/src/ip.rs @@ -54,6 +54,19 @@ pub struct IpData { pub hostname: String, } +#[macro_export] +macro_rules! ipdata { + ($t:expr,$ip:expr,$src:expr,$date:expr,$hostname:expr) => { + IpData { + t: $t.clone(), + ip: $ip.clone(), + src: $src.clone(), + date: $date.clone(), + hostname: $hostname.clone(), + } + }; +} + impl PartialEq for IpData { fn eq(&self, other: &IpData) -> bool { self.ip.as_bytes() == other.ip.as_bytes() && self.src == other.src @@ -123,6 +136,14 @@ pub fn filter( } }; + let ipaddr: IpAddr = match s_ipaddr.parse() { + Ok(ip) => ip, + Err(err) => { + println!("unparseable IP: {err} {s_ipaddr}"); + continue; + } + }; + let s_date: DateTime; match R_DATE.captures(l.as_str()) { Some(sdt) => { @@ -136,22 +157,8 @@ pub fn filter( } }; - let ipaddr: IpAddr = match s_ipaddr.parse() { - Ok(ip) => ip, - Err(err) => { - println!("unparseable IP: {err} {s_ipaddr}"); - continue; - } - }; - if !is_trusted(&ipaddr, &trustnets) { - iplist.push(IpData { - ip: s_ipaddr, - t: t, - src: src.to_owned(), - date: s_date.to_rfc3339().to_owned(), - hostname: hostname.to_owned(), - }); + iplist.push(ipdata!(t, s_ipaddr, src, s_date.to_rfc3339(), hostname)); ips += 1; }; } diff --git a/src/ipblc.rs b/src/ipblc.rs index 7e40f85..9c56704 100644 --- a/src/ipblc.rs +++ b/src/ipblc.rs @@ -69,12 +69,10 @@ pub async fn run() { ipevent = ipeventrx.recv() => { let received_ip = ipevent.unwrap(); - let (toblock,server); - { + let (toblock,server) = { let ctx = ctxclone.read().await; - toblock = ctx.get_blocklist_toblock().await; - server = ctx.flags.server.clone(); - } + (ctx.get_blocklist_toblock().await,ctx.flags.server.clone()) + }; if received_ip.msgtype == "bootstrap".to_string() { for ip_to_send in toblock { @@ -88,11 +86,9 @@ pub async fn run() { } // refresh context blocklist - let filtered_ipevent; - { - let mut ctx = ctxarc.write().await; - filtered_ipevent = ctx.update_blocklist(&received_ip).await; - } + let filtered_ipevent = { + ctxarc.write().await.update_blocklist(&received_ip).await + }; // send ip list to api and ws sockets if let Some(ipevent) = filtered_ipevent { @@ -132,9 +128,8 @@ async fn handle_cfg_reload( ) { let now_cfg_reload = Local::now().trunc_subsecs(0); if (now_cfg_reload - *last_cfg_reload) > Duration::seconds(LOOP_MAX_WAIT as i64) { - let mut ctx = ctxclone.write().await; let inotify = inoarc.read().await; - match ctx.load(&inotify).await { + match ctxclone.write().await.load(&inotify).await { Ok(_) => { *last_cfg_reload = Local::now().trunc_subsecs(0); } @@ -201,19 +196,16 @@ async fn compare_files_changes( let modfiles = inrx.recv().await.unwrap(); let mut iplist: Vec = vec![]; - let sask; - let sas; - { + let sas = { let ctx = ctxarc.read().await; - sas = ctx.sas.clone(); - sask = sas.keys(); tnets = ctx.cfg.build_trustnets(); - } + ctx.sas.clone() + }; match modfiles.inevent.name { Some(name) => { let filename = name.to_str().unwrap(); - for sak in sask { + for sak in sas.clone().keys() { let sa = sas.get(sak).unwrap(); if modfiles.inevent.wd == sa.wd { let handle: String; @@ -225,13 +217,11 @@ async fn compare_files_changes( continue; } - let (filesize, sizechanged); - { + let (filesize, sizechanged) = { let mut ctx = ctxarc.write().await; let sa = ctx.sas.get_mut(sak).unwrap(); - (filesize, sizechanged) = - get_last_file_size(&mut sa.watchedfiles, &handle).await; - } + get_last_file_size(&mut sa.watchedfiles, &handle).await + }; if !sizechanged { continue; diff --git a/src/monitoring.rs b/src/monitoring.rs index 583a6c2..c3679d3 100644 --- a/src/monitoring.rs +++ b/src/monitoring.rs @@ -9,16 +9,18 @@ use tokio::sync::RwLock; pub async fn apiserver(ctxarc: &Arc>) -> io::Result<()> { let ctxarc = ctxarc.clone(); - let addr; - { - let ctx = ctxarc.read().await; - addr = ctx.cfg.api.parse().unwrap(); - } + let addr = { ctxarc.read().await.cfg.api.parse().unwrap() }; let socket = TcpSocket::new_v4().unwrap(); - socket.bind(addr).unwrap(); + match socket.bind(addr) { + Ok(_) => {} + Err(_) => { + println!("can't bind monitoring socket, exiting..."); + std::process::exit(1); + } + } socket.set_reuseaddr(true).unwrap(); - let listener = socket.listen(1024).unwrap(); + let listener = socket.listen(128).unwrap(); tokio::spawn(async move { loop { diff --git a/src/old.rs b/src/old.rs new file mode 100644 index 0000000..84bbe50 --- /dev/null +++ b/src/old.rs @@ -0,0 +1,28 @@ +pub fn _search_subfolders(path: &Path) -> Vec { + let dirs = std::fs::read_dir(path).unwrap(); + let mut folders: Vec = vec![]; + for dir in dirs { + let dirpath = dir.unwrap().path(); + let path = Path::new(dirpath.as_path()); + if path.is_dir() { + folders.push(dirpath.to_str().unwrap().to_string()); + for f in _search_subfolders(path) { + folders.push(f); + } + } + } + folders +} + +pub fn _dedup(list: &mut Vec) -> usize { + // Begin with sorting entries + list.sort(); + // Then deduplicate + list.dedup(); + // Return the length + list.len() +} + +pub async fn _sleep_ms(ms: u64) { + sleep(Duration::from_millis(ms)).await; +} diff --git a/src/utils.rs b/src/utils.rs index 3b754ca..fd04fb2 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -1,16 +1,9 @@ -use lazy_static::lazy_static; use nix::unistd; -use regex::Regex; use std::boxed::Box; use std::fs::File; use std::io::*; -use std::path::Path; use tokio::time::{sleep, Duration}; -lazy_static! { - static ref R_FILE_GZIP: Regex = Regex::new(r".*\.gz.*").unwrap(); -} - pub fn read_lines(filename: &String, offset: u64) -> Option> { let mut file = match File::open(filename) { Ok(f) => f, @@ -24,19 +17,6 @@ pub fn read_lines(filename: &String, offset: u64) -> Option> { Some(lines) } -pub fn _dedup(list: &mut Vec) -> usize { - // Begin with sorting entries - list.sort(); - // Then deduplicate - list.dedup(); - // Return the length - list.len() -} - -pub async fn _sleep_ms(ms: u64) { - sleep(Duration::from_millis(ms)).await; -} - pub async fn sleep_s(s: u64) { sleep(Duration::from_secs(s)).await; } @@ -53,19 +33,3 @@ pub fn gethostname(show_fqdn: bool) -> String { } hostname[0].to_string() } - -pub fn _search_subfolders(path: &Path) -> Vec { - let dirs = std::fs::read_dir(path).unwrap(); - let mut folders: Vec = vec![]; - for dir in dirs { - let dirpath = dir.unwrap().path(); - let path = Path::new(dirpath.as_path()); - if path.is_dir() { - folders.push(dirpath.to_str().unwrap().to_string()); - for f in _search_subfolders(path) { - folders.push(f); - } - } - } - folders -} -- 2.39.5 From 7d45f708c3d993c2206874ba541e03b0cbbb773b Mon Sep 17 00:00:00 2001 From: Paul Lecuq Date: Fri, 10 Nov 2023 23:37:01 +0100 Subject: [PATCH 3/3] update to 1.6.0 --- Cargo.lock | 2 +- Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index be8a143..b290189 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -543,7 +543,7 @@ dependencies = [ [[package]] name = "ipblc" -version = "1.5.2" +version = "1.6.0" dependencies = [ "chrono", "clap", diff --git a/Cargo.toml b/Cargo.toml index 970f33b..e426c27 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "ipblc" -version = "1.5.2" +version = "1.6.0" edition = "2021" authors = ["PaulBSD "] description = "ipblc is a tool that search and send attacking ip addresses to ipbl" -- 2.39.5