mirror of
https://github.com/DaLaw2/NetGuardia.git
synced 2026-08-24 14:10:28 +09:00
Add ssh service protect
This commit is contained in:
parent
3d0970ad99
commit
e3d2ed077d
@ -11,7 +11,7 @@ pub const MAX_STATS: u32 = 100000;
|
||||
///
|
||||
/// Limits the number of rules that can be configured to ensure
|
||||
/// predictable performance and resource usage.
|
||||
pub const MAX_RULES: u32 = 32;
|
||||
pub const MAX_RULES: u32 = 1000;
|
||||
/// Maximum number of port-specific rules allowed
|
||||
///
|
||||
/// Defines the upper limit for port-based filtering rules to maintain
|
||||
|
||||
@ -3,4 +3,5 @@ pub mod flow_stats;
|
||||
pub mod http_method;
|
||||
pub mod ip_address;
|
||||
pub mod packet_status;
|
||||
pub mod placeholder;
|
||||
pub mod pseudo_header;
|
||||
|
||||
1
net-guardia-common/src/model/placeholder.rs
Normal file
1
net-guardia-common/src/model/placeholder.rs
Normal file
@ -0,0 +1 @@
|
||||
pub type PlaceHolder = u8;
|
||||
@ -5,40 +5,30 @@ use net_guardia_common::model::ip_address::{IPv4, IPv6, Port};
|
||||
use net_guardia_common::{MAX_RULES, MAX_RULES_PORT};
|
||||
|
||||
#[map]
|
||||
static BLOCKED_IPV4: HashMap<IPv4, [Port; MAX_RULES_PORT]> =
|
||||
static PERMANENT_BLACKLIST_IPV4: HashMap<IPv4, [Port; MAX_RULES_PORT]> =
|
||||
HashMap::with_max_entries(MAX_RULES, 0);
|
||||
#[map]
|
||||
static BLOCKED_IPV6: HashMap<IPv6, [Port; MAX_RULES_PORT]> =
|
||||
static PERMANENT_BLACKLIST_IPV6: HashMap<IPv6, [Port; MAX_RULES_PORT]> =
|
||||
HashMap::with_max_entries(MAX_RULES, 0);
|
||||
|
||||
pub fn should_block_ipv4(event: &IPv4Event) -> bool {
|
||||
unsafe {
|
||||
if let Some(ports) = BLOCKED_IPV4.get(&event.source_ip) {
|
||||
if let Some(ports) = PERMANENT_BLACKLIST_IPV4.get(&event.source_ip) {
|
||||
if is_port_blocked(ports, event.source_port) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
if let Some(ports) = BLOCKED_IPV4.get(&event.destination_ip) {
|
||||
if is_port_blocked(ports, event.destination_port) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
false
|
||||
}
|
||||
|
||||
pub fn should_block_ipv6(event: &IPv6Event) -> bool {
|
||||
unsafe {
|
||||
if let Some(ports) = BLOCKED_IPV6.get(&event.source_ip) {
|
||||
if let Some(ports) = PERMANENT_BLACKLIST_IPV6.get(&event.source_ip) {
|
||||
if is_port_blocked(ports, event.source_port) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
if let Some(ports) = BLOCKED_IPV6.get(&event.destination_ip) {
|
||||
if is_port_blocked(ports, event.destination_port) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
false
|
||||
}
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
pub mod forward;
|
||||
pub mod blocking;
|
||||
pub mod detect;
|
||||
pub mod defence;
|
||||
pub mod forward;
|
||||
pub mod monitor;
|
||||
pub mod service;
|
||||
|
||||
@ -1,7 +1,8 @@
|
||||
use aya_ebpf::maps::HashMap;
|
||||
use aya_ebpf::maps::{Array, HashMap};
|
||||
use net_guardia_common::model::event::{IPv4Event, IPv6Event};
|
||||
use net_guardia_common::model::http_method::EbpfHttpMethod;
|
||||
use net_guardia_common::model::ip_address::{EbpfAddrPortV4, EbpfAddrPortV6};
|
||||
use net_guardia_common::model::ip_address::{EbpfAddrPortV4, EbpfAddrPortV6, IPv4, IPv6};
|
||||
use net_guardia_common::model::placeholder::PlaceHolder;
|
||||
use net_guardia_common::MAX_RULES;
|
||||
|
||||
static HTTP_SERVICE_V4: HashMap<EbpfAddrPortV4, EbpfHttpMethod> =
|
||||
@ -9,35 +10,47 @@ static HTTP_SERVICE_V4: HashMap<EbpfAddrPortV4, EbpfHttpMethod> =
|
||||
static HTTP_SERVICE_V6: HashMap<EbpfAddrPortV6, EbpfHttpMethod> =
|
||||
HashMap::with_max_entries(MAX_RULES, 0);
|
||||
|
||||
pub fn ipv4_service_rule(event: &IPv4Event, start: usize, end: usize, offset: usize) -> bool {
|
||||
static SSH_WHITE_LIST_ONLY: Array<PlaceHolder> = Array::with_max_entries(1, 0);
|
||||
static IPV4_SSH_SERVICE: HashMap<EbpfAddrPortV4, PlaceHolder> =
|
||||
HashMap::with_max_entries(MAX_RULES, 0);
|
||||
static IPV6_SSH_SERVICE: HashMap<EbpfAddrPortV6, PlaceHolder> =
|
||||
HashMap::with_max_entries(MAX_RULES, 0);
|
||||
static IPV4_SSH_WHITE_LIST: HashMap<IPv4, PlaceHolder> = HashMap::with_max_entries(MAX_RULES, 0);
|
||||
static IPV6_SSH_WHITE_LIST: HashMap<IPv6, PlaceHolder> = HashMap::with_max_entries(MAX_RULES, 0);
|
||||
static IPV4_SSH_BLACK_LIST: HashMap<IPv4, PlaceHolder> = HashMap::with_max_entries(MAX_RULES, 0);
|
||||
static IPV6_SSH_BLACK_LIST: HashMap<IPv6, PlaceHolder> = HashMap::with_max_entries(MAX_RULES, 0);
|
||||
|
||||
pub fn ipv4_service_rule_violation(event: &IPv4Event, start: usize, end: usize, offset: usize) -> bool {
|
||||
let source = event.get_source();
|
||||
let destination = event.get_destination();
|
||||
ipv4_http_service(destination, start, end, offset)
|
||||
ipv4_http_service_violation(&destination, start, end, offset) || ipv4_ssh_service_violation(&source, &destination)
|
||||
}
|
||||
|
||||
pub fn ipv6_service_rule(event: &IPv6Event, start: usize, end: usize, offset: usize) -> bool {
|
||||
pub fn ipv6_service_rule_violation(event: &IPv6Event, start: usize, end: usize, offset: usize) -> bool {
|
||||
let source = event.get_source();
|
||||
let destination = event.get_destination();
|
||||
ipv6_http_service(destination, start, end, offset)
|
||||
ipv6_http_service_violation(&destination, start, end, offset) || ipv6_ssh_service_violation(&source, &destination)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn ipv4_http_service(addr_port: EbpfAddrPortV4, start: usize, end: usize, offset: usize) -> bool {
|
||||
match HTTP_SERVICE_V4.get_ptr_mut(&addr_port) {
|
||||
fn ipv4_http_service_violation(addr_port: &EbpfAddrPortV4, start: usize, end: usize, offset: usize) -> bool {
|
||||
match HTTP_SERVICE_V4.get_ptr_mut(addr_port) {
|
||||
Some(allow_method) => match get_http_request_method(start, end, offset) {
|
||||
Some(http_method) => unsafe { *allow_method & http_method != 0 },
|
||||
None => false,
|
||||
Some(http_method) => unsafe { *allow_method & http_method == 0 },
|
||||
None => true,
|
||||
},
|
||||
None => true,
|
||||
None => false,
|
||||
}
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn ipv6_http_service(addr_port: EbpfAddrPortV6, start: usize, end: usize, offset: usize) -> bool {
|
||||
match HTTP_SERVICE_V6.get_ptr_mut(&addr_port) {
|
||||
fn ipv6_http_service_violation(addr_port: &EbpfAddrPortV6, start: usize, end: usize, offset: usize) -> bool {
|
||||
match HTTP_SERVICE_V6.get_ptr_mut(addr_port) {
|
||||
Some(allow_method) => match get_http_request_method(start, end, offset) {
|
||||
Some(http_method) => unsafe { *allow_method & http_method != 0 },
|
||||
None => false,
|
||||
Some(http_method) => unsafe { *allow_method & http_method == 0 },
|
||||
None => true,
|
||||
},
|
||||
None => true,
|
||||
None => false,
|
||||
}
|
||||
}
|
||||
|
||||
@ -60,3 +73,33 @@ fn get_http_request_method(start: usize, end: usize, offset: usize) -> Option<Eb
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn ipv4_ssh_service_violation(source_ip: &EbpfAddrPortV4, destination: &EbpfAddrPortV4) -> bool {
|
||||
unsafe {
|
||||
if IPV4_SSH_SERVICE.get(destination).is_some() {
|
||||
if SSH_WHITE_LIST_ONLY.get(0).is_some() {
|
||||
IPV4_SSH_WHITE_LIST.get(&source_ip[0]).is_none()
|
||||
} else {
|
||||
IPV4_SSH_BLACK_LIST.get(&source_ip[0]).is_some()
|
||||
}
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn ipv6_ssh_service_violation(source_ip: &EbpfAddrPortV6, destination: &EbpfAddrPortV6) -> bool {
|
||||
unsafe {
|
||||
if IPV6_SSH_SERVICE.get(destination).is_some() {
|
||||
if SSH_WHITE_LIST_ONLY.get(0).is_some() {
|
||||
IPV6_SSH_WHITE_LIST.get(&source_ip[0]).is_none()
|
||||
} else {
|
||||
IPV6_SSH_BLACK_LIST.get(&source_ip[0]).is_some()
|
||||
}
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -10,6 +10,7 @@ use aya_ebpf::{bindings::xdp_action, macros::xdp, programs::XdpContext};
|
||||
#[allow(unused_imports)]
|
||||
use aya_log_ebpf::info;
|
||||
use network_types::eth::EtherType;
|
||||
use crate::action::service;
|
||||
|
||||
#[xdp]
|
||||
pub fn net_guardia(ctx: XdpContext) -> u32 {
|
||||
@ -29,7 +30,9 @@ fn try_net_guardia(ctx: XdpContext) -> Result<u32, ()> {
|
||||
if blocking::should_block_ipv4(&event) {
|
||||
return Ok(xdp_action::XDP_DROP);
|
||||
}
|
||||
|
||||
if service::ipv4_service_rule_violation(&event, start, end, offset) {
|
||||
return Ok(xdp_action::XDP_DROP);
|
||||
}
|
||||
monitor::update_stats_ipv4(&event);
|
||||
}
|
||||
EtherType::Ipv6 => {
|
||||
@ -37,6 +40,9 @@ fn try_net_guardia(ctx: XdpContext) -> Result<u32, ()> {
|
||||
if blocking::should_block_ipv6(&event) {
|
||||
return Ok(xdp_action::XDP_DROP);
|
||||
}
|
||||
if service::ipv6_service_rule_violation(&event, start, end, offset) {
|
||||
return Ok(xdp_action::XDP_DROP);
|
||||
}
|
||||
monitor::update_stats_ipv6(&event);
|
||||
}
|
||||
_ => Err(())?,
|
||||
|
||||
@ -2,7 +2,7 @@ use aya::maps::{HashMap as AyaHashMap, MapData};
|
||||
use net_guardia_common::MAX_RULES_PORT;
|
||||
use net_guardia_common::model::ip_address::{IPv4, IPv6, Port};
|
||||
|
||||
pub struct Blocking {
|
||||
pub struct Control {
|
||||
ipv4_black_list: AyaHashMap<MapData, IPv4, [Port; MAX_RULES_PORT]>,
|
||||
ipv6_black_list: AyaHashMap<MapData, IPv6, [Port; MAX_RULES_PORT]>,
|
||||
}
|
||||
@ -1,4 +1,4 @@
|
||||
pub mod config_manager;
|
||||
pub mod control;
|
||||
pub mod monitor;
|
||||
pub mod system;
|
||||
mod blocking;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user