How to block DDoS attacks at the edge with eBPF and XDP
Learn how to stop denial-of-service attacks at the network edge using eBPF and XDP to process packets directly inside the Linux kernel.
Summary
- eBPF allows running safe code inside the operating system kernel without recompiling it.
- XDP operates at the lowest network card layer to drop malicious packets before memory allocation.
- Edge filtering drastically reduces CPU usage during massive floods of unwanted traffic.
- Programs written in C and compiled to BPF bytecode guarantee deterministic execution in microseconds.
- Kernel maps integration enables updating blocklists dynamically without restarting network services.
Why traditional firewalls struggle with modern attacks
When a server receives millions of requests per second during a denial-of-service attack, standard operating systems begin to struggle. Every incoming network packet must travel a long path through multiple software layers inside the kernel before reaching the final application. In practice, this means the CPU spends precious cycles simply opening and closing digital envelopes containing data that will ultimately be discarded. Under extreme pressure, systems run out of memory and crash before even logging the incident.
To solve this bottleneck, network engineers have turned to technologies that intercept traffic much earlier. Just like we explored in our guide on how to block Layer 4 DDoS attacks with iptables and hashlimit, the core idea is to place smart barriers along the data path. However, legacy tools still rely on older structures that lose efficiency when packet volumes reach tens of gigabits per second. It is precisely in this high-pressure scenario that kernel-level packet manipulation ecosystems become indispensable for keeping servers online.
What is eBPF and how it revolutionizes network security
eBPF, which stands for Extended Berkeley Packet Filter, is a revolutionary technology that allows running small custom programs securely inside the operating system kernel. Think of it as placing a trained security guard right at the front gate of a massive building, capable of inspecting every package before it goes upstairs. This guard undergoes rigorous safety checks before starting work, ensuring they never crash the entire system due to a programming bug.
In practice, eBPF turns the Linux kernel into a programmable platform. Instead of relying on rigid rules built into the system, engineers can write custom logic to inspect network packets, record performance metrics, or drop suspicious traffic. Because this code runs as soon as data arrives, it avoids allocating heavy structures in RAM, saving vital machine resources to keep legitimate services running smoothly.
Accelerating blocks with XDP and driver-level manipulation
XDP, known as eXpress Data Path, acts as the right hand of eBPF specifically tailored for ultra-high-speed networks. When a network card receives an electrical or optical signal, it turns it into a raw data packet and temporarily stores it in memory. XDP grabs this packet the exact moment the network card driver wakes up to collect it, long before the operating system creates any internal representation for it.
At this early stage, the XDP program can make three main decisions: drop the packet instantly with a denial command, bounce it back where it came from, or pass it along to the normal Linux flow. If the packet is a clear attack from a known malicious IP, the drop happens in microseconds. To further harden your infrastructure, combine this approach with complementary filtering techniques like how to block port scans at the edge with nftables to stop early reconnaissance.
Building a high-performance packet filter
To put this technology into practice, we need to write a C program that gets translated into a binary format understood by the kernel. This code examines Ethernet, IP, and TCP headers of every incoming packet to identify typical malicious traffic signatures. Below is a basic example of an eBPF program using XDP that rejects packets destined for a specific port under attack.
#include <linux/bpf.h>#include <linux/if_ether.h>#include <linux/ip.h>#include <linux/tcp.h>#include <bpf/bpf_helpers.h>SEC("xdp")int block_target_port(struct xdp_md *ctx) { void *data = (void *)(long)ctx->data; void *data_end = (void *)(long)ctx->data_end; struct ethhdr *eth = data; if ((void *)(eth + 1) > data_end) return XDP_PASS; if (eth->h_proto != __constant_htons(ETH_P_IP)) return XDP_PASS; struct iphdr *iph = data + sizeof(*eth); if ((void *)(iph + 1) > data_end) return XDP_PASS; if (iph->protocol == IPPROTO_TCP) { struct tcphdr *tcph = (void *)iph + (iph->ihl * 4); if ((void *)(tcph + 1) > data_end) return XDP_PASS; if (tcph->dest == __constant_htons(80)) { return XDP_DROP; } } return XDP_PASS;}char _license[] <!-- SEC --> ("GPL");To load this code onto your Linux server network card, you use modern management tools like iproute2. The following command attaches the compiled program directly to the primary network interface, activating the defense barrier immediately.
- Compile the C source code into an eBPF object binary file.
- Identify the exact name of the primary edge server network interface.
- Load the program in native driver mode using the network configuration command.
clang -O2 -target bpf -c filter.c -o filter.oip link set dev eth0 xdp obj filter.o sec xdpMonitoring and updating blocklists in real time
One of the biggest advantages of using eBPF at the edge is the ability to change security rules without restarting the operating system or bouncing the network card. This is achieved through structures called eBPF maps, which act as small shared memory tables between user space and kernel space. When monitoring systems spot a new attacker, they inject the unwanted IP address into the map.
The eBPF program running on the network card queries this map in nanoseconds for every received packet, deciding whether to drop or forward the traffic. This architecture guarantees total operational flexibility, allowing automated mitigation of active threats. If you also manage remote access across your infrastructure, make sure to secure your servers against automated intrusions by applying tutorials like how to block SSH brute force attacks with Fail2Ban.
Final thoughts on edge resilience
Implementing eBPF and XDP-based filters represents a quantum leap in defense capability for any internet-connected infrastructure. By pushing malicious packet processing down to the lowest driver level of the network card, we gain massive headroom against volumetric attacks that would otherwise crash standard servers. While it requires specialized technical knowledge to write and maintain C programs, the payoff in operational stability and hardware savings makes every engineering effort worthwhile.