DDoS Protection

Securing an OVH VPS against DDoS attacks: 2026 checklist

May 22, 2026 · 9 min read
Illustration immersive du sujet : secure OVH VPS DDoS

To secure OVH VPS DDoS attacks in 2025 and beyond, modern infrastructure teams must deploy kernel-level packet filtering at the earliest possible network stack layer. OVH provides robust upstream mitigation, but volumetric floods and application-layer attacks still reach the VPS; XDP and nftables form the last line of defense, dropping malicious traffic before it consumes CPU cycles or RAM. This guide explains how to configure XDP/eBPF and stateful nftables on your OVH VPS, integrate automated blacklist synchronization, and maintain zero conflict with existing Docker or fail2ban rules—all managed from a single control plane.



Why OVH VPS Requires an Additional Kernel-Level DDoS Defense

OVH's Game and Infrastruture divisions offer upstream anti-DDoS scrubbing that inspects inbound traffic at the network edge, filtering reflection amplification attacks (NTP, DNS, Memcached) and large SYN floods. However, three scenarios bypass or overwhelm the VAC (OVH's mitigation system):

  • Low-rate application floods: 10 000 PPS distributed across hundreds of source IPs may not trigger VAC thresholds yet saturate a single-core game server process.
  • Protocol-specific abuse: malformed packets, oversized queries, or connection exhaustion attacks targeting TCP state tables.
  • Mitigation lag: even a 30-second delay between attack onset and VAC activation can crash a time-sensitive service.

Kernel-level protection complements OVH's edge scrubbing by making real-time, per-packet decisions on the VPS itself. XDP (eXpress Data Path) operates at the network driver layer—before the Linux kernel allocates an SKB structure—enabling sub-microsecond DROP or PASS verdicts. Stateful nftables rules then enforce connection tracking, TCP flag validation, and per-source-IP rate-limits in the inet family, coexisting peacefully with Docker's nat table and fail2ban's dynamic sets.

A dual-layer architecture (XDP + nftables) deployed on an OVH VPS typically handles several million packets per second on a single core, with negligible added latency for legitimate traffic. The PAKKT.io platform automates rule deployment, metric collection, and IP blacklist synchronization across both layers, reducing manual SSH editing and log-file correlation.


Photorealistic wide shot of a modern datacenter aisle with rows of server racks under cyan LED strip lighting, fiber optic cables neatly bundled overhead, shallow depth of field emphasizing the front rack, industrial concrete floor, clean professional atmosphere


Installing and Configuring XDP on OVH VPS: Kernel Requirements and BPF Loader

OVH VPS instances running Ubuntu 22.04, Debian 12, or Rocky Linux 9 ship with kernel 5.15 or higher, satisfying the minimum XDP requirement. Verify your kernel version and XDP driver support:

uname -r
# Expected output: 5.15.0-xx or higher

ethtool -i ens3 | grep -i driver
# Common drivers: virtio_net (generic mode), i40e / ice (native mode on Rise/HGR ranges)

The VPS network interface (commonly ens3 or eth0) must support either native XDP (zero-copy) or generic XDP (skb-based fallback). Native mode delivers maximum throughput; generic mode suffices for low-to-mid traffic workloads and is always available.

Compiling and Attaching a Single XDP Program

Unlike iptables chains, XDP allows only one program per interface. The PAKKT Engine consolidates up to 256 rules into a single eBPF object, driven by BPF maps updated in real time from user space. Manual compilation with Clang + LLVM requires kernel headers:

apt-get install -y clang llvm libbpf-dev linux-headers-$(uname -r)
clang -O2 -g -target bpf -c pakkt_engine.c -o pakkt_engine.bpf.o
ip link set dev ens3 xdp obj pakkt_engine.bpf.o sec xdp

Verify attachment status:

ip link show ens3 | grep xdp
# Expected: prog/xdp id XXX

The pakkt_engine.bpf.o program reads from three BPF maps: pakkt_rules (array of rule definitions), pakkt_blacklist (hash map of IPv4/IPv6 addresses), and pakkt_counters (per-rule packet and byte statistics). User-space tooling—provided by the PAKKT agent—updates these maps via bpf(2) syscalls, applying new rules in under 10 milliseconds without reloading the XDP program.

Configuring XDP Rules: Port Range, Protocol, Rate-Limit, and Packet Size

A typical rule protects a game server port (e.g., TCP 25565 for Minecraft) by enforcing a global PPS ceiling and per-source IP limit:

{
  "port_start": 25565,
  "port_end": 25565,
  "protocol": "tcp",
  "rule_type": "rate_limit",
  "max_pps": 100000,
  "max_port_pps": 500,
  "min_packet_size": 40,
  "max_packet_size": 1500
}

When a packet arrives on TCP port 25565, the XDP program increments counters in pakkt_counters and checks:

  • Global PPS across all sources: if exceeded, DROP.
  • Per-source PPS (tracked in a least-recently-used hash map): if exceeded, DROP.
  • Packet size: if below 40 bytes or above 1500 bytes, DROP (filters empty ACKs or fragmented floods).

All decisions execute in eBPF bytecode before the kernel's TCP stack allocates memory, preventing SYN-flood exhaustion of the tcp_max_syn_backlog queue.


Close-up of a Linux terminal window displaying colorful XDP and bpftool command output with packet statistics and map dumps, dark theme, glowing green and cyan text on black background, shallow depth of field with blurred server rack LEDs in the background


Layering Stateful nftables Rules for Connection Tracking and TCP Flag Validation

XDP operates at Layer 2/3 and is stateless: each packet is evaluated independently. To enforce stateful policies—such as "allow established connections" or "drop SYN packets exceeding 50/second per source IP"—nftables with conntrack must complement XDP. OVH VPS instances ship with nftables 1.0.5 or later, supporting the inet address family (dual-stack IPv4/IPv6).

Creating an Isolated inet pakkt Table

To avoid conflicts with Docker's nat table and fail2ban's filter table, create a dedicated inet pakkt table with priority 0 (after raw, before mangle):

nft add table inet pakkt
nft add chain inet pakkt input { type filter hook input priority 0 \; policy accept \; }
nft add chain inet pakkt forward { type filter hook forward priority 0 \; policy accept \; }

Default policy accept ensures that legitimate traffic passes unless explicitly matched by a DROP or REJECT rule. The input chain processes packets destined for the VPS itself; the forward chain handles routed traffic (relevant for VPS acting as a gateway).

Enforcing Per-Connection Rate-Limits with Meters

A common DDoS pattern is a botnet sending one SYN packet per second from thousands of IPs, staying below per-IP PPS thresholds. Stateful meters aggregate flows by connection tuple:

nft add set inet pakkt syn_meter { type ipv4_addr \; size 65536 \; flags dynamic,timeout \; timeout 60s \; }
nft add rule inet pakkt input tcp dport 25565 tcp flags syn ct state new meter syn_meter { ip saddr limit rate over 10/minute } drop

This rule tracks new TCP connections (SYN + ct state new) per source IP and drops excess attempts beyond 10 per minute. The timeout 60s parameter evicts idle entries, preventing memory exhaustion.

Validating TCP Flags to Block Invalid Packets

Attackers often send packets with unusual flag combinations (e.g., SYN+FIN, or all flags set) to evade stateful firewalls. Nftables can reject these at line rate:

nft add rule inet pakkt input tcp flags \& \(fin\|syn\|rst\|psh\|ack\|urg\) == fin\|syn drop
nft add rule inet pakkt input tcp flags \& \(fin\|syn\|rst\|psh\|ack\|urg\) == 0x0 drop

The first rule drops packets with both FIN and SYN set; the second drops NULL packets (no flags). These rules execute before conntrack, reducing state-table pollution.

Synchronizing IP Blacklists Between XDP and nftables

An IP banned via the PAKKT control panel must be blocked in both the XDP BPF map and an nftables set to guarantee coverage regardless of packet path. The PAKKT agent maintains a named set:

nft add set inet pakkt blacklist_v4 { type ipv4_addr \; }
nft add rule inet pakkt input ip saddr @blacklist_v4 drop

When you add 192.0.2.50 to the blacklist via the web UI, the agent executes:

bpftool map update name pakkt_blacklist key 192.0.2.50 value 1
nft add element inet pakkt blacklist_v4 { 192.0.2.50 }

Both updates complete in under 5 milliseconds, achieving near-instantaneous enforcement across kernel layers. The same mechanism applies to whitelists, typically implemented as early-return ACCEPT rules.



Monitoring, Metrics, and Real-Time Dashboards for OVH VPS Protection

Effective DDoS mitigation requires continuous visibility into traffic patterns, rule hit counts, and top attack sources. The PAKKT agent collects per-rule and per-port metrics every second by reading BPF map counters and nftables rule statistics, then transmits them over mTLS to the centralized TimescaleDB backend.

GeoIP Visualization and Top Source IPs

The PAKKT dashboard renders a world map heatmap showing attack origins, with drill-down to city-level for ASNs known to host residential proxies or VPN exit nodes. The "Top Source IPs" widget displays:

  • IP address and reverse DNS (if available).
  • Packet count and byte count in the last 60 seconds.
  • GeoIP country and ASN.
  • One-click "Add to Blacklist" button, propagating the ban to all XDP and nftables rules within 30 seconds (the agent's heartbeat interval).

This workflow eliminates manual SSH log parsing and accelerates incident response from minutes to seconds.

Per-Port and Per-Rule Packet Statistics

Each XDP rule exposes three counters: packets_allowed, packets_dropped, and packets_rate_limited. The dashboard graphs these time-series with 1-second granularity, enabling operators to correlate traffic spikes with external events (e.g., server listing on a public directory, streamer mention). When packets_dropped exceeds a threshold—configurable per rule—the platform can trigger webhooks to Slack, Discord, or PagerDuty.

Audit Log and Agent Self-Update

Every rule change, blacklist modification, and agent configuration edit is recorded in the audit log with timestamp, user identity, and SHA256 hash of the resulting BPF bytecode. The Go agent self-updates via HTTPS, verifying the new binary's signature before replacing itself; garble obfuscation hardens the agent against reverse engineering. Resource consumption remains below 1 % CPU and 5 MB RAM even under sustained 10 Mpps load.

For pricing details and trial activation, visit PAKKT pricing (€3/agent/month, 7-day free trial on the first agent).



Integrating PAKKT with OVH API, Pterodactyl, and Infrastructure-as-Code Workflows

Large hosting providers and game-server networks manage hundreds of OVH VPS instances programmatically. The PAKKT public API (bearer-token authentication) supports:

  • Agent provisioning: POST /api/v1/agents returns an installation token; inject it into your Terraform or Ansible playbook to install the agent during VPS bootstrap.
  • Rule templating: GET /api/v1/templates retrieves community-shared XDP/nftables rulesets for Minecraft, CS2, Rust, or generic web services. Apply templates in bulk across agent groups.
  • Blacklist synchronization: POST /api/v1/blacklist accepts CSV or JSON arrays of IPs; the platform fans out the update to all agents in the selected group within one heartbeat cycle.

The Pterodactyl v1.x integration (production-ready) adds a "DDoS Protection" tab to each game-server instance, displaying live PPS graphs and a one-click emergency "block all traffic except whitelisted IPs" button. Pelican and WHMCS integrations are in active development; subscribe to the PAKKT blog for release announcements.

Example: Automated Agent Deployment with Terraform

resource "null_resource" "pakkt_agent" {
  provisioner "remote-exec" {
    inline = [
      "curl -sSL https://install.pakkt.io | bash -s -- ${var.pakkt_token}",
      "systemctl enable pakkt-agent",
      "systemctl start pakkt-agent"
    ]
    connection {
      type = "ssh"
      host = ovh_vps.example.ip_address
      user = "root"
    }
  }
}

This snippet installs the agent, registers it with your PAKKT organization, and enables the systemd service—all in under 30 seconds per VPS.

Compliance and External References

Kernel-level packet filtering aligns with security frameworks such as MITRE ATT&CK T1498 (Network Denial of Service) and NIST SP 800-61 (Incident Handling). For in-depth XDP programming details, consult the official Linux kernel BPF documentation and the eBPF.io community hub.



Conclusion

Securing an OVH VPS against DDoS attacks in 2025 demands a multi-layer strategy: upstream scrubbing at the network edge, XDP for sub-microsecond stateless filtering, and nftables for stateful connection tracking and TCP validation. By deploying both technologies in an isolated inet pakkt table and automating rule updates through a centralized control plane, infrastructure teams achieve line-rate protection with negligible CPU overhead and zero conflicts with Docker or fail2ban. Real-time metrics, GeoIP visualization, and public-API integration transform reactive log analysis into proactive, policy-driven defense.



FAQ

Does XDP on an OVH VPS interfere with OVH's upstream VAC mitigation?

No. OVH's VAC operates at the network edge, filtering traffic before it reaches your VPS. XDP runs on the VPS itself, processing packets that VAC has already passed. The two layers are complementary: VAC blocks volumetric floods (terabits-per-second), while XDP handles application-layer abuse and low-rate attacks that fall below VAC thresholds.

Can I use both iptables-persistent and nftables on the same OVH VPS without conflict?

Yes, provided you assign distinct priorities and table names. Nftables inet pakkt table with priority 0 coexists with legacy iptables rules (which translate to nftables ip filter table internally). However, mixing rule management tools (iptables-save vs. nft) complicates troubleshooting; migrating fully to nftables and isolating PAKKT rules in a dedicated table is recommended for clarity.

What happens if the PAKKT agent loses connectivity to the control plane?

The agent continues to enforce the last-known ruleset loaded into XDP and nftables; no traffic disruption occurs. The agent queues metric samples and audit events locally (up to 1 hour of buffered data) and retransmits them once mTLS connectivity is restored. If the outage exceeds 24 hours, the agent enters a read-only mode, maintaining protection but disabling remote rule updates until the control plane is reachable.

Protect your servers

Deploy PAKKT in 30 seconds

Dual-layer kernel protection. XDP + nftables. Driven from a central panel. 7-day free trial.