Compare commits
1 Commits
Author | SHA1 | Date | |
---|---|---|---|
563fbb557f |
509
Cargo.lock
generated
509
Cargo.lock
generated
File diff suppressed because it is too large
Load Diff
@ -12,18 +12,18 @@ repository = "https://git.paulbsd.com/paulbsd/ipblc"
|
|||||||
chrono = { version = "0.4", features = ["serde"] }
|
chrono = { version = "0.4", features = ["serde"] }
|
||||||
clap = { version = "4.5", features = ["string"] }
|
clap = { version = "4.5", features = ["string"] }
|
||||||
git-version = "0.3"
|
git-version = "0.3"
|
||||||
ipnet = "2.10"
|
ipnet = "2.11"
|
||||||
lazy_static = "1.5"
|
lazy_static = "1.5"
|
||||||
nix = { version = "0.29", features = ["hostname", "inotify"] }
|
nix = { version = "0.29", features = ["hostname", "inotify"] }
|
||||||
regex = "1.11"
|
regex = "1.11"
|
||||||
reqwest = { version = "0.12", default-features = false, features = ["json", "rustls-tls"] }
|
reqwest = { version = "0.12", default-features = false, features = ["json", "rustls-tls"] }
|
||||||
rustables = "0.8.5"
|
rustables = "0.8.6"
|
||||||
rustables-macros = "0.1.2"
|
rustables-macros = "0.1.2"
|
||||||
serde = { version = "1.0", features = ["derive"] }
|
serde = { version = "1.0", features = ["derive"] }
|
||||||
serde_json = "1.0"
|
serde_json = "1.0"
|
||||||
sd-notify = { version = "0.4" }
|
sd-notify = { version = "0.4" }
|
||||||
tokio = { version = "1.41", features = ["full", "sync"] }
|
tokio = { version = "1.43", features = ["full", "sync"] }
|
||||||
tungstenite = { version = "0.24", features = ["handshake", "rustls-tls-native-roots"] }
|
tungstenite = { version = "0.26", features = ["handshake", "rustls-tls-native-roots"] }
|
||||||
|
|
||||||
## to optimize binary size (slow compile time)
|
## to optimize binary size (slow compile time)
|
||||||
#[profile.release]
|
#[profile.release]
|
||||||
|
@ -2,13 +2,12 @@ use crate::ip::{BlockIpData, IpData, IpEvent};
|
|||||||
use crate::utils::{gethostname, sleep_s};
|
use crate::utils::{gethostname, sleep_s};
|
||||||
|
|
||||||
use std::{
|
use std::{
|
||||||
collections::HashMap,
|
collections::{HashMap, HashSet},
|
||||||
hash::{Hash, Hasher},
|
hash::{Hash, Hasher},
|
||||||
path::Path,
|
path::Path,
|
||||||
};
|
};
|
||||||
|
|
||||||
use chrono::prelude::*;
|
use chrono::{prelude::*, Duration};
|
||||||
use chrono::Duration;
|
|
||||||
use clap::{Arg, ArgAction, ArgMatches, Command};
|
use clap::{Arg, ArgAction, ArgMatches, Command};
|
||||||
use git_version::git_version;
|
use git_version::git_version;
|
||||||
use ipnet::IpNet;
|
use ipnet::IpNet;
|
||||||
@ -201,7 +200,7 @@ impl Context {
|
|||||||
.with_timezone(&chrono::Local);
|
.with_timezone(&chrono::Local);
|
||||||
let blocktime = set.blocktime;
|
let blocktime = set.blocktime;
|
||||||
let blocked = false;
|
let blocked = false;
|
||||||
let handle = u64::MIN;
|
let handle = HashSet::new();
|
||||||
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
|
||||||
|
27
src/fw.rs
27
src/fw.rs
@ -6,9 +6,8 @@ use std::{
|
|||||||
sync::Arc,
|
sync::Arc,
|
||||||
};
|
};
|
||||||
|
|
||||||
use tokio::sync::RwLock;
|
|
||||||
|
|
||||||
use rustables::{expr::*, *};
|
use rustables::{expr::*, *};
|
||||||
|
use tokio::sync::RwLock;
|
||||||
|
|
||||||
pub enum FwTableType {
|
pub enum FwTableType {
|
||||||
IPv4,
|
IPv4,
|
||||||
@ -38,6 +37,10 @@ macro_rules! makerules {
|
|||||||
Rule::new(&$chain)
|
Rule::new(&$chain)
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.saddr(ip.into())
|
.saddr(ip.into())
|
||||||
|
.with_expr(Conntrack::new(ConntrackKey::State))
|
||||||
|
.with_expr(Bitwise::new(10u32.to_le_bytes(), 0u32.to_be_bytes()).unwrap())
|
||||||
|
.with_expr(Cmp::new(CmpOp::Neq, 0u32.to_be_bytes()))
|
||||||
|
.with_expr(Counter::default())
|
||||||
.drop()
|
.drop()
|
||||||
.add_to_batch(&mut $batch);
|
.add_to_batch(&mut $batch);
|
||||||
};
|
};
|
||||||
@ -50,14 +53,14 @@ pub fn fwglobalinit(t: FwTableType, reset: bool) -> (Batch, 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::Inet).with_name(table_name);
|
||||||
chain = Chain::new(&table)
|
chain = Chain::new(&table)
|
||||||
.with_policy(ChainPolicy::Accept)
|
.with_policy(ChainPolicy::Accept)
|
||||||
.with_name(PKG_NAME);
|
.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::Inet).with_name(table_name);
|
||||||
chain = Chain::new(&table)
|
chain = Chain::new(&table)
|
||||||
.with_policy(ChainPolicy::Accept)
|
.with_policy(ChainPolicy::Accept)
|
||||||
.with_name(PKG_NAME);
|
.with_name(PKG_NAME);
|
||||||
@ -106,8 +109,10 @@ pub fn fwunblock<'a>(ip_del: &BlockIpData) -> std::result::Result<&String, error
|
|||||||
|
|
||||||
match ip_del.ipdata.t {
|
match ip_del.ipdata.t {
|
||||||
4 => {
|
4 => {
|
||||||
let r = Rule::new(&chain4).unwrap().with_handle(ip_del.handle);
|
for h in &ip_del.handle {
|
||||||
|
let r = Rule::new(&chain4).unwrap().with_handle(*h);
|
||||||
batch4.add(&r, MsgType::Del);
|
batch4.add(&r, MsgType::Del);
|
||||||
|
}
|
||||||
match batch4.send() {
|
match batch4.send() {
|
||||||
Ok(_) => {}
|
Ok(_) => {}
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
@ -116,8 +121,10 @@ pub fn fwunblock<'a>(ip_del: &BlockIpData) -> std::result::Result<&String, error
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
6 => {
|
6 => {
|
||||||
let r = Rule::new(&chain6).unwrap().with_handle(ip_del.handle);
|
for h in &ip_del.handle {
|
||||||
|
let r = Rule::new(&chain6).unwrap().with_handle(*h);
|
||||||
batch6.add(&r, MsgType::Del);
|
batch6.add(&r, MsgType::Del);
|
||||||
|
}
|
||||||
match batch6.send() {
|
match batch6.send() {
|
||||||
Ok(_) => {}
|
Ok(_) => {}
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
@ -136,13 +143,13 @@ pub async fn get_current_rules(
|
|||||||
fwlen: &mut usize,
|
fwlen: &mut usize,
|
||||||
) -> Result<(), Error> {
|
) -> Result<(), Error> {
|
||||||
let mut ips_all_count = 0;
|
let mut ips_all_count = 0;
|
||||||
let tables = vec![format!("{PKG_NAME}4"), format!("{PKG_NAME}6")];
|
let tables: &[String] = &[format!("{PKG_NAME}4"), format!("{PKG_NAME}6")];
|
||||||
for table_name in tables {
|
for table_name in tables {
|
||||||
let get_table = || -> Result<Option<Table>, Error> {
|
let get_table = || -> Result<Option<Table>, Error> {
|
||||||
let tables = list_tables().unwrap();
|
let tables = list_tables().unwrap();
|
||||||
for table in tables {
|
for table in tables {
|
||||||
if let Some(name) = table.get_name() {
|
if let Some(name) = table.get_name() {
|
||||||
if *name == table_name {
|
if name == table_name {
|
||||||
return Ok(Some(table));
|
return Ok(Some(table));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -170,7 +177,7 @@ pub async fn get_current_rules(
|
|||||||
let mut ctx = { ctx.write().await };
|
let mut ctx = { ctx.write().await };
|
||||||
let rules = list_rules_for_chain(&chain).unwrap().clone();
|
let rules = list_rules_for_chain(&chain).unwrap().clone();
|
||||||
|
|
||||||
for (ip, c) in ctx.blocklist.iter_mut() {
|
for (ip, b) in ctx.blocklist.iter_mut() {
|
||||||
let ip_parsed: IpAddr = ip.parse().unwrap();
|
let ip_parsed: IpAddr = ip.parse().unwrap();
|
||||||
|
|
||||||
let cmprule = Rule::new(&chain).unwrap().saddr(ip_parsed).drop();
|
let cmprule = Rule::new(&chain).unwrap().saddr(ip_parsed).drop();
|
||||||
@ -185,8 +192,8 @@ pub async fn get_current_rules(
|
|||||||
for expr in rule.get_expressions().unwrap().iter() {
|
for expr in rule.get_expressions().unwrap().iter() {
|
||||||
if let Some(expr::ExpressionVariant::Cmp(_)) = expr.get_data() {
|
if let Some(expr::ExpressionVariant::Cmp(_)) = expr.get_data() {
|
||||||
if gexpr == expr.clone() {
|
if gexpr == expr.clone() {
|
||||||
|
b.handle.insert(*rule.get_handle().unwrap());
|
||||||
ips_all_count += 1;
|
ips_all_count += 1;
|
||||||
c.handle = *rule.get_handle().unwrap();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,13 +2,13 @@ use crate::utils::gethostname;
|
|||||||
|
|
||||||
use std::{
|
use std::{
|
||||||
cmp::Ordering,
|
cmp::Ordering,
|
||||||
|
collections::HashSet,
|
||||||
fmt::{Display, Formatter},
|
fmt::{Display, Formatter},
|
||||||
io::{BufRead, BufReader, Read},
|
io::{BufRead, BufReader, Read},
|
||||||
net::IpAddr,
|
net::IpAddr,
|
||||||
};
|
};
|
||||||
|
|
||||||
use chrono::offset::LocalResult;
|
use chrono::{offset::LocalResult, prelude::*};
|
||||||
use chrono::prelude::*;
|
|
||||||
use ipnet::IpNet;
|
use ipnet::IpNet;
|
||||||
use lazy_static::lazy_static;
|
use lazy_static::lazy_static;
|
||||||
use regex::Regex;
|
use regex::Regex;
|
||||||
@ -55,7 +55,7 @@ pub struct BlockIpData {
|
|||||||
pub blocktime: i64,
|
pub blocktime: i64,
|
||||||
pub starttime: DateTime<Local>,
|
pub starttime: DateTime<Local>,
|
||||||
pub blocked: bool,
|
pub blocked: bool,
|
||||||
pub handle: u64,
|
pub handle: HashSet<u64>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, Serialize, Deserialize, Eq)]
|
#[derive(Clone, Debug, Serialize, Deserialize, Eq)]
|
||||||
|
10
src/ipblc.rs
10
src/ipblc.rs
@ -9,13 +9,13 @@ use crate::websocket::{send_to_ipbl_websocket, websocketpubsub, websocketreqrep}
|
|||||||
|
|
||||||
use std::{collections::HashMap, sync::Arc};
|
use std::{collections::HashMap, sync::Arc};
|
||||||
|
|
||||||
use chrono::prelude::*;
|
use chrono::{prelude::*, Duration};
|
||||||
use chrono::prelude::{DateTime, Local};
|
|
||||||
use chrono::Duration;
|
|
||||||
use nix::sys::inotify::{InitFlags, Inotify, InotifyEvent};
|
use nix::sys::inotify::{InitFlags, Inotify, InotifyEvent};
|
||||||
use sd_notify::*;
|
use sd_notify::*;
|
||||||
use tokio::sync::mpsc::{channel, Receiver, Sender};
|
use tokio::sync::{
|
||||||
use tokio::sync::RwLock;
|
mpsc::{channel, Receiver, Sender},
|
||||||
|
RwLock,
|
||||||
|
};
|
||||||
|
|
||||||
pub const PKG_NAME: &str = env!("CARGO_PKG_NAME");
|
pub const PKG_NAME: &str = env!("CARGO_PKG_NAME");
|
||||||
const BL_CHAN_SIZE: usize = 32;
|
const BL_CHAN_SIZE: usize = 32;
|
||||||
|
@ -3,9 +3,7 @@ use crate::config::Context;
|
|||||||
use std::{io, sync::Arc};
|
use std::{io, sync::Arc};
|
||||||
|
|
||||||
use serde_json;
|
use serde_json;
|
||||||
use tokio::io::AsyncWriteExt;
|
use tokio::{io::AsyncWriteExt, net::TcpListener, sync::RwLock};
|
||||||
use tokio::net::TcpListener;
|
|
||||||
use tokio::sync::RwLock;
|
|
||||||
|
|
||||||
pub async fn apiserver(ctxarc: &Arc<RwLock<Context>>) -> io::Result<()> {
|
pub async fn apiserver(ctxarc: &Arc<RwLock<Context>>) -> io::Result<()> {
|
||||||
let ctxarc = ctxarc.clone();
|
let ctxarc = ctxarc.clone();
|
||||||
|
@ -2,8 +2,7 @@ use crate::config::{httpclient, Context};
|
|||||||
use crate::ip::{IpData, IpEvent};
|
use crate::ip::{IpData, IpEvent};
|
||||||
use crate::utils::sleep_s;
|
use crate::utils::sleep_s;
|
||||||
|
|
||||||
use reqwest::Client;
|
use reqwest::{Client, Error as ReqError};
|
||||||
use reqwest::Error as ReqError;
|
|
||||||
|
|
||||||
const MAX_FAILED_API_RATE: u64 = 10;
|
const MAX_FAILED_API_RATE: u64 = 10;
|
||||||
|
|
||||||
|
@ -9,10 +9,8 @@ use std::{
|
|||||||
};
|
};
|
||||||
|
|
||||||
use serde_json::json;
|
use serde_json::json;
|
||||||
use tokio::sync::mpsc::Sender;
|
use tokio::sync::{mpsc::Sender, RwLock};
|
||||||
use tokio::sync::RwLock;
|
use tungstenite::{stream::*, *};
|
||||||
use tungstenite::stream::*;
|
|
||||||
use tungstenite::*;
|
|
||||||
|
|
||||||
pub async fn websocketreqrep(
|
pub async fn websocketreqrep(
|
||||||
ctxarc: &Arc<RwLock<Context>>,
|
ctxarc: &Arc<RwLock<Context>>,
|
||||||
@ -102,7 +100,7 @@ pub async fn websocketconnect<'a>(
|
|||||||
}
|
}
|
||||||
println!("connected to {endpoint}");
|
println!("connected to {endpoint}");
|
||||||
let msg = json!({ "hostname": hostname });
|
let msg = json!({ "hostname": hostname });
|
||||||
socket.send(Message::Text(msg.to_string())).unwrap();
|
socket.send(Message::Text(msg.to_string().into())).unwrap();
|
||||||
Ok(socket)
|
Ok(socket)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -113,7 +111,7 @@ pub async fn send_to_ipbl_websocket(
|
|||||||
let msg = format!("{val}", val = serde_json::to_string(&ip).unwrap());
|
let msg = format!("{val}", val = serde_json::to_string(&ip).unwrap());
|
||||||
|
|
||||||
if ws.can_write() {
|
if ws.can_write() {
|
||||||
match ws.send(Message::Text(msg)) {
|
match ws.send(Message::Text(msg.into())) {
|
||||||
Ok(_) => {}
|
Ok(_) => {}
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
println!("err send read: {e:?}");
|
println!("err send read: {e:?}");
|
||||||
|
Loading…
Reference in New Issue
Block a user