Asset Inventory¶
rimae/scan builds a comprehensive inventory of every managed host by combining Wazuh agent telemetry with active application probing. The inventory is the foundation for all vulnerability correlation -- without it, CVEs cannot be matched to your environment.
How Assets Are Discovered¶
Wazuh Integration¶
Assets are imported from a Wazuh manager via its REST API (v4+). During each inventory sync rimae/scan:
- Enumerates all agents with pagination (500 agents per page), collecting hostname, IP address, OS metadata, and last keep-alive timestamp.
- Fetches OS packages for each agent via the syscollector API, recording package name, installed version, architecture, and source.
- Upserts asset records -- new agents create new assets; returning agents update existing records.
- Links to OS version configs -- each asset is matched against your configured distro/version combinations so the correct advisory feeds apply.
Every sync creates a ScanRun audit record with status, timing, and error details.
Note: The Wazuh manager pseudo-agent (ID
000) is automatically excluded from the inventory.
Staleness Detection¶
An asset is marked stale when its Wazuh lastKeepAlive timestamp is older than 24 hours. Stale assets:
- Are flagged with
inventory_stale = truein the database and UI. - Are excluded from application probing and Docker scanning to avoid wasted network calls.
- Still appear in the asset list and can be filtered with the
staletoggle. - Contribute to the "stale" count shown on the Dashboard KPI card.
Asset List View¶
The asset list supports filtering and pagination:
| Filter | Description |
|---|---|
| OS distro | Exact match on the detected distribution (e.g. ubuntu, debian, almalinux). |
| OS version | Exact match on the version string. |
| Stale | Toggle to show only stale or only fresh assets. |
| Hostname | Partial, case-insensitive search on hostname. |
Results are sorted alphabetically by hostname and paginated (default 50 per page, max 500).
Asset Detail View¶
Clicking an asset opens its detail view, which aggregates counts for all related data:
| Tab | Content |
|---|---|
| Overview | Hostname, IP, OS distro/version/codename, architecture, Wazuh agent ID, first seen, last inventoried, tags. |
| Packages | Paginated list of OS packages with name, installed version, architecture, source. |
| Applications | Detected application instances with version, probe method, probe status, and last probed timestamp. |
| Infrastructure | Infrastructure components such as Docker Engine, containerd, runc, Ceph daemons. |
| Docker Images | Pulled container images with name, tag, digest, inferred base OS, and size. |
| Vulnerabilities | Correlated vulnerability matches for this asset, sorted by composite score descending. |
Editing Assets¶
The PATCH endpoint on an asset allows updating user-editable fields:
- Tags -- assign arbitrary string tags for grouping and filtering.
All other fields are managed by automated sync and probe processes.
Application Probing¶
rimae/scan detects application versions on each asset through three probe methods.
Command Probes (via Wazuh Active Response)¶
Commands are dispatched to the Wazuh agent on each host and the output is parsed for version strings. The following applications have dedicated version-parse patterns:
| Application | Pattern Example |
|---|---|
| Python 3 | Python 3.11.2 |
| Node.js | v20.10.0 |
| Go | go1.22.1 |
| JDK | version "21.0.1" |
| Google Cloud SDK | "Google Cloud SDK": "467.0.0" |
| kubectl | "gitVersion": "v1.29.0" |
| Helm | v3.14.0 |
| Terraform | "terraform_version": "1.7.0" |
| AWS CLI | aws-cli/2.15.0 |
| Azure CLI | "azure-cli": "2.56.0" |
| Ansible | ansible 2.16.2 |
| BIND 9 | BIND 9.18.24 |
| Kea | 2.4.1 |
| chrony | chronyc (chrony) version 4.5 |
| step-ca | "version": "0.25.0" |
| containerd | containerd v1.7.11 |
| runc | runc version 1.1.12 |
| Docker Engine | 24.0.7 |
| Ceph (per daemon) | ceph version 18.2.1 |
If no dedicated pattern matches, a generic semver fallback (\d+\.\d+\.\d+) is used.
HTTP Probes¶
For applications that expose version information over HTTP endpoints, rimae/scan probes configured URLs:
- Each application defines a
probe_url_templatewith{host}and{port}placeholders. - Version extraction strategies, in order of preference:
- Jenkins: version from
X-Jenkinsresponse header. - Regex pattern: a configured
version_parse_patternapplied to the response body. - JSON version field: looks for a
versionkey in the JSON response body (including nesteddata.version).
HTTP probes use a 10-second timeout with 2 retries and follow redirects.
Docker Probe¶
On each non-stale asset, rimae/scan connects to the Docker daemon API (port 2375) and collects:
- Engine version -- Docker Engine version, API version, OS, arch, kernel version.
- containerd version -- extracted from the Docker version API components list.
- runc version -- extracted similarly from components.
- Pulled images -- every image with
RepoTagsis recorded with name, tag, digest, and size.
Base OS Inference for Docker Images¶
rimae/scan infers the base operating system of each Docker image using two strategies:
- OCI labels (high confidence) -- checks
org.opencontainers.image.base.nameandorg.opencontainers.image.base.versionlabels. - Image tag pattern matching (lower confidence) -- matches against known base image patterns including Ubuntu, Debian, Alpine, CentOS, AlmaLinux, Rocky Linux, Fedora, Amazon Linux, Arch Linux, BusyBox, and Distroless.
Each image receives a confidence level: verified, inferred, or unknown.
Ceph Probe¶
If Ceph is configured, rimae/scan queries the Ceph Manager REST API to discover:
- Cluster-level version via
/api/summary. - Per-daemon versions via
/api/host, covering: MON, OSD, MGR, MDS, and RGW daemon types. - Hosts that are not already in the asset inventory are created as stub assets.
Wazuh Agent Command Probes¶
Command probes use the Wazuh active response mechanism to execute version-detection commands directly on managed agents. When a probe runs, rimae/scan sends a command request to the Wazuh manager, which dispatches it to the target agent via active response. The agent executes a whitelisted detection script and returns the output, which rimae/scan parses for version strings.
This mechanism is used to detect the following 20 applications:
| # | Application |
|---|---|
| 1 | Python 3 |
| 2 | Node.js |
| 3 | Go |
| 4 | JDK |
| 5 | kubectl |
| 6 | Helm |
| 7 | Terraform |
| 8 | AWS CLI |
| 9 | Azure CLI |
| 10 | Ansible |
| 11 | BIND9 |
| 12 | Kea |
| 13 | Chrony |
| 14 | step-ca |
| 15 | containerd |
| 16 | runc |
| 17 | Docker Engine |
| 18 | Ceph |
| 19 | Google Cloud SDK |
| 20 | npm |
Prerequisites¶
- Active response must be enabled on the Wazuh manager (
ossec.confmust have<active-response>support enabled). - The custom probe script must be deployed on every agent that should be probed.
Setup Instructions¶
1. Deploy the probe script on each agent¶
Create the file /var/ossec/active-response/bin/custom-probe.sh on each Wazuh agent:
#!/bin/bash
# rimae/scan custom probe script for Wazuh active response
# This script is called by the Wazuh manager via active response
# and returns version information for installed applications.
read INPUT_JSON
COMMAND=$(echo "$INPUT_JSON" | jq -r '.parameters.extra_args[0] // empty' 2>/dev/null)
if [ -z "$COMMAND" ]; then
echo '{"error": "no command specified"}'
exit 1
fi
# Execute only whitelisted commands
case "$COMMAND" in
python3|node|go|java|gcloud|kubectl|helm|terraform|aws|az|\
ansible|named|kea-ctrl-agent|chronyc|step-ca|containerd|\
runc|docker|ceph|npm)
OUTPUT=$(eval "${COMMAND} --version" 2>&1 || echo "not_found")
echo "{\"command\": \"${COMMAND}\", \"output\": \"${OUTPUT}\"}"
;;
*)
echo '{"error": "command not whitelisted"}'
exit 1
;;
esac
2. Set file permissions¶
chmod 750 /var/ossec/active-response/bin/custom-probe.sh
chown root:wazuh /var/ossec/active-response/bin/custom-probe.sh
3. Add the command block to the Wazuh manager ossec.conf¶
Add the following inside the <ossec_config> block on the Wazuh manager:
<command>
<name>custom-probe</name>
<executable>custom-probe.sh</executable>
<timeout_allowed>yes</timeout_allowed>
</command>
4. Restart the Wazuh manager¶
5. Verify the setup¶
Send a test probe via the Wazuh API to confirm active response is working:
curl -k -X PUT "https://WAZUH_MANAGER:55000/active-response?pretty" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"command": "custom-probe.sh", "arguments": ["go"], "alert": {"data": {"srcip": "127.0.0.1"}}}'
A successful response indicates the command was dispatched to the agent.
Security Considerations¶
Command probes execute shell commands on remote agents. To limit risk:
- The probe script uses a strict whitelist of allowed commands. Any command not in the whitelist is rejected.
- The script runs under the
wazuhuser with limited privileges. - Only the Wazuh manager can trigger active response commands; rimae/scan never connects to agents directly.
- Review and audit the probe script before deployment. Restrict filesystem permissions so only
rootandwazuhcan read or modify it.
Note: HTTP probes (10 applications such as Jenkins, Nginx, Grafana, etc.) detect versions by querying HTTP endpoints and do not require active response or any agent-side setup. They work out of the box once the application's HTTP endpoint is reachable from the rimae/scan server.
Data Model Summary¶
| Model | Purpose |
|---|---|
Asset |
Core host record with OS metadata, Wazuh linkage, staleness flag. |
OsPackage |
OS-level packages (apt, rpm, etc.) installed on an asset. |
AppInstance |
Detected application with version, probe method, and status. |
InfraComponent |
Infrastructure software (Docker Engine, containerd, runc, Ceph daemons). |
DockerImage |
Container images pulled on an asset with base OS inference. |
Related Documentation¶
- Dashboard -- asset counts and staleness on the KPI cards
- Correlation Engine -- how packages and apps are matched to CVEs
- Vulnerabilities -- the CVEs that correlation produces