Detection tools and workflows¶
Which detection engines LogsTotal runs, how to keep them and their rules current, and how workflows combine them.
Detection tools¶
| Tool | Runs as | Log types | Output |
|---|---|---|---|
| Zircolite | Docker image, pinned by digest in workflows/*.yml |
EVTX, JSON EVTX, Winlogbeat, Windows Event XML, Auditd, Sysmon for Linux, Journald | JSON array |
| Chainsaw | Binary | EVTX | JSONL |
| Hayabusa | Binary | EVTX | JSONL |
| RSigma | Binary | EVTX, JSON EVTX, Winlogbeat | JSONL with full events |
| ChopChopGo | Binary | Auditd, Syslog | JSON (stdout) |
Chainsaw, Hayabusa, ChopChopGo and RSigma ship as binaries under tools/, with their rule sets, so an installation can analyse Windows and Linux logs without downloading anything. There is no macOS build of ChopChopGo.
Zircolite is the only tool that runs as a container. The worker needs a reachable Docker daemon, and pulls the image (about 500 MB) the first time a job needs it, inside that job; pre-pull it on a slow or metered link. The image is pinned by digest, so an upstream rebuild cannot change what runs on a worker that has access to the Docker socket — see Moving the Zircolite image pin.
Each workflow task sets its own tool_path, docker_image and rules_path — see Workflows.
Linux log types¶
| Log type | Engine | Notes |
|---|---|---|
| Auditd | Zircolite -AU |
Emits one row per audit record with the native field names, which drive entities and relationships. ChopChopGo's auditd mode merges records and matches type-specific rules unreliably, so the shipped auditd workflow does not use it. |
| Syslog | ChopChopGo -target syslog |
Zircolite does not parse free-form syslog. |
| Sysmon for Linux | Zircolite -S |
Uses the Linux rule set. |
| Journald | Zircolite -j with field aliases |
Partial coverage. ChopChopGo reads only the live journal, not an uploaded file, so it is not used. Zircolite reads a journalctl -o json export, and tools/zircolite/rules/zircolite_journald.yaml maps _EXE, _CMDLINE, _COMM, _HOSTNAME and _UID to the field names the Sysmon and auditd rules expect. Rules that need fields journald does not record (parent process, hashes, network details) cannot match. |
ChopChopGo reads its field mappings from tools/chopchopgo/mappings/ and a subset of the SigmaHQ Linux rules from tools/chopchopgo/rules/. Its target (syslog or auditd) follows the job's log type; a task can override it with target.
Zircolite tags events that carry no host name with host: "offline". LogsTotal ignores that value, so it never becomes a computer entity.
Windows Event XML¶
Exports come in two layouts: a bare sequence of <Event> elements (wevtutil qe /f:xml) and a document with an <Events> root. Zircolite needs a different option for each, so LogsTotal inspects each file and picks the right one. Do not put -x or --evtxtract-input in a task's extra_args: an explicit input option overrides that choice, and the wrong one parses a fraction of the file while still reporting success.
RSigma on Windows logs¶
Windows Full Analysis includes RSigma 0.23.0, running locally on Linux x86-64,
Linux ARM64 or macOS Apple Silicon. Its Linux x86-64 binary requires glibc 2.39 or
newer; the ARM64 binary requires glibc 2.34 or newer. Use the LogsTotal worker image
on older hosts. RSigma batch evaluation is single-threaded: omit threads or set it to 1.
The adapter accepts binary EVTX and JSON exports with one event object per line.
Native Event.System / Event.EventData, flattened native fields, and Winlogbeat/ECS
fields are mapped to Sigma names while retaining the original event. Category rules are
restricted by provider, channel and event ID; service rules are restricted by channel.
For exports without a provider, the mapping uses the provider associated with the exact
known channel. JSON arrays and malformed lines fail the scan. Windows XML, Linux logs,
correlation rules and RSigma container execution are outside this integration.
tools/rsigma/rules/ is an independent SigmaHQ Windows snapshot from rules,
rules-emerging-threats and rules-threat-hunting; it does not read Chainsaw's files.
Categories requiring unavailable Windows Event Log telemetry (file_access, file_rename)
are excluded. Custom rules must declare product: windows; any category or service must
be supported by app/tools/rsigma_windows.py. Product-only rules can inspect every Windows
event. Unknown sources fail before evaluation. Service channels follow the
SigmaHQ Windows mappings.
Use one rules_path. The adapter loads its bundled configuration and
tools/rsigma/mappings/windows.yml; mapping_path may point to an operator-maintained
pipeline using the same event aliases. Reserve input, output and completion options for
the adapter: it rejects extra_args that override those flags. Missing completion
statistics, malformed detections or reported parser errors fail the task, preserving a
.partial file for diagnosis instead of publishing incomplete raw evidence to analytics.
Checking for updates¶
A stale rule set does not announce itself: it reports a clean job. Check how current the tools and rules are with:
./logstotal tools:check
It compares each engine's version and each rule snapshot's commit with upstream, verifies the installed binary and rule checksums, and reports the upstream date of each snapshot. It changes nothing, so it is safe on a production host; it needs internet access.
- A new major version is reported as BREAKING, not as an update. These tools rename commands and options between major versions, and LogsTotal builds their command lines, so a major version needs testing before use.
./logstotal tools:updaterefuses one unless you add--allow-majorafter the tool name (./logstotal tools:update -- hayabusa --allow-major); it also requires that option when the installed version cannot be read. - For RSigma before 1.0, a new minor version also reports BREAKING and requires
--allow-majorafter validating the adapter against the new CLI and output format. - Rule sets matter as well as binaries. A stale rule set can miss newer techniques.
./logstotal tools:check -- --strictexits non-zero when an update is pending, a version is unknown, a file has changed or upstream is unreachable — useful in a scheduled check.
Updating rule sets¶
Rule sets are snapshots shipped with each release, not live mirrors: nothing fetches newer rules on its own.
| Tool | Rules live in | Upstream | Refresh with |
|---|---|---|---|
| Zircolite | tools/zircolite/rules/*.json (compiled) |
Zircolite rules | ./logstotal tools:update -- zircolite |
| Chainsaw | tools/chainsaw/sigma/, tools/chainsaw/rules/, tools/chainsaw/mappings/ |
SigmaHQ, Chainsaw | ./logstotal tools:update -- chainsaw |
| Hayabusa | tools/hayabusa/rules/, tools/hayabusa/config/ |
hayabusa-rules | ./logstotal tools:update -- hayabusa |
| ChopChopGo | tools/chopchopgo/rules/, tools/chopchopgo/mappings/ |
SigmaHQ Linux rules | ./logstotal tools:update -- chopchopgo |
| RSigma | tools/rsigma/rules/, tools/rsigma/mappings/, tools/rsigma/config/ |
SigmaHQ Windows rules; LogsTotal Windows mapping | ./logstotal tools:update -- rsigma |
./logstotal tools:update -- <tool> (one or more tool names) downloads the latest release binaries, rules and matching mappings or configuration. Each download must match the SHA-256 digest GitHub publishes for it, the expected executable name and the right architecture; if anything fails, the command exits non-zero before replacing any of that tool's files. The previous files are kept under backups/tools-<tool>-*/, and the installed versions are recorded in tools/<tool>/upstream.json. For Zircolite it refreshes the compiled rules only (keeping zircolite_journald.yaml); the container image is moved separately.
Run updates while no job is running, then check each tool against real logs before relying on it: upload the sample logs and compare the findings with those from before the update. On larger logs compare the matched events as well as the rule names — an upstream fix can move an event to a more specific rule without losing the detection.
The containers run the files built into the image, so apply an update with ./logstotal docker:up, which rebuilds the image and restarts the services. A fleet worker runs its own copy: update the tree you deploy from and deploy it again with ./logstotal deploy.
Note
An upgrade of LogsTotal replaces tools/ with the release's copy, including any rules you edited there. Keep your own rules out of that directory (below).
To run existing jobs against new rules, Resubmit them from the job page. Existing findings are not re-evaluated.
Keeping your own rules¶
Put your rules outside the install directory and point the task's rules_path at them in workflows/*.yml. Each task has its own rules_path, so you can move one tool and leave the rest. On Docker the path must also exist inside the worker container: mount it with a Compose override file.
tasks:
- tool: hayabusa
profile: default
rules_path: /srv/sigma/hayabusa-rules/ # outside the install — upgrades leave it alone
Moving the Zircolite image pin¶
The container is pinned by digest so that an upstream rebuild cannot change what runs on a worker with access to the Docker socket. To move it, on a machine with Docker:
docker pull wagga40/zircolite:<new-version>
docker inspect --format='{{index .RepoDigests 0}}' wagga40/zircolite:<new-version>
Add a docker_image: repo:<version>@sha256:… override to the Zircolite tasks you want to
update, then load the workflows again (see Workflows). Without an override,
the shipped profiles use the release's shared image pin. Test the new image before relying
on it. When maintaining a LogsTotal release, update the shared pin in the tool catalog once;
the profiles and offline bundle inventory use that same value.
Workflows¶
A workflow is a list of tools to run against a log file. Manage workflows on /workflows, or in the YAML files under workflows/.
The web service loads every workflows/*.yml into the database each time it starts, matching on the workflow's name. On Docker the files are built into the image, so after editing one run ./logstotal docker:up to rebuild and restart. On a development checkout, ./logstotal sync-workflows loads them without a restart.
Important
A workflow edited on /workflows whose name matches a file under workflows/ is overwritten from that file the next time the web service starts. To keep an edit made in the browser, save it under a new name, or make the same change in the file.
An excerpt from the shipped workflows/windows_full.yml:
tasks:
- tool: chainsaw
profile: default # binaries and curated rule directories
timeout: 300 # per-task execution timeout in seconds
threads: 2 # CPU threads for this tool
- tool: zircolite
profile: windows # pinned container and Windows rules
timeout: 300
Profiles are optional. Hayabusa, Chainsaw, ChopChopGo and RSigma provide default;
Zircolite provides windows, linux and journald. A task without profile keeps its
existing explicit configuration. Adding a profile supplies reusable paths and settings;
the workflow still chooses its tools, accepted log types, timeout and thread limits.
Explicit task values override profile defaults. Lists and architecture maps replace their
defaults; keys under options merge individually.
An explicit tool_path, docker_image or dockerfile replaces the profile's execution
choice. For example, a local Zircolite tool_path removes its default Docker image.
Select one execution method per task. A profile does not make an engine support additional
log types: incompatible engines in a mixed workflow are still skipped.
Note
Name Chainsaw rule directories individually. tools/chainsaw/sigma/ holds five SigmaHQ rule sets: rules, rules-emerging-threats, rules-threat-hunting, rules-dfir and rules-compliance. The shipped workflow uses the first three; add the others to rules_path if you want them. Chainsaw loads a directory recursively, so pointing rules_path at tools/chainsaw/sigma/ itself would load all five at once. The deprecated and unsupported SigmaHQ sets are not shipped.
Task keys¶
| Key | Meaning |
|---|---|
tool |
zircolite, chainsaw, hayabusa, chopchopgo or rsigma |
profile |
Optional named defaults: Zircolite windows, linux, journald; other tools default. Explicit task settings override them |
tool_path |
Path to the binary: a string, or a map keyed by {arch}-{os} (x86_64-linux, aarch64-linux, aarch64-darwin). A task with no entry for the host's architecture is skipped with a message instead of failing the job |
docker_image |
Run the tool from this container image. The shipped Zircolite profiles use it. Select one execution method; legacy tasks with both a usable tool_path and a Docker image run the local binary |
dockerfile |
Build the image from a Dockerfile instead of pulling it |
rules_path |
The rules for this task — a directory or a compiled bundle, depending on the tool. May be a list of directories, which Chainsaw turns into one --sigma option each. A container-run tool accepts a single path and refuses a list |
timeout |
Execution timeout in seconds. The tool's whole process group is killed when it expires |
threads |
CPU threads for this tool. Defaults to 1 when omitted; the shipped workflows set 2 for Hayabusa and Chainsaw. Zircolite ignores it. See Scaling |
target |
ChopChopGo only: syslog or auditd |
extra_args |
Extra command-line options, appended as given |
options |
Tool-specific settings, such as Hayabusa's min_level or Chainsaw's status (passed to --status; unset by default, so rules of every status load) |
Workflow keys¶
These sit beside tasks: and describe the workflow:
| Key | Meaning |
|---|---|
name |
Display name, and the key the loader matches on: renaming a workflow in its file adds a second workflow rather than renaming the first |
description |
Shown beside the name in the upload form, cut to 60 characters |
log_types |
The detected log types this workflow accepts. An empty list accepts every type, including unknown. Also editable on /workflows |
is_default |
Pre-select this workflow on the upload form. At most one workflow holds it |
The default workflow¶
is_default decides which workflow the upload form pre-selects, and nothing else: it is not a fallback on the server, and every upload still names its workflow.
It only breaks ties. Dropping a file narrows the list to the workflows whose log_types accept the detected type, and the default is chosen from those. The six shipped workflows accept different log types, so the flag matters only once you add a workflow for a type another one already covers.
Ticking it on /workflows clears it on every other workflow. Keep is_default: true in exactly one file under workflows/, because the loader writes the value from each file as it is.
Related: Scaling · Upgrade and roll back · Troubleshooting