How to Set Up NetFlow Monitoring on FreeBSD
NetFlow monitoring tells you who is talking to whom, how much data is flowing, and which protocols are in use across your network. On FreeBSD, you have two ways to export NetFlow data -- the userland softflowd daemon and the kernel-level ng_netflow netgraph module -- plus multiple collectors to analyze the data.
This guide covers both export methods, setting up nfsen as a collector and analysis tool, deploying ntopng for real-time monitoring, and building a complete traffic analysis pipeline.
NetFlow, sFlow, and IPFIX: A Quick Primer
These are all flow monitoring protocols that export metadata about network traffic:
- NetFlow v5: Cisco's original format. Fixed fields, IPv4 only. Still widely supported.
- NetFlow v9: Template-based, supports IPv6 and custom fields.
- IPFIX: The IETF standard based on NetFlow v9. The future-proof choice.
- sFlow: Packet sampling protocol. Different architecture -- samples 1-in-N packets rather than tracking all flows.
FreeBSD supports NetFlow v5, v9, and IPFIX through different tools. For most deployments, NetFlow v9 or IPFIX is the right choice.
Architecture Overview
A NetFlow monitoring setup has three components:
- Exporter: Captures flow data from network interfaces and sends it to a collector. This runs on your FreeBSD router or server.
- Collector: Receives flow records, stores them, and provides data for analysis.
- Analyzer: Visualizes the flow data. Often combined with the collector.
shell[FreeBSD Server/Router] ---(NetFlow UDP)---> [Collector/Analyzer] (softflowd or ng_netflow) (nfsen, ntopng, etc.)
Method 1: softflowd (Userland Exporter)
Softflowd is the simplest way to export NetFlow from FreeBSD. It runs in userland, captures packets via BPF, assembles them into flows, and exports NetFlow records.
Install softflowd
shpkg install softflowd
Basic Configuration
Export NetFlow v9 from your main interface to a collector:
shsysrc softflowd_enable="YES" sysrc softflowd_interface="em0" sysrc softflowd_dest="collector.example.com:9995" sysrc softflowd_flags="-v 9 -t maxlife=300"
Start the service:
shservice softflowd start
Configuration Details
The key flags:
-v 9: NetFlow version 9 (use-v 10for IPFIX)-t maxlife=300: Maximum flow lifetime of 300 seconds before export-n collector:port: Destination (can also be set viasoftflowd_dest)-T full: Export full flow tracking (bidirectional)
For multiple interfaces, run separate softflowd instances. Create /usr/local/etc/rc.d/softflowd_wan as a copy of the softflowd rc script, or use a wrapper:
sh# Monitor both WAN and LAN softflowd -i em0 -n collector.example.com:9995 -v 9 softflowd -i em1 -n collector.example.com:9995 -v 9
Verify Exports
Check that softflowd is tracking flows:
shsoftflowctl statistics
Output shows active flows, exported records, and flow counts.
Method 2: ng_netflow (Kernel-Level Exporter)
For higher-performance setups or when you are already using netgraph for networking, ng_netflow operates in the kernel and handles traffic at wire speed without the overhead of BPF captures.
Load the Module
shkldload ng_netflow ng_ether ng_ksocket ng_one2many
Make it persistent:
shsysrc kld_list+="ng_netflow ng_ether ng_ksocket"
Configure ng_netflow
Set up a netgraph topology that taps the network interface and exports flows:
sh# Create the netflow node ngctl mkpeer em0: netflow lower iface0 # Connect the output hook ngctl connect em0:. em0:lower out0 iface0 # Name the netflow node ngctl name em0:lower netflow0 # Set up the export destination via ksocket ngctl mkpeer netflow0: ksocket export inet/dgram/udp ngctl msg netflow0:export connect inet/collector.example.com:9995 # Configure NetFlow version 9 ngctl msg netflow0: setconfig {iface=0 conf=1} # Set timeouts ngctl msg netflow0: settimeouts {inactive=15 active=300}
Persistent Configuration
To make this survive reboots, create /usr/local/etc/rc.d/ng_netflow_setup or add the commands to /etc/rc.local:
sh#!/bin/sh # /etc/rc.local -- ng_netflow setup kldload ng_netflow ng_ether ng_ksocket 2>/dev/null ngctl mkpeer em0: netflow lower iface0 ngctl connect em0:. em0:lower out0 iface0 ngctl name em0:lower netflow0 ngctl mkpeer netflow0: ksocket export inet/dgram/udp ngctl msg netflow0:export connect inet/collector.example.com:9995 ngctl msg netflow0: setconfig {iface=0 conf=1} ngctl msg netflow0: settimeouts {inactive=15 active=300}
Verify
Check the netgraph topology:
shngctl list ngctl show netflow0:
View flow statistics:
shngctl msg netflow0: info
Setting Up nfsen as a Collector
nfsen provides a web-based frontend for collecting, storing, and analyzing NetFlow data. It uses nfdump as the backend.
Install nfsen and nfdump
shpkg install nfsen nfdump
Configure nfsen
Edit /usr/local/etc/nfsen/nfsen.conf:
sh# /usr/local/etc/nfsen/nfsen.conf (key settings) $BASEDIR = "/var/nfsen"; $HTMLDIR = "/usr/local/www/nfsen"; $BACKEND_PLUGINDIR = "/usr/local/libexec/nfsen/plugins"; # Data retention (days) $CYCLETIME = 300; %sources = ( 'freebsd-router' => { 'port' => '9995', 'col' => '#0000ff', 'type' => 'netflow', }, 'switch-core' => { 'port' => '9996', 'col' => '#ff0000', 'type' => 'netflow', }, );
Initialize nfsen
shnfsen install sysrc nfsen_enable="YES" service nfsen start
Web Interface
Configure your web server (nginx or Apache) to serve the nfsen PHP pages:
sh# Nginx configuration snippet server { listen 80; server_name netflow.example.com; root /usr/local/www/nfsen; index nfsen.php; location ~ \.php$ { fastcgi_pass unix:/var/run/php-fpm.sock; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; include fastcgi_params; } }
Access http://netflow.example.com/nfsen.php to view flow data.
nfdump Command-Line Analysis
nfdump is powerful for command-line analysis of collected flow data:
sh# Top 10 talkers in the last hour nfdump -R /var/nfsen/profiles-data/live/freebsd-router -s srcip -n 10 # Show flows to a specific IP nfdump -R /var/nfsen/profiles-data/live/freebsd-router -c 100 'dst ip 203.0.113.50' # Top 10 destination ports nfdump -R /var/nfsen/profiles-data/live/freebsd-router -s dstport -n 10 # Show flows for a specific time range nfdump -R /var/nfsen/profiles-data/live/freebsd-router \ -t 2026/04/09.10:00:00-2026/04/09.11:00:00 -s record -n 20
Setting Up ntopng for Real-Time Analysis
ntopng provides a modern web interface for real-time traffic analysis. It can receive NetFlow data or capture traffic directly.
Install ntopng
shpkg install ntopng
Configure ntopng
Edit /usr/local/etc/ntopng/ntopng.conf:
sh# /usr/local/etc/ntopng/ntopng.conf # Web interface -w=3000 # NetFlow collector mode -i=tcp://127.0.0.1:5556 # Data directory -d=/var/db/ntopng # Community edition (free) -G=/var/run/ntopng.pid
For NetFlow collection, ntopng needs nprobe or can use its built-in collector:
sh# Direct interface monitoring (alternative to NetFlow) # -i=em0 # NetFlow/IPFIX collector on port 2055 -i=ntopng://0.0.0.0:2055
Start ntopng
shsysrc ntopng_enable="YES" service ntopng start
Access the web interface at http://your-server:3000. Default credentials are admin/admin.
Point Your Exporter to ntopng
If using softflowd, change the destination:
shsysrc softflowd_dest="localhost:2055" service softflowd restart
Building a Complete Monitoring Pipeline
For a production setup, combine multiple components:
Architecture
shellInternet | [FreeBSD Router] ---> softflowd (NetFlow v9) ---> port 9995 | | [Internal Network] v [Collector Server] nfsen (port 9995) -- long-term storage ntopng (port 2055) -- real-time analysis
On the FreeBSD Router
shpkg install softflowd # Export to both collectors softflowd -i em0 -n collector:9995 -v 9 & softflowd -i em0 -n collector:2055 -v 9 &
Or configure softflowd to export to multiple destinations by running multiple instances.
On the Collector Server
shpkg install nfsen nfdump ntopng # nfsen listens on 9995 for long-term storage service nfsen start # ntopng listens on 2055 for real-time service ntopng start
Firewall Rules
Allow NetFlow traffic through PF:
sh# /etc/pf.conf pass in on $int_if proto udp from <netflow_sources> to self port { 9995, 2055 }
IPFIX Configuration
IPFIX (IP Flow Information Export) is the modern standard. To use IPFIX instead of NetFlow:
With softflowd:
shsysrc softflowd_flags="-v 10 -t maxlife=300" service softflowd restart
Version 10 is IPFIX. It supports variable-length fields, enterprise-specific information elements, and IPv6 natively.
Traffic Analysis Techniques
Identifying Top Bandwidth Consumers
shnfdump -R /var/nfsen/profiles-data/live/freebsd-router \ -s srcip/bytes -n 20 -o extended
Detecting Port Scans
shnfdump -R /var/nfsen/profiles-data/live/freebsd-router \ -s srcip/flows -n 20 'flows > 100 and duration < 1'
Monitoring Specific Services
sh# SSH traffic nfdump -R /var/nfsen/profiles-data/live/freebsd-router 'dst port 22' -s srcip # DNS traffic nfdump -R /var/nfsen/profiles-data/live/freebsd-router 'dst port 53' -s srcip/bytes # HTTP/HTTPS nfdump -R /var/nfsen/profiles-data/live/freebsd-router 'dst port in [80, 443]' -s dstip/bytes
Generating Reports
sh# Daily summary report nfdump -R /var/nfsen/profiles-data/live/freebsd-router \ -t 2026/04/08.00:00:00-2026/04/09.00:00:00 \ -s record/bytes -n 50 -o csv > /tmp/daily-report.csv
Data Retention and Storage
nfsen Retention
Configure retention in /usr/local/etc/nfsen/nfsen.conf:
sh# Number of 5-minute slots to keep at full resolution $CYCLETIME = 300; # Profile data expiry %ProfileDataRetention = ( 'low' => 180, # 180 days 'medium' => 90, # 90 days 'high' => 30, # 30 days );
Storage Estimates
NetFlow storage depends on traffic volume. As a rough guide:
- A 1 Gbps link with moderate utilization generates approximately 20-50 GB of flow data per month at full resolution
- Aggregated or sampled data is significantly less
Use ZFS compression on the flow data directory:
shzfs create -o compression=lz4 zroot/var/nfsen
FAQ
Should I use softflowd or ng_netflow?
Use softflowd for simplicity and most use cases. Use ng_netflow if you need kernel-level performance on a high-throughput router (10+ Gbps) or are already using netgraph for your network stack.
Can I collect NetFlow from third-party devices (Cisco, Juniper)?
Yes. nfsen and ntopng accept standard NetFlow from any exporter. Point your Cisco router's NetFlow export to the collector IP and port. The FreeBSD collector does not care about the exporter platform.
How much CPU does NetFlow export consume?
Softflowd uses minimal CPU -- typically under 2% even on busy links. ng_netflow operates in the kernel and is even lighter. The collector (nfsen/ntopng) uses more resources for storage and analysis.
Can I monitor encrypted traffic with NetFlow?
NetFlow captures metadata (source/destination IP, ports, byte counts, timestamps) not payload. It works on encrypted traffic because it does not inspect content. You see who is talking to whom and how much data flows, but not what the data contains.
What is the difference between NetFlow and packet capture (tcpdump)?
tcpdump captures full packets including payload. NetFlow exports aggregated metadata about flows. NetFlow is far more efficient for long-term traffic monitoring. Use tcpdump for debugging specific issues; use NetFlow for ongoing traffic analysis.
How do I handle NAT with NetFlow?
Export flows from both the internal and external interfaces. Internal flows show real client IPs. External flows show NATted addresses. Correlating the two requires timestamps and can be done with nfdump queries.