<eBPF Layer 7 DDoS Firewall: Build a Custom XDP Program | eServers
EXCLUSIVE OFFER: UNLOCK 15% SAVINGS IN LONDON! Claim Offer

eBPF Layer 7 DDoS Firewall: Build a Custom XDP Packet Inspection Program on Linux

eBPF Layer 7 DDoS Firewall Mitigation with XDP on eServers Infrastructure
Ask AI to extract steps & commands from this tutorial:

What is Layer 7 DDoS and Why Is It Harder to Stop?

A Layer 7 DDoS attack (also called an application-layer DDoS or HTTP flood) overwhelms a web server by sending enormous volumes of seemingly legitimate HTTP requests rather than raw network packets.

Unlike Layer 3/4 floods (UDP amplification, SYN floods), Layer 7 attacks:

  • Complete a full TCP three-way handshake — making them indistinguishable from real users at the network level

  • Bypass standard iptables rate-limiting rules without exhausting CPU resources first

  • Exploit expensive server-side operations, such as database queries triggered by specific URL paths

Modern botnets frequently use this technique because traditional firewalls cannot inspect HTTP headers without terminating the TCP connection — an operation that is far too expensive at high traffic volumes.

Why XDP + eBPF Is the Right Tool

eBPF (Extended Berkeley Packet Filter) allows you to run sandboxed programs inside the Linux kernel without modifying kernel source code. Paired with XDP (eXpress Data Path), these programs execute directly inside the NIC driver — the earliest possible point in the networking stack.

Mitigation Method Where It Runs CPU Cost at 10Gbps L7 Inspection
iptables / nftables Netfilter (post-kernel) High No
eBPF + TC (Traffic Control) After kernel ingress Medium Yes
eBPF + XDP (this guide) Inside NIC driver Near-zero Yes
Cloud WAF Remote scrubbing centre Zero (offloaded) Yes

XDP is the fastest software-based mitigation available on Linux. On a 10Gbps unmetered bare metal server, an XDP program can process and drop packets faster than the OS can schedule a user-space process to even acknowledge them.

The Challenge: Parsing All Four Network Layers in eBPF

XDP operates at the lowest level of the Linux networking stack. To reach Layer 7 (HTTP data), your eBPF program must manually walk the entire packet structure from the ground up:

  • [ Ethernet Header ] → 14 bytes

  • [ IPv4 Header ] → 20 bytes (variable with options)

  • [ TCP Header ] → 20 bytes (variable with options, doff field)

  • [ TCP Payload ] → HTTP data starts here

Critical constraint: The Linux kernel eBPF verifier performs strict bounds checking on every memory access. Any attempt to read beyond data_end will cause the program to be rejected at load time — not at runtime. Every pointer dereference must be guarded.

Prerequisites

This guide is tested on Ubuntu 24.04 LTS on an eServers bare metal instance. Install the required build tools:

bash
sudo apt update
sudo apt install clang llvm libbpf-dev linux-headers-$(uname -r) gcc-multilib build-essential

Verify your kernel version supports XDP (Linux 4.8+ required, 5.x+ recommended):

bash
uname -r

Step 1: Write the eBPF C Program

Create a file named l7_firewall.c. This program inspects each incoming packet. When it detects a malicious HTTP signature — in this example, a botnet repeatedly hitting GET /attack-target — it returns XDP_DROP, discarding the packet instantly at the NIC level.

c
#include <linux/bpf.h>
#include <linux/if_ether.h>
#include <linux/ip.h>
#include <linux/tcp.h>
#include <linux/in.h>
#include <bpf/bpf_helpers.h>

SEC("xdp")
int xdp_l7_filter(struct xdp_md *ctx) {
    // Define pointers to the start and end of the packet data
    void *data_end = (void *)(long)ctx->data_end;
    void *data     = (void *)(long)ctx->data;

    // 1. Parse Ethernet Header
    struct ethhdr *eth = data;
    if ((void *)(eth + 1) > data_end)
        return XDP_PASS;

    // Only inspect IPv4 packets
    if (eth->h_proto != __constant_htons(ETH_P_IP))
        return XDP_PASS;

    // 2. Parse IP Header
    struct iphdr *ip = (void *)(eth + 1);
    if ((void *)(ip + 1) > data_end)
        return XDP_PASS;

    // Only inspect TCP packets
    if (ip->protocol != IPPROTO_TCP)
        return XDP_PASS;

    // 3. Parse TCP Header (ihl = IP header length in 32-bit words)
    struct tcphdr *tcp = (void *)ip + (ip->ihl * 4);
    if ((void *)(tcp + 1) > data_end)
        return XDP_PASS;

    // 4. Calculate TCP Payload Offset
    // doff = TCP data offset in 32-bit words
    unsigned char *payload = (unsigned char *)tcp + (tcp->doff * 4);

    // Bounds check: ensure at least 14 bytes of payload exist
    // ("GET /attack-tar" = 14 characters)
    if ((void *)(payload + 14) > data_end)
        return XDP_PASS;

    // 5. Inspect the HTTP Payload for malicious signature
    // Target: "GET /attack" prefix
    if (payload[0] == 'G' && payload[1] == 'E' && payload[2] == 'T' &&
        payload[3] == ' ' && payload[4] == '/' && payload[5] == 'a' &&
        payload[6] == 't' && payload[7] == 't' && payload[8] == 'a' &&
        payload[9] == 'c' && payload[10] == 'k') {

        // Malicious signature detected — drop at the NIC, zero CPU cost
        return XDP_DROP;
    }

    // Allow all other traffic
    return XDP_PASS;
}

char _license[] SEC("license") = "GPL";

What to customise: Replace GET /attack with your actual attack signature. Common targets include /wp-login.php, /xmlrpc.php, or any endpoint your logs show being flooded.

Step 2: Compile to eBPF Bytecode

Compile the C program into an eBPF object file using Clang, targeting the BPF architecture:

bash
clang -O2 -g -Wall -target bpf -c l7_firewall.c -o l7_firewall.o

Flag explanations:

  • -O2 — optimisation required; unoptimised eBPF often fails the kernel verifier

  • -target bpf — compile for the eBPF virtual machine, not your host CPU architecture

  • -g — include debug symbols (useful for bpftool inspection workflows)

On success, this produces l7_firewall.o. The kernel verifier will validate this bytecode for memory safety before loading it.

Step 3: Attach the Firewall to Your NIC

Find your primary network interface name:

bash
ip a

Common names: eth0, eno1, enp3s0. Attach the eBPF program using ip link:

bash
sudo ip link set dev eth0 xdp obj l7_firewall.o sec xdp

Your bare metal server is now inspecting TCP payloads and dropping matching Layer 7 traffic directly at the NIC — before the Linux kernel network stack ever sees the packet.

Step 4: Verify and Monitor

Confirm the XDP program is successfully attached:

bash
ip link show dev eth0

Look for xdp in the output interface flags. To inspect drop statistics using bpftool:

bash
sudo bpftool prog show
sudo bpftool prog dump xlated id <ID>

Monitor dropped packets across interface statistics in real time:

bash
watch -n1 'cat /proc/net/dev | grep eth0'

Remove the Filter

To detach the XDP program and restore normal standard packet processing routes:

bash
sudo ip link set dev eth0 xdp off

Why Bare Metal Matters for eBPF Performance

eBPF and XDP can be loaded on any Linux system, but the performance benefit is only real on physical hardware.

On cloud VPS instances, the host hypervisor processes every packet before it reaches your virtual NIC interface layer. Your XDP program fires after the hypervisor — meaning the CPU structural overhead cost has already been paid, and the "near-zero infrastructure penalty" guarantee no longer holds true.

For genuine line-rate DDoS mitigation profiles, you need direct hardware access to a physical NIC device.

eServers Dedicated Bare Metal — Built for This Use Case
UK businesses running high-traffic workloads choose eServers dedicated bare metal servers for eBPF-based DDoS mitigation configurations because:

  • Direct NIC access: XDP runs at the raw hardware level, not inside an abstract hypervisor architecture

  • 10Gbps unmetered bandwidth: Absorb volumetric floods cleanly without cloud egress network fees or traffic throttling policies

  • 15–30 minute hardware SLA: On-site UK engineers across London, Coventry, and Manchester replace edge deployment components efficiently

  • Ubuntu 24.04 LTS pre-installed: Deploy this exact kernel tutorial from the first automated boot sequence

Conclusion

Building edge defense layers via eBPF structures allows platforms to handle high request volumes safely inside network pathways. Deploy raw power arrays with zero virtualization taxes to keep applications secure.

Upgrade your filtering architecture today with our ultra-fast, high-throughput dedicated servers.

Discover eServers Dedicated Server Locations

eServers provides reliable dedicated servers across multiple global regions. Whether you need low latency, regional compliance, or proximity to your audience, our wide geographic coverage ensures the perfect hosting environment for your project.

Frequently Asked Questions (FAQ)

Can eBPF inspect HTTPS (TLS-encrypted) traffic? +

No. XDP operates before TLS termination. For encrypted traffic, you need a reverse proxy (e.g., Nginx or HAProxy) with eBPF applied downstream, or a dedicated TLS-aware WAF.

Does this work on Ubuntu 22.04 as well as 24.04? +

Yes. The libbpf API and XDP support used here have been stable since Ubuntu 20.04. Ensure your kernel is 5.4 or later (uname -r).

What is the maximum throughput of an XDP firewall? +

On a 10Gbps NIC with a simple XDP_DROP program, modern systems can sustain wire-rate drops of 14–24 million packets per second with negligible CPU usage. L7 inspection adds minimal overhead because the program exits early on non-matching traffic.

Can I block multiple attack signatures at once? +

Yes. Extend the payload inspection block with additional if conditions, or use an eBPF hash map (BPF_MAP_TYPE_HASH) to store a dynamic blocklist of URL patterns updatable without reloading the program.

Is a kernel module required? +

No. eBPF programs load entirely from user space using the bpf() syscall or tools like ip link and bpftool. No kernel recompilation or module signing is needed.

How is this different from iptables -m string? +

iptables string matching runs inside Netfilter, after the kernel has fully processed the packet through multiple hooks. XDP drops the packet inside the driver, before Netfilter, skbuff allocation, or any kernel TCP processing — making it 5–10× more CPU-efficient at high packet rates.

Our Bandwith providers

We are Partners with 15 +

At eServers , we proudly partner with 15+ leading global tech providers to deliver secure, high-performance hosting solutions. These trusted alliances with top hardware, software, and network innovators ensure our clients benefit from modern technology and enterprise-grade reliability.

Hosting Solutions