chore: wip code
This commit is contained in:
parent
576c28d81a
commit
c38834f18c
@ -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
153
src/fw.rs
@ -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
|
||||||
|
}
|
||||||
|
@ -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)]
|
||||||
|
23
src/ipblc.rs
23
src/ipblc.rs
@ -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")
|
||||||
|
Loading…
Reference in New Issue
Block a user