Repository navigation
Releases: logiqum/luna
Release list
LUnA v2.0.0
Download: logrok.com/download — installers for every platform, checksums and install commands.
Upgrading to 2.0.0
2.0.0 is a major version because the service has a new name on Linux, macOS and FreeBSD (it is now
logrok-universal-agent everywhere, as it already was on Windows), and because the Apex modules that
1.x only warned about are now enforced. Every configuration that 1.x accepts is
accepted unchanged, with one exception: a misspelt option name on the filetail, linux_audit, etw or
windows_eventlog input, which 1.x ignored.
-
Unlicensed agents that use
etw,wmi,linux_audit,mqtt_in,redact,lookup,
adaptive_sampleor a destination other than syslog: 1.x warned that these Apex modules would be
disabled in the next major version. 2.0.0 disables them: without a covering license the agent removes
them at start and keeps running everything else, so events stop reaching such a destination. Before
upgrading, install a license or enroll with a logrok control plane (an enrolled agent receives its
entitlement from it), or move the pipeline to Core modules. The startup log names every module it removed. -
Before a remote upgrade: run
logrok-universal-agent -check-configwith the 1.x agent's configuration
and correct any option it names as unknown. The upgrade check 2.0.0 runs before it installs refuses such a
key, so the agent stays on its current version until the key is fixed. -
Installed folders and the service user now use the product name. The package upgrade moves them, with
the agent stopped, and leaves nothing of the old names behind: no folder, no link, no old user. The enrolled
identity and any undelivered events move with the state folder; nothing is copied or re-created, so the
agent does not enroll again.- Your local
agent.yamlis updated to match. Every path under an old folder becomes the same path under
the new one (for example a spool folder or a CA file); each changed line is shown in the install output.
The new agent must accept the changed file before the upgrade goes on. If it does not, the file is left
exactly as it was, the upgrade stops with the reason, and the agent is not started: correct the file and
finish the upgrade again. - Configurations delivered from a control plane are not changed on the host. Update any that name an
old path in the control plane before upgrading the package, and change scripts or other tools of yours that name
an old path. - A state folder that is a mount point of its own stops the upgrade before anything is changed, because
moving it would mean copying it. The message says how to mount the volume at the new path; do that, then
upgrade again. - Linux:
/etc/logrok-agent→/etc/logrok-universal-agent,/var/lib/logrok-agent→
/var/lib/logrok-universal-agent,/var/log/logrok-agent→/var/log/logrok-universal-agent(when you
created it forlog_file), and the userlogrok-agentis renamedlogrok-universal-agentwith
the same UID and GID. - macOS:
/usr/local/etc/logrok-agent→/usr/local/etc/logrok-universal-agent,
/usr/local/var/db/logrok-agent→/usr/local/var/db/logrok-universal-agent, and the log files are now
/usr/local/var/log/logrok-universal-agent.out.logand.err.log. - FreeBSD:
/usr/local/etc/logrok-agent→/usr/local/etc/logrok-universal-agent,/var/db/logrok-agent
→/var/db/logrok-universal-agent,/var/log/logrok-agent.log→/var/log/logrok-universal-agent.log,
moved on the first start of the new service, which also updates the configuration as above. A path you
set yourself in rc.conf stays where it is. If the move or the check cannot be done, the service does not
start and says why. - Windows: unchanged (
C:\ProgramData\logrok-universal-agent). - Containers: the image now reads
/etc/logrok-universal-agent/agent.yamland keeps its state in
/var/lib/logrok-universal-agent. If you run the image yourself, mount your config file and your existing
volume at these paths; the volume's contents carry over unchanged. With the Helm chart, the collector's
folder on each node is/var/lib/logrok-universal-agent.
- Your local
-
Linux (deb, rpm): nothing to do. Upgrading the package moves an enabled or running agent to
logrok-universal-agent.service, andlogrok-agentstays an alias, so existingsystemctlcommands and
scripts keep working. Anagent.yamlyou edited stays your configuration without a prompt, and the new
default is put beside it asagent.yaml.dpkg-dist(rpm:agent.yaml.rpmnew); one you never edited is
replaced by the new default. If the upgrade stopped on the configuration check, correctagent.yamland
finish it withdpkg --configure -a(rpm: reinstall the package). -
macOS (.pkg): nothing to do. The installer unloads and removes the old
com.logiqum.logrok-agent
LaunchDaemon and startscom.logiqum.logrok-universal-agent. Scripts that calllaunchctlwith the old
label need the new one. Anagent.yamlstill exactly as an earlier package installed it is replaced with
the new macOS default (the old file is kept asagent.yaml.pre-2.0); a file you edited is never changed.
From 2.0.0 on, anagent.yamlyou have not edited is updated with each package, as on Linux and Windows.
The folders move to their new names as described above. -
FreeBSD (rc.d): replace the rc script:
service logrok_agent stop, remove
/usr/local/etc/rc.d/logrok_agent, install the new script and startlogrok_universal_agent. Your
logrok_agent_*settings in rc.conf keep working while the new names are unset. The new service refuses to
start while the old script is installed, so two agents never run on one spool. Ifnewsyslog.confrotates
/var/log/logrok-agent.log, change it to the new file name. -
Windows: nothing changes; the service was already
logrok-universal-agent. -
Agents upgraded remotely from the control plane get the new binary and keep their current service name
until their package is upgraded. -
No 32-bit ARM rpm. The
armv7hlrpm packages are no longer published. On 32-bit ARM, use the armhf.debor theluna-linux-armv7binary; the binary is the same as before.
Added
- UDP syslog and GELF on several cores, and UDP loss you can see.
syslog_inandgelf_incan read one UDP port on several cores (udp_listeners, a number orauto, Linux and FreeBSD). Traffic from even one busy sender, such as a relay or a firewall, is spread over the listeners, with no extra privileges needed. Message order across listeners is not kept; the default of 1 keeps today's behaviour. Each UDP socket now asks for an 8 MiB receive buffer (udp_receive_buffer_bytes), GELF receives UDP faster, and on Linux the datagrams the operating system dropped because they were not read in time are counted inlogrok_agent_input_udp_kernel_drops_total. - Several batches on the way to Splunk at once (
max_in_flight). Thehecoutput can now keep up to 64 batches on the way at once instead of waiting for each answer before sending the next — for a distant or slow Splunk receiver, where the round trip, not the agent, limits throughput. In our test with a receiver on the same host, four batches in flight more than doubled the HEC throughput (about 280,000 to 610,000 events per second on 10 cores). Off by default (1, unchanged behaviour). Splunk may then receive batches out of order; inputs still advance strictly in read order, a failed batch is spooled before anything after it is acknowledged, and delivery stays at-least-once. Other outputs do not accept the key:-check-configrefuses it there. Older agents do not know it either. - Warning up front when read positions cannot be saved. If an input saves its read position by default and the folder it would use is not writable by the agent,
-check-configand the agent's startup now say so once, with what to change (management.state_path, theSTATE_DIRECTORYsetting, or the input's own position option) — instead of the problem showing only as warnings after the agent is running. The check creates nothing. On Windows it cannot tell, so it stays silent there. - Pipeline stage metrics. With
service.workersabove 1,/metricsshows how long each part of the pipeline was busy or waiting, plus how many workers run and how many processors they cover — so you can see whether more workers would help or whether sending is the limit. - Longer, configurable stop grace (
service.shutdown_grace). When the agent stops it now keeps delivering its last batch for up to 15 seconds (it used to be 2) before giving up; setshutdown_graceunderservice:(1 second to 10 minutes) to change it. A batch not delivered in time is read again after the restart by file, journal and event-log inputs; network inputs that cannot be replayed lose it. An agent of an earlier release does not know the key: it starts and keeps its shorter stop grace, and its-check-configreportsshutdown_graceas unknown. - Processors on several cores (
service.workers). Setworkersunderservice:to 2 or more and the agent runs its leading parallel-safe processors — the parsers,add_fields,filter,expr,redact,trim_fields,lookup,file_hash,noise_fingerprintand keyedsample— on that many workers, whilededup,throttle,quota, unkeyedsample,adaptive_sampleandaggregatekeep running in arrival order. Events reach each destination in the same order and batches as before, and inputs still save their position only after their events are delivered or durably spooled. List the parallel-safe processors first; the agent logs which processors run in parallel and warns when none can. The default stays1, the pipeline of earlier releases unchanged. An agent of an earlier release does not know the key:...
LUnA v1.6.0
Added
- Four propagation gaps between agent and control plane closed. (1) An agent that was deleted on the
control plane, or whose key a reinstall replaced, now re-enrolls by itself once it has an enrollment token
(at most once per 10 minutes); a revoked agent stops its management calls and says so — in its log and as
logrok_agent_management_revokedon/metrics— while log collection continues, instead of retrying
forever. (2) In enrolled mTLS mode the agent now trusts every CA root the control plane delivers with its
certificate and reloads that trust when a renewal changes it, so a control-plane CA rotation needs no
restart and no edit ofca_file; each heartbeat reports the roots it trusts. (3) Each heartbeat reports
the fingerprint of the license entitlement actually applied, so a lost reply can no longer leave an agent
on a stale entitlement. (4) Enrollment sends a hashed stable machine identity (host_id) so the control
plane can tell a reinstall from a different host with the same name; the raw machine id never leaves the
host. - Group moves reach a running agent. Moving a host into or out of a group in logrok now takes effect
on the agent's very next heartbeat — no restart, and no waiting for the agent to re-enroll. Earlier, an
agent only learned its group at enrollment (or from an offline enrollment bundle), so a group assigned or
changed afterward never reached the running process, and group-scoped searches and detections in logrok
missed its events until the agent was restarted. Requires a control plane that reports the current group
on heartbeat.
Fixed
- Remote upgrade no longer leaves older staged binaries behind until the next cold start: the previous
staged binary is removed as soon as the new one is verified and in place.
Security
- Licences, control-plane entitlements, enrollment bundles and upgrade offers are accepted only from Logiqum's production signing key — directly, or through a per-installation signing key that Logiqum has certified for your licence. A certified key is bounded by its certificate: the agent never grants a higher tier or a later end date than the certificate allows (the host count is enforced by the control plane). Licence files must be signed by Logiqum directly. Licences issued before this release with the earlier signing key are no longer accepted: contact support for a replacement before upgrading. A control plane without a certified key cannot grant Apex features or offer upgrades to agents on this release; they run on Core and keep forwarding.
About these downloads. LUnA ships as signed binaries — the luna-* assets above are the release.
Verify them with SHA256SUMS and cosign (public key: cosign.pub in this repository).
The "Source code (zip)" / "Source code (tar.gz)" links below are added automatically by GitHub to every
release and cannot be removed. They are not the agent's source, and they are empty: this repository
publishes signed binaries and documentation only. LUnA's source is not publicly distributed.
LUnA v1.5.0
Added
-
Upgrade agents from the control plane. With central management, the fleet page can offer agents a
new version and they upgrade themselves — no session on the host. Before anything is installed the agent
checks that the offer is signed by its control plane and meant for this host, that the downloaded
binary's checksum is in a manifest signed with the logrok release key (verified with the key built into
the agent, so a control plane cannot substitute a binary), and that the new binary runs and accepts this
host's configuration. It then swaps, restarts, and reports each stage back; a failure anywhere leaves the
running binary untouched and shows its reason in the fleet view. On Linux, macOS and the BSDs the file
your package manager installed is never overwritten — the verified binary is staged beside the agent's
state and run from there; on Windows the previous executable is kept as.prev.exe. Off switch:
management.remote_upgrade: false. Requires agent 1.5.0 or later on the host and the release pack
uploaded to the control plane's catalog. See "Upgrading agents from the control plane" in the user guide. -
A log file, and a trace of every crash.
service.log_fileappends the structured log to a file
(rotated once at 50 MiB) and routes crash reports there. The Windows MSI's default configuration sets it,
because a Windows service has no console: until now a crashed service left only the service manager's
"terminated unexpectedly" event. The service now also writes a panic (with its stack) or a fatal exit to
the Windows Application event log under the sourcelogrok-universal-agent(events 1 and 2), and
configures its own restart-on-failure recovery at every start. -
A configuration-compatibility guarantee, enforced. A new agent version accepts every configuration
the previous minor version accepted (a major version, every configuration of the previous major) —
keys are deprecated with a warning for at least one minor version before they can go, and never
silently ignored by a check. Every release is tested against the configurations the previous releases
shipped before it can be published, and a release is only offered to agents inside that window. New
flag:logrok-universal-agent -check-config -config <file>validates a configuration against the binary
you run exactly as it would at start — every key, module type and module option, including the checks a
module makes on its own values — without opening a socket or a file, and names what it refuses. The same
check runs on the host before an upgrade is installed. See the support policy. -
Every platform and architecture upgrades itself. The Linux deb/rpm services, the FreeBSD rc service
and the container image now keep the enrollment state and a delivered upgrade under the service's own
state directory (they used to default to the config directory, which the hardened services cannot
write), and the Linux packages let the agent write a configuration pulled from the control plane beside
the operator's file. The release pack ships with every release asluna-<version>-release.tar, plus a
stable-nameluna-release.tarfor the latest.
Changed
- Every heartbeat now carries the CPU architecture (
arch) beside the platform. - The enrollment state file defaults to the service manager's state directory when it names one
(systemdStateDirectory=, the FreeBSD rc script, the container image) instead of the config
directory. Existing installs that setmanagement.state_pathare unaffected; a packaged Linux install
that never managed to enroll (its config directory was read-only to the service) enrolls on the next
start. - On Windows, an agent that exits because of an error reports a failure to the Service Control Manager
(so the recovery action restarts it) instead of a clean stop.
About these downloads. LUnA ships as signed binaries — the luna-* assets above are the release.
Verify them with SHA256SUMS and cosign (public key: cosign.pub in this repository).
The "Source code (zip)" / "Source code (tar.gz)" links below are added automatically by GitHub to every
release and cannot be removed. They are not the agent's source, and they are empty: this repository
publishes signed binaries and documentation only. LUnA's source is not publicly distributed.
LUnA v1.4.0
Added
- Noise decided centrally, removed at the source (Apex). A new
noise_fingerprintprocessor enforces the
platform's noise decisions on the host: it computes the same template fingerprint the platform computes
at ingest and drops or marks every event whose fingerprint is in its set — one hash lookup per event,
so thousands of templates cost the same as one. A managed configuration can carry the set today; the
control plane filling it in automatically follows on its side. By default events of severity err and
worse always pass. - The control plane can see — and adopt — the configuration an agent is running. Each heartbeat now
tells the control plane which configuration the agent runs, so the fleet view can show it and adopt it
as the managed configuration without anyone copying files off the host. Secrets never leave the host:
every token, key, password, passphrase and authorization header is replaced by a keep marker before the
text is sent, and a configuration pulled back with that marker keeps the agent's own local value. A
pulled configuration the agent has to refuse is now reported on the heartbeat as a failed apply for that
version, instead of a log line only on the host. Off switch:management.report_config: false. - Primary and secondary collectors for the syslog output. Give
failover_endpointsan ordered list and
the agent moves to the next collector inside the same delivery attempt when the active one refuses or
drops a connection, then probes the primary everyfailback_everyand returns to it. The spool now takes
over only when every endpoint is down. New per-destination metrics report the active endpoint and each
switch. Syslog and Snare, TCP/TLS. In our end-to-end test the switch took under a second. - Your heartbeat and
/metricsnow tell you how stale delivered data is, and how much each processor removed.
output_event_delay_secondsis the age of the newest event a destination just accepted (source timestamp
to acceptance — includes upstream lag and spool wait);pipeline_latency_secondsis how long the agent
itself held it (independent of source clocks). Both have per-destination variants.
processor_<name>_dropped_totalfor every processor andprocessor_reduction_ratio(share of received
events removed by processors, 0–1) make the edge-reduction funnel a number rather than a claim. The FIPS
posture (fips140_enabled,fips140_ems_relaxed) now rides every heartbeat too. Every metric carries a
plain-language description; the Configuration Reference explains each one and/metricscarries the same
explanation in its HELP text.
Fixed
buffer.flush_everynow takes effect. The setting was accepted and validated but never read: the
spool drain loop ran at a fixed 2 seconds whatever you configured, and the configuration reference marked
it "partial". It now paces how often each destination retries its backlog once the output is reachable
again (live events still ship immediately). If your configuration carries a value other than2s, drain
cadence changes to what you asked for on upgrade.
About these downloads. LUnA ships as signed binaries — the luna-* assets above are the release.
Verify them with SHA256SUMS and cosign (public key: cosign.pub in this repository).
The "Source code (zip)" / "Source code (tar.gz)" links below are added automatically by GitHub to every
release and cannot be removed. They are not the agent's source, and they are empty: this repository
publishes signed binaries and documentation only. LUnA's source is not publicly distributed.
LUnA v1.3.0
Turn FIPS off for a receiver that cannot do it
FIPS 140-3 is on by default. Almost every receiver works with it — syslog-ng (including mTLS), Kafka,
Loki, S3, MQTT, the ack'd relay and the control plane are all verified each release.
Splunk HEC is the exception. FIPS allows TLS 1.2 only with Extended Master Secret, and Splunk 9.4
offers neither that nor TLS 1.3 — so no handshake can succeed and delivery never starts. You would see a
healthy agent, a growing spool, and nothing arriving; events are buffered, not lost.
The best fix is enabling TLS 1.3 on the receiver, which needs no EMS. If you cannot:
service:
fips: off # on | off — unset runs the binary as built (the shipped build is FIPS)The agent applies this at startup by restarting itself once, keeping the same process ID — your
service manager sees one continuous process. It takes effect at startup, so changing it needs a restart.
On Windows, set GODEBUG=fips140=off in the service environment instead.
If you would rather keep FIPS on everywhere and only relax the one requirement, set
GODEBUG=fips140ems=0 in the service environment. Those connections are then not FIPS-approved, and
the agent says so plainly — in -version and on /metrics — rather than continuing to
report unqualified FIPS.
Run the agent on pfSense, OPNsense and FreeBSD
Firewall and VPN logs are among the highest-value security telemetry on a network, and until now you could
download a FreeBSD binary but had no supported way to run it on an appliance — no supervised start, no
boot persistence, no documented home for config and state.
The documentation bundle now includes an rc.d service:
install -m 0555 deploy/freebsd/logrok-universal-agent.rc /usr/local/etc/rc.d/logrok_agent
sysrc logrok_agent_enable=YES
service logrok_agent startIt supervises and restarts the agent, runs it as an unprivileged user, and keeps state in a private
directory you can relocate with logrok_agent_statedir — appliance root filesystems are often small or
read-mostly. Verified on real FreeBSD: start, status, stop, and restart-after-crash.
Worth planning for: FreeBSD counts as an extended platform, and both that and the disk spool are paid
capabilities. Running unlicensed on an appliance still forwards, but the spool becomes drain-only — it
delivers what it already holds and buffers nothing new. On a site behind an intermittent link that is
usually the whole reason for deploying, so size the entitlement in advance.
Proxmox VE and VyOS are Debian-based, so the existing .deb installs and runs unchanged.
FIPS 140-3 is now standard on every build
Every binary in this release runs in FIPS 140-3 mode, on every platform, at no extra cost and with no
licence tier attached. If you need validated-module cryptography, it is already in the download you just
took. If you don't, nothing about the agent changes for you — it costs 36 KB of binary, no measurable
throughput, and about 2 ms of startup.
New: you can now require FIPS on a host, and a FIPS build tells you when its own cipher-suite
restrictions are what broke a connection.
service:
fips_mode: required # auto (default) | required | disabledrequired refuses to start unless the agent is running in FIPS mode; disabled refuses if it is. This is
a check, not a switch: it asserts the posture the running agent actually has — FIPS by default, or off
where service.fips: off was set for a receiver that cannot do FIPS (see above). A FIPS agent and one
that was switched off look identical from the outside, so without this check a regulated deployment could
only discover a host running the wrong posture during an audit. disabled matters for the opposite
reason: an agent in FIPS mode refuses older cipher suites, so an estate that must reach a legacy receiver
wants to know at startup rather than at the first delivery.
And if an agent in FIPS mode cannot complete a TLS handshake because the receiver offers only ChaCha20-Poly1305 or
a CBC-SHA suite — common on older aggregators — the agent now says so. TLS on its own reports only
remote error: tls: handshake failure, which never mentions FIPS and usually appears on the first run
against the very system you are migrating away from.
There is no separate FIPS artifact to request: the validated module is in the standard download, the
same single static binary for every platform. Verify the binary you actually hold:
$ logrok-universal-agent -version
1.3.0
fips140: enabled (Go Cryptographic Module v1.0.0, CMVP certificate #5247)
That line is read from the module at runtime rather than printed from a build note, and it is absent when
FIPS has been turned off. For fleets, /metrics exports logrok_agent_fips140_enabled as 0 or 1 always —
never omitted when off, because an absent metric and a failed scrape look the same to a monitoring system,
so "alert if any agent is not in FIPS mode" would be silent exactly when it mattered.
What this means, stated plainly. The binary is built against the Go Cryptographic Module v1.0.0, which
holds CMVP certificate #5247, and that module is operating in FIPS 140-3 mode. It does not mean the
agent is itself FIPS-certified, or that deploying it makes your system compliant — the validated component
is the module, and whether that satisfies your obligations is your assessor's decision.
One limitation, disclosed rather than discovered later: SNMPv3 privacy uses CFB mode as its
specification requires, which is not FIPS-approved. It keeps working in FIPS mode, but if your
obligation is that only approved algorithms are used anywhere in the process, do not enable SNMPv3 privacy
there. Everything else is unaffected.
Licensing — four Apex modules are now actually withdrawn when unlicensed
snmptrap_in, modbus_in, bsm_audit and file_hash are Apex capabilities that were meant to be enforced
immediately (they never shipped free, so they have no notice window). They were detected and reported — an
unlicensed agent using them logged the licensing warning and read posture degraded — but they were never
removed from the pipeline, so they kept running. The same defect quota had until 1.2.0. From this release an
unlicensed agent withdraws them at startup, exactly as the licensing documentation has said all along.
Licensed and logrok-managed deployments see no change.
Solaris audit trail (bsm_audit)
Solaris deployments can now collect the BSM audit trail — logins, privilege use, process execution and,
with the right audit flags, file changes. Every record arrives with the acting user, process and session, the
same evidence linux_audit provides on Linux.
bsm_audit is an Apex capability, enforced immediately: an unlicensed agent withdraws it at startup, with a warning naming it, rather than running it through a notice period.
inputs:
- type: bsm_audit
# dir: /var/audit
# read_from: endIt decodes the trail using the operating system's own praudit. The trail is a binary format, and a
hand-written decoder that misread one token layout would produce plausible but wrong values rather than
failing — not a trade worth making for audit evidence.
Two things to set up, and the second is easy to miss: the agent needs read access to /var/audit (it is
root-owned), and the audit flags decide what is in the trail — file-change records require the file
classes to be enabled. With no relevant flags there is no traffic at all, which looks exactly like a broken
input.
On restart it resumes from the end of the trail by default and keeps no byte offset, because the format can
only be re-entered at a record boundary. Anything missed remains in the trail file and can be replayed from
the beginning.
file_hash — the content half of file-integrity evidence
Your file-change events already tell you who. This adds what the file now is.
file_hash is an Apex capability, enforced immediately: an unlicensed agent withdraws it at startup, with a warning naming it, rather than running it through a notice period.
The new file_hash processor reads the path out of a change event, hashes that file, and attaches the digest.
Point it at the fields your sources use and it serves all of them at once:
- type: file_hash
path_fields: [path, TargetFilename, ObjectName]
roots: [/etc, /usr/bin]
algorithm: sha256roots is required, and it is a security control rather than a setting. The path arrives inside an event,
and on a pipeline that receives events over the network an event can be influenced by whoever sends it. Without
a bound, "hash the path in this field" would let a crafted event ask the agent to read any file its user can
open and publish a digest of it. Symlinks are resolved before the check, so a link inside an allowed directory
cannot reach outside it. There is deliberately no permissive default.
Two things stated plainly because they affect how you read the output. The digest describes the file when it
was hashed, not when it changed — the event arrives after the write, so the file may have changed again or
gone. And every event gets a file_hash_status (ok, no_path, not_found, denied, too_large, not_regular,
unreadable), so a missing digest is always a recorded outcome, never a silently absent field.
sha1 is available alongside sha256 and sha512 so you can compare against an existing file-integrity
baseline without rehashing an estate. It is not the default.
This is still collection, not detection: the agent keeps no baseline and decides nothing about whether a
change was authorised.
File-integrity events — and a straight answer about FIM
If you have been asking whether the agent does File Integrity Monitoring, the answer is half of it,
deliberately — and that half works today with no new module.
The agent forwards file-chan...
LUnA v1.2.1
A documentation and verification-status release. No agent code changed — the binaries in this
release behave identically to 1.2.0.
FreeBSD on arm64 is now runtime-verified
The freebsd/arm64 build was previously published as cross-compiled: it built and linked, but had
never been executed on that platform. It now runs the full pipeline — file tail → disk spool →
RFC 5424 syslog over TCP → a real receiver — inside an emulated machine booting an official
FreeBSD 14.3-RELEASE arm64 image, with an exact delivered-event assertion. The check runs nightly, so
the result cannot quietly go stale.
The platform table in the User Guide is updated accordingly. To be precise about what this does and
does not prove: the operating system executing the binary is genuinely FreeBSD, which is a stronger
claim than our emulated Linux rows, where the host kernel serves the syscalls. The hardware is
still emulated, so this is "verified under emulation", not "verified on arm64 hardware". Its amd64
counterpart remains verified on the real operating system.
aix/ppc64 is now the only published target that has never been executed.
macOS installers — carried forward from 1.2.0 (updated 2026-08-28)
This section has been corrected, and the release assets changed after publication. What follows is
what happened, so nothing here is a silent swap.
luna-darwin-amd64.pkg and luna-darwin-arm64.pkg were originally absent from 1.2.1: they were
not rebuilt for this release. That left the macOS download links on our download page returning 404,
which we did not intend and which no release note excuses.
They are now attached. They are the 1.2.0 installers, carried forward unchanged — byte-identical
to the files published on the 1.2.0 release, verified against that release's published SHA-256 sums
before upload. They are not rebuilt from the 1.2.1 tree.
That carry-forward is safe here for one specific reason: no agent code changed between 1.2.0 and
1.2.1. This release altered documentation and platform-verification status only, so the 1.2.0
installer contains the same agent you would get from a 1.2.1 build. If that had not been true, the
right fix would have been a rebuild, not a copy.
SHA256SUMS has been regenerated to cover them, so every asset on this release is checksummed.
Installers will return in the next release.
About these downloads. LUnA ships as signed binaries — the luna-* assets above are the release.
Verify them with SHA256SUMS and cosign (public key: cosign.pub in this repository).
The "Source code (zip)" / "Source code (tar.gz)" links below are added automatically by GitHub to every
release and cannot be removed. They are not the agent's source, and they are empty: this repository
publishes signed binaries and documentation only. LUnA's source is not publicly distributed.
LUnA v1.2.0
Licensing — fifteen modules are now marked Apex (advance notice; nothing is disabled)
Fifteen modules belong to the paid Apex tier but were not marked as Apex in the
documentation and were not checked at startup. They are now marked and checked. This release
disables none of them.
| Modules | |
|---|---|
| Inputs | etw · wmi · linux_audit · mqtt_in |
| Processors | redact · lookup · adaptive_sample |
| Outputs | snare · hec · sentinel · xsiam · kafka · s3 · loki · otlp |
What you will see. If your entitlement does not cover these and your configuration uses
them, the agent logs one warning at startup naming exactly which modules are affected, and
reports its licence posture as degraded on /metrics and on every heartbeat. Every module
keeps running and no events are lost. Managed fleets will see affected agents marked
degraded in the fleet view — that is the notice reaching you, not a fault.
What changes later. These modules are disabled at the next major version, in line with
the published deprecation policy — one full release line of notice. Before upgrading to that
version, either install a licence (licensing.license_file), enroll the agent with a licensed
logrok deployment (Apex is included at no charge), or move the pipeline onto Core modules.
The free Core tier is unchanged and nothing was taken out of it: file tail, syslog-in,
journald, HTTP-in, the parsers (parse_json, parse_csv, parse_kv, parse_xml, expr,
add_fields, filter), RFC 5424 syslog output over TCP/TLS, and /metrics — free, at any
scale, with no licence. Core forwarding is never blocked in any licence posture, and TLS is
never gated. The dividing line is now stated plainly in the operator documentation: Core
collects from the host and forwards one open standard to one destination; anything that reads a
privileged or proprietary operating-system subsystem, or speaks a named vendor or platform API,
is Apex.
Existing licensed and logrok-managed deployments are unaffected — an Apex entitlement already
covers all fifteen.
Fixed
- The
quotaprocessor is now actually withdrawn when unlicensed.quotais an Apex
capability and was correctly detected and reported as one, but the degrade path never removed
it — so an agent that had degraded to Core carried on enforcing its daily volume cap. If you
are runningquotawithout an entitlement, that cap now stops being applied when the agent
degrades. Licensed deployments are unaffected.
About these downloads. LUnA ships as signed binaries — the luna-* assets above are the release.
Verify them with SHA256SUMS and cosign (public key: cosign.pub in this repository).
The "Source code (zip)" / "Source code (tar.gz)" links below are added automatically by GitHub to every
release and cannot be removed. They are not the agent's source, and they are empty: this repository
publishes signed binaries and documentation only. LUnA's source is not publicly distributed.
LUnA v1.1.0
Documentation bundle re-issued 2026-08-24. The
luna-docs.tar.gzasset on
this release was replaced to remove an internal engineering document that was
included in error. No customer-facing documentation changed — every other file
in the bundle is unchanged — and the agent binaries, their checksums and
SHA256SUMSare untouched. The bundle'sluna-docs.tar.gz.sha256sidecar was
updated to match the replacement;SHA256SUMSnever covered this asset, so it
did not need to change.
The OT and edge release. The agent gains native collection from industrial and network
equipment — Modbus over both TCP and RS-485/RS-232 serial, and SNMP traps — designed to
forward events rather than raw telemetry, so a quiet plant stays quiet. Around it: enrolment for sites with no path to a
control plane, builds for the architectures industrial gateways actually use, a much wider
set of destinations (Kafka, S3, Microsoft Sentinel, Cortex XSIAM, Grafana Loki, AWS
Security Lake format), multi-destination fan-out with per-destination routing, and
verifiable evidence — signed export manifests, rollback detection in the tamper-evident
buffer, a per-release SBOM, and complete third-party attribution with source.
No breaking changes: upgrades from 1.0.x are drop-in.
Changed
- Dead-letter quarantine handles rejection storms gracefully. The per-rejection size check of
the quarantine directory no longer rescans the whole directory every time (measured ~160× faster
once thousands of quarantined files have accumulated), and files an operator deletes from the
quarantine directory now free capacity immediately — no restart needed.
Added
- Complete third-party attribution, and source for the components that require it. Every
release now shipsTHIRD-PARTY-NOTICES.md: every open-source component distributed with the
agent — each library compiled into the binaries, the Go standard library, and the packages
present in the container image — with the full text of each licence. It is generated from what
is actually built and shipped rather than maintained by hand, so it cannot drift from the
product. The agent binary itself contains no copyleft-licensed code; the container image is
built on a minimal Debian base that includes a few GPL-licensed packages, and the complete
corresponding source for those is now published as athird-party-sourcearchive attached to
the same release as the binaries. If your organisation reviews open-source obligations before
deployment, this is the page and the archive to hand them. - Collect OT events from Modbus TCP devices: the
modbus_ininput. The agent can now poll
PLCs, RTUs, drives and meters directly — and it forwards events, not register readings. You
name the registers that matter and set what makes them interesting; the agent emits only a value
that changed, a value that crossed a bound you set (and again when it returns inside), a device
that stopped answering, and — optionally — a slow-cadence snapshot for audit. A plant running
normally produces almost no events, which is the intent: raw register telemetry belongs in a
time-series database, not in a log platform. Analog noise is handled by a per-watchdeadband
that suppresses jitter without creating a blind spot, so a slow drift is still reported once it
accumulates. Restarting the agent is quiet — the first poll of a device records its state and
reports nothing, so a restart never looks like every register in the plant changing at once.
Both transports are supported: Modbus TCP to a device or gateway, and Modbus RTU directly over
an RS-485/RS-232 serial port (transport: rtu), so equipment with no Ethernet at all can be
collected without a gateway in front of it. Everything above the wire is identical — same watches,
same events, same read-only guarantee.
The agent cannot write to your controllers: only the Modbus read function codes exist in the
binary, so there is no setting, bug or crafted input through which it could command a device.
Devices are polled politely — one connection and one request in flight each, adjacent registers
combined into single reads, and a floor under the poll interval. Both register-numbering
conventions are supported (address_base: protocolordata_model), and a number that looks
pasted from a vendor table is called out at startup. Verified end to end against a Modbus TCP
simulator, and over a virtual serial pair for RTU; a run against live industrial hardware is
still outstanding. - Watch live events without restarting: the
/tapendpoint. When the metrics listener is
enabled,curl 'http://127.0.0.1:9090/tap?stage=processed&n=20'streams a bounded live sample of
the events passing a pipeline stage — inputs (in), post-processing (processed), or what one
destination is being offered (output:<name>), with an optionalmatchsubstring filter. The
answer to "why is nothing arriving?" without raising the log level or restarting the agent. A tap
never slows the pipeline (a sample that outruns your reader drops the excess, and the stream says
how many), costs nothing when unused, and — because it shows event content — is refused unless
the metrics listener is bound to loopback. - Daily volume budget: the
quotaprocessor. A hard per-day cap on what a pipeline may emit —
setmax_eventsand/ormax_bytes(approximate, pre-encoding) and events over budget are
dropped and counted until the UTC day rolls over. Severity exemptions (keep_min_severity,
keep_if) guarantee page-worthy events always pass. The budget is held in memory, so an agent
restart refills it — treat it as an operating dial, not a billing guarantee. - Find the control plane automatically on a LAN (
endpoint: auto). Instead of hard-coding the
same URL into every config on a flat or OT segment, the agent can browse for a control plane
advertising itself over mDNS. It is opt-in (an agent with an endpoint configured is never
re-pointed by the network), it is re-resolved each run rather than remembered, and — the part that
matters — discovery only locates; it never authenticates: the enrolment token and TLS still
prove the control plane, so a rogue advertiser achieves nothing but being ignored. If nothing is
advertising, the agent says so and runs unmanaged for that run. - Enrol agents that have no path to a control plane: enrolment bundles. Point
management.enrollment_bundleat a signed file and the agent adopts its identity, entitlement and
(optionally) its starting configuration entirely offline — for air-gapped sites, diode-fed OT
zones, and depot pre-staging, where the usual first-start HTTP exchange is impossible. The bundle
is verified against the same signing key as licence files, adopted once (so leaving the media
mounted never clobbers later edits or rotated credentials), and refused with a reason if it is
altered, expired, or signed by the wrong key. Note the honest limits: there is no revocation
offline, expiry is judged by the local clock, and a bundle is a bearer credential — treat it like
a key. - New platforms: RISC-V and MIPS builds. Releases now include
linux-riscv64(RISC-V
single-board computers and edge boxes) andlinux-mipsle(MIPS little-endian router/gateway
hardware; built soft-float so chips without an FPU run it) — 15 platform binaries per release.
Both are cross-compiled and vetted but not yet runtime-verified on real hardware; treat
accordingly (the same maturity labeling as the AIX build). - SNMP trap receiver: collect from network and OT devices natively. The new
snmptrap_in
input listens for SNMP traps and informs (v1, v2c, and v3 with per-user authentication and
encryption) and turns each notification into a forwarded event — nosnmptrapdside-daemon,
no second configuration. Informs are acknowledged on receipt, so devices using acknowledged
notifications stop retrying, and every accepted event gets the agent's usual on-disk
durability. Label your important OIDs with theoid_namesmap — no MIB compiler required.
Verified against the net-snmp reference tools across the v3 authentication/privacy matrix. - Support, versioning & deprecation policy published. docs/SUPPORT-POLICY.md
states which releases receive fixes (the latest release line), how versions are numbered
(Semantic Versioning), and the deprecation commitment: operator-facing surfaces are deprecated
in release notes at least one minor version before behavior changes, and removed only at a
major version. - Per-release software bill of materials. Every release now ships a
CycloneDX SBOM (luna-sbom.cdx.jsonamong the release assets)
listing the release's third-party components and their licenses, alongside the existing
NOTICEattribution file. - Cortex XSIAM output: native delivery to Palo Alto Cortex XSIAM. Events post to your
tenant's HTTP log collector as gzip-compressed, newline-delimited JSON, split automatically under
the vendor-recommended request size and authenticated with the collector's API key (standard
XSIAM_API_KEYenvironment variable supported). Outages, throttling, and authentication failures
keep events in the disk spool — a rotated key delivers the backlog. This completes the agent's
broad destination set: syslog, Snare, OTLP, Splunk HEC, Grafana Loki, Kafka, S3, Microsoft
Sentinel, and Cortex XSIAM, all with the same store-and-forward delivery guarantees. - AWS Security Lake feed: the S3 output gains an OCSF/Parquet mode. With
format: parquet-ocsf, events are written as OCSF-formatted, zstd-compressed Parquet objects in
the exact partition layout AWS Security Lake requires of custom sources, accumulated locally and
delivered on Security Lake's five-minute cadence. Accumulated events are stored dura...
LUnA v1.0.0
First major release. Two changes need action before you upgrade a fleet, both described in full below:
- The structured-data enterprise number changed. If anything downstream extracts those fields, it must be
updated in the same maintenance window — otherwise the fields stop being extracted, with no error. - License enforcement is now on by default. A configuration using paid-tier capabilities without a
covering license has them withdrawn at load instead of running with a warning. Core-only deployments are
unaffected.
Everything else in this release is additive or a fix.
Changed
- MQTT QoS-1 messages are now acknowledged only once the event is durable. Previously the agent sent the
PUBACKas soon as the message was accepted for processing; if the agent then crashed before the event
reached the disk spool, the broker had already been told the message was taken and would not redeliver it.
The acknowledgement is now deferred until the event is actually spooled, delivered, or deliberately dropped,
so nothing is acknowledged that could still be lost. Acknowledgements are sent in the order the messages
arrived, so a slow event briefly holds back the ones behind it — expect marginally later acknowledgement
under load, in exchange for no silent loss at a crash boundary. ⚠️ Structured-data enterprise number changed to the registered IANA PEN66371. Structured fields
are emitted under[logrok@66371 …](and[seq@66371 …]whensequenceis on) instead of the previous
@99999. IANA assigned Private Enterprise Number 66371 to Logiqum Kft., and structured data now carries
that registered identifier. This is a wire-format change
and receivers key on the literal SD-ID. If your collector extracts these fields — including a logrok
deployment, whose extraction matches the ID exactly — it must be updated to the new enterprise number in
the same maintenance window, or those fields will stop being parsed. Events themselves continue to be
delivered and parsed as ordinary RFC 5424 either way; it is only the structured-field extraction that
keys on this number. Nothing else about the message format changes.- License enforcement is now on by default (degrade-to-Core). A configuration that uses Apex-tier
capabilities without a covering license now has those capabilities withdrawn at load, instead of running
with a warning. Everything in the free Core tier keeps running — the agent never exits and never blocks
Core forwarding over licensing — and an expired license passes through a grace window (default 30 days,
with escalating warnings and a live countdown) before anything is withdrawn. Installing a valid license
restores the capabilities on the next restart or config reload. Core-only deployments are entirely
unaffected, andLICENSE_ENFORCE=0remains available as a per-run escape hatch. See the new
Licensing guide for the license states, and the User Guide's Licensing and
Troubleshooting sections for the operator playbook. - Withdrawing store-and-forward never strands events already buffered. When the disk spool is the
capability being withdrawn, it is set to drain-only rather than switched off: everything already
written to it is still delivered, and only new events are refused. Ordinary forwarding is unaffected while
that backlog drains, and any event lost because no buffering is available is counted in
logrok_agent_events_dropped_totaland logged rather than lost silently. The spool directory and its
contents are never deleted. (Operators who previously opted in withLICENSE_ENFORCE=1saw the spool
simply disabled, which meant it was never re-opened and therefore never drained — events the agent had
already accepted stayed on disk, undeliverable and unreported. That is fixed.) - Licenses now refresh automatically. A managed (enrolled) agent picks up license changes on its next
heartbeat — no re-enrollment or restart. If an agent was enrolled before its license was issued, or its
entitlement changes (renewal, tier change, grace extension), the new terms apply on the next beat via a brief
automatic reload. Unchanged licenses cause no reload.
Added
- Redact sensitive values before they leave the host. A new
redactprocessor removes PII and secrets on
the endpoint that produced the event, so a value you must not retain never crosses the wire — masking at the
collector still means it travelled and was written down upstream. Built-in patterns for email addresses,
IPv4 addresses and payment card numbers, plus your own regular expressions for anything site-specific. The
built-ins are deliberately cautious, because an over-eager pattern destroys data nobody downstream can
recover: card numbers are checksum-validated rather than "any 16 digits", and address patterns reject
near-misses like version strings. Three modes — mask, remove, or a salted hash that keeps values
correlatable without retaining them, so you can still count distinct users or join events. Redaction can
be scoped to named fields, and aredactstep configured to match nothing is refused at startup rather than
silently passing data through. See the Configuration Reference and the User Guide. - Licensing guide. The licensing model is now documented in the shipped docs set: tiers and what's in
them, the license-file format and offline (no phone-home) verification, where the license lives, and the
license states including grace and degrade-to-Core. - Reconnect drain pacing for plain syslog (opt-in). For a high-volume plain-syslog feed (
syslog/snare
over TCP or UDP) into a receiver with a bounded queue, you can now cap how fast the disk spool drains after
an outage. Without it, the agent re-sends its whole backlog at full speed on reconnect — and because plain
syslog has no delivery acknowledgment, a receiver that sheds the overflow does so invisibly, so the agent
can silently lose its own backlog and knock the receiver back over. Enable it with adrain_pacingblock on
the output (rate_epscap, plus a slow-start ramp that eases a recovered receiver back in and optional
fleet jitter). Off by default — existing setups are unchanged. The acknowledged transports (relay,
otlp, HEC indexer-ack) are already paced by the receiver's acknowledgment and don't need it.
Fixed
- A small log file that is rewritten in place is now always re-read, whatever the timing. Files smaller
thanfingerprint_sizehave no stable identity, so the agent detects a rewrite by comparing the head bytes
it has already read. The check and the read of the new lines were two separate operations, and a rewrite
landing between them could not be seen: the agent carried on from its old position, so the rewritten
content was never sent — or, when the new content was longer, only the tail of it was sent as a mangled
line. Small files are now read in one operation and the comparison is made against that same read, so
detection no longer depends on how quickly the file is rewritten or how loaded the host is. Affects small,
in-place-rewritten files such as status or state logs; ordinary appended logs and files at or above
fingerprint_sizewere never affected. Small files also cost one less file operation per poll now. - Managed agents are protected from a license-change reload storm. A centrally managed agent reloads to
apply a new license delivered on its heartbeat. If a control plane re-issued an equivalent license on every
beat, an agent could reload continuously. Agents now apply at most one license-triggered reload per 10 minutes
(a genuine change still applies on the next beat; only rapid repeats are throttled), and the throttle survives
the reload itself. No effect in normal operation. - Over-large UDP syslog messages that get truncated are now visible. When a message sent over plain UDP
syslog is bigger thanmax_datagram_size, the agent trims it to fit (an oversized UDP packet can't be sent
otherwise). It used to do this silently — so if your limit was set too low, downstream received cut messages
with no hint why. The agent now counts audp_truncated_totalmetric and logs a one-time warning per output,
so you can spot it and raise the limit. Messages are trimmed, never dropped. - A mistyped config option is no longer silently ignored. If you misspelled a module option key (say
dead_letter_dir), the agent used to quietly drop it and fall back to the default — so a setting you thought
was in effect wasn't, with no warning. The agent now logs a warning at startup naming the module and the
unrecognized key, so a typo is caught immediately. The config still loads (an unknown key isn't fatal), so a
leftover key after an upgrade won't stop the agent — but you'll see it flagged. - A failing spool disk no longer silently drops events. If the disk store-and-forward buffer hit a genuine
write or fsync error, the agent could count those events as delivered and advance its read position past them —
a small window where a crash at the wrong moment lost data, and a delivered/dropped counter mismatch. The agent
now tells a real disk fault apart from an intentional capacity drop: on a disk error it retries the batch and
never drops or "forgets" it, so a transient blip self-heals and a persistent fault slows the inputs down (visible
backpressure) instead of losing data — even when the buffer is configured to drop on overflow, since that setting
is about capacity, not hardware failure. A newspool_write_errors_totalmetric surfaces a failing spool disk. - The disk buffer now honors a size cap smaller than 8 MiB. With
buffer.max_bytesset below the internal
8 MiB segment size andwhen_full: drop_oldest, a burst could grow the buffer past the cap before it was
trimmed back — over-retention (never data l...
LUnA v0.17.0
Automated mirror of v0.17.0. Verify with SHA256SUMS and cosign — see logrok.com/download.
About these downloads. LUnA ships as signed binaries — the luna-* assets above are the release.
Verify them with SHA256SUMS and cosign (public key: cosign.pub in this repository).
The "Source code (zip)" / "Source code (tar.gz)" links below are added automatically by GitHub to every
release and cannot be removed. They are not the agent's source, and they are empty: this repository
publishes signed binaries and documentation only. LUnA's source is not publicly distributed.