Release Notes 2.0.1.33¶
Release history for the Automated Cryptography Discovery & Inventory (ACDI) Sniffer.
- Version:
2.0.1.33 - Build Date: October 22, 2026
- Artifacts: Rocky Linux 8 RPMs for
x86_64andaarch64 - Documentation Build: Static HTML generated with MkDocs Material, published as
pqc-sniffer-docs-2.0.1.33.zip
This release follows 2.0.0.97 Beta 1. It is a large one: it closes the security review raised against the beta, reworks capture and threading for multi-core hosts, widens protocol coverage beyond TLS, and corrects how connection records are counted and when they are written.
Upgrade Notes¶
Read these before upgrading an existing deployment. Each one changes behavior you may be relying on.
- Connection records are now written when a flow ends, not when its handshake is analyzed. A record now carries the packet and byte totals for the whole conversation. The cost is timing: a long-running TLS session, and a non-TLS TCP session that closes, appear in the output when they end rather than when they start. A session that keeps talking without closing is still written while it runs, 60 seconds after it was first seen. Offline replay is unaffected in content, because every surviving flow is written at end of capture. A query over a window of live capture will no longer show sessions that are still open.
-
A mistyped configuration value is now refused instead of silently becoming a default. A typed setting given a value it cannot convert, such as
buffer_size_kb: lotsorrotation_enabled: maybe, used to load as that setting's default and log nothing, so the file said one thing and the sniffer did another. The load now fails, naming the setting and the value:offline_output.buffer_size_kb must be a whole number, but is 'lots'.Check your configuration before you upgrade: run the new binary with
--validate-configagainst your existing file and it names anything it cannot convert. Two cases are worth knowing about. A mistyped boolean such asrotation_enabled: maybepreviously loaded astrue, so a deployment that meant to switch rotation off has been running with it on. And1and0are not booleans here:rotation_enabled: 1was also quietly running on the default. Writetrue/false,yes/no,on/offory/n, in any case.Two keys are deliberately exempt, because they accept a word as well as a number:
capture.processing_threadsandcapture.fanout_threadstake a whole number orauto. Anything else logs a warning naming the key and the value, then sizes that pool automatically rather than refusing the file. -
A configuration with no
offline_outputsection is now refused. It used to load and write to/var/log/pqc-sniffer/connections.ndjson, a path the file never named. The other three required sections,sniffer,captureandlogging, were already refused in practice. A section written as a bareoffline_output:with nothing under it counts as absent; written asoffline_output: {}it is present and every setting in it takes its default. - A configuration that leaves out
logging.fileorlogging.databaseis now accepted. Neither sub-block is in the documented required set, but omitting either used to be refused, and the second asked an offline-only deployment to choose a database log level. An omitted sub-block now takes the same defaults as one written empty. - The default capture filter is wider. It now admits UDP, GRE, and IPv6 extension-header traffic. Deployments that relied on the old narrow default will see more flows, and QUIC, DTLS, IKEv2, and tunnelled traffic that was previously dropped before the parser now appears in output.
- The
b64:credential format has been removed. Connected-mode deployments using it must migrate; the release includes a migration path off it. - The service drops root privileges after capture initialization and no longer retains
CAP_NET_RAWwhile parsing packet data. - RPM filenames now match the package's own architecture metadata. No source RPM is published.
What's New¶
Protocol and PQC Detection¶
- Non-TLS IoT flows are recorded: DTLS and IKEv2 NAT-T are identified, plaintext MQTT is classified, and a continuous flow is reported while it is still running rather than only at its end.
- TLS inside DTLS 1.3, STARTTLS, and NTS-KE is read and analyzed.
- SSH key exchange is parsed and given a quantum-safety verdict, correcting SSH KEX misclassification. HQC, LMS, and XMSS coverage was added.
- The certificate signature algorithm is read from the certificate rather than inferred from the cipher suite.
- PQC assessment reports what the server selected, not what the client offered.
- An offered algorithm is reported under the name its code point is registered with.
- Protocol labels now match what was actually parsed: SMTPS on 465 is labelled SMTPS, HTTP/3 is dispatched to its parser, and DoH is identified by resolver evidence rather than a fixed host list.
- HTTPS is no longer assumed from port 443 alone.
- GRE and ERSPAN tunnels are decapsulated on the capture path.
DLT_RAW,DLT_NULL, andDLT_LOOPlink types are decoded, and the capture link type is carried through the pipeline.
Connection Records and Output¶
- Each packet and payload byte is counted once, per direction, in one place. UDP flows previously reported double.
- A connection record reports the whole flow. Records used to freeze at the handshake.
- Sealed-file NDJSON output mode for BigFix and other agentless file collection, with gzip on seal.
- The directory form of
offline_output.output_fileis accepted, as every documentation example shows it. - Duplicate packets no longer break the capture and flow pipeline.
filter_rejectedis now incremented, rather than reported every cycle as zero.- Connection-table and refusal messages report the limit that caused the refusal, at the scale that limit uses.
- Batch size and batch timeout are both honored; a batch is no longer written on every enqueue.
- Remediation priority is emitted for more than just Vulnerable connections.
- Switching
rotation_modeno longer orphans circular NDJSON files.
Capture and Performance¶
- Capture and processing thread counts are sized from the CPUs the process can actually use, and adapt at runtime to measured loss instead of being fixed at startup.
- A paced PCAP replay runs to the end and reports what it refused, rather than dropping data silently.
- Malformed, padded and truncated packets no longer distort the capture. Each packet is read against the lengths it declares, so Ethernet padding is not counted as payload, a fragment does not invent a flow, and a truncated datagram still produces a record.
- A flood of incomplete DTLS handshakes can no longer grow memory without limit, and fragments from one flow are never assembled into another.
- Running at
infono longer pays for the debug detail it discards, and a malformed-packet flood is summarised with a suppressed count in the shutdown statistics rather than one log line per packet. - Heartbeat CPU percentage is measured over a fixed window by a single owner, correcting a sampling artefact that reported 188% against a steady 107% measured externally.
- The connection idle timeout is configurable rather than hardcoded.
- Memory is used against a configured limit, with admission control that resumes on its own.
Reliability and Service Behavior¶
- A runtime watchdog detects a main loop that has stopped progressing and lets systemd restart the service.
- If the sniffer does crash, it writes a crash report before it exits, with a stack trace that resolves to function, file and line, and the service restarts on its own.
- The crash report is produced without calling into the system stack unwinder, which could block indefinitely when the crash had interrupted the dynamic loader. A crash that would previously have left the service hung until its systemd start timeout expired now writes its report and exits. The trace can be shorter than before, because it stops where it reaches a bundled third-party library.
- The service stops within seconds of a stop request, on every capture path, including the
anypseudo-interface and raw sockets. - The background tcpdump process is lifecycle-managed by the sniffer, and the configured PCAP cleanup setting is honored.
- Application log rotation truncates reused files.
Security¶
- Log, NDJSON, and buffer file permissions no longer depend on the process umask, and the active configuration is readable only by the service account.
- Configured output paths no longer follow symbolic links.
- Offline PCAP input rejects special files and unrestricted input paths.
- Command injection via configuration file parameters is closed.
- The production binary carries the recommended exploit mitigations, is stripped, and no longer embeds stale RUNPATH entries or build-cache paths.
- systemd hardening directives are applied to the shipped unit.
- The bundled OpenSSL is upgraded to 3.5.9, clearing 13 unpatched CVEs including one High.
- The TLS verification bypass is removed from release builds.
Packaging and Documentation¶
- Third-party license notices ship with the package.
- The documentation is published with each build as a versioned zip named for that build, so the
pages you have match the package you installed. It opens from a local folder by double-clicking
index.htmland needs no network connection, fonts included.
Validation¶
- The full unit and integration suite, run on Rocky Linux 8.
- The RPM installed on a host and its file ownership and permissions checked against the package.
- Static security analysis across the source at its most sensitive reporting level.
- The documentation built strictly, with every internal link and navigation target resolved.
Known Notes¶
- Connected mode (PostgreSQL) is suppressed for this release.
- The emit timer that reports a still-running flow is fixed at 60 seconds and is not configurable.