Skip to main content

Flow Collector Scaling and Exporter Authentication

The collector publishes converted NetFlow, IPFIX and sFlow telemetry to NATS JetStream. EventWriter persists it to the configured telemetry backend.

Secure defaults and upgrade migration​

NetFlow v9 and IPFIX UDP source addresses do not authenticate exporters. Spoofing an exporter's address, port and domain can replace its templates, sampling state or pending records. IP allowlists and disabling persistence do not close this local poisoning path.

Template-based UDP is rejected before parser admission by default. The whole datagram is checked, including trailing packets after a valid legacy prefix. Template-free NetFlow v5 and sFlow UDP remain available.

Before upgrading:

  1. Remove all template_store overrides, including retained Helm values. Non-null shared-store configuration fails startup with a migration error, and Helm chart rendering fails fast. The collector never reads, writes or deletes old KV entries.
  2. Configure mutually authenticated native IPFIX TLS/TCP for capable exporters. Approve each client certificate's SHA-256 leaf fingerprint explicitly.
  3. For UDP-only devices, set allow_unauthenticated_templates: true on the relevant netflow listener only if accepting spoofing risk on a separately protected network. This mode is insecure. State is listener-local, starts cold on restart and is never shared through KV.

Existing v9/IPFIX UDP stops ingesting with secure defaults. Opening port 4740 alone does not configure TLS. The existing NATS security block authenticates the collector to NATS, not the exporter.

Native IPFIX TLS configuration​

Use protocol: ipfix_tls, default address 0.0.0.0:4740. Supply a server certificate/key, client CA bundle and nonempty map of approved leaf fingerprints to exporter IDs. Chain/validity verification and private-key possession happen before authorization and parser creation. CA-trusted but unlisted clients and plaintext IPFIX are rejected. TLS 1.2/1.3 are supported; early data and session resumption are disabled.

Invented Helm example; replace the fingerprint before use:

flowCollector:
enabled: true
ipfixTlsSecretName: flow-ingress-server-tls
config:
template_store: null
listeners:
- protocol: ipfix_tls
subject: flows.raw.ipfix
cert_file: /etc/serviceradar/ipfix-tls/server.pem
key_file: /etc/serviceradar/ipfix-tls/server-key.pem
client_ca_file: /etc/serviceradar/ipfix-tls/client-ca.pem
exporters:
"0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef": exporter-01
max_sessions: 64
max_sessions_per_exporter: 2
handshake_timeout_secs: 10
read_timeout_secs: 60
max_message_size: 65535
max_sources: 128
max_templates: 2000
service:
ports:
ipfixTls:
enabled: true
port: 4740
targetPort: 4740

The optional Secret mount holds collector server-side TLS material and the public client CA bundle. Exporter private keys stay on exporters; public fingerprints are configuration. This adds no device/integration credential store; those credentials use the unified CNPG credential model.

Calculate lowercase colon-free SHA-256 over the leaf DER certificate:

openssl x509 -in exporter-client.pem -outform DER | openssl dgst -sha256

During rotation, map both old and new fingerprints to the same exporter ID. They share its session allowance. Roll the collector to apply configuration changes and terminate sessions authorized by a removed mapping. Exporters must validate the collector server certificate and trust its CA.

Session ownership and capacity​

Each authenticated connection owns its templates, options templates, pending records, sampling rates and observation-domain parsers. Sessions with identical source IPs, domains and template IDs cannot overwrite or withdraw each other's state, even if approved as the same exporter. Disconnect, read failure, listener cancellation and restart discard that state. Every new connection requires templates again per RFC 7011 section 8.

Only complete version 10 messages are parsed. Length must be 16-65535 bytes and within the configured maximum. One deadline covers header and body, including idle or partial-message stalls. Invalid, truncated and timed-out messages terminate the connection. Multiple messages per TCP write and fragmented writes are supported through message-length framing.

TLS settingDefaultSupported bound
max_sessions641-4096, including handshakes
max_sessions_per_exporter2Positive, no greater than total
handshake_timeout_secs101-600 seconds
read_timeout_secs601-3600 seconds
max_message_size6553516-65535 bytes
max_sources1281-10000 observation domains per session
max_templates20001-10000 templates per domain
max_template_fields100001-100000 fields per template
exportersrequired1-4096 fingerprints; IDs 1-64 ASCII characters
pending_flowsdisabledAt most 10000 pending flows, TTL at most 3600s

Total permits are acquired before handshake; exporter permits after authentication. All exits release them. A busy exporter cannot consume another exporter's allowance. Listener shutdown cancels its child sessions.

The bootstrap Helm Job establishes stream ownership before pods start. TCP load balancing keeps each session on one pod; new sessions can use other replicas but start cold. More replicas spread sessions; higher CPU/memory limits supply per-pod headroom. Size memory for the product of admitted sessions, observation domains, templates (max_templates, default 2000, bounds 1..=10000), fields per template (max_template_fields, default 10000, bounds 1..=100000), and pending records.

Each listener has a bounded publisher channel (channel_size, default 10000) feeding the common JetStream publisher (batch_size 100, publish_timeout_ms 5000). Overflow rejects the newest message. Each handler retains at most 65536 transport/domain/sampler-rate identities; existing entries can still be updated, and a rate included in the current record takes priority. TLS handlers are session-local. Insecure UDP max_sources defaults to 10000; eviction prefers identities owned by the creating IP, then global LRU.

Metrics and rollout verification​

Prometheus is served at /metrics on metrics_addr, default 0.0.0.0:50046. Security labels contain only configured protocol/listener addresses, never peer identities or fingerprints.

MetricMeaning
flow_collector_tls_authenticated_sessions_totalApproved authenticated connections
flow_collector_tls_active_sessionsActive authenticated sessions
flow_collector_tls_auth_rejections_totalFailed, expired or unapproved authentication
flow_collector_tls_session_limit_rejections_totalTotal or exporter capacity reached
flow_collector_ipfix_frame_rejections_totalInvalid, partial or timed-out TLS message
flow_collector_udp_template_rejections_totalDefault gate rejected template or non-legacy input
flow_collector_sourcesLive domain parsers across listener sessions
flow_collector_sampler_rate_rejections_totalSampler inserts rejected at capacity
flow_collector_sampling_rate_clamped_totalExporter-declared rates clamped to max_sampling_rate
flow_collector_channel_full_drops_totalPublisher overflow
flow_collector_flows_converted_totalValid converted records

A non-zero flow_collector_sampling_rate_clamped_total means an exporter declared a sampling rate above max_sampling_rate (default 1,000,000) and the published value was bounded. The counter covers every protocol: NetFlow v5, v9 and IPFIX, and sFlow, whose samples declare a u32 rate reaching 4,294,967,295. A NetFlow listener routes sFlow datagrams through its own sFlow fallback, so the ceiling set on that listener applies to them as well. Because analytics multiply byte and packet counts by this rate, and every v9/IPFIX sampling field is unauthenticated wire input that decodes to a full u64, an unbounded value would inflate a single flow into fabricated volume. Investigate the exporter rather than raising the ceiling; 1:1,000,000 is already far past operational practice.

Deprecated template_store_* metrics remain zero for dashboard compatibility. Remove shared-bucket/restoration alerts. Missing templates on reconnect are expected until that session announces them.

After new pods are ready, use an approved synthetic exporter and confirm its records reach the expected JetStream subject. Reconnect without templates; confirm no records until reannouncement. CA-trusted unlisted clients, plaintext TLS-port traffic and default UDP v9/IPFIX must produce rejection counters and no flow records. Give every observation a deadline and an explicit failure branch. Device interoperability remains separate from synthetic transport regressions.