From 8417253e525131652ad0fa28cb7479dbd3117a47 Mon Sep 17 00:00:00 2001 From: sanjaybhat2004 Date: Fri, 20 Sep 2024 18:16:46 +0530 Subject: [PATCH 01/10] make readme more clean, move some lines to todo --- README.md | 25 ++----------------------- TODO.md | 24 +++++++++++++++++++++--- 2 files changed, 23 insertions(+), 26 deletions(-) diff --git a/README.md b/README.md index 8964a55..4db8e70 100644 --- a/README.md +++ b/README.md @@ -6,14 +6,12 @@ **FlowSentryX** is an open-source XDP-based fast packet processing DOS and DDOS Mitigation Framework solution designed to protect your network infrastructure from Denial of Service (DOS) and Distributed Denial of Service (DDOS) attacks at Layer 3 & 4. -> Current work is being done for Layer 3 based DOS and DDOS mitigation. +Current work is being done for Layer 3 based DOS and DDOS mitigation. The framework is a collection of XDP programs which track your network traffic and parse packets till the IP layer and make the descision to drop packets from malicious IP addresses using different algorithms and models for DOS and DDOS mitigation. We also plan to extend the ability BlackList IP addresses and write rules manually from the user space to block certain packets. The rules will be written in the config file which will be read by the xdp program and action will be taken accordingly, hence extending the framework to act as a _Basic Firewall_. -> Refine this text , use better words like packet inspection and filtering, Logging etc. - ## Table of Contents @@ -61,38 +59,25 @@ This framework is a set of [xdp](https://www.iovisor.org/technology/xdp) program The XDP programs parse all the packets in the ingress network traffic till the IP layer and make the descision to drop packets from malicious IP addresses using some Rate Limiting Algorithms like token bucket algorithm, fixed window algorithm and sliding window algorithm for DOS attack mitigation and using the features extracted from the packets and passing them to a trained ML model in the user space for inference of deciding whether that particular IP was involved in the DDOS attack. -> Explain why XDP is faster and why we plan to use it. - -> Describe the project in a little bit more detail and refine this. ### Why DOS/DDOS Mitigation? DOS and DDOS attacks can disrupt your network, causing downtime and financial losses. Our framework helps you safeguard your infrastructure by efficiently filtering malicious traffic, ensuring your network remains operational. - > Write about different Attach here the content from cloudfare blog - Ping of Death - Flood Attacks - Buffer overflow Attacks - > Also Write in detail about DDOS attack - ### Basic Firewall -> Fill this section with how we plan to extend our project to a stateless Firewall with Dynamic DOS and DDOS mitigation abilities. - We plan to extend the framework to an XDP based stateless Firewall, by allowing config files where the user can manually configure parameters such as the Threshold values and the time duration for black listing the IP address for the already existing features. We also plan to add Dynamic Rule Management to Manage dynamic rules and configurations, such as adding or removing IP addresses from the blocklist. This component can communicate with the kernel space to apply or remove rules as needed. Also we plan to add config files which can be used to blacklist user configured IP's and rules to drop certain packets. -> Need a better description for the above - ## Installation and Usage **Note**: This section is under development. -> Add Link to the Dependencies.md page and also like a checklist version of required features - - This section will provide clear instructions on how to install and run the framework. We'll include details on dependencies, installation commands, and sample usage commands. A setup script will be provided to simplify the installation process. ### Prerequisites @@ -146,7 +131,6 @@ The XDP-based DOS and DDOS Mitigation Framework operates at the network level to - The plan is to create 2 Maps - Rate of Packet Arrival(per sec) per IP, and a normal Black listed IP table. - The packet arrival per IP per sec table is going to be updated with the count of the packet and then we need to refresh the table every one second for now - The algorithm that is going to be used is the simple Fixed window algorithm. - We pick the blacklisted to the BlackList IP table and drop the packets for that particular IP. - - _I think that is it_ - **User Space Program** : - _Clear the BlackList IP table_ - @@ -157,10 +141,6 @@ The XDP-based DOS and DDOS Mitigation Framework operates at the network level to - **eBPF Maps and Datastructures** - We are planning to use BPF_HASH_ARRAY_TYPE map for storing the IP address and the Packet Per second - - - - -> Need a way better description for the above ## Rate Limiting Algorithms @@ -225,7 +205,7 @@ Some other resources 30) Hooking : https://en.wikipedia.org/wiki/Hooking 31) eBPF.io : https://ebpf.io/what-is-ebpf/#development-toolchains -References from others (Didn't go through them) +References from others: 32) https://www.youtube.com/watch?v=iBkR4gvjxtE 33) https://blog.yadutaf.fr/2017/07/28/tracing-a-packet-journey-using-linux-tracepoints-perf-ebpf/ @@ -272,7 +252,6 @@ Rate Limiting Blogs: 54) [token bucket, fixed and sliding window ](https://dev.to/satrobit/rate-limiting-using-the-token-bucket-algorithm-3cjh) -> Need to reorder and neatly write it ## Project Status This project is currently in the development phase. We are actively working on building the framework and welcome contributions from the open-source community. diff --git a/TODO.md b/TODO.md index 3fc435a..e48a8fb 100644 --- a/TODO.md +++ b/TODO.md @@ -106,10 +106,28 @@ For now we are doing layer 3 based DOS mitigation _Dynamic Rules Management_: You can create a user space component that communicates with the kernel space to add or remove IP addresses from the blocklist dynamically. +ToDo List: + + - [ ] Integrating the in-kernel ml model + + - [ ] Refine Readme text, use better words like packet inspection and filtering, Logging etc. -Integrating the in-kernel ml model - - + - [ ] Explain why XDP is faster and why we plan to use it. + + - [ ] Describe the project in a little bit more detail and refine this. + + - [ ] Write about different Attach here the content from cloudfare blog + + - [ ] Also Write in detail about DDOS attack + + - [ ] Fill this section with how we plan to extend our project to a stateless Firewall with Dynamic DOS and DDOS mitigation abilities. + + - [ ] Add Link to the Dependencies.md page and also like a checklist version of required features + + - [ ] Need a way better description for the System Architechture section + + + From 0927d2e05663d63c93387ee248f85c4e21864063 Mon Sep 17 00:00:00 2001 From: sanjaybhat2004 Date: Sat, 21 Sep 2024 01:41:22 +0530 Subject: [PATCH 02/10] Add install_dependencies script as well update README.md to have installation instructions --- README.md | 17 ++++++++++++----- install_dependencies.sh | 14 ++++++++++++++ src/fsx_kern.o | Bin 23904 -> 23864 bytes 3 files changed, 26 insertions(+), 5 deletions(-) create mode 100755 install_dependencies.sh diff --git a/README.md b/README.md index 4db8e70..698e8eb 100644 --- a/README.md +++ b/README.md @@ -101,11 +101,18 @@ Refer to [Dependencies](Dependencies.md). ### Installation -To install the framework, follow these steps: - -1. Step-by-step installation instructions. -2. Include any scripts or commands necessary for setup. -3. Submodules - Installation +To install the framework on Debian/Ubuntu, follow these steps: + +1. Clone the repo using the following command: +``` +git clone --recurse-submodules https://github.com/MeherRushi/FlowSentryX.git +``` +2. Then, type the following command to go into the repo and install all the dependencies required: +``` +cd FlowSentryX +chmod +x ./install_dependencies.sh +./install_dependencies.sh +``` ### Usage Provide guidance on how to use the framework: diff --git a/install_dependencies.sh b/install_dependencies.sh new file mode 100755 index 0000000..50887f3 --- /dev/null +++ b/install_dependencies.sh @@ -0,0 +1,14 @@ +sudo apt install clang llvm libelf-dev libpcap-dev build-essential libc6-dev-i386 m4 +sudo apt install linux-headers-$(uname -r) +sudo apt install linux-tools-$(uname -r) +sudo apt install linux-tools-common linux-tools-generic +sudo apt install tcpdump + +cd modules/xdp-tools +./configure +make +make install +cd ../../ +cd src +make +cd .. \ No newline at end of file diff --git a/src/fsx_kern.o b/src/fsx_kern.o index d601259ace8acd391c88635d165ef33215ad83ff..49ba1da1a1ec3982df95a9d37fb2b58981b0016f 100644 GIT binary patch delta 4087 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 J$jV(f?0=ow-oO9= delta 4077 zcmaKv4RBP|701teckjzC*@fMZ$YK)nvIMeA!b?EM07*z1#6&*Egr*oE8u?fz0TLpK zAE0ET)gg#uA=i;0wT%^qR5La)R6?*AXQ&0W8m!tNilO)sEVYbNHFhfP|L)$^m1(;( zzs>obd+vSb-S@H3KcI~aXuJHnxvY2kTOKXg_pN7#uI2S@Pdu%MR(B9lI<2DB>*I)g z+O-s1pd-+8slj3h*lJoA&e#fR{c|$IYpL$64S`Wdo8)v~+Qhqo} znM<`LXdq(@4aUtzJ#BM}G_R>WB8t6NhuSCl;|I~#G_7g~e<(oH_1*p&I$+_#;AzkWUeqW=LkQjnAA`@qmq5oAaDgO{4zj@YK;9^eKowXCYQTEX1h#_v!OuVk z=mZDBv!D+QfYlzCiF#V8gW^2i#yXm;z>i>p&rx4{ib#U>R5g>OeiX z18f2Jfrr2j&<;94C)f`TgIB>D;9c+@I9q_P^WbmbTj0c9x~qBo;dtM2{{zhBL1b zUuRZ|#r`z0(VuVg*EL=*Y61mf)bAGG_*aRQfpXCuIP9I))V!*>siuBaW6g%(mOwt4 z_|&cQ3oR>A?4G{c@HcF_+nguA7q|JCpuUjX|vywz(_SNDu|5ajm z#tdOt4ROJZO+m~T$Fg(8lYvz68*66YISX@=b3b~1W`!myXO)HIO-OAT+41KV#Lt1i zV;Z@YkHDvPXyk>D!>zFdjK4_ak8uN@t9+*%w`o+a<`2N_V_Nv3lIx#>J5zLOjf{tA zR2KMk+NBoo;L^vJYt$Lz2D~RSfwC~}n2kwTOfI+??pdqj{SooU;r2G2{K_#c{K-{* z0ORH^ovOl)oBk`g;A1-VTrr_vd30RvgxrBl+;2`irk7&eE+1Qr{h%S`C8&4d5j2%A zgI9Fvlq)@ic`{)lAs^-NC4f76bQ->5!pIflW6DQl{h&_eI1xENdVnhB(eXy*mr)-- zic0_w$qCUCHco}uX zxD(!K!%I&Vhw$V4Nu{&l#0 zgwbr}(H$t`xc;&r`YBfh(H&@2{()?u%tpJEe*yO|woylnd*PkR)9`!cEw@ou%y>G+ zdt!Vdd@vM~@E~zQc_9{Xt+mmJ@@RvE1Ivah2P-? zo(ko8@U&1h9wU`lj>J{?i5*ma7koZ`6^CNnBY!2)h-@JIV!<GW3o*er#;8?!5T5)GMqSFI_t2p72QltSvC)w7 zBk)qwM#JCxTFOIW3%!~%2h++?l}SN zBk|OnsUi6@brVvwwoU0g(qhE_cuhN!?6VIS?tF9W@lStOpZ&tR1-_E~ zNZM8mzu123bJv`>_o%Heapy*F{xfoZT>6$ZWpNLWx=!BTdG`FdZ;#5-XPNol=7u{@ z+wM;}f5V==*S#W>OD}GD`q7)Zx22vucjG|Y!QMAy^5(dO+f$FbPwp`ObmR8m{2lMe zu9@6E(_mi-SN`PCqc9JP{{?Ctmch=pnA|kjeyzY@@3$=E4uc&) z1sUv2OE-5&L1f`jSm|pj;C91eJ3_c*++(o4D0Q(3SZ5gPR2b|TBurGi8(FFwT5*Xx zdHhX1u0h!QZyXj@YP-J5Zfyu+L=tcqBh2{nO}O}vVH5#}7idaomv zZ(2x!-1awhtlS$}>@D5m$@b;kwWuG}-I%Ny?7WWscoMPOVDDfD(=haFT!E_$_DAS^ zAC6$LUhIi0WUz}`0Wa}kt1Q<3-8S(QA7-QR0`4<1c=8N`{S^BaK26*jFJp0>%64>C zn#1!@SZwlHXw%}U#*{SNTxc&`Y~lYmnwC?$sXmzVU;g=SME?CQ_7$G)yJz0;Bt5QD zEM0a?+tuf}I|JK O#aq?$v^L?nHS<3_$=*l+ From e4cffaf53e7d998579e25672369e855d8517321f Mon Sep 17 00:00:00 2001 From: Sidhub723 Date: Tue, 1 Oct 2024 17:15:06 +0530 Subject: [PATCH 03/10] Fixed link in references --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 698e8eb..46dc6ef 100644 --- a/README.md +++ b/README.md @@ -163,7 +163,7 @@ We plan to implement a static window rate limiting algorithm. This algorithm tra ## References -- [Learning eBPF and XDP Repository](https://example.com/learning-ebpf-xdp): This repository provided valuable insights into the technologies used in this project. +- [Learning eBPF and XDP Repository](https://github.com/lizrice/learning-ebpf): This repository provided valuable insights into the technologies used in this project. References and Literature Survey From 541cc61b09f0c92b2bace01f9cb844fb2f85ab32 Mon Sep 17 00:00:00 2001 From: Amruth Date: Wed, 27 Nov 2024 16:44:19 +0530 Subject: [PATCH 04/10] Makefile: added load and detach commands --- src/Makefile | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/src/Makefile b/src/Makefile index bf75626..f9a7f8f 100644 --- a/src/Makefile +++ b/src/Makefile @@ -2,6 +2,7 @@ TARGETS = fsx HEADERS = fsx_struct.h parsing_helper.h INCLUDE_DIRS = -I/usr/include/$(shell uname -m)-linux-gnu -I . +IFACE = lo all: $(TARGETS) .PHONY: all @@ -19,4 +20,15 @@ $(TARGETS): % : %_kern.o clean: - rm *.o - - rm -f /sys/fs/bpf/$(TARGETS) \ No newline at end of file + - rm -f /sys/fs/bpf/$(TARGETS) + + +load: fsx_kern.o + sudo ip link set dev $(IFACE) xdp obj fsx_kern.o section xdp + sudo mkdir -p /sys/fs/bpf + sudo mount -t bpf none /sys/fs/bpf +#pin any maps here + +detach: + sudo ip link set dev $(IFACE) xdp off +#remove the pinned maps here \ No newline at end of file From 89fc44fe938d5bfe86541fe7be54974f5b58d058 Mon Sep 17 00:00:00 2001 From: Amruth Date: Wed, 27 Nov 2024 16:48:25 +0530 Subject: [PATCH 05/10] fsx_struct.h: added structs for tcp_syn, tcp_rst --- src/fsx_struct.h | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/src/fsx_struct.h b/src/fsx_struct.h index 8de915e..775a2e8 100644 --- a/src/fsx_struct.h +++ b/src/fsx_struct.h @@ -21,5 +21,31 @@ struct ip_stats __u64 track_time; // time at which the packet arrived }; +struct tcp_rst_port_node{ + __u64 port_time; + __u32 rst_cnt; + struct bpf_spin_lock semaphore; +}; + +struct tcp_syn__u128 { + __u64 hi; // Higher 64 bits for IPv6 + __u64 lo; // Lower 64 bits for IPv6 +}; + +union tcp_syn_ip_address { + __u32 ipv4; // 32-bit IPv4 address + struct tcp_syn__u128 ipv6; // 128-bit IPv6 address +}; + +struct tcp_syn_packet_id_key{ + union tcp_syn_ip_address ipadd; // IPv4 or IPv6 + __u16 dest; + __u16 source; + __u8 ip_type; +}; +struct Semp{ + struct bpf_spin_lock semaphore; +}; + #endif \ No newline at end of file From 71a8afec606bbe38cfb5cafa6794e36c03e9bfeb Mon Sep 17 00:00:00 2001 From: Amruth Date: Wed, 27 Nov 2024 16:55:10 +0530 Subject: [PATCH 06/10] fsx_kern.c: added maps for tcp_syn and tcp_rst --- src/fsx_kern.c | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/src/fsx_kern.c b/src/fsx_kern.c index 2cd645c..e1309c1 100644 --- a/src/fsx_kern.c +++ b/src/fsx_kern.c @@ -13,6 +13,13 @@ in the fsx_struct.h map */ #include "fsx_struct.h" #include "parsing_helper.h" + +#define SIZEOFPORTS_RST 65536 //number of ports +#define TIMEOUT_RST 1000000000 //1 sec +#define THRESHOLD_RST 100 //limit on number of packets to be configurable later +#define LIMIT_SYN 100 //limit on number of packets to be configurable later +#define EXTRA_TIME_SYN 1000000000 //1 sec + #ifndef memcpy #define memcpy(dest, src, n) __builtin_memcpy((dest), (src), (n)) #endif @@ -93,6 +100,27 @@ struct __type(value, __u64); } ipv6_blacklist_map SEC(".maps"); +struct { + __uint(type, BPF_MAP_TYPE_ARRAY); + __uint(max_entries, 2); + __type(key, __u32); + __type(value, __u64); +} tcp_syn_size_oldtime SEC(".maps"); + +struct { + __uint(type, BPF_MAP_TYPE_LRU_HASH); + __uint(max_entries, 1000); + __type(key, struct tcp_syn_packet_id_key); + __type(value, __u64); +} tcp_syn_lru_hash_map SEC(".maps"); + +struct { + __uint(type, BPF_MAP_TYPE_ARRAY); + __uint(max_entries, SIZEOFPORTS_RST); + __type(key, __u32); + __type(value, struct tcp_rst_port_node); +} tcp_rst_port SEC(".maps"); + SEC("xdp") int fsx(struct xdp_md *ctx) { From ca3a31c8f8223046beca59dcdf6acee9d0fff2c3 Mon Sep 17 00:00:00 2001 From: Amruth Date: Wed, 27 Nov 2024 16:56:21 +0530 Subject: [PATCH 07/10] fsx_kern.c: added functionality for tcp_syn and tcp_rst --- src/fsx_kern.c | 155 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 155 insertions(+) diff --git a/src/fsx_kern.c b/src/fsx_kern.c index e1309c1..8ac19e2 100644 --- a/src/fsx_kern.c +++ b/src/fsx_kern.c @@ -371,6 +371,161 @@ int fsx(struct xdp_md *ctx) bpf_printk("No of packets allowed %llu\n", stats->allowed); } + struct tcphdr *tcp=NULL; + struct udphdr *udp = NULL; + struct icmphdr *icmp = NULL; + + __u32 zero = 0,one = 1; + struct tcp_syn_packet_id_key packet_key; + __u32 application_layer_type = 0; //1 for tcp, 2 for udp, 3 for icmp + if(ip4hdr){ + packet_key.ip_type = 1; + packet_key.ipadd.ipv4 = ip4hdr->saddr; + if (ip4hdr->protocol == IPPROTO_TCP) { + tcp = (void *)((unsigned char *)ip4hdr + (ip4hdr->ihl * 4)); + application_layer_type = 1; + if ((void *)(tcp + 1) > data_end){ + return XDP_PASS; + } + } + else if(ip4hdr->protocol == IPPROTO_UDP){ + udp = (void*)(unsigned char *)ip4hdr + (ip4hdr->ihl * 4); + application_layer_type = 2; + if ((void *)(udp + 1) > data_end) { + return XDP_PASS; + } + } + else if(ip4hdr->protocol == IPPROTO_ICMP) { + icmp = (void *)((unsigned char *)ip4hdr + (ip4hdr->ihl * 4)); + application_layer_type = 3; + if ((void *)(icmp + 1) > data_end) { + return XDP_PASS; + } + } + } + else if(ip6hdr){ + packet_key.ip_type = 2; + __builtin_memcpy(&packet_key.ipadd.ipv6, &ip6hdr->saddr, sizeof(struct in6_addr)); + if (ip6hdr->nexthdr == IPPROTO_TCP){ + tcp = (void *)((unsigned char *)ip6hdr + 1); + application_layer_type = 1; + if ((void *)(tcp + 1) > data_end){ + return XDP_PASS; + } + } + else if(ip6hdr->nexthdr == IPPROTO_UDP){ + udp = (void *)((unsigned char *)ip6hdr + 1); + application_layer_type = 2; + if ((void *)(udp + 1) > data_end){ + return XDP_PASS; + } + } + // icmpv6 here + } + + if(application_layer_type==1 && tcp!=NULL){ + return XDP_PASS; + } + else if(application_layer_type==1 && tcp){ + packet_key.dest = tcp->dest; + packet_key.source = tcp->source; + __u64 *size_allowed,*old_time; + __u32 dest = tcp->dest; + size_allowed = bpf_map_lookup_elem(&tcp_syn_size_oldtime,&zero); + old_time = bpf_map_lookup_elem(&tcp_syn_size_oldtime,&one); + if(!size_allowed || !old_time){ + return XDP_PASS; + } + if(!(tcp->fin || + tcp->psh || + tcp->urg || + tcp->ece || + tcp->cwr || + tcp->rst )){ + if (tcp->syn && !tcp->ack) { + __u64 curr_time = bpf_ktime_get_ns(); + //check if time is greater than old time + extra + if(*old_time + EXTRA_TIME_SYN < curr_time){ + // if yes update old time and make size as 1 + *size_allowed = 1; + *old_time = curr_time; + bpf_map_update_elem(&tcp_syn_lru_hash_map,&packet_key,&curr_time,BPF_ANY); + bpf_printk("Passed"); + return XDP_PASS; + } + else{ + // else check size == limit + if(*size_allowed == LIMIT_SYN){ + // if yes DROP + bpf_printk("Dropped"); + return XDP_DROP; + } + else{ + //else update size and insert into hash and PASS + *size_allowed += 1; + bpf_map_update_elem(&tcp_syn_lru_hash_map,&packet_key,&curr_time,BPF_ANY); + bpf_printk("Passed"); + return XDP_PASS; + } + } + } + if (tcp->syn && tcp->ack) { + bpf_printk("TCP SYN-ACK packet detected!\n"); + return XDP_PASS; + } + if (!tcp->syn && tcp->ack) { + //check if element is present + __u64 *packet_time = bpf_map_lookup_elem(&tcp_syn_lru_hash_map,&packet_key); + if(!packet_time){ + // if yes check time is in range + if(*packet_time < *old_time + EXTRA_TIME_SYN){ + //size =-1 remove from map and PASS + *size_allowed -= 1; + bpf_map_delete_elem(&tcp_syn_lru_hash_map,&packet_key); + return XDP_PASS; + } + else{ + //PASS + return XDP_PASS; + } + } + else{ + // PASS + return XDP_PASS; + } + } + } + else if(tcp->rst){ + struct tcp_rst_port_node *node = bpf_map_lookup_elem(&tcp_rst_port,&dest); + if(!node){ + return XDP_PASS; + } + __u64 curr_time = bpf_ktime_get_ns(); + bpf_spin_lock(&node->semaphore); + if(node->port_time + TIMEOUT_RST < curr_time){ + node->port_time = curr_time; + node->rst_cnt = 1; + bpf_spin_unlock(&node->semaphore); + bpf_printk("Passed"); + return XDP_PASS; + } + else{ + if(node->rst_cntrst_cnt++; + bpf_spin_unlock(&node->semaphore); + bpf_printk("Passed"); + return XDP_PASS; + } + else{ + bpf_spin_unlock(&node->semaphore); + bpf_printk("Dropped"); + return XDP_DROP; + } + } + } + return XDP_PASS; + } + return XDP_PASS; } From 3638ce05800d9dca39c7d54144c7bc64a178e3cd Mon Sep 17 00:00:00 2001 From: Kirito2op Date: Wed, 27 Nov 2024 21:59:24 +0530 Subject: [PATCH 08/10] fsx_struct.h: added structs for udp and icmp --- src/fsx_struct.h | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/fsx_struct.h b/src/fsx_struct.h index 775a2e8..30b7255 100644 --- a/src/fsx_struct.h +++ b/src/fsx_struct.h @@ -47,5 +47,14 @@ struct Semp{ struct bpf_spin_lock semaphore; }; +struct icmp_rate_limit_data { + __u64 last_reset_time; + __u32 packet_count; +}; + +struct udp_port_stat { + __u32 packet_count; + __u64 last_check; +}; #endif \ No newline at end of file From 28b756819b37cc156947278d084f35447a00aca7 Mon Sep 17 00:00:00 2001 From: Kirito2op Date: Wed, 27 Nov 2024 22:01:42 +0530 Subject: [PATCH 09/10] fsx_kern.c: added maps for udp and icmp --- src/fsx_kern.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/src/fsx_kern.c b/src/fsx_kern.c index 8ac19e2..8a96293 100644 --- a/src/fsx_kern.c +++ b/src/fsx_kern.c @@ -19,6 +19,11 @@ in the fsx_struct.h map */ #define THRESHOLD_RST 100 //limit on number of packets to be configurable later #define LIMIT_SYN 100 //limit on number of packets to be configurable later #define EXTRA_TIME_SYN 1000000000 //1 sec +#define ICMP_MAX_PACKET_SIZE 1000 // not sure about a good limit, can modify it later +#define UDP_MAX_PACKET_RATE 100 +#define ICMP_INTERVAL_NS 1000000000 // 1 second +#define UDP_THRESHOLD_PACKETS 100 // Maximum packets per interval for a single port +#define UDP_TIME_WINDOW 1000000000 // 1 second #ifndef memcpy #define memcpy(dest, src, n) __builtin_memcpy((dest), (src), (n)) @@ -121,6 +126,20 @@ struct { __type(value, struct tcp_rst_port_node); } tcp_rst_port SEC(".maps"); +struct { + __uint(type, BPF_MAP_TYPE_HASH); + __type(key, __u16); + __type(value, struct udp_port_stat); + __uint(max_entries, 65536); +} udp_port_counters_map SEC(".maps"); + +struct { + __uint(type, BPF_MAP_TYPE_HASH); + __uint(max_entries, 1); + __type(key, __u32); + __type(value, struct icmp_rate_limit_data); +} icmp_rate_limit_map SEC(".maps"); + SEC("xdp") int fsx(struct xdp_md *ctx) { From 248ca24b20a0d9954e4975c18a107a81d408851d Mon Sep 17 00:00:00 2001 From: Kirito2op Date: Wed, 27 Nov 2024 22:03:37 +0530 Subject: [PATCH 10/10] fsx_kern.c: added functionality for udp and icmp --- src/fsx_kern.c | 60 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 60 insertions(+) diff --git a/src/fsx_kern.c b/src/fsx_kern.c index 8a96293..b86559d 100644 --- a/src/fsx_kern.c +++ b/src/fsx_kern.c @@ -544,6 +544,66 @@ int fsx(struct xdp_md *ctx) } return XDP_PASS; } + if(application_layer_type == 2 && udp){ + __u16 dest_port = 0; + dest_port = bpf_ntohs(udp->dest); + struct udp_port_stat *stat = bpf_map_lookup_elem(&udp_port_counters_map, &dest_port); + __u64 now = bpf_ktime_get_ns(); + + if (stat) { + if (now - (stat->last_check) < UDP_TIME_WINDOW) { + stat->packet_count += 1; + + // If packet count exceeds threshold, drop packet + if (stat->packet_count > UDP_THRESHOLD_PACKETS) { + bpf_printk("Dropping UDP packet to port %d due to flood\n", dest_port); + return XDP_DROP; + } + } else { + stat->packet_count = 1; + stat->last_check = now; + } + bpf_map_update_elem(&udp_port_counters_map, &dest_port, stat, BPF_ANY); + } else { + struct udp_port_stat new_stat = {}; + new_stat.packet_count = 1; + new_stat.last_check = now; + bpf_map_update_elem(&udp_port_counters_map, &dest_port, &new_stat, BPF_ANY); + } + } + if(application_layer_type == 3 && icmp){ + if (icmp->type == 8) { // 8 == icmp echo request packets + int packet_size = data_end - data; + + if (packet_size > ICMP_MAX_PACKET_SIZE) { + return XDP_DROP; + } + __u32 key = 0; + struct icmp_rate_limit_data *rate_data = bpf_map_lookup_elem(&icmp_rate_limit_map, &key); + __u64 now = bpf_ktime_get_ns(); + + if (rate_data) { + __u64 elapsed = now - rate_data->last_reset_time; + + if (elapsed >= ICMP_INTERVAL_NS) { // if too much time has passed since the first packet arrival time. + rate_data->packet_count = 1; + rate_data->last_reset_time = now; + } else { + if (rate_data->packet_count >= UDP_MAX_PACKET_RATE) { + return XDP_DROP; + } + rate_data->packet_count++; + } + bpf_map_update_elem(&icmp_rate_limit_map, &key, rate_data, BPF_ANY); + } else { + struct icmp_rate_limit_data new_data = { + .last_reset_time = now, + .packet_count = 1 + }; + bpf_map_update_elem(&icmp_rate_limit_map, &key, &new_data, BPF_ANY); + } + } + } return XDP_PASS; }