Integration
LibreNMS Integration
Share the NfSen data folders over NFS (read-only) so a LibreNMS server on a different machine can show NetFlow graphs + Top-N statistics. Written for NetLens (Dockerized NfSen 1.3.6p1 + NfDump 1.6.17) with a manually installed LibreNMS on Ubuntu.
At a glance
- NetLens stays on the VPS and keeps writing to its local folders — no other writer ever touches the live data.
- Share exactly two folders over NFS, read-only:nfsen-data/andnfsen-stat/
- Build nfdump 1.6.25 on the LibreNMS server to match the container's v1.6 file format (1.7.3 and 1.6.17 are both wrong on Ubuntu 24.04).
- Configure LibreNMS with
lnms config:setand the Netflow tab appears on every device page. - Never run two NfSen instances writing to the same shared folder — SysV semaphores are per-host and they will corrupt each other's 5-minute files.
1 — What LibreNMS actually needs from NfSen
LibreNMS has a built-in Netflow tab (still present in current LibreNMS — verified in their source at includes/html/pages/device/nfsen/). It needs three things:
A. The NfSen RRD graph files — read via the nfsen_rrds config (profiles-stat/live/<source>.rrd) → the channel graphs.
B. The raw flow files — read via the nfdump binary. LibreNMS runs this command on its own server:
How LibreNMS reads the flow files
Runs on the LibreNMS server itself — this is what produces the "Top N" statistics.
So it must be able to see profiles-data/live/... and have nfdump installed. This produces the "Top N" statistics.
C. Matching names — the NfSen source (ident) must map to the LibreNMS device hostname (see Part 7).
If LibreNMS runs on a different machine, the cleanest way to give it B and A is an NFS read-only share of the two data folders.
Two data consumers, one writer
nfsen_rrds. These are separate read paths, but both depend on the same NfSen source name and the same read-only NFS mounts.2 — Recommended architecture
Recommended architecture
Your VPS
Docker NetLens · one writer
nfsen-data/= profiles-datanfsen-stat/= profiles-statnfsen-var/not sharednfsen-etc/.htpasswd!
NfSen writes here — only the Dockerized NfSen.
LibreNMS server
reads, never writes
/var/nfsen/profiles-data/var/nfsen/profiles-stat- nfdump 1.6.25
- RRD graphs
Reads the raw flows + RRD graphs through NFS.
One writer rule: the NFS share is read-only for LibreNMS, and NfSen never reads back from it — it can never corrupt data.
Rule: NFS share = read-only for the LibreNMS server. NfSen never reads back from it. This is the "one writer" rule — it can never corrupt data.
Data flow
Data flow
Router exporters
send NetFlow over UDP
UDP ports 2055 / 2056
published into the container
nfcapd
writes raw flow files to nfsen-data
nfsen-data/live/
raw flows → nfsend → NfSen dashboard
nfsen-stat/live/
RRD graphs
NFS · read-only
LibreNMS server mounts the two folders
LibreNMS nfdump
Top-N statistics
Netflow tab
graphs + stats per device
Why not share the other folders?
nfsen-var/ (logs, runtime) or nfsen-etc/ —nfsen-etc contains .htpasswd, your Web UI password hashes.Keep the boundary explicit
nfsen-data/ and nfsen-stat/ cross the NFS boundary. The LibreNMS server reads them; it never writes to them.3 — Part 1: NFS server setup (on the VPS that runs NetLens)
Step 1 — Install the NFS server
sudo apt update
sudo apt install -y nfs-kernel-serverStep 2 — Find your project path
cd /path/to/netlens # e.g. /root/netlens or /opt/netlens
pwd # remember this as <VPS_PROJECT_PATH>Step 3 — Add the read-only exports
Edit /etc/exports and add the following (replace the IP and path):
<VPS_PROJECT_PATH>/nfsen-data <LibreNMS_IP>/32(ro,sync,no_subtree_check)
<VPS_PROJECT_PATH>/nfsen-stat <LibreNMS_IP>/32(ro,sync,no_subtree_check)Example (LibreNMS server = 192.168.1.50, project in /root/netlens):
/root/netlens/nfsen-data 192.168.1.50/32(ro,sync,no_subtree_check)
/root/netlens/nfsen-stat 192.168.1.50/32(ro,sync,no_subtree_check)ro= read-only (recommended — the LibreNMS server only needs to read).- If you ever want NfSen to write onto the share instead (alternative pattern, Part 11), change to
rw+no_root_squashthen. Not now.
Step 4 — Activate and verify the exports
sudo exportfs -rav
sudo systemctl enable --now nfs-server
sudo showmount -e localhost # you should see the 2 exportsStep 5 — Allow NFS through the firewall
On the cloud VPS and with ufw, allow NFS from the LibreNMS IP:
sudo ufw allow from 127.0.0.1 to any port 111 proto tcp
sudo ufw allow from 127.0.0.1 to any port 2049 proto tcp
sudo ufw allow from 127.0.0.1 to any port 111 proto udp
sudo ufw allow from 127.0.0.1 to any port 2049 proto udprpcbind port range
4 — Part 2: NFS client setup (on the LibreNMS server)
Step 1 — Install the NFS client
sudo apt update
sudo apt install -y nfs-commonStep 2 — Create the LibreNMS mount points
Use the same paths LibreNMS expects, so no symlinks are needed:
sudo mkdir -p /var/nfsen/profiles-data /var/nfsen/profiles-statStep 3 — Mount the two exports
Replace <VPS_IP> and the project path:
sudo mount -t nfs4 <VPS_IP>:<VPS_PROJECT_PATH>/nfsen-data /var/nfsen/profiles-data
sudo mount -t nfs4 <VPS_IP>:<VPS_PROJECT_PATH>/nfsen-stat /var/nfsen/profiles-statExample:
sudo mount -t nfs4 127.0.0.1:/root/netlens/nfsen-data /var/nfsen/profiles-data
sudo mount -t nfs4 127.0.0.1:/root/netlens/nfsen-stat /var/nfsen/profiles-statStep 4 — Make the mounts permanent
Append these two lines to /etc/fstab (each has exactly 6 fields: device, mountpoint, fstype, options, dump, pass):
<VPS_IP>:<VPS_PROJECT_PATH>/nfsen-data /var/nfsen/profiles-data nfs4 ro,soft,timeo=50,retrans=2,_netdev 0 0
<VPS_IP>:<VPS_PROJECT_PATH>/nfsen-stat /var/nfsen/profiles-stat nfs4 ro,soft,timeo=50,retrans=2,_netdev 0 0ro + soft = safe for a monitoring box: if NFS hiccups, LibreNMS just shows "no data" instead of hanging forever. _netdev tells systemd to wait for the network before mounting at boot.
Do not put mount commands in fstab
/etc/fstab accepts the six-field mount entries below, not the sudo mount commands from Step 3. Mixing them causes a parse error and can prevent the shares from returning after reboot.fstab gotchas (all bit us in production)
- Write only the two fstab lines above. Do not paste the
sudo mountcommands from Step 3 into/etc/fstab— boot then fails with/etc/fstab: parse errorand the shares never come back. - Check the file is clean:
sudo cat -A /etc/fstab— each line must end with just$(no^M/CRLF if you pasted from Windows). - After a reboot the mounts must be there with plain
df -h | grep nfsen. If they are gone, runsudo mount -a(should be silent) and re-check fstab.
Step 5 — Verify the mounted data
ls /var/nfsen/profiles-data/live/ # should list your sources, e.g. router1
ls /var/nfsen/profiles-stat/live/ # should list .rrd files5 — Part 3: Install nfdump on the LibreNMS server (version rule)
LibreNMS runs nfdump against your flow files. The file format must match the container's nfdump, otherwise LibreNMS cannot read anything:
- The NetLens container uses nfdump 1.6.17 (raw flow file format v1.6.x).
- nfdump 1.7+ writes/reads a new binary format — it cannot read 1.6.17 files.
- Ubuntu 24.04's default package is nfdump 1.7.3 = WRONG. Do not use it.
- Ubuntu 20.04's apt package is nfdump 1.6.17 = perfect match (only relevant if you ever run LibreNMS on 20.04).
Do NOT use 1.6.17 on Ubuntu 24.04
nfdump -M ... -R . dies with *** buffer overflow detected ***. 1.6.25 is the last release of the 1.6.x tree — same v1.6 file format as the container's 1.6.17, but with years of bug fixes.Step 1 — Install build dependencies
sudo apt update
sudo apt install -y build-essential autoconf automake libtool pkg-config \
flex bison byacc libpcap-dev libbz2-devStep 2 — Download and extract nfdump 1.6.25
cd /tmp
wget https://github.com/phaag/nfdump/archive/v1.6.25.tar.gz
tar xzf v1.6.25.tar.gz
cd nfdump-1.6.25Step 3 — Build and install
Use the same configure family as the Dockerfile:
sh ./autogen.sh
./configure --prefix=/usr/local
make -j"$(nproc)"
sudo make install
sudo ldconfigStep 4 — Verify the installed version
/usr/local/bin/nfdump -V # must show: Version: 1.6.25Ignore any /usr/bin/nfdump 1.7.3 that apt left behind — LibreNMS will be pointed at /usr/local/bin/nfdump (Part 6).
Step 5 — Run a quick read test
This should print flow stats, not an error:
/usr/local/bin/nfdump -M /var/nfsen/profiles-data/live/router1 -R . -s record/flows | tail -5- The
-Margument is the full path to the source directory (<base>/profiles-data/live/<source>). -Rselects the time range..= all files. Without-R, nfdump refuses with:-M needs either -r or -R to specify the file or file list.-R .reads every file since the beginning — on a busy profile that takes minutes (18M flows took ~40 s in testing). It is not stuck. For a fast check use a file range instead:
/usr/local/bin/nfdump -M /var/nfsen/profiles-data/live/<source> \
-R 'nfcapd.202608151945:nfcapd.202608151950' -s record/flows | tail -5Never pass a directory path to -R
*** buffer overflow detected ***.If it says "Can't open ... permission denied", fix per Part 9.
6 — Part 4: Configure LibreNMS
Step 1 — Set the LibreNMS configuration
Run these as the librenms user (or with sudo -u librenms):
Set the compatible binary and flat layout
nfcapd.YYYYMMDDHHMM files, so nfsen_subdirlayout must be 0; otherwise LibreNMS looks for YYYY/MM/DD/ subdirectories and finds nothing.Never leave nfsen_suffix empty
_none is safe when it does not occur in device hostnames.lnms config:set nfsen_enable true
lnms config:set nfsen_split_char '_'
lnms config:set nfsen_base.+ '/var/nfsen/'
lnms config:set nfsen_rrds.+ '/var/nfsen/profiles-stat/live/'
lnms config:set nfsen_rrds.+ '/var/nfsen/profiles-stat'
lnms config:set nfdump /usr/local/bin/nfdump # the 1.6.25 we built (NOT /usr/bin/nfdump = 1.7.3)
lnms config:set nfsen_subdirlayout 0 # flat file layout - this NfSen stores
# nfcapd.YYYYMMDDHHMM files with no
# YYYY/MM/DD/ subdirs. Without 0,
# LibreNMS finds nothing.
lnms config:set nfsen_suffix '_none' # REQUIRED, never leave emptynfsen_suffix must never be empty
_none (the LibreNMS docs' trick): lnms config:set nfsen_suffix '_yourdomain_com'. Whatever you choose, the value must be non-empty — empty = no Netflow tab.Step 2 — Open the Netflow tab
Open LibreNMS → Devices → click the device → Netflow tab at the end of the tab bar under the device header (scroll it sideways if it wraps). Quick test:
http://<librenms>/device/device=<id>/tab=netflow/Step 3 — Diagnose a missing tab
If the tab is missing, work through Part 8. The three usual causes: nfsen_enable not true, nfsen_suffix empty, or the RRD file name not matching the device's actual hostname ( Part 7).
Step 4 — Understand the two views
Stats (Top N) use nfdump → your NFS data. Graphs use the RRDs. The General view can look empty (it looks for per-channel subfolders this NfSen doesn't create) — the Stats view is the one with your flow data.
Tuning knobs (optional, all documented in LibreNMS):
lnms config:set nfsen_last_default 900
lnms config:set nfsen_top_default 20
lnms config:set nfsen_stats_default srcip
lnms config:set nfsen_order_default packets
lnms config:set nfsen_last_max 153600 # max seconds for stats7 — Matching NfSen sources to LibreNMS devices
LibreNMS finds a device's flow data by name. The NfSen source (ident) name becomes the RRD filename and the directory name under profiles-data/live/.
- The NfSen ident must match the LibreNMS device hostname, but:
- NfSen idents are limited to 21 characters.
- Dots (
.) are not allowed in the same way — LibreNMS replaces.with thenfsen_split_char(we set_).
- Example:
LibreNMS device hostname : core-router.example.com (longer than 21)
NfSen source ident : core_router_example_com (dots -> '_', short)LibreNMS will look for the RRD named after the transformed hostname (nfsen_split_char = _, done above).
Devices added by IP in LibreNMS: create symbolic links so the IP-based names resolve to the real source. You need two — one for the RRD graphs and one for the raw flow data (nfdump stats use it too).
Create symlinks on the VPS, not on the LibreNMS server
docker-compose.yml) — they show up on the LibreNMS side through NFS:# on the VPS (NetLens host), inside the project folder:
cd /path/to/netlens/nfsen-stat/live
sudo ln -s router1.rrd 192_168_1_50.rrd # <deviceIP with _>.rrd
cd /path/to/netlens/nfsen-data/live
sudo ln -s router1 192_168_1_50 # data dir for nfdump statsReplace router1 with the real source that collects that router's traffic, and 192_168_1_50 with the LibreNMS device hostname/IP with . replaced by the nfsen_split_char (i.e. _).
Use the device's ACTUAL hostname
device:poll 192.168.1.50). A symlink with the wrong name means the Netflow tab never appears — the name must match exactly, e.g. a device polled as 127.0.0.1 needs 127_0_0_1.rrd.On the NfSen side, when you add a real source in nfsen.conf, name it to match (see the project README for adding sources):
'core_router_example_com' => { 'port' => '2070', 'col' => '#FF0000', 'type' => 'netflow' },8 — Verification checklist
On the VPS (NetLens):
sudo showmount -e localhost
ls -la nfsen-data/live/ nfsen-stat/live/On the LibreNMS server:
df -h | grep nfsen # mounts are up
ls /var/nfsen/profiles-data/live/ # sources + any IP symlinks
ls /var/nfsen/profiles-stat/live/ # .rrd files + any IP symlinks
/usr/local/bin/nfdump -V # must be 1.6.25
/usr/local/bin/nfdump -M /var/nfsen/profiles-data/live/<source> -R 'nfcapd.<file1>:nfcapd.<file2>' -s record/flows | tail -5
lnms config:get nfsen_enable # must be true
lnms config:get nfsen_suffix # must NOT be empty
lnms config:get nfsen_subdirlayout # must be 0 (flat file layout)
lnms config:get nfsen_rrds # must list the profiles-stat paths
sudo -u librenms ./validate.php # LibreNMS self-check (in its install dir)In the browser:
- Device page → tab bar (at the end of it) → Netflow → Stats view shows Top-N.
- Direct URL test:
http://<librenms>/device/device=<id>/tab=netflow/
If the tab is missing, run sudo tail -n 50 /opt/librenms/logs/librenms.log and check, in order: nfsen_enable true? nfsen_suffix non-empty? RRD file name matches the device's real hostname (Part 7)? The tab only appears when all three are true.
9 — Permissions and ownership
Inside the container the users are:
netflow= uid 1000 (ownsprofiles-data/live— writes flow files)www-data= uid 33 (ownsprofiles-stat— writes RRDs)
Over NFS, uid 33 and uid 1000 are just numbers. The live directories are chmod 775 with netflow:www-data ownership, so any local user (including www-data/root, which is how LibreNMS runs nfdump) can read them. That is why a read-only export works with no special uid mapping.
If you ever see Permission denied:
- Check perms on the VPS:
ls -la nfsen-data/live/(expectdrwxrwxr-x) - Check the export flags:
cat /etc/exports(rois fine for reading) - On some setups the export needs:
rw,sync,no_root_squash(only needed if NfSen itself must write to the share — Part 11)
10 — Danger zone
Things that WILL break your data
- Running TWO NfSen instances that write to the same live folder over NFS. NfSen uses SysV semaphores which exist per-host — the two instances cannot coordinate, so they corrupt each other's 5-minute files.
- Exporting
nfsen-etc/— it contains.htpasswd(Web UI password hashes). - Exporting
nfsen-var/— unnecessary (logs, runtime). - Using the default Ubuntu 24.04 nfdump package (1.7.3) on the LibreNMS host — new file format, cannot read the 1.6.17 files. Build 1.6.25 from source (Part 5) and point LibreNMS at
/usr/local/bin/nfdump. - Leaving
nfsen_suffixempty in LibreNMS — the tab's RRD check builds an empty regex and silently fails, so the Netflow tab never appears. - Pasting the
sudo mountcommands into/etc/fstabinstead of the proper 6-field lines — boot fails to mount the shares ("parse error"). - A slow/unreliable network as the WRITE target for NfSen — dropped NFS = stuck nfcapd writes. For the recommended read-only setup this is a non-issue.
11 — Alternative pattern
Pattern B — NFS as the primary storage for the NfSen data (single writer):
- Mount the NFS share on the VPS under the project (e.g. replace the
nfsen-data/folder with an NFS mount to a NAS). - Docker keeps working unchanged (it's still a bind mount).
- Requirements: export
rw,sync,no_root_squash(the entrypoint runs chown/chmod as root), the NFS server must be reliable, and the mount must be up beforedocker compose up. - Pros: data survives VPS loss; easy to point multiple read-only consumers (LibreNMS) at the same NAS.
- Cons: single point of failure (the NAS) + NFS dependency at boot.
For the goal of this guide (LibreNMS on another server), pattern A (read-only export) is the right choice — no reason to move NfSen's primary storage.
Summary
- Goal: LibreNMS (separate server) shows NetFlow graphs + top-N stats from the Dockerized NfSen.
- How: NFS share the two data folders (
nfsen-data= raw flows,nfsen-stat= RRD graphs) read-only from the NetLens VPS to the LibreNMS server. NfSen keeps writing locally (one writer rule — never two NfSen instances on the same live data). - On the LibreNMS server: install
nfs-common, mount the shares at/var/nfsen/profiles-dataand/var/nfsen/profiles-stat, and install nfdump 1.6.25 (last of the 1.6.x tree) to match the container's v1.6 file format — on Ubuntu 24.04 build it from source, do not use 1.6.17 (its range parsing crashes with "buffer overflow detected" on 24.04's toolchain). Then enable the integration withlnms config:set nfsen_enable true(+ paths +nfdump→/usr/local/bin/nfdump). - NfSen source names must match LibreNMS device hostnames (21-char limit, dots →
_); for devices added by IP create two symlinks on the VPS (RRD.rrd+ data dir) named after the device's real hostname (check the poll log, e.g.127.0.0.1→127_0_0_1.rrd). The mount is read-only, so the symlinks must be created VPS-side. - LibreNMS config that must be right:
nfsen_enabletrue,nfsen_suffixnon-empty (empty = no tab),nfsen_subdirlayout0 (this NfSen stores flat nfcapd files),nfsen_rrdspointing atprofiles-stat. - fstab entries need
_netdevand must be proper 6-field lines — pasting thesudo mountcommands into fstab breaks boot mounting. - Never export
nfsen-etc(contains.htpasswd) ornfsen-var. - Verified against: LibreNMS docs and LibreNMS master source (
nfdump -M <base>/profiles-data/live/<source>).
Final verification checklist
Use this final pass after completing the guide. Every item should be true before troubleshooting the LibreNMS UI:
- NetLens is the only NfSen instance writing to the live data folders.
- The VPS exports only
nfsen-data/andnfsen-stat/withro,sync,no_subtree_check. nfsen-var/andnfsen-etc/are not exported.- The LibreNMS server mounts the shares at
/var/nfsen/profiles-dataand/var/nfsen/profiles-stat. /etc/fstabcontains two valid six-fieldnfs4entries withroand_netdev./usr/local/bin/nfdump -Vreports1.6.25on Ubuntu 24.04.nfsen_enableistrueandnfsen_suffixis non-empty.nfsen_subdirlayoutis0for NetLens's flat file layout.nfsen_rrdspoints to the mountedprofiles-statpaths.- The NfSen source ident matches the LibreNMS hostname after dot-to-underscore conversion.
- Devices added by IP have both the RRD and raw-data symlinks created on the VPS.
- The LibreNMS device page shows Netflow → Stats with Top-N data.