chore: wip code

This commit is contained in:
Paul 2024-12-01 19:49:54 +01:00
parent 576c28d81a
commit c38834f18c
4 changed files with 125 additions and 63 deletions

View File

@ -155,11 +155,11 @@ impl Context {
pub async fn get_blocklist_toblock(&self) -> Vec<IpData> { pub async fn get_blocklist_toblock(&self) -> Vec<IpData> {
let mut res: Vec<IpData> = vec![]; let mut res: Vec<IpData> = vec![];
for (_, block) in self.blocklist.iter() { for (_, ipblock) in self.blocklist.iter() {
match self.cfg.sets.get(&block.ipdata.src) { match self.cfg.sets.get(&ipblock.ipdata.src) {
Some(set) => { Some(set) => {
if block.tryfail >= set.tryfail { if ipblock.tryfail >= set.tryfail && !ipblock.blocked {
res.push(block.ipdata.clone()); res.push(ipblock.ipdata.clone());
} }
} }
None => {} None => {}
@ -176,6 +176,7 @@ impl Context {
.unwrap() .unwrap()
.with_timezone(&chrono::Local); .with_timezone(&chrono::Local);
let blocktime = set.blocktime; let blocktime = set.blocktime;
let blocked = false;
if ipevent.mode == "file".to_string() && gethostname(true) == ipevent.hostname { if ipevent.mode == "file".to_string() && gethostname(true) == ipevent.hostname {
let block = let block =
self.blocklist self.blocklist
@ -185,6 +186,7 @@ impl Context {
tryfail: 0, tryfail: 0,
starttime, starttime,
blocktime, blocktime,
blocked,
}); });
block.tryfail += 1; block.tryfail += 1;
block.blocktime = blocktime; block.blocktime = blocktime;
@ -199,6 +201,7 @@ impl Context {
tryfail: set.tryfail, tryfail: set.tryfail,
starttime, starttime,
blocktime, blocktime,
blocked,
}); });
} }
} }

153
src/fw.rs
View File

@ -12,23 +12,24 @@ pub enum FwTableType {
IPv6, IPv6,
} }
pub fn fwglobalinit<'a>() -> ((Batch, Table), (Batch, Table)) { pub enum FwAction {
let (batch4, table4) = fwinit(FwTableType::IPv4); Add,
let (batch6, table6) = fwinit(FwTableType::IPv6); Delete,
((batch4, table4), (batch6, table6))
} }
macro_rules! initrules { macro_rules! initrules {
($batch:expr, $table:expr, $chain:ident) => { ($batch:expr, $table:expr, $chain:ident, $reset:expr) => {
$chain.set_hook(Hook::new(HookClass::In, 1)); $chain.set_hook(Hook::new(HookClass::In, 1));
$batch.add(&$chain, MsgType::Add); $batch.add(&$chain, MsgType::Add);
$batch.add(&Rule::new(&$chain).unwrap(), MsgType::Del); if $reset {
$batch.add(&Rule::new(&$chain).unwrap(), MsgType::Del);
}
}; };
} }
macro_rules! createrules { macro_rules! makerules {
($ipdata:ident, $chain:ident, $batch:ident, $t:ty, $ip_t:ident) => { ($ipdata:ident, $chain:ident, $batch:ident, $t:ty, $ip_t:ident,$action:ty) => {
let ip = $ipdata.ip.parse::<$t>().unwrap(); let ip = $ipdata.ip.parse::<$t>().unwrap();
Rule::new(&$chain) Rule::new(&$chain)
.unwrap() .unwrap()
@ -38,66 +39,46 @@ macro_rules! createrules {
}; };
} }
fn fwinit(t: FwTableType) -> (Batch, Table) { pub fn fwglobalinit(t: FwTableType, reset: bool) -> (Batch, Chain) {
let table_name: String; let table_name: String;
let table: Table; let table: Table;
let mut chain: Chain;
match t { match t {
FwTableType::IPv4 => { FwTableType::IPv4 => {
table_name = format!("{PKG_NAME}4"); table_name = format!("{PKG_NAME}4");
table = Table::new(ProtocolFamily::Ipv4).with_name(table_name) table = Table::new(ProtocolFamily::Ipv4).with_name(table_name);
chain = Chain::new(&table)
.with_policy(ChainPolicy::Accept)
.with_name(PKG_NAME);
} }
FwTableType::IPv6 => { FwTableType::IPv6 => {
table_name = format!("{PKG_NAME}6"); table_name = format!("{PKG_NAME}6");
table = Table::new(ProtocolFamily::Ipv6).with_name(table_name); table = Table::new(ProtocolFamily::Ipv6).with_name(table_name);
chain = Chain::new(&table)
.with_policy(ChainPolicy::Accept)
.with_name(PKG_NAME);
} }
} }
let mut batch = Batch::new(); let mut batch = Batch::new();
batch.add(&table, MsgType::Add); batch.add(&table, MsgType::Add);
(batch, table) initrules!(batch, table, chain, reset);
(batch, chain)
} }
pub fn fwblock<'a>( pub fn fwblock<'a>(ip_add: &IpData) -> std::result::Result<(), error::QueryError> {
ips_add_all: &Vec<IpData>, let (mut batch4, chain4) = fwglobalinit(FwTableType::IPv4, false);
ret: &mut Vec<String>, let (mut batch6, chain6) = fwglobalinit(FwTableType::IPv6, false);
fwlen: &mut usize,
) -> std::result::Result<(), Error> {
let ((mut batch4, table4), (mut batch6, table6)) = fwglobalinit();
let mut chain4 = Chain::new(&table4) match ip_add.t {
.with_policy(ChainPolicy::Accept) 4 => {
.with_name(PKG_NAME); makerules!(ip_add, chain4, batch4, Ipv4Addr, ipv4, FwAction::Add);
let mut chain6 = Chain::new(&table6)
.with_policy(ChainPolicy::Accept)
.with_name(PKG_NAME);
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);
}
_ => {}
}
} }
6 => {
makerules!(ip_add, chain6, batch6, Ipv6Addr, ipv6, FwAction::Add);
}
_ => {}
} }
// validate and send batch // validate and send batch
@ -106,16 +87,74 @@ pub fn fwblock<'a>(
Ok(_) => {} Ok(_) => {}
Err(e) => { Err(e) => {
println!("error sending batch: {e}"); println!("error sending batch: {e}");
return Err(e);
} }
}; };
} }
if fwlen != &mut ips_add_all.len() {
ret.push(format!(
"{length} ip in firewall",
length = ips_add_all.len()
));
}
*fwlen = ips_add_all.len();
Ok(()) Ok(())
} }
pub fn fwunblock<'a>(ips_del: &Vec<IpData>) -> std::result::Result<(), Error> {
let (mut batch4, chain4) = fwglobalinit(FwTableType::IPv4, false);
let (mut batch6, chain6) = fwglobalinit(FwTableType::IPv6, false);
// to implement
/*for ip_del in ips_del {
match ip_del.t {
4 => {
makerules!(ip_del, chain4, batch4, Ipv4Addr, ipv4, FwAction::Del);
}
6 => {
makerules!(ip_del, chain6, batch6, Ipv6Addr, ipv6, FwAction::Del);
}
_ => {}
}
}*/
Ok(())
}
pub fn get_current_rules(table_name: &str, chain_name: &str) -> Result<(), Error> {
let get_table = || -> Result<Option<Table>, Error> {
let tables = list_tables().unwrap();
for table in tables {
if let Some(name) = table.get_name() {
println!("Found table {}", name);
if *name == table_name {
return Ok(Some(table));
}
}
}
Ok(None)
};
let get_chain = |table: &Table| -> Result<Option<Chain>, Error> {
let chains = list_chains_for_table(table).unwrap();
for chain in chains {
if let Some(name) = chain.get_name() {
println!("Found chain {}", name);
if *name == chain_name {
return Ok(Some(chain));
}
}
}
Ok(None)
};
let table = get_table()?.expect("no table?");
let chain = get_chain(&table)?.expect("no chain?");
let rules = list_rules_for_chain(&chain).unwrap();
for mut rule in rules {
println!("{:?}", rule);
}
Ok(())
}
pub fn fw_rules_count() -> i64 {
0
}

View File

@ -51,6 +51,7 @@ pub struct BlockIpData {
pub tryfail: i64, pub tryfail: i64,
pub blocktime: i64, pub blocktime: i64,
pub starttime: DateTime<Local>, pub starttime: DateTime<Local>,
pub blocked: bool,
} }
#[derive(Clone, Debug, Serialize, Deserialize, Eq)] #[derive(Clone, Debug, Serialize, Deserialize, Eq)]

View File

@ -1,5 +1,5 @@
use crate::config::{Context, GIT_VERSION}; use crate::config::{Context, GIT_VERSION};
use crate::fw::fwblock; use crate::fw::*;
use crate::ip::{filter, IpData, IpEvent}; use crate::ip::{filter, IpData, IpEvent};
use crate::ipevent; use crate::ipevent;
use crate::monitoring::apiserver; use crate::monitoring::apiserver;
@ -33,6 +33,10 @@ pub async fn run() {
let inotify = Inotify::init(InitFlags::empty()).unwrap(); let inotify = Inotify::init(InitFlags::empty()).unwrap();
let globalctx = Context::new(&inotify).await; let globalctx = Context::new(&inotify).await;
let ctxarc = Arc::new(RwLock::new(globalctx)); let ctxarc = Arc::new(RwLock::new(globalctx));
let (batch4, _) = fwglobalinit(FwTableType::IPv4, true);
let (batch6, _) = fwglobalinit(FwTableType::IPv6, true);
batch4.send().unwrap();
batch6.send().unwrap();
let mut fwlen: usize = 0; let mut fwlen: usize = 0;
@ -132,8 +136,23 @@ pub async fn run() {
let ctx = ctxclone.read().await; let ctx = ctxclone.read().await;
ctx.get_blocklist_toblock().await ctx.get_blocklist_toblock().await
}; };
// apply firewall blocking // apply firewall blocking
match fwblock(&toblock, &mut ret, &mut fwlen) { for b in toblock {
match fwblock(&b) {
Ok(_) => {
let mut ctx = ctxclone.write().await;
if let Some(x) = ctx.blocklist.get_mut(&b.ip) {
x.blocked = true;
}
}
Err(e) => {
println!("err: {e}, unable to push firewall rules, use super user")
}
};
}
get_current_rules("ipblc4", "ipblc").unwrap();
match fwunblock(&tounblock) {
Ok(_) => {} Ok(_) => {}
Err(e) => { Err(e) => {
println!("err: {e}, unable to push firewall rules, use super user") println!("err: {e}, unable to push firewall rules, use super user")