Skip to content

Commit

Permalink
lol
Browse files Browse the repository at this point in the history
  • Loading branch information
adgaultier committed Oct 7, 2024
1 parent f3db11e commit 73ad77a
Show file tree
Hide file tree
Showing 2 changed files with 131 additions and 35 deletions.
42 changes: 34 additions & 8 deletions oryx-ebpf/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,13 +34,17 @@ static TRANSPORT_FILTERS: Array<u32> = Array::with_max_entries(8, 0);
static LINK_FILTERS: Array<u32> = Array::with_max_entries(8, 0);

#[map]
static BLOCKLIST_IPV6_INGRESS: HashMap<u128, u16> = HashMap::<u128, u16>::with_max_entries(128, 0);
static BLOCKLIST_IPV6_INGRESS: HashMap<u128, [u16; 32]> =
HashMap::<u128, [u16; 32]>::with_max_entries(128, 0);
#[map]
static BLOCKLIST_IPV6_EGRESS: HashMap<u128, u16> = HashMap::<u128, u16>::with_max_entries(128, 0);
static BLOCKLIST_IPV6_EGRESS: HashMap<u128, [u16; 32]> =
HashMap::<u128, [u16; 32]>::with_max_entries(128, 0);
#[map]
static BLOCKLIST_IPV4_INGRESS: HashMap<u32, u16> = HashMap::<u32, u16>::with_max_entries(128, 0);
static BLOCKLIST_IPV4_INGRESS: HashMap<u32, [u16; 32]> =
HashMap::<u32, [u16; 32]>::with_max_entries(128, 0);
#[map]
static BLOCKLIST_IPV4_EGRESS: HashMap<u32, u16> = HashMap::<u32, u16>::with_max_entries(128, 0);
static BLOCKLIST_IPV4_EGRESS: HashMap<u32, [u16; 32]> =
HashMap::<u32, [u16; 32]>::with_max_entries(128, 0);

#[classifier]
pub fn oryx(ctx: TcContext) -> i32 {
Expand Down Expand Up @@ -70,6 +74,28 @@ fn ptr_at<T>(ctx: &TcContext, offset: usize) -> Result<*const T, ()> {
Ok((start + offset) as *const T)
}

#[inline]
fn filter_for_ipv4_address(
addr: u32,
port: u16,
blocked_ports_map: &HashMap<u32, [u16; 32]>,
) -> bool {
if let Some(blocked_ports) = unsafe { blocked_ports_map.get(&addr) } {
for (idx, blocked_port) in blocked_ports.iter().enumerate() {
if *blocked_port == 0 {
if idx == 0 {
return true;
} else {
break;
}
} else if *blocked_port == port {
return true;
}
}
}
false
}

#[inline]
fn filter_packet(protocol: Protocol) -> bool {
match protocol {
Expand Down Expand Up @@ -108,8 +134,8 @@ fn process(ctx: TcContext) -> Result<i32, ()> {
let src_port = u16::from_be(unsafe { (*tcphdr).source });
let dst_port = u16::from_be(unsafe { (*tcphdr).dest });

if unsafe { BLOCKLIST_IPV4_INGRESS.get(&src_addr) } == Some(&src_port)
|| unsafe { BLOCKLIST_IPV4_EGRESS.get(&dst_addr) } == Some(&dst_port)
if filter_for_ipv4_address(src_addr, src_port, &BLOCKLIST_IPV4_INGRESS)
|| filter_for_ipv4_address(dst_addr, dst_port, &BLOCKLIST_IPV4_EGRESS)
{
return Ok(TC_ACT_SHOT);
}
Expand All @@ -129,8 +155,8 @@ fn process(ctx: TcContext) -> Result<i32, ()> {
let src_port = u16::from_be(unsafe { (*udphdr).source });
let dst_port = u16::from_be(unsafe { (*udphdr).dest });

if unsafe { BLOCKLIST_IPV4_INGRESS.get(&src_addr) } == Some(&src_port)
|| unsafe { BLOCKLIST_IPV4_EGRESS.get(&dst_addr) } == Some(&dst_port)
if filter_for_ipv4_address(src_addr, src_port, &BLOCKLIST_IPV4_INGRESS)
|| filter_for_ipv4_address(dst_addr, dst_port, &BLOCKLIST_IPV4_EGRESS)
{
return Ok(TC_ACT_SHOT);
}
Expand Down
124 changes: 97 additions & 27 deletions oryx-tui/src/ebpf.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use std::{
io,
net::IpAddr,
net::{IpAddr, Ipv4Addr, Ipv6Addr},
os::fd::AsRawFd,
sync::{atomic::AtomicBool, Arc},
thread::{self, spawn},
Expand Down Expand Up @@ -63,6 +63,86 @@ impl Source for RingBuffer<'_> {
}
}

fn update_ipv4_blocklist(
ipv4_firewall: &mut HashMap<MapData, u32, [u16; 32]>,
addr: Ipv4Addr,
port: u16,
enabled: bool,
) {
if let Ok(mut blocked_ports) = ipv4_firewall.get(&addr.to_bits(), 0) {
if enabled {
// add port to blocklist
if let Some(first_zero) = blocked_ports.iter().enumerate().find(|&x| *x.1 == 0) {
blocked_ports[first_zero.0] = port;
dbg!("UPSERTING");
dbg!(blocked_ports[0], blocked_ports[1]);
ipv4_firewall
.insert(addr.to_bits(), blocked_ports, 0)
.unwrap();
} else {
todo!(); // list is full
}
} else {
// remove port from blocklist
if let Some(matching_port) = blocked_ports.iter().enumerate().find(|&x| *x.1 == port) {
blocked_ports[matching_port.0] = 0;
dbg!("REMOVING");
dbg!(blocked_ports[0], blocked_ports[1]);
ipv4_firewall
.insert(addr.to_bits(), blocked_ports, 0)
.unwrap();
}
}
} else {
// shouldn't be disabling if blocklist is empty
assert!(enabled);
//create new blocklist with port as first element
let mut blocked_ports: [u16; 32] = [0; 32];
blocked_ports[0] = port;
ipv4_firewall
.insert(addr.to_bits(), blocked_ports, 0)
.unwrap();
}
}

fn update_ipv6_blocklist(
ipv6_firewall: &mut HashMap<MapData, u128, [u16; 32]>,
addr: Ipv6Addr,
port: u16,
enabled: bool,
) {
if let Ok(mut blocked_ports) = ipv6_firewall.get(&addr.to_bits(), 0) {
if enabled {
// add port to blocklist
if let Some(first_zero) = blocked_ports.iter().enumerate().find(|&x| *x.1 == 0) {
blocked_ports[first_zero.0] = port;
ipv6_firewall
.insert(addr.to_bits(), blocked_ports, 0)
.unwrap();
} else {
todo!(); // list is full
}
} else {
// remove port from blocklist
if let Some(matching_port) = blocked_ports.iter().enumerate().find(|&x| *x.1 == port) {
blocked_ports[matching_port.0] = 0;
ipv6_firewall
.insert(addr.to_bits(), blocked_ports, 0)
.unwrap();
}
}
} else {
// shouldn't be disabling if blocklist is empty
assert!(enabled);
//create new blocklist with port as first element
let mut blocked_ports: [u16; 32] = [0; 32];
blocked_ports[0] = port;
ipv6_firewall
.insert(addr.to_bits(), blocked_ports, 0)
.unwrap();
}
}

impl Ebpf {
pub fn load_ingress(
iface: String,
Expand Down Expand Up @@ -160,37 +240,27 @@ impl Ebpf {
let mut link_filters: Array<_, u32> =
Array::try_from(bpf.take_map("LINK_FILTERS").unwrap()).unwrap();
// firewall-ebpf interface
let mut ipv4_firewall: HashMap<_, u32, u16> =
let mut ipv4_firewall: HashMap<_, u32, [u16; 32]> =
HashMap::try_from(bpf.take_map("BLOCKLIST_IPV4_INGRESS").unwrap()).unwrap();
let mut ipv6_firewall: HashMap<_, u128, u16> =
let mut ipv6_firewall: HashMap<_, u128, [u16; 32]> =
HashMap::try_from(bpf.take_map("BLOCKLIST_IPV6_INGRESS").unwrap()).unwrap();

thread::spawn(move || loop {
if let Ok(rule) = firewall_ingress_receiver.recv() {
match rule.enabled {
true => match rule.ip {
IpAddr::V4(addr) => {
ipv4_firewall.insert(addr.to_bits(), rule.port, 0).unwrap();
}
IpAddr::V6(addr) => {
let _ = ipv6_firewall.insert(
u128::from_be_bytes(addr.octets()),
rule.port,
0,
);
}
},

false => match rule.ip {
IpAddr::V4(addr) => {
ipv4_firewall.remove(&addr.to_bits()).unwrap();
}

IpAddr::V6(addr) => {
let _ =
ipv6_firewall.remove(&u128::from_be_bytes(addr.octets()));
}
},
match rule.ip {
IpAddr::V4(addr) => update_ipv4_blocklist(
&mut ipv4_firewall,
addr,
rule.port,
rule.enabled,
),

IpAddr::V6(addr) => update_ipv6_blocklist(
&mut ipv6_firewall,
addr,
rule.port,
rule.enabled,
),
}
}
});
Expand Down

0 comments on commit 73ad77a

Please sign in to comment.