diff --git a/net-guardia/src/core/control.rs b/net-guardia/src/core/control.rs index a946318..f830b57 100644 --- a/net-guardia/src/core/control.rs +++ b/net-guardia/src/core/control.rs @@ -1,14 +1,17 @@ -use std::net::{IpAddr, Ipv4Addr, Ipv6Addr, SocketAddrV4, SocketAddrV6}; -use std::sync::OnceLock; +use crate::core::system::System; +use crate::model::http_method::HttpMethod; +use crate::utils::ip_address::convert_ports_to_vec; +use crate::utils::log_entry::system::SystemEntry; use aya::maps::{Array as AyaArray, HashMap as AyaHashMap, MapData}; -use tokio::sync::{RwLock, RwLockReadGuard, RwLockWriteGuard}; -use tracing::{error, info}; -use net_guardia_common::MAX_RULES_PORT; use net_guardia_common::model::http_method::EbpfHttpMethod; use net_guardia_common::model::ip_address::{EbpfAddrPortV4, EbpfAddrPortV6, IPv4, IPv6, Port}; use net_guardia_common::model::placeholder::PlaceHolder; -use crate::core::system::System; -use crate::utils::log_entry::system::SystemEntry; +use net_guardia_common::MAX_RULES_PORT; +use std::collections::HashMap as StdHashMap; +use std::net::{IpAddr, Ipv4Addr, Ipv6Addr, SocketAddrV4, SocketAddrV6}; +use std::sync::OnceLock; +use tokio::sync::{RwLock, RwLockReadGuard, RwLockWriteGuard}; +use tracing::{error, info}; static CONTROL: OnceLock> = OnceLock::new(); @@ -25,7 +28,7 @@ pub struct Control { ipv4_ssh_black_list: AyaHashMap, ipv6_ssh_black_list: AyaHashMap, ipv4_scanner_list: AyaHashMap, - ipv6_scanner_list: AyaHashMap + ipv6_scanner_list: AyaHashMap, } impl Control { @@ -33,7 +36,7 @@ impl Control { info!("{}", SystemEntry::Initializing); let mut system = System::instance_mut().await; let mut ebpf = &mut system.ebpf; - let control = Control { + let mut control = Control { ipv4_black_list: AyaHashMap::try_from(ebpf.take_map("IPV4_BLACKLIST").unwrap())?, ipv6_black_list: AyaHashMap::try_from(ebpf.take_map("IPV6_BLACKLIST").unwrap())?, ipv4_http_service: AyaHashMap::try_from(ebpf.take_map("IPV4_HTTP_SERVICE").unwrap())?, @@ -41,13 +44,24 @@ impl Control { ssh_white_list_only: AyaArray::try_from(ebpf.take_map("SSH_WHITE_LIST_ONLY").unwrap())?, ipv4_ssh_service: AyaHashMap::try_from(ebpf.take_map("IPV4_SSH_SERVICE").unwrap())?, ipv6_ssh_service: AyaHashMap::try_from(ebpf.take_map("IPV6_SSH_SERVICE").unwrap())?, - ipv4_ssh_white_list: AyaHashMap::try_from(ebpf.take_map("IPV4_SSH_WHITE_LIST").unwrap())?, - ipv6_ssh_white_list: AyaHashMap::try_from(ebpf.take_map("IPV6_SSH_WHITE_LIST").unwrap())?, - ipv4_ssh_black_list: AyaHashMap::try_from(ebpf.take_map("IPV4_SSH_BLACK_LIST").unwrap())?, - ipv6_ssh_black_list: AyaHashMap::try_from(ebpf.take_map("IPV6_SSH_BLACK_LIST").unwrap())?, + ipv4_ssh_white_list: AyaHashMap::try_from( + ebpf.take_map("IPV4_SSH_WHITE_LIST").unwrap(), + )?, + ipv6_ssh_white_list: AyaHashMap::try_from( + ebpf.take_map("IPV6_SSH_WHITE_LIST").unwrap(), + )?, + ipv4_ssh_black_list: AyaHashMap::try_from( + ebpf.take_map("IPV4_SSH_BLACK_LIST").unwrap(), + )?, + ipv6_ssh_black_list: AyaHashMap::try_from( + ebpf.take_map("IPV6_SSH_BLACK_LIST").unwrap(), + )?, ipv4_scanner_list: AyaHashMap::try_from(ebpf.take_map("IPV4_SCANNER_LIST").unwrap())?, ipv6_scanner_list: AyaHashMap::try_from(ebpf.take_map("IPV6_SCANNER_LIST").unwrap())?, }; + if control.ssh_white_list_only.set(0, 0_u8, 0).is_err() { + error!(" "); + } CONTROL.get_or_init(|| RwLock::new(control)); info!("{}", SystemEntry::InitializeComplete); Ok(()) @@ -69,17 +83,122 @@ impl Control { once_lock.write().await } - pub async fn add_ipv4_http_service(address: SocketAddrV4, ) { + pub async fn get_ipv4_black_list() -> StdHashMap> { + let control = Control::instance().await; + control + .ipv4_black_list + .iter() + .filter_map(Result::ok) + .map(|(key, value)| (Ipv4Addr::from(key), convert_ports_to_vec(value))) + .collect() + } + + pub async fn get_ipv6_black_list() -> StdHashMap> { + let control = Control::instance().await; + control + .ipv6_black_list + .iter() + .filter_map(Result::ok) + .map(|(key, value)| (Ipv6Addr::from(key), convert_ports_to_vec(value))) + .collect() + } + + pub async fn add_ipv4_black_list() { + let mut control = Control::instance_mut().await; + } + + pub async fn add_ipv6_black_list() { + let mut control = Control::instance_mut().await; + } + + pub async fn remove_ipv4_black_list() { } - pub async fn enable_ssh_white_list() { + pub async fn remove_ipv6_black_list() { + + } + + pub async fn get_ipv4_http_service() -> Vec { + + } + + pub async fn get_ipv6_http_service() -> Vec { + + } + + pub async fn add_ipv4_http_service(address: SocketAddrV4, http_method: Vec) { + let ip: u32 = (*address.ip()).into(); + let port = address.port(); + let addr_port = [ip, port as u32]; + let ebpf_method = HttpMethod::convert_to_ebpf(http_method); + let mut control = Control::instance_mut().await; + if control + .ipv4_http_service + .insert(addr_port, ebpf_method, 0) + .is_err() + { + error!(" "); + } + } + + pub async fn add_ipv6_http_service(address: SocketAddrV6, http_method: Vec) { + let ip: u128 = (*address.ip()).into(); + let port = address.port(); + let addr_port = [ip, port as u128]; + let ebpf_method = HttpMethod::convert_to_ebpf(http_method); + let mut control = Control::instance_mut().await; + if control + .ipv6_http_service + .insert(addr_port, ebpf_method, 0) + .is_err() + { + error!(" "); + } + } + + pub async fn remove_ipv4_http_service(address: SocketAddrV4, http_method: Vec) { + + } + + pub async fn remove_ipv6_http_service(address: SocketAddrV6, http_method: Vec) { + + } + + pub async fn is_ssh_white_list_enable() -> bool { let control = Control::instance().await; + match control.ssh_white_list_only.get(&0, 0) { + Ok(status) => if status == 0 { + false + } else { + true + } + Err(_) => false + } + } + + pub async fn enable_ssh_white_list() { + let mut control = Control::instance_mut().await; + if control.ssh_white_list_only.set(0, 1_u8, 0).is_err() { + error!(" "); + } + } + + pub async fn disable_ssh_white_list() { + let mut control = Control::instance_mut().await; if control.ssh_white_list_only.set(0, 0_u8, 0).is_err() { error!(" "); } } + pub async fn get_ipv4_ssh_white_list() { + + } + + pub async fn get_ipv6_ssh_white_list() { + + } + pub async fn add_ipv4_ssh_white_list(ip: Ipv4Addr) { let ip: u32 = ip.into(); let mut control = Control::instance_mut().await; @@ -96,6 +215,22 @@ impl Control { } } + pub async fn remove_ipv4_ssh_white_list() { + + } + + pub async fn remove_ipv6_ssh_white_list() { + + } + + pub async fn get_ipv4_ssh_black_list(ip: Ipv4Addr) { + + } + + pub async fn get_ipv6_ssh_black_list(ip: Ipv4Addr) { + + } + pub async fn add_ipv4_ssh_black_list(ip: Ipv4Addr) { let ip: u32 = ip.into(); let mut control = Control::instance_mut().await; @@ -111,4 +246,28 @@ impl Control { error!(" "); } } + + pub async fn remove_ipv6_ssh_black_list() { + + } + + pub async fn remove_ipv4_ssh_black_list() { + + } + + pub async fn get_ipv4_scanner_list() { + + } + + pub async fn get_ipv6_scanner_list() { + + } + + pub async fn remove_ipv4_scanner_list() { + + } + + pub async fn remove_ipv6_scanner_list() { + + } } diff --git a/net-guardia/src/core/monitor.rs b/net-guardia/src/core/monitor.rs index e7a2a2a..874d6ab 100644 --- a/net-guardia/src/core/monitor.rs +++ b/net-guardia/src/core/monitor.rs @@ -1,4 +1,5 @@ use crate::core::system::System; +use crate::model::flow_stats::FlowStats; use crate::model::flow_type::{IPv4FlowType, IPv6FlowType}; use crate::utils::log_entry::system::SystemEntry; use aya::maps::{HashMap as AyaHashMap, MapData}; @@ -6,6 +7,7 @@ use aya::Pod; use net_guardia_common::model::flow_stats::EbpfFlowStats; use net_guardia_common::model::ip_address::{EbpfAddrPortV4, EbpfAddrPortV6}; use std::collections::HashMap as StdHashMap; +use std::net::{Ipv4Addr, Ipv6Addr, SocketAddrV4, SocketAddrV6}; use std::sync::OnceLock; use tokio::sync::{RwLock, RwLockReadGuard, RwLockWriteGuard}; use tracing::info; @@ -133,7 +135,7 @@ impl Monitor { pub async fn get_ipv4_flow_data( ipv4_flow_type: IPv4FlowType, - ) -> StdHashMap { + ) -> StdHashMap { let monitor = Monitor::instance().await; let iter = match ipv4_flow_type { IPv4FlowType::Src1Min => monitor.ipv4_src_1min.iter(), @@ -143,12 +145,18 @@ impl Monitor { IPv4FlowType::Dst10Min => monitor.ipv4_dst_10min.iter(), IPv4FlowType::Dst1Hour => monitor.ipv4_dst_1hour.iter(), }; - iter.filter_map(|result| result.ok()).collect() + iter.filter_map(Result::ok) + .map(|(key, value)| { + let ip = Ipv4Addr::from(key[0]); + let port = key[1] as u16; + (SocketAddrV4::new(ip, port), FlowStats::from(value)) + }) + .collect() } pub async fn get_ipv6_flow_data( ipv6_flow_type: IPv6FlowType, - ) -> StdHashMap { + ) -> StdHashMap { let monitor = Monitor::instance().await; let iter = match ipv6_flow_type { IPv6FlowType::Src1Min => monitor.ipv6_src_1min.iter(), @@ -158,6 +166,12 @@ impl Monitor { IPv6FlowType::Dst10Min => monitor.ipv6_dst_10min.iter(), IPv6FlowType::Dst1Hour => monitor.ipv6_dst_1hour.iter(), }; - iter.filter_map(|result| result.ok()).collect() + iter.filter_map(Result::ok) + .map(|(key, value)| { + let ip = Ipv6Addr::from(key[0]); + let port = key[1] as u16; + (SocketAddrV6::new(ip, port, 0, 0), FlowStats::from(value)) + }) + .collect() } } diff --git a/net-guardia/src/model/http_method.rs b/net-guardia/src/model/http_method.rs new file mode 100644 index 0000000..b3ab24b --- /dev/null +++ b/net-guardia/src/model/http_method.rs @@ -0,0 +1,35 @@ +use serde::{Deserialize, Serialize}; +use net_guardia_common::model::http_method::EbpfHttpMethod; + +#[derive(Serialize, Deserialize, Debug, Copy, Clone)] +pub enum HttpMethod { + GET, + POST, + PUT, + DELETE, + HEAD, + OPTIONS, + PATCH, + TRACE, + CONNECT, +} + +impl HttpMethod { + pub fn convert_to_ebpf(http_methods: Vec) -> EbpfHttpMethod { + let mut ebpf_http_method = 0_u16; + for http_method in http_methods { + match http_method { + HttpMethod::GET => ebpf_http_method |= 0b0000_0000_0000_0001, + HttpMethod::POST => ebpf_http_method |= 0b0000_0000_0000_0010, + HttpMethod::PUT => ebpf_http_method |= 0b0000_0000_0000_0100, + HttpMethod::DELETE => ebpf_http_method |= 0b0000_0000_0000_1000, + HttpMethod::HEAD => ebpf_http_method |= 0b0000_0000_0001_0000, + HttpMethod::OPTIONS => ebpf_http_method |= 0b0000_0000_0010_0000, + HttpMethod::PATCH => ebpf_http_method |= 0b0000_0000_0100_0000, + HttpMethod::TRACE => ebpf_http_method |= 0b0000_0000_1000_0000, + HttpMethod::CONNECT => ebpf_http_method |= 0b0000_0001_0000_0000, + } + } + ebpf_http_method + } +} diff --git a/net-guardia/src/model/ip_address.rs b/net-guardia/src/model/ip_address.rs deleted file mode 100644 index 5593077..0000000 --- a/net-guardia/src/model/ip_address.rs +++ /dev/null @@ -1,19 +0,0 @@ -use crate::utils::definition::IntoString; -use net_guardia_common::model::ip_address::{EbpfAddrPortV4, EbpfAddrPortV6}; -use std::net::{Ipv4Addr, Ipv6Addr}; - -impl IntoString for EbpfAddrPortV4 { - fn into_string(self) -> String { - let ip_addr = Ipv4Addr::from(self[0]); - let port = self[1] as u16; - format!("{}:{}", ip_addr, port) - } -} - -impl IntoString for EbpfAddrPortV6 { - fn into_string(self) -> String { - let ip_addr = Ipv6Addr::from(self[0]); - let port = self[1] as u16; - format!("[{}]:{}", ip_addr, port) - } -} diff --git a/net-guardia/src/model/mod.rs b/net-guardia/src/model/mod.rs index 9245b19..8d5e085 100644 --- a/net-guardia/src/model/mod.rs +++ b/net-guardia/src/model/mod.rs @@ -1,4 +1,4 @@ pub mod config; pub mod flow_stats; pub mod flow_type; -pub mod ip_address; +pub mod http_method; diff --git a/net-guardia/src/utils/ip_address.rs b/net-guardia/src/utils/ip_address.rs new file mode 100644 index 0000000..2fc0b03 --- /dev/null +++ b/net-guardia/src/utils/ip_address.rs @@ -0,0 +1,13 @@ +use net_guardia_common::MAX_RULES_PORT; +use net_guardia_common::model::ip_address::Port; + +pub fn convert_ports_to_vec(ports: [u16; MAX_RULES_PORT]) -> Vec { + let mut filtered_ports: Vec = ports + .into_iter() + .filter(|&port| port != 0) + .collect(); + if filtered_ports.is_empty() { + filtered_ports.push(0); + } + filtered_ports +} diff --git a/net-guardia/src/utils/mod.rs b/net-guardia/src/utils/mod.rs index 2b9085c..6ec34f4 100644 --- a/net-guardia/src/utils/mod.rs +++ b/net-guardia/src/utils/mod.rs @@ -1,4 +1,5 @@ pub mod log_entry; pub mod definition; +pub mod ip_address; pub mod logging; pub mod static_files; diff --git a/net-guardia/src/web/api/monitor.rs b/net-guardia/src/web/api/monitor.rs index dcde60a..0da98a7 100644 --- a/net-guardia/src/web/api/monitor.rs +++ b/net-guardia/src/web/api/monitor.rs @@ -1,9 +1,7 @@ use crate::core::monitor::Monitor; use crate::model::flow_type::{IPv4FlowType, IPv6FlowType}; -use crate::web::utils::map_util::{transform_ipv4_flow_data, transform_ipv6_flow_data}; use actix_web::{get, web, Error, HttpRequest, HttpResponse, Responder, Scope}; use actix_web_actors::ws::start; -use tracing::info; use crate::web::utils::flow_websocket::{IPv4FlowWebSocket, IPv6FlowWebSocket}; pub fn initialize() -> Scope { @@ -27,85 +25,73 @@ pub fn initialize() -> Scope { #[get("/get/ipv4/src/1min")] async fn get_ipv4_src_1min() -> impl Responder { let flow_data = Monitor::get_ipv4_flow_data(IPv4FlowType::Src1Min).await; - let formated = transform_ipv4_flow_data(flow_data); - HttpResponse::Ok().json(web::Json(formated)) + HttpResponse::Ok().json(web::Json(flow_data)) } #[get("/get/ipv4/src/10min")] async fn get_ipv4_src_10min() -> impl Responder { let flow_data = Monitor::get_ipv4_flow_data(IPv4FlowType::Src10Min).await; - let formated = transform_ipv4_flow_data(flow_data); - HttpResponse::Ok().json(web::Json(formated)) + HttpResponse::Ok().json(web::Json(flow_data)) } #[get("/get/ipv4/src/1hour")] async fn get_ipv4_src_1hour() -> impl Responder { let flow_data = Monitor::get_ipv4_flow_data(IPv4FlowType::Src1Hour).await; - let formated = transform_ipv4_flow_data(flow_data); - HttpResponse::Ok().json(web::Json(formated)) + HttpResponse::Ok().json(web::Json(flow_data)) } #[get("/get/ipv6/src/1min")] async fn get_ipv6_src_1min() -> impl Responder { let flow_data = Monitor::get_ipv6_flow_data(IPv6FlowType::Src1Min).await; - let formated = transform_ipv6_flow_data(flow_data); - HttpResponse::Ok().json(web::Json(formated)) + HttpResponse::Ok().json(web::Json(flow_data)) } #[get("/get/ipv6/src/10min")] async fn get_ipv6_src_10min() -> impl Responder { let flow_data = Monitor::get_ipv6_flow_data(IPv6FlowType::Src10Min).await; - let formated = transform_ipv6_flow_data(flow_data); - HttpResponse::Ok().json(web::Json(formated)) + HttpResponse::Ok().json(web::Json(flow_data)) } #[get("/get/ipv6/src/1hour")] async fn get_ipv6_src_1hour() -> impl Responder { let flow_data = Monitor::get_ipv6_flow_data(IPv6FlowType::Src1Hour).await; - let formated = transform_ipv6_flow_data(flow_data); - HttpResponse::Ok().json(web::Json(formated)) + HttpResponse::Ok().json(web::Json(flow_data)) } #[get("/get/ipv4/dst/1min")] async fn get_ipv4_dst_1min() -> impl Responder { let flow_data = Monitor::get_ipv4_flow_data(IPv4FlowType::Dst1Min).await; - let formated = transform_ipv4_flow_data(flow_data); - HttpResponse::Ok().json(web::Json(formated)) + HttpResponse::Ok().json(web::Json(flow_data)) } #[get("/get/ipv4/dst/10min")] async fn get_ipv4_dst_10min() -> impl Responder { let flow_data = Monitor::get_ipv4_flow_data(IPv4FlowType::Dst10Min).await; - let formated = transform_ipv4_flow_data(flow_data); - HttpResponse::Ok().json(web::Json(formated)) + HttpResponse::Ok().json(web::Json(flow_data)) } #[get("/get/ipv4/dst/1hour")] async fn get_ipv4_dst_1hour() -> impl Responder { let flow_data = Monitor::get_ipv4_flow_data(IPv4FlowType::Dst1Hour).await; - let formated = transform_ipv4_flow_data(flow_data); - HttpResponse::Ok().json(web::Json(formated)) + HttpResponse::Ok().json(web::Json(flow_data)) } #[get("/get/ipv6/dst/1min")] async fn get_ipv6_dst_1min() -> impl Responder { let flow_data = Monitor::get_ipv6_flow_data(IPv6FlowType::Src1Min).await; - let formated = transform_ipv6_flow_data(flow_data); - HttpResponse::Ok().json(web::Json(formated)) + HttpResponse::Ok().json(web::Json(flow_data)) } #[get("/get/ipv6/dst/10min")] async fn get_ipv6_dst_10min() -> impl Responder { let flow_data = Monitor::get_ipv6_flow_data(IPv6FlowType::Src10Min).await; - let formated = transform_ipv6_flow_data(flow_data); - HttpResponse::Ok().json(web::Json(formated)) + HttpResponse::Ok().json(web::Json(flow_data)) } #[get("/get/ipv6/dst/1hour")] async fn get_ipv6_dst_1hour() -> impl Responder { let flow_data = Monitor::get_ipv6_flow_data(IPv6FlowType::Src1Hour).await; - let formated = transform_ipv6_flow_data(flow_data); - HttpResponse::Ok().json(web::Json(formated)) + HttpResponse::Ok().json(web::Json(flow_data)) } #[get("/websocket/ipv4/{flow_type}")] diff --git a/net-guardia/src/web/utils/flow_websocket.rs b/net-guardia/src/web/utils/flow_websocket.rs index 96ff929..89486f3 100644 --- a/net-guardia/src/web/utils/flow_websocket.rs +++ b/net-guardia/src/web/utils/flow_websocket.rs @@ -1,7 +1,6 @@ use crate::core::config_manager::ConfigManager; use crate::core::monitor::Monitor; use crate::model::flow_type::{IPv4FlowType, IPv6FlowType}; -use crate::web::utils::map_util::{transform_ipv4_flow_data, transform_ipv6_flow_data}; use actix::prelude::*; use actix_web_actors::ws; use std::time::Duration; @@ -20,8 +19,7 @@ impl Actor for IPv4FlowWebSocket { let interval = ctx.run_interval(refresh_interval, |actor, ctx| { let flow_type = actor.flow_type.clone(); let future = async move { - let flow_data = Monitor::get_ipv4_flow_data(flow_type).await; - transform_ipv4_flow_data(flow_data) + Monitor::get_ipv4_flow_data(flow_type).await }; ctx.wait(future.into_actor(actor).map(|flow_data, _, ctx| { if let Ok(json) = serde_json::to_string(&flow_data) { @@ -67,8 +65,7 @@ impl Actor for IPv6FlowWebSocket { let interval = ctx.run_interval(refresh_interval, |actor, ctx| { let flow_type = actor.flow_type.clone(); let future = async move { - let flow_data = Monitor::get_ipv6_flow_data(flow_type).await; - transform_ipv6_flow_data(flow_data) + Monitor::get_ipv6_flow_data(flow_type).await }; ctx.wait(future.into_actor(actor).map(|flow_data, _, ctx| { if let Ok(json) = serde_json::to_string(&flow_data) { diff --git a/net-guardia/src/web/utils/map_util.rs b/net-guardia/src/web/utils/map_util.rs deleted file mode 100644 index 6dcca20..0000000 --- a/net-guardia/src/web/utils/map_util.rs +++ /dev/null @@ -1,25 +0,0 @@ -use crate::model::flow_stats::FlowStats; -use net_guardia_common::model::flow_stats::EbpfFlowStats as EbpfFlowStats; -use net_guardia_common::model::ip_address::{ - EbpfAddrPortV4 as EbpfAddrPortV4, EbpfAddrPortV6 as EbpfAddrPortV6, -}; -use std::collections::HashMap; -use crate::utils::definition::IntoString; - -pub fn transform_ipv4_flow_data( - original: HashMap, -) -> HashMap { - original - .into_iter() - .map(|(key, value)| (key.into_string(), FlowStats::from(value))) - .collect() -} - -pub fn transform_ipv6_flow_data( - original: HashMap, -) -> HashMap { - original - .into_iter() - .map(|(key, value)| (key.into_string(), FlowStats::from(value))) - .collect() -} diff --git a/net-guardia/src/web/utils/mod.rs b/net-guardia/src/web/utils/mod.rs index d751bb0..eae45eb 100644 --- a/net-guardia/src/web/utils/mod.rs +++ b/net-guardia/src/web/utils/mod.rs @@ -1,2 +1 @@ pub mod flow_websocket; -pub mod map_util; \ No newline at end of file