Skip to content

Releases: logiqum/luna

LUnA v2.0.0

Choose a tag to compare

@logiqum logiqum released this 26 Oct 18:17
af69236

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_sample or 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-config with 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.yaml is 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 for log_file), and the user logrok-agent is renamed logrok-universal-agent with
      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.log and .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.yaml and 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.
  • Linux (deb, rpm): nothing to do. Upgrading the package moves an enabled or running agent to
    logrok-universal-agent.service, and logrok-agent stays an alias, so existing systemctl commands and
    scripts keep working. An agent.yaml you edited stays your configuration without a prompt, and the new
    default is put beside it as agent.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, correct agent.yaml and
    finish it with dpkg --configure -a (rpm: reinstall the package).

  • macOS (.pkg): nothing to do. The installer unloads and removes the old com.logiqum.logrok-agent
    LaunchDaemon and starts com.logiqum.logrok-universal-agent. Scripts that call launchctl with the old
    label need the new one. An agent.yaml still exactly as an earlier package installed it is replaced with
    the new macOS default (the old file is kept as agent.yaml.pre-2.0); a file you edited is never changed.
    From 2.0.0 on, an agent.yaml you 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 start logrok_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. If newsyslog.conf rotates
    /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 armv7hl rpm packages are no longer published. On 32-bit ARM, use the armhf .deb or the luna-linux-armv7 binary; the binary is the same as before.

Added

  • UDP syslog and GELF on several cores, and UDP loss you can see. syslog_in and gelf_in can read one UDP port on several cores (udp_listeners, a number or auto, 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 in logrok_agent_input_udp_kernel_drops_total.
  • Several batches on the way to Splunk at once (max_in_flight). The hec output 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-config refuses 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-config and the agent's startup now say so once, with what to change (management.state_path, the STATE_DIRECTORY setting, 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.workers above 1, /metrics shows 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; set shutdown_grace under service: (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-config reports shutdown_grace as unknown.
  • Processors on several cores (service.workers). Set workers under service: 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_fingerprint and keyed sample — on that many workers, while dedup, throttle, quota, unkeyed sample, adaptive_sample and aggregate keep 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 stays 1, the pipeline of earlier releases unchanged. An agent of an earlier release does not know the key:...
Read more

LUnA v1.6.0

Choose a tag to compare

@logiqum logiqum released this 05 Oct 08:31
4480425

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_revoked on /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 of ca_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

Choose a tag to compare

@logiqum logiqum released this 26 Sep 20:01
4a221c3

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_file appends 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 source logrok-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 as luna-<version>-release.tar, plus a
    stable-name luna-release.tar for 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
    (systemd StateDirectory=, the FreeBSD rc script, the container image) instead of the config
    directory. Existing installs that set management.state_path are 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

Choose a tag to compare

@logiqum logiqum released this 22 Sep 10:35
5f9bf4b

Added

  • Noise decided centrally, removed at the source (Apex). A new noise_fingerprint processor 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_endpoints an 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 every failback_every and 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 /metrics now tell you how stale delivered data is, and how much each processor removed.
    output_event_delay_seconds is the age of the newest event a destination just accepted (source timestamp
    to acceptance — includes upstream lag and spool wait); pipeline_latency_seconds is how long the agent
    itself held it (independent of source clocks). Both have per-destination variants.
    processor_<name>_dropped_total for every processor and processor_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 /metrics carries the same
    explanation in its HELP text.

Fixed

  • buffer.flush_every now 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 than 2s, 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

Choose a tag to compare

@logiqum logiqum released this 07 Sep 23:04
00614e6

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 start

It 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 | disabled

required 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: end

It 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: sha256

roots 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...

Read more

LUnA v1.2.1

Choose a tag to compare

@logiqum logiqum released this 26 Aug 08:09
028c507

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

Choose a tag to compare

@logiqum logiqum released this 23 Aug 21:59
d2952da

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 quota processor is now actually withdrawn when unlicensed. quota is 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 running quota without 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

Choose a tag to compare

@logiqum logiqum released this 21 Aug 23:56
0683c67

Documentation bundle re-issued 2026-08-24. The luna-docs.tar.gz asset 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
SHA256SUMS are untouched. The bundle's luna-docs.tar.gz.sha256 sidecar was
updated to match the replacement; SHA256SUMS never 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 ships THIRD-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 a third-party-source archive 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_in input. 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-watch deadband
    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: protocol or data_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 /tap endpoint. 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 optional match substring 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 quota processor. A hard per-day cap on what a pipeline may emit —
    set max_events and/or max_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_bundle at 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) and linux-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 — no snmptrapd side-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 the oid_names map — 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.json among the release assets)
    listing the release's third-party components and their licenses, alongside the existing
    NOTICE attribution 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_KEY environment 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...
Read more

LUnA v1.0.0

Choose a tag to compare

@logiqum logiqum released this 05 Aug 19:18
f591a2f

First major release. Two changes need action before you upgrade a fleet, both described in full below:

  1. 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.
  2. 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
    PUBACK as 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 PEN 66371. Structured fields
    are emitted under [logrok@66371 …] (and [seq@66371 …] when sequence is 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, and LICENSE_ENFORCE=0 remains 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_total and logged rather than lost silently. The spool directory and its
    contents are never deleted. (Operators who previously opted in with LICENSE_ENFORCE=1 saw 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 redact processor 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 a redact step 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 a drain_pacing block on
    the output (rate_eps cap, 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
    than fingerprint_size have 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_size were 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 than max_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 a udp_truncated_total metric 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 new spool_write_errors_total metric surfaces a failing spool disk.
  • The disk buffer now honors a size cap smaller than 8 MiB. With buffer.max_bytes set below the internal
    8 MiB segment size and when_full: drop_oldest, a burst could grow the buffer past the cap before it was
    trimmed back — over-retention (never data l...
Read more

LUnA v0.17.0

Choose a tag to compare

@logiqum logiqum released this 18 Jul 13:13
v0.17.0
c30e663

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.