Plugin: netflow-plugin Module: static-metadata
Annotate network flows with operator-defined labels for exporters, interfaces,
networks, and sampling rates. Static Metadata is a YAML-defined enrichment source
that lives entirely in netflow.yaml. Use it when there is no IPAM, no CMDB, and
no MMDB to query – you simply know your own networks, your own routers, and what
the interfaces on those routers do, and you want those labels visible on the
Network Flows view.
Three independent surfaces are configured under this card, each populating a different set of flow-record fields:
enrichment.metadata_static.exporters.<ip-or-cidr> – per-exporter labels
(matched against the source IP of the UDP datagram) and per-interface labels
(matched against the ifIndex from the flow record).enrichment.networks.<cidr> – labels for arbitrary CIDR blocks (your own
corp ranges, customer ranges, public blocks you operate). Matched against the
flow’s source and destination IPs.enrichment.override_sampling_rate.<cidr> – per-prefix sampling-rate
substitution for exporters that do not communicate their rate (e.g. NetFlow
v7, which has no sampling field, or a v9 exporter that never sends a Sampling
Options Template).Fields populated:
metadata_static.exporters (per-exporter):
EXPORTER_NAME, EXPORTER_GROUP, EXPORTER_ROLE, EXPORTER_SITE,
EXPORTER_REGION, EXPORTER_TENANT.metadata_static.exporters.if_indexes (per-interface):
IN_IF_NAME / OUT_IF_NAME, IN_IF_DESCRIPTION / OUT_IF_DESCRIPTION,
IN_IF_SPEED / OUT_IF_SPEED (in bits per second), IN_IF_PROVIDER /
OUT_IF_PROVIDER, IN_IF_CONNECTIVITY / OUT_IF_CONNECTIVITY,
IN_IF_BOUNDARY / OUT_IF_BOUNDARY (1 = external, 2 = internal,
0/omitted = removed from output).enrichment.networks (per-CIDR):
SRC_NET_NAME / DST_NET_NAME, SRC_NET_ROLE / DST_NET_ROLE,
SRC_NET_SITE / DST_NET_SITE, SRC_NET_REGION / DST_NET_REGION,
SRC_NET_TENANT / DST_NET_TENANT, plus overrides for the GeoIP-derived
SRC_COUNTRY / DST_COUNTRY, SRC_GEO_STATE / DST_GEO_STATE,
SRC_GEO_CITY / DST_GEO_CITY, SRC_GEO_LATITUDE / DST_GEO_LATITUDE,
SRC_GEO_LONGITUDE / DST_GEO_LONGITUDE. Setting asn: on a networks
entry overrides the AS number via the same merge path; the AS name
still comes from the ASN database (see “Composition with dynamic sources”
below).override_sampling_rate (longest-prefix match against the exporter IP):
SAMPLING_RATE is set unconditionally when an override prefix matches. This
is different from default_sampling_rate, which only applies when the flow
does not already carry a rate.For the cross-cutting Enrichment concept (provider chains, merge order rules, how static composes with dynamic sources, the static-blocks-classifiers interaction, and shared failure modes), see Enrichment.
Edit netflow.yaml, restart the plugin, and the YAML-defined data is loaded
into the same in-memory tries the GeoIP, IPAM, and BGP enrichment paths read
from. There is no network access, no file watching, and no hot reload –
changes take effect on the next plugin startup.
This integration is only supported on the following platforms:
This integration runs as a single instance per Netdata Agent.
Disabled by default. Add entries under enrichment.metadata_static, enrichment.networks, and / or enrichment.override_sampling_rate to populate it.
Resource use scales with the number of exporter, interface, network, and sampling-override entries. Keep CIDR ranges and interface maps specific enough to match the routers you actually export.
Static lookups are local map/trie lookups during enrichment. Cost is usually small compared with flow decode and journal writes, but very large maps add memory and lookup work.
You need to know which IP addresses your routers / switches / firewalls export from, the integer ifIndex values they use for each interface, and the CIDR ranges that belong to each of your sites / tenants / roles. None of this is auto-discovered – this card is the “I will tell you” path. For sources that auto-discover the same data, see Generic IPAM, NetBox, and the cloud IP-range cards.
if_indexes keys are the integer ifIndex the router puts in the flow
record. Some platforms reassign ifIndex on line-card reseat or stack
rebuild. After hardware changes, audit the labels – a stale ifIndex
entry silently no longer applies. The default interface block is used
instead, or no labels are written when skip_missing_interfaces: true is set.
All keys live under enrichment: in netflow.yaml. Unknown keys fail config
load with a parse error.
| Option | Description | Default | Required |
|---|---|---|---|
| enrichment.metadata_static.exporters | Map keyed by exporter IP or CIDR. Longest-prefix match wins. A /32 key and a bare IP are equivalent. Each entry holds exporter-level labels (name, group, role, site, region, tenant), an optional default interface block, an if_indexes map keyed by integer ifIndex, and skip_missing_interfaces. | {} | no |
| enrichment.metadata_static.exporters.<key>.if_indexes | Map keyed by integer ifIndex (the value the router puts in the flow record). Each entry holds name, description, speed (bits per second), provider, connectivity, and boundary. | {} | no |
| enrichment.metadata_static.exporters.<key>.default | Interface block applied to flow records whose ifIndex is not present in if_indexes. Same shape as an if_indexes entry. Ignored when skip_missing_interfaces: true is set. | {} | no |
| enrichment.metadata_static.exporters.<key>.skip_missing_interfaces | When true, flow records whose ifIndex is not in if_indexes get no interface labels at all (not even from default). Useful when you only care about a known set of WAN interfaces and want unknown ones to stay blank instead of inheriting a placeholder. | false | no |
| enrichment.metadata_static.exporters.<key>.if_indexes.<n>.boundary | Interface boundary marker. Accepts the integers 0 (undefined), 1 (external – faces the outside world: Internet, peer, transit), 2 (internal – faces your own infrastructure), or the case-insensitive strings "undefined", "external", "internal". Any other value fails config load. Filtering for IN_IF_BOUNDARY=1 cleanly gives you “traffic that arrived from outside”. | 0 | no |
| enrichment.metadata_static.exporters.<key>.if_indexes.<n>.speed | Interface speed in bits per second. A 1 Gbps interface is 1000000000, not 1000 and not 1000000. Operators thinking in megabits get the value wrong by a factor of 1000 to 1000000. A 0 value means “not set” and removes the field from the output. | 0 | no |
| enrichment.networks | Map keyed by CIDR. Longest-prefix match contributes the most-specific fields; less-specific containing prefixes contribute their non-empty fields too. The same merge rule is used by network_sources. Each value is either a string (shorthand for name:) or a map with name, role, site, region, country, state, city, latitude, longitude, tenant, asn. | {} | no |
| enrichment.networks.<cidr>.asn | Forces the AS number for traffic in this prefix, overriding whatever the asn_providers chain computed. The AS name is still resolved from the ASN MMDB – there is no asn_name config field. See the ASN section of Enrichment. | 0 | no |
| enrichment.networks.<cidr>.latitude / longitude | Per-CIDR coordinate override. Out-of-range values (latitude not in [-90, 90] or longitude not in [-180, 180]) and non-finite values are silently coerced to empty strings – the field is dropped, no error. Validate input out of band if your data matters. | null | no |
| enrichment.default_sampling_rate | Global fallback applied only when the flow record does not already carry a sampling rate. Either a single integer or a CIDR-keyed map (longest-prefix match against the exporter IP). | 0 | no |
| enrichment.override_sampling_rate | Per-exporter substitution that always wins when its prefix matches the exporter IP, regardless of what the flow record carried. Either a single integer or a CIDR-keyed map. | {} | no |
The configuration file name for this integration is netflow.yaml.
You can edit the configuration file using the edit-config script from the
Netdata config directory.
cd /etc/netdata 2>/dev/null || cd /opt/netdata/etc/netdata
sudo ./edit-config netflow.yaml
One edge router and one spine. The default block applies to any
ifIndex not listed under if_indexes – handy when you only care about
a few WAN ports and want everything else to inherit a placeholder.
enrichment:
metadata_static:
exporters:
192.0.2.10: # bare IP == /32
name: edge-router-1
site: par1
region: eu-west
role: edge
tenant: tenant-a
default:
description: unclassified port
if_indexes:
1:
name: Gi0/0/1
description: uplink to ISP-A
speed: 10000000000 # 10 Gbps in bits per second
provider: isp-a
connectivity: transit
boundary: external
2:
name: Gi0/0/2
description: LAN core
speed: 1000000000
connectivity: lan
boundary: internal
198.51.100.0/24: # all routers in this subnet
site: dc-fra1
region: eu-central
role: spine
default:
connectivity: lan
boundary: internal
The shorthand form (203.0.113.0/24: transit-a) sets only the name.
The map form takes any subset of the schema fields. Less-specific
supernets contribute non-empty fields to more-specific subnets via
ascending-prefix-length merge – declare RFC1918 once at /8 and
a /24 inherits everything you did not override.
enrichment:
networks:
10.0.0.0/8:
name: corp-internal
role: internal
tenant: tenant-a
198.51.100.0/24: # a public block you operate
name: customer-acme
role: customer
site: par1
country: FR
city: Paris
latitude: 48.8566
longitude: 2.3522
asn: 64500
203.0.113.0/24: transit-a # shorthand: name only
With skip_missing_interfaces: true, an ifIndex that is not in
if_indexes produces no interface labels at all – the default
block is ignored. Useful when you want clearly-blank values for
unmodelled interfaces instead of a placeholder description.
enrichment:
metadata_static:
exporters:
192.0.2.10:
name: edge-router-1
skip_missing_interfaces: true
if_indexes:
1:
name: Gi0/0/1
description: uplink to ISP-A
connectivity: transit
boundary: external
NetFlow v7 has no sampling field; some v9 exporters never send a
Sampling Options Template. Without an override, the bytes/packets
stored in the journal are exporter-side sampled counters with
no scaling factor. override_sampling_rate always wins;
default_sampling_rate is the fallback used only when the flow
did not carry a rate.
enrichment:
default_sampling_rate: 1 # global fallback
override_sampling_rate:
10.1.0.0/16: 1024 # an old NetFlow v7 stack
192.0.2.10/32: 4096 # one specific exporter
Tags flow records with operator-defined labels and (optionally) substitutes
the sampling rate; produces no metrics of its own. Verify on the Network
Flows tab via the EXPORTER_*, IN_IF_*, OUT_IF_*, *_NET_*,
*_COUNTRY, *_GEO_*, and SAMPLING_RATE columns.
There are no alerts configured by default for this integration.
enrichment.networks merges containing prefixes from least-specific to
most-specific. Leaving a field blank on a /24 does not clear the /16’s value
for that field – you must explicitly set the field on the more-specific
entry to overwrite. The same merge rule applies to entries from
network_sources, which interleave at the same prefix lengths.
Until you declare your RFC1918 / RFC6598 / link-local ranges as
enrichment.networks entries, the GeoIP-derived country / city / coord
fields can pick up junk for those addresses. Adding a networks entry
for the range overrides the GeoIP layer at the merge step.
if_indexes keys are the numeric ifIndex sent in the flow record. A
line-card reseat or stack rebuild can renumber the interfaces; the old
ifIndex no longer matches and the per-interface block silently no longer
applies. Audit after hardware changes.
speed: is in bits per second. speed: 1000 means 1 kbps, not
1 Mbps. A 1 Gbps interface is 1000000000. speed: 0 means “not set”
and removes the field from the output.
When the configured ifIndex is not present in the flow record, the
default block is used instead – unless skip_missing_interfaces: true
is set, in which case no interface labels are written at all. If you expected your block to apply but the labels are blank, the
router is sending a different ifIndex.
Out-of-range latitude / longitude (latitude: 91.5) and non-finite
values become empty strings without an error. The map quietly stops drawing the marker. Validate input externally if
the data matters.
When static metadata sets any of group, role, site, region,
tenant for an exporter, the exporter_classifiers rule chain does not
run for that exporter at all. The same is true for an interface: any of provider, connectivity,
boundary set by static metadata short-circuits
interface_classifiers. If
you want classifiers to run on top of static metadata, drop the static
fields they are supposed to set.
The schema is deny_unknown_fields at every level. A typo such as
if_index (the canonical key is if_indexes; aliases ifindexes,
if-indexes are accepted) or a misspelt attribute (teannt:) fails plugin
start with a YAML parse error rather than being silently ignored.
override_sampling_rate always wins when its prefix matches; if the
field still looks unset, check that the exporter IP – not the
flow’s source / destination IP – falls under the configured prefix.
default_sampling_rate is only consulted when the flow did not already
carry a rate.
Static metadata is loaded at plugin startup and there is no file-change
watcher. Restart the plugin (or the agent) after editing
netflow.yaml.
Want a personalised demo of Netdata for your use case?