Compare commits

..

No commits in common. "master" and "1.6.7" have entirely different histories.

8 changed files with 345 additions and 441 deletions

659
Cargo.lock generated

File diff suppressed because it is too large Load Diff

View File

@ -1,6 +1,6 @@
[package]
name = "ipblc"
version = "1.7.0"
version = "1.6.7"
edition = "2021"
authors = ["PaulBSD <paul@paulbsd.com>"]
description = "ipblc is a tool that search and send attacking ip addresses to ipbl"
@ -21,7 +21,6 @@ regex = "1.10"
reqwest = { version = "0.11", default-features = false, features = ["json", "rustls-tls"] }
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
sd-notify = { version = "0.4" }
tokio = { version = "1.35", features = ["full", "sync"] }
tungstenite = { version = "0.21", features = ["handshake", "rustls-tls-native-roots"] }

View File

@ -103,12 +103,12 @@ impl Context {
.send()
.await;
let req = match resp {
Ok(o) => o,
Err(e) => return Err(e),
Ok(re) => re,
Err(err) => return Err(err),
};
let data: Discovery = match req.json().await {
Ok(o) => o,
Err(e) => return Err(e),
Ok(res) => res,
Err(err) => return Err(err),
};
Ok(data)
}
@ -127,8 +127,8 @@ impl Context {
}
break;
}
Err(e) => {
println!("error loading config: {e}, retrying in {CONFIG_RETRY_INTERVAL}s");
Err(err) => {
println!("error loading config: {err}, retrying in {CONFIG_RETRY_INTERVAL}s");
last_in_err = true;
sleep_s(CONFIG_RETRY_INTERVAL).await;
}
@ -365,12 +365,12 @@ impl Config {
.send()
.await;
let req = match resp {
Ok(o) => o,
Err(e) => return Err(e),
Ok(re) => re,
Err(err) => return Err(err),
};
let data: GlobalConfigV2 = match req.json::<GlobalConfigV2>().await {
Ok(o) => o,
Err(e) => return Err(e),
Ok(res) => res,
Err(err) => return Err(err),
};
for d in data.sets {
@ -400,13 +400,13 @@ impl Config {
.await;
let req = match resp {
Ok(o) => o,
Err(e) => return Err(e),
Ok(re) => re,
Err(err) => return Err(err),
};
let data: Vec<IpData> = match req.json::<Vec<IpData>>().await {
Ok(o) => o,
Err(e) => return Err(e),
Ok(res) => res,
Err(err) => return Err(err),
};
Ok(data)
@ -417,8 +417,8 @@ impl Config {
for trustnet in &self.trustnets {
match trustnet.parse() {
Ok(net) => trustnets.push(net),
Err(e) => {
println!("error parsing {trustnet}, error: {e}");
Err(err) => {
println!("error parsing {trustnet}, error: {err}");
}
};
}

View File

@ -21,6 +21,7 @@ pub fn fwglobalinit<'a>() -> ((Batch, Table), (Batch, Table)) {
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);
@ -28,11 +29,13 @@ macro_rules! initrules {
$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);
};
}
@ -83,42 +86,25 @@ fn fwinit(t: FwTableType) -> (Batch, Table) {
}
pub fn fwblock(
ips_add_all: &Vec<IpData>,
ips_add: &Vec<IpData>,
ret: &mut Vec<String>,
fwlen: &mut usize,
) -> std::result::Result<(), Error> {
let ((mut batch4, table4), (mut batch6, table6)) = fwglobalinit();
let mut chain4 = Chain::new(&CString::new(PKG_NAME).unwrap(), &table4);
let mut chain6 = Chain::new(&CString::new(PKG_NAME).unwrap(), &table6);
initrules!(batch4, table4, chain4);
initrules!(batch6, table6, chain6);
let mut factor = 1;
if ips_add_all.len() > 100 {
factor = (ips_add_all.len() / 10) as usize
}
let ips_add_tmp: Vec<IpData> = ips_add_all.clone().iter().map(|x| x.clone()).collect();
let mut ips_add_iter = ips_add_tmp.chunks(factor);
let mut ips_add: Vec<&[IpData]> = vec![];
while let Some(x) = ips_add_iter.next() {
ips_add.push(x);
}
// build and add rules
for ipdata_group in ips_add.clone() {
for ipdata in ipdata_group {
match ipdata.t {
4 => {
createrules!(ipdata, chain4, batch4, Ipv4Addr, ipv4);
}
6 => {
createrules!(ipdata, chain6, batch6, Ipv6Addr, ipv6);
}
_ => {}
for ipdata in ips_add.clone() {
match ipdata.t {
4 => {
createrules!(ipdata, chain4, batch4, Ipv4Addr, ipv4);
}
6 => {
createrules!(ipdata, chain6, batch6, Ipv6Addr, ipv6);
}
_ => {}
}
}
@ -132,13 +118,10 @@ pub fn fwblock(
}
};
}
if fwlen != &mut ips_add_all.len() {
ret.push(format!(
"{length} ip in firewall",
length = ips_add_all.len()
));
if fwlen != &mut ips_add.len() {
ret.push(format!("{length} ip in firewall", length = ips_add.len()));
}
*fwlen = ips_add_all.len();
*fwlen = ips_add.len();
Ok(())
}

View File

@ -11,7 +11,6 @@ use chrono::prelude::*;
use chrono::prelude::{DateTime, Local};
use chrono::Duration;
use nix::sys::inotify::{InitFlags, Inotify, InotifyEvent};
use sd_notify::*;
use std::collections::HashMap;
use std::sync::Arc;
use tokio::sync::mpsc::{channel, Receiver, Sender};
@ -22,13 +21,6 @@ const BL_CHAN_SIZE: usize = 32;
const WS_CHAN_SIZE: usize = 64;
const LOOP_MAX_WAIT: u64 = 5;
macro_rules! log_with_systemd {
($msg:expr) => {
println!("{}", $msg);
notify(false, &[NotifyState::Status(format!("{}", $msg).as_str())]).unwrap();
};
}
pub async fn run() {
let inotify = Inotify::init(InitFlags::empty()).unwrap();
let globalctx = Context::new(&inotify).await;
@ -39,7 +31,7 @@ pub async fn run() {
let pkgversion = format!("{}@{}", env!("CARGO_PKG_VERSION"), GIT_VERSION);
let mut last_cfg_reload: DateTime<Local> = Local::now().trunc_subsecs(0);
log_with_systemd!(format!("Launching {}, version {}", PKG_NAME, pkgversion));
println!("Launching {}, version {}", PKG_NAME, pkgversion);
fwglobalinit();
let ctxapi = Arc::clone(&ctxarc);
@ -68,8 +60,6 @@ pub async fn run() {
compare_files_changes(&ctxclone, &mut blrx, &ipeventclone).await;
});
notify(false, &[NotifyState::Ready]).unwrap();
loop {
let mut ret: Vec<String> = Vec::new();
@ -104,7 +94,7 @@ pub async fn run() {
// send ip list to api and ws sockets
if let Some(ipevent) = filtered_ipevent {
if received_ip.msgtype != "init" {
log_with_systemd!(format!("sending {} to api and ws", ipevent.ipdata.clone().unwrap().ip));
println!("sending {} to api and ws", ipevent.ipdata.clone().unwrap().ip);
let ipe = ipevent!("add","ws",gethostname(true),ipevent.ipdata);
send_to_ipbl_api(&server.clone(), &ipe).await;
if !send_to_ipbl_websocket(&mut wssocketrr, &ipe).await {
@ -129,8 +119,7 @@ pub async fn run() {
// log lines
if ret.len() > 0 {
let result = ret.join(", ");
log_with_systemd!(format!("{result}"));
println!("{ret}", ret = ret.join(", "));
}
let ctxclone = Arc::clone(&ctxarc);
@ -189,8 +178,8 @@ async fn handle_fwblock(ctxclone: Arc<RwLock<Context>>, ret: &mut Vec<String>, f
// apply firewall blocking
match fwblock(&toblock, ret, fwlen) {
Ok(_) => {}
Err(e) => {
println!("err: {e}, unable to push firewall rules, use super user")
Err(err) => {
println!("Err: {err}, unable to push firewall rules, use super user")
}
};
}

View File

@ -11,9 +11,9 @@ pub async fn apiserver(ctxarc: &Arc<RwLock<Context>>) -> io::Result<()> {
let ctxarc = ctxarc.clone();
let addr: String = { ctxarc.read().await.cfg.api.parse().unwrap() };
let listener = match TcpListener::bind(addr).await {
Ok(o) => o,
Err(e) => {
println!("error: {e}");
Ok(l) => l,
Err(err) => {
println!("Error: {err}");
std::process::exit(1);
}
};
@ -29,13 +29,13 @@ pub async fn apiserver(ctxarc: &Arc<RwLock<Context>>) -> io::Result<()> {
match socket.try_read(&mut buf) {
Ok(_) => {}
Err(e) => {
println!("error: {e}");
println!("{e}");
continue;
}
};
}
Err(e) => {
println!("error: {e}");
println!("{e}");
continue;
}
}
@ -49,8 +49,8 @@ pub async fn apiserver(ctxarc: &Arc<RwLock<Context>>) -> io::Result<()> {
match socket.write_all(res.as_bytes()).await {
Ok(_) => {}
Err(e) => {
println!("error: {e}");
Err(err) => {
println!("ee {err}");
}
}
}

View File

@ -6,9 +6,9 @@ use tokio::time::{sleep, Duration};
pub fn read_lines(filename: &String, offset: u64) -> Option<Box<dyn Read>> {
let mut file = match File::open(filename) {
Ok(o) => o,
Err(e) => {
println!("error: {e}");
Ok(f) => f,
Err(err) => {
println!("{err}");
return None;
}
};

View File

@ -15,8 +15,8 @@ pub async fn send_to_ipbl_api(server: &str, ip: &IpEvent) {
Ok(_) => {
break;
}
Err(e) => {
println!("error: {e}");
Err(err) => {
println!("{err}");
sleep_s(1).await;
if try_req == MAX_FAILED_API_RATE {
break;