From dbacd4c58556845bcb5ff0df335f037223ce05a1 Mon Sep 17 00:00:00 2001 From: containerscrew Date: Thu, 5 Dec 2024 00:20:53 +0100 Subject: [PATCH] Fix prefix_len dynamically --- nflux-ebpf/src/actions.rs | 10 ------ nflux-ebpf/src/main.rs | 64 +++++++++++++++++++-------------------- nflux.toml | 5 ++- nflux/src/main.rs | 2 +- 4 files changed, 34 insertions(+), 47 deletions(-) delete mode 100644 nflux-ebpf/src/actions.rs diff --git a/nflux-ebpf/src/actions.rs b/nflux-ebpf/src/actions.rs deleted file mode 100644 index a8c9ebf..0000000 --- a/nflux-ebpf/src/actions.rs +++ /dev/null @@ -1,10 +0,0 @@ -use alloc::string::String; -use aya_ebpf::bindings::xdp_action; - -pub fn set_default_action(action: String) { - let default_action = match action.as_str() { - "allow" => xdp_action::XDP_PASS, - "block" => xdp_action::XDP_DROP, - _ => xdp_action::XDP_DROP, - }; -} diff --git a/nflux-ebpf/src/main.rs b/nflux-ebpf/src/main.rs index 8f2552f..3924a49 100644 --- a/nflux-ebpf/src/main.rs +++ b/nflux-ebpf/src/main.rs @@ -74,50 +74,48 @@ fn start_nflux(ctx: XdpContext) -> Result { let source_ip = u32::from_be(unsafe { (*ipv4hdr).src_addr }); let proto = unsafe { (*ipv4hdr).proto }; - let key = Key::new( - 32, - LpmKeyIpv4 { - prefix_len: 32, - ip: source_ip, - }, - ); - - if let Some(rule) = IPV4_RULES.get(&key) { - match proto { - IpProto::Tcp => { - let tcphdr: *const TcpHdr = - unsafe { ptr_at(&ctx, EthHdr::LEN + Ipv4Hdr::LEN)? }; - let dst_port = u16::from_be(unsafe { (*tcphdr).dest }); - - if rule.ports.contains(&dst_port) { - if rule.action == 1 { + for prefix_len in (1..=32).rev() { + let key = Key::new( + prefix_len, + LpmKeyIpv4 { + prefix_len, + ip: source_ip & (u32::MAX << (32 - prefix_len)), + }, + ); + + if let Some(rule) = IPV4_RULES.get(&key) { + match proto { + IpProto::Tcp => { + let tcphdr: *const TcpHdr = + unsafe { ptr_at(&ctx, EthHdr::LEN + Ipv4Hdr::LEN)? }; + let dst_port = u16::from_be(unsafe { (*tcphdr).dest }); + + if rule.ports.contains(&dst_port) && rule.action == 1 { log_new_connection(ctx, source_ip, dst_port, 6); return Ok(xdp_action::XDP_PASS); } + return Ok(xdp_action::XDP_DROP); } - return Ok(xdp_action::XDP_DROP); - } - IpProto::Udp => { - let udphdr: *const UdpHdr = - unsafe { ptr_at(&ctx, EthHdr::LEN + Ipv4Hdr::LEN)? }; - let dst_port = u16::from_be(unsafe { (*udphdr).dest }); + IpProto::Udp => { + let udphdr: *const UdpHdr = + unsafe { ptr_at(&ctx, EthHdr::LEN + Ipv4Hdr::LEN)? }; + let dst_port = u16::from_be(unsafe { (*udphdr).dest }); - if rule.ports.contains(&dst_port) { - if rule.action == 1 { + if rule.ports.contains(&dst_port) && rule.action == 1 { log_new_connection(ctx, source_ip, dst_port, 17); return Ok(xdp_action::XDP_PASS); } + return Ok(xdp_action::XDP_DROP); } - return Ok(xdp_action::XDP_DROP); - } - IpProto::Icmp => { - if rule.action == 1 { - log_new_connection(ctx, source_ip, 0, 1); - return Ok(xdp_action::XDP_PASS); + IpProto::Icmp => { + if rule.action == 1 { + log_new_connection(ctx, source_ip, 0, 1); + return Ok(xdp_action::XDP_PASS); + } + return Ok(xdp_action::XDP_DROP); } - return Ok(xdp_action::XDP_DROP); + _ => return Ok(xdp_action::XDP_DROP), } - _ => return Ok(xdp_action::XDP_DROP), } } diff --git a/nflux.toml b/nflux.toml index 0719914..a821855 100644 --- a/nflux.toml +++ b/nflux.toml @@ -9,9 +9,8 @@ log_type = "text" # text or json. Defaults to text if not set [ip_rules] # Fine-tuned rules for IP-based filtering -"192.168.0.0/24" = { priority = 1, action = "allow", ports = [22], log = false, protocol = "tcp", description = "Allow SSH from entire local subnet" } -"192.168.0.172/32" = { priority = 2, action = "deny", ports = [53], protocol = "udp", log = false, description = "Block UDP port" } -# "192.168.0.170/24" = { priority = 2, action = "deny", ports = [22], protocol = "tcp", log = false, description = "Deny SSH from entire subnet" } +"192.168.0.0/24" = { priority = 1, action = "deny", ports = [22], log = false, protocol = "tcp", description = "Allow SSH from entire local subnet" } +# "192.168.0.172/32" = { priority = 2, action = "deny", ports = [53], protocol = "udp", log = false, description = "Block UDP port" } # "2001:0db8:85a3:0000:0000:8a2e:0370:7334" = { action = "deny", ports = [80], protocol = "tcp" } # [icmp_rules] diff --git a/nflux/src/main.rs b/nflux/src/main.rs index 30453e6..082b0af 100644 --- a/nflux/src/main.rs +++ b/nflux/src/main.rs @@ -131,7 +131,6 @@ fn populate_ipv4_rules(bpf: &mut Ebpf, ip_rules: &HashMap) -> any sorted_rules.sort_by_key(|(_, rule)| rule.priority); for (cidr, rule) in sorted_rules { - println!("Loading rule: CIDR={}, {:?}", cidr, rule); let (ip, prefix_len) = parse_cidr_v4(cidr)?; let ip_rule = prepare_ip_rule(rule)?; @@ -142,6 +141,7 @@ fn populate_ipv4_rules(bpf: &mut Ebpf, ip_rules: &HashMap) -> any ip: ip.into(), }, ); + ipv4_map .insert(&key, &ip_rule, 0) .context("Failed to insert IPv4 rule")?;