NetFlow DDoS Detection: Thresholds, Baselines, Sampling
To detect DDoS attacks with NetFlow or IPFIX, export sampled flow records from your edge routers to a collector. The collector then compares per-destination-IP and per-prefix traffic (bits per second and packets per second) against thresholds, and it triggers an alert or a mitigation action when a threshold is exceeded for a sustained period. The hard part is not the export. It is choosing thresholds that catch real attacks without flagging your busiest customers.
This guide covers the full chain: router configuration, bps vs. pps thresholds, per-IP baselines, sampling math, and the most common causes of false positives.
How flow-based DDoS detection works
Routers aggregate packets into flows (source/destination IP, ports, protocol, TCP flags, byte and packet counters) and export them over UDP to a collector. The collector sums the counters per destination IP over a short window and converts them to rates.
Flow-based detection has real advantages over mirroring traffic: it scales to multi-terabit edges, needs no taps or SPAN capacity, and works across many routers. It has limits too. Detection is bounded by the router's flow export timers and by sampling accuracy, and you see headers only, not payload.
| Protocol | Typical use | Notes |
|---|---|---|
| NetFlow v5 | Legacy, IPv4 only | Fixed fields, no IPv6 |
| NetFlow v9 / Flexible NetFlow | Cisco and others | Template-based, IPv6 supported |
| IPFIX | Standards-based NetFlow v9 successor | Juniper inline-jflow, many vendors |
| sFlow | Packet sampling on switches | Samples packets, not flows |
Step 1: Export flows from your routers
Use the shortest practical active timeout (10–15 seconds in most setups). Long default timeouts of 60 seconds or more directly delay detection.
Juniper MX (inline IPFIX)
set services flow-monitoring version-ipfix template ipv4 flow-active-timeout 15
set services flow-monitoring version-ipfix template ipv4 flow-inactive-timeout 10
set services flow-monitoring version-ipfix template ipv4 template-refresh-rate seconds 30
set services flow-monitoring version-ipfix template ipv4 ipv4-template
set chassis fpc 0 sampling-instance DDOS
set forwarding-options sampling instance DDOS input rate 1000
set forwarding-options sampling instance DDOS family inet output flow-server 192.0.2.10 port 2055
set forwarding-options sampling instance DDOS family inet output flow-server 192.0.2.10 version-ipfix template ipv4
set forwarding-options sampling instance DDOS family inet output inline-jflow source-address 192.0.2.1
set interfaces xe-0/0/0 unit 0 family inet sampling input
Cisco IOS-XE (Flexible NetFlow)
flow exporter NIXMON
destination 192.0.2.10
source Loopback0
transport udp 2055
export-protocol ipfix
!
flow record DDOS-REC
match ipv4 source address
match ipv4 destination address
match ipv4 protocol
match transport source-port
match transport destination-port
collect transport tcp flags
collect counter bytes long
collect counter packets long
!
sampler SMP-1000
mode random 1 out-of 1000
!
flow monitor DDOS-MON
exporter NIXMON
record DDOS-REC
cache timeout active 15
cache timeout inactive 10
!
interface TenGigabitEthernet0/0/0
ip flow monitor DDOS-MON sampler SMP-1000 input
MikroTik RouterOS
/ip traffic-flow set enabled=yes interfaces=sfp-sfpplus1 active-flow-timeout=15s inactive-flow-timeout=10s
/ip traffic-flow target add dst-address=192.0.2.10 port=2055 version=9
RouterOS Traffic Flow is not a sampled export in the way Juniper or Cisco sampling is, so watch CPU load on smaller devices. Enable it only on the interfaces you need, typically upstream and IX ports.
Linux (softflowd)
For a Linux router or a mirror port feeding a Linux box:
softflowd -i eth0 -v 10 -n 192.0.2.10:2055 -s 1000 -t maxlife=15
Always check what your platform reports. Some devices send the sampling rate inside the export; others require you to configure it on the collector.
Which direction to sample
Sample ingress on all external-facing interfaces (transit, peering, IX). Sampling only one direction, or only some uplinks, makes traffic look smaller than it is, and it hides attacks arriving over the links you skipped. With asymmetric routing, per-router views are partial, so the collector must aggregate across routers.
Step 2: Choose thresholds in both bps and pps
Use both metrics, because attacks hit different resources:
- High bps (UDP amplification, large-packet floods) saturates links.
- High pps (SYN floods, small-packet UDP floods) exhausts routers, firewalls and server network stacks, often at modest bandwidth.
A 200 Mbps SYN flood can break a server while looking harmless in a bps-only graph.
Illustrative starting points for a hosting network (adjust to your own traffic and port speeds):
| Target | Threshold type | Example start |
|---|---|---|
| Single VPS on 1G port | bps | ~600–800 Mbps |
| Single VPS on 1G port | pps | ~100–150 kpps |
| Any host | UDP pps | lower than total pps |
| Any host | TCP SYN pps | well below total pps |
| Any host | ICMP / fragments | low, since legit use is small |
| /24 customer prefix | bps and pps | sized to the customer's uplink |
These are examples only, not recommendations for your network. The point is to set per-protocol thresholds (UDP, SYN, ICMP, fragments) as well as total thresholds, and to scale them to what the target can actually handle.
Require a sustained breach
Trigger only after the rate stays above the threshold for several consecutive intervals. This removes short spikes from backups, software updates and bursty applications. Keep the duration short enough that real attacks don't have time to saturate the link first.
Step 3: Build per-IP baselines
A single global threshold fits nobody. A game server, a DNS resolver and an idle VPS have very different normal traffic. A baseline approach works like this:
- Collect per-IP bps and pps for at least two weeks, so weekday and weekend patterns are included.
- Calculate a high percentile (for example p95 or p99) per IP, ideally per hour of the week.
- Set the threshold as the larger of a static floor and a multiple of the baseline.
- Group IPs into profiles (web, DNS, game, customer-dedicated, default) rather than tuning thousands of hosts by hand.
The static floor matters: a quiet IP with a 2 Mbps baseline would otherwise trigger at 10 Mbps, which is not an attack. Per-prefix thresholds work well as a second layer, catching carpet-bombing attacks that spread traffic across a whole /24 so no single IP crosses its own limit.
Step 4: Handle sampling correctly
With 1:1000 sampling, the collector multiplies observed values by 1000. That has two consequences:
- Large attacks are estimated well. A 100 kpps flood yields roughly 100 sampled packets per second.
- Small attacks are noisy. A target receiving 5 kpps yields about 5 samples per second. A single sample then represents 1,000 packets, so rates jump around.
Practical rules:
- Use a lower sampling ratio (for example 1:512 or 1:256) on lower-speed links if the router can handle it.
- Don't set thresholds so low that they depend on a handful of samples. Require a minimum number of samples before an alert is considered valid.
- Confirm the collector uses the correct sampling rate for each exporter. A wrong rate silently makes every threshold wrong by that factor.
- Remember that sampled TCP flags in short windows can mislead. Cross-check SYN ratios over several intervals.
Step 5: Reduce false positives
Most false positives come from a small set of causes:
- Legitimate heavy hosts. CDN nodes, DNS resolvers, mirrors, backup targets. Give them their own profile or higher thresholds.
- Flash crowds. A product launch or streaming event looks like a flood. Check the number of distinct source IPs and the protocol mix. Flash crowds usually look like real TCP sessions from diverse sources, while attacks often show spoofed or reflected patterns, such as UDP from source port 53, 123 or 11211.
- Wrong sampling rate or double counting. Exporting the same traffic on ingress and egress, or from two routers on the same path, doubles the numbers.
- Missing the direction. Count traffic toward your IP when detecting inbound attacks.
- Overly aggressive automation. Blackholing a customer IP stops the attack but also finishes the attacker's job for that IP.
For response, prefer targeted actions where possible. A BGP FlowSpec rule matching UDP source port 123 to one destination affects only the attack traffic. RTBH drops everything to the IP, so reserve it for cases where the attack exceeds what the link can carry. Use automatic expiry for both so a false positive heals itself.
Common mistakes
- Leaving default flow timeouts at 60 seconds or longer.
- Using only bps thresholds.
- One global threshold for all hosts.
- Wrong or missing sampling rate on the collector.
- Not sampling every external interface.
- Automatic RTBH with no whitelist for critical infrastructure such as your DNS, route servers and monitoring IPs.
- Never testing. Run a controlled test against a lab or owned IP and measure time from first packet to alert.
Putting it into practice with NixMon
NixMon ingests NetFlow v5/v9, IPFIX and sFlow, analyzes traffic with sub-second analytics, and applies per-IP and per-prefix bps/pps thresholds. When a threshold is hit, it can announce a BGP blackhole or a BGP FlowSpec rule, or act through the on-prem NixGuard firewall. Attack alerts also reach you through the native iOS and Android apps.
If an attack is larger than your uplinks can carry, local filtering won't help. That is the use case for NixGuard Edge, which is for networks with their own ASN and at least one /24. Your prefixes are announced from the scrubbing edge and clean traffic returns over a GRE tunnel with a BGP session inside.
You can point your routers at a collector and test your thresholds with the 15-day free trial. No credit card is required.
Frequently asked questions
What sampling rate should I use for NetFlow DDoS detection?
It depends on link speed and router capability. Faster links usually use higher ratios such as 1:1000, while lower-speed links can use 1:256 or 1:512 for better accuracy on small attacks. Whatever you choose, make sure the collector uses the same rate for that exporter.
Should DDoS thresholds be set in bps or pps?
Both. Bps catches volumetric floods that fill links, while pps catches small-packet floods like SYN floods that exhaust devices at low bandwidth. Add per-protocol thresholds for UDP, SYN, ICMP and fragments as well.
How fast can NetFlow detect a DDoS attack?
Detection speed is limited mostly by the router's flow active timeout and export interval. Setting the active timeout to 10–15 seconds instead of the default 60 seconds or more makes a large difference. Collector analytics add little delay by comparison.
How do I tell a flash crowd from a DDoS attack in flow data?
Look at the source diversity, protocol mix and ports. Flash crowds tend to be real TCP sessions to expected services from many sources. Attacks often show reflection ports like UDP 53, 123 or 11211, spoofed sources, unusual packet sizes or abnormal SYN ratios.