NetFlow Fundamentals
NetFlow is a network protocol for collecting IP traffic statistics from routers and switches. While Zeek and Suricata require a packet tap, NetFlow is built into Cisco routers, Juniper devices, and most enterprise switching hardware. NetFlow records provide flow-level telemetry (who talked to whom, how much data, which ports) from every device in the network, giving visibility into traffic that never touches your packet capture sensor.
A financial firm has 50 branch offices connected via MPLS. No packet sensors exist at branch sites. But every branch router exports NetFlow v9 to a central collector. When malware in a Denver branch office starts exfiltrating data to an external IP, the NetFlow data shows the sustained high-byte-count flows from the branch router's interface, even though no PCAP is available from that site. NetFlow is often the only telemetry available for remote sites and internal network segments.
NetFlow Architecture
NetFlow / IPFIX Data Collection Architecture
═══════════════════════════════════════════════════════════════════
Data sources (exporters):
├── Cisco IOS/IOS-XE router: native NetFlow v5, v9, IPFIX
├── Juniper Junos router: jFlow (NetFlow-compatible)
├── Linux server: softflowd, nfcapd for kernel flow export
├── Cloud: AWS VPC Flow Logs (v5-compatible), Azure NSG Flow Logs
└── Firewall: Palo Alto, Fortinet, Check Point all export flows
Transport:
UDP port 2055 (NetFlow) or 4739 (IPFIX) to collector
No acknowledgment — flows may be lost if collector is unreachable
Collector:
├── nfdump / nfcapd: open-source, writes binary .nf files
├── ElastiFlow: Elasticsearch-native, parses all NetFlow/IPFIX
├── SILK: SiLK toolkit (CMU SEI CERT), large-scale analysis
└── Commercial: Scrutinizer, Kentik, ManageEngine
NetFlow record (v5):
├── src_addr, dst_addr, src_port, dst_port, protocol
├── byte count, packet count
├── flow start time, flow end time
├── input/output interface (ifindex)
├── TCP flags (union of all flags seen in flow)
└── next_hop
NetFlow v9 / IPFIX (template-based — more flexible):
├── Same 5-tuple + bytes/packets
├── Can include: application ID, TOS/DSCP, MPLS labels
├── Can include: BGP AS numbers, routing info
└── Can include: custom fields defined in templates
NetFlow Collection Setup
#!/bin/bash
echo "=== Install nfdump (collector + analysis tools) ==="
apt-get install -y nfdump
echo ""
echo "=== Start nfcapd (collector daemon) ==="
mkdir -p /data/netflow
# -p: listen port, -l: log directory, -T all: capture all templates
# -z: compress output, -n: rotate every N seconds (300=5min)
nfcapd -p 2055 -l /data/netflow -T all -z -n 300 -D -w -b 0.0.0.0
echo "nfcapd listening on UDP 2055, writing to /data/netflow"
echo ""
echo "=== Basic nfdump query ==="
# Read all NetFlow files in directory, filter, show top talkers
nfdump -R /data/netflow -s record/bytes -n 20 -o "fmt:%sa %da %sp %dp %pkt %byt %fl"
echo ""
echo "=== Query: top destinations by bytes (last 24 hours) ==="
nfdump -R /data/netflow/$(date -d 'yesterday' +%Y/%m/%d) \
-s dstip/bytes -n 20 -o "fmt:%da %byt %fl"
echo ""
echo "=== Query: connections from specific host to external ==="
nfdump -R /data/netflow \
-f "src ip 10.0.0.50 and dst net not 10.0.0.0/8" \
-o extended | head -30
echo ""
echo "=== Generate summary statistics ==="
nfdump -R /data/netflow -s proto/bytes -n 10
echo ""
nfdump -R /data/netflow -s record/bytes -n 10
echo ""
echo "=== Configure Cisco IOS router for NetFlow export ==="
cat << 'CONFIG'
! On Cisco IOS router:
ip flow-export version 9
ip flow-export destination 10.0.0.200 2055 ! Collector IP:port
ip flow-export source Loopback0 ! Source interface for flow packets
ip flow-cache timeout active 5 ! Export active flows every 5 min
ip flow-cache timeout inactive 30 ! Export inactive flows after 30s
interface GigabitEthernet0/0 ! Monitor this interface
ip flow ingress
ip flow egress
CONFIG
A critical limitation of NetFlow: it summarizes flows, not packets. When a router exports a NetFlow record for a flow, it reports the total bytes and packets — but you cannot recover the payload content from a NetFlow record. There is no way to do DPI or extract application-layer details from NetFlow alone. Additionally, at high traffic volumes, NetFlow is often sampled: the router only exports records for 1 in N packets (where N might be 1:1000 or 1:4096). This means the byte counts in NetFlow records for high-volume links are estimates, not exact counts. For forensics: NetFlow is authoritative for "did this flow exist and roughly how much data moved?" but not for "what was in the payload?" or exact byte accounting. It's most valuable for: (1) visibility into network segments without packet sensors, (2) lateral movement detection across internal segments, (3) detecting beaconing by statistical analysis of flow records, (4) identifying top talkers and anomalous large transfers that warrant deeper investigation with PCAP.
Q & A
Q: What's the difference between NetFlow v5, v9, and IPFIX, and which should I use?
NetFlow v5 (Cisco, 1994): fixed 7-field format, only IPv4, no template negotiation — very simple to parse and collect, still common on older Cisco gear. Limitation: IPv6 support requires v9 or IPFIX. NetFlow v9 (Cisco, 2004): template-based — the exporter sends template definitions, then exports records using those templates. Supports IPv6, MPLS, BGP attributes, flexible field inclusion. More complex to parse but far more flexible. IPFIX (IETF RFC 7011, 2013): standardized, vendor-neutral version of NetFlow v9 with the same template-based approach. IPFIX is the modern standard — if your equipment supports it, prefer IPFIX over NetFlow v9 for new deployments; they're wire-format similar and most collectors handle both. For collection: nfdump handles v5, v9, and IPFIX transparently. For analysis at scale: ElastiFlow or commercial collectors normalize all three formats into a unified schema. If you're writing your own parser, start with v5 (fixed format, easy), then add v9/IPFIX (require template caching before you can parse records).