Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
137 changes: 137 additions & 0 deletions integrations/vestrix_integration/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
# Vestrix-Wazuh Integration

## Table of Contents

* [Introduction](#introduction)
* [Prerequisites](#prerequisites)
* [Installation and Configuration](#installation-and-configuration)
* [Installing Vestrix](#installing-vestrix)
* [Initial Vestrix Configuration](#initial-vestrix-configuration)
* [Installing Wazuh](#installing-wazuh)
* [Initial Wazuh Configuration](#initial-wazuh-configuration)
* [Using the Integration Files](#using-the-integration-files)
* [Integration Steps](#integration-steps)
* [Integration Testing](#integration-testing)
* [Included and Omitted Components](#included-and-omitted-components)
* [Provenance and Maintenance](#provenance-and-maintenance)
* [Sources](#sources)

## Introduction

This integration decodes Vestrix JSON physical-security events and applies
Wazuh rules for high-confidence intrusion, missing PACS correlation, sensor
tampering, and a composite authentication-anomaly correlation.

## Prerequisites

* A Wazuh manager. Version 4.14.5 is the only version tested.
* Vestrix producing one-line JSON events containing `"source":"vestrix"`.
* Prevalidated `confidence_level` values from Vestrix.
* An upstream PACS enricher for rule `100202`, if missing-badge correlation is
required.

Compatibility with earlier Wazuh 4.x versions is untested. Rules `100210` and
`100211` depend on Wazuh 4.14.5 built-in OpenSSH rule IDs `5712` and `5763`.

## Installation and Configuration

### Installing Vestrix

Install Vestrix using the instructions in the
[Vestrix repository](https://github.com/dev-rehaann/VESTRIX). This contribution
contains only the Wazuh decoder and rules; it does not install Vestrix or a log
transport.

### Initial Vestrix Configuration

Configure the Vestrix-to-Wazuh transport to deliver one mapped JSON object per
log record. Each record must contain `"source":"vestrix"`. The Wazuh rules
consume the mapped `confidence_level`; they do not calculate that value.

### Installing Wazuh

A standard Wazuh manager installation is sufficient. Follow the
[official installation guide](https://documentation.wazuh.com/current/installation-guide/index.html)
if Wazuh is not already installed.

### Initial Wazuh Configuration

Configure the manager's existing log collection path to receive the Vestrix
JSON records. No additional API key, Python dependency, or network listener is
provided by this ruleset-only integration.

### Using the Integration Files

From this integration directory, install the decoder and rules in Wazuh's
custom-content directories:

```console
sudo install -m 0640 ruleset/decoders/0585-vestrix_decoders.xml /var/ossec/etc/decoders/0585-vestrix_decoders.xml
sudo install -m 0640 ruleset/rules/1000-vestrix_rules.xml /var/ossec/etc/rules/1000-vestrix_rules.xml
sudo systemctl restart wazuh-manager
```

Preserve any existing local files and apply the owner and group used by other
files in those directories. The default Wazuh configuration loads custom XML
from these directories, so no additional `ossec.conf` entry is required.

## Integration Steps

1. Vestrix classifies a physical-security event and maps it to one JSON record.
2. The configured transport delivers that record to the Wazuh manager.
3. The `vestrix` decoder selects records whose `source` is `vestrix` and uses
Wazuh's `JSON_Decoder` to extract fields.
4. Rule `100200` groups the event; child rules generate alerts for supported
intrusion, PACS, tamper, and authentication-correlation conditions.

Example input:

```json
{"class":"intrusion","confidence":0.97,"confidence_level":"high","node_id":"node-07","site_id":"hq-karachi","source":"vestrix","zone_id":"server-room-west"}
```

The example selects decoder `vestrix` and alert rule `100201` at level 10.

## Integration Testing

After installing the XML files, verify the positive detection on the manager:

```console
printf '%s\n' '{"class":"intrusion","confidence":0.97,"confidence_level":"high","node_id":"node-07","site_id":"hq-karachi","source":"vestrix","zone_id":"server-room-west"}' | sudo /var/ossec/bin/wazuh-logtest -U 100201:10:vestrix
```

A successful run ends with `Unit test OK`. The
`ruleset/testing/test.ini` file also contains a positive detection, a negative
non-match, and a regression case for the JSON decoder-name collision.

For events delivered through the configured transport, inspect
`/var/ossec/logs/alerts/alerts.json` or the Wazuh dashboard's Security Events
view and confirm that the expected rule ID and level are present.

## Included and Omitted Components

* Rules and decoder: included.
* Active response: not applicable; alerting/logging only.
* SCA: not applicable to this physical-layer sensor integration.
* Threat intelligence: not currently provided or consumed.
* Dashboard: planned, not yet built.

## Provenance and Maintenance

* Original source: [Vestrix](https://github.com/dev-rehaann/VESTRIX).
* Adapted by: Vestrix contributors.
* Adaptation: packages the tested Vestrix decoder and rules for this repository;
the decoder, rule, and test logic is unchanged.
* Tested versions: Wazuh 4.14.5 with the Vestrix submission package from
[commit `fbfed6c`](https://github.com/dev-rehaann/VESTRIX/commit/fbfed6ce494cd06dfcdd2117ad7b9edf1388194a).
* Maintainer: Vestrix project maintainers.
* Support boundary: community-maintained through
[Vestrix GitHub issues](https://github.com/dev-rehaann/VESTRIX/issues) and
provided as-is.

## Sources

* [Wazuh integrations repository](https://github.com/wazuh/integrations)
* [Wazuh integrations contribution guide](https://github.com/wazuh/integrations/blob/main/CONTRIBUTING.md)
* [Wazuh custom decoder documentation](https://documentation.wazuh.com/current/user-manual/ruleset/decoders/custom.html)
* [Wazuh custom rule documentation](https://documentation.wazuh.com/current/user-manual/ruleset/rules/custom.html)
4 changes: 4 additions & 0 deletions integrations/vestrix_integration/active_response/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# Active response

Not applicable — Vestrix does not currently implement active response actions;
alerting/logging only.
4 changes: 4 additions & 0 deletions integrations/vestrix_integration/dashboards/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# Dashboards

Planned but not yet built. A Wazuh dashboard for Vestrix physical-intrusion and
sensor-tamper alerts is a known future work item.
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<!-- Vestrix canonical alert JSON. Field extraction is performed only by JSON_Decoder. -->
<decoder name="vestrix">
<parent>json</parent>
<prematch type="pcre2">"source"\s*:\s*"vestrix"</prematch>
<use_own_name>true</use_own_name>
<plugin_decoder>JSON_Decoder</plugin_decoder>
<json_null_field>discard</json_null_field>
<json_array_structure>array</json_array_structure>
</decoder>
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
<group name="vestrix,physical_intrusion,">
<!-- Group every canonical Vestrix event without generating an alert. -->
<rule id="100200" level="0">
<decoded_as>vestrix</decoded_as>
<field name="source" type="pcre2">^vestrix$</field>
<description>Vestrix canonical SOC event</description>
<options>no_full_log</options>
</rule>

<!-- confidence_level is derived and validated by mapper.py per SCHEMA.md. -->
<rule id="100201" level="10">
<if_sid>100200</if_sid>
<field name="class" type="pcre2">^intrusion$</field>
<field name="confidence_level" type="pcre2">^high$</field>
<description>Vestrix: high-confidence physical intrusion at $(site_id)/$(zone_id), sensor $(node_id)</description>
<group>physical_security,intrusion_detection,</group>
</rule>

<!--
PACS fields are illustrative placeholders populated by an upstream enricher.
pacs_event_status=missing means its badge-correlation window has closed with
no match; Wazuh is not inferring absence here.
-->
<rule id="100202" level="12">
<if_sid>100200</if_sid>
<field name="class" type="pcre2">^intrusion$</field>
<field name="pacs_event_status" type="pcre2">^missing$</field>
<description>Vestrix: physical intrusion with no corresponding badge/PACS event at $(site_id)/$(zone_id)</description>
<group>physical_security,access_control,</group>
</rule>

<rule id="100203" level="12">
<if_sid>100200</if_sid>
<field name="class" type="pcre2">^sensor_tamper$</field>
<description>Vestrix: sensor tamper detected on $(node_id) at $(site_id)/$(zone_id)</description>
<group>physical_security,sensor_tamper,defense_evasion,</group>
</rule>

<!--
Correlation helper for current Wazuh built-in OpenSSH brute-force rules:
5712 - nonexistent-user brute force
5763 - repeated authentication-failure brute force
It is level 1 (not 0) so if_matched_sid history can retain it; no_log
prevents a duplicate alert. These IDs are version-dependent assumptions.
-->
<rule id="100210" level="1">
<if_sid>5712,5763</if_sid>
<description>Vestrix correlation helper: recent SSH authentication anomaly</description>
<options>no_log</options>
<group>vestrix_auth_anomaly,</group>
</rule>

<!--
This direction fires when a high-confidence Vestrix intrusion arrives within
120 seconds after the authentication anomaly. It is intentionally global
until the auth source is enriched with a Vestrix site_id/zone_id.
-->
<rule id="100211" level="14" timeframe="120">
<if_sid>100201</if_sid>
<if_matched_sid>100210</if_matched_sid>
<description>Vestrix: physical intrusion within 120s of an SSH authentication anomaly at $(site_id)/$(zone_id)</description>
<group>physical_security,authentication_failures,correlation,</group>
</rule>
</group>
25 changes: 25 additions & 0 deletions integrations/vestrix_integration/ruleset/testing/test.ini
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
; Copyright (C) 2026, Vestrix contributors
;
; Tests for product:
; Vestrix
;
; Candidate rule IDs remain unchanged from the live-tested local integration.
; They require an upstream core-ID allocation before submission.

[High-confidence Vestrix intrusion]
log 1 pass = {"class":"intrusion","confidence":0.97,"confidence_level":"high","csi_window_sha256":"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa","event_id":"vestrix-20260713T201501Z-node-07-0042","model_id":"rf-csi-v1.4.2","node_id":"node-07","pacs_event_id":"pacs-884103","pacs_event_status":"matched","pacs_reader_id":"reader-west-02","record_hash":"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb","schema_version":"1.0","seq":1201,"sequence_number":4421,"shap_top_feature":"subcarrier_variance_12_18","shap_top_value":0.41,"site_id":"hq-karachi","source":"vestrix","ts_utc":"2026-07-13T20:15:01Z","zone_id":"server-room-west"}
rule = 100201
alert = 10
decoder = vestrix

[Non-Vestrix JSON does not match the Vestrix decoder and base rule]
log 1 fail = {"class":"intrusion","confidence":0.97,"confidence_level":"high","csi_window_sha256":"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa","event_id":"not-vestrix-20260713T201501Z-node-07-0042","model_id":"rf-csi-v1.4.2","node_id":"node-07","pacs_event_id":"pacs-884103","pacs_event_status":"matched","pacs_reader_id":"reader-west-02","record_hash":"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb","schema_version":"1.0","seq":1201,"sequence_number":4421,"shap_top_feature":"subcarrier_variance_12_18","shap_top_value":0.41,"site_id":"hq-karachi","source":"not-vestrix","ts_utc":"2026-07-13T20:15:01Z","zone_id":"server-room-west"}
rule = 100200
alert = 0
decoder = vestrix

[Regression - generic JSON parent retains the Vestrix decoder name]
log 1 pass = {"class":"normal","confidence":0.98,"confidence_level":"high","csi_window_sha256":"3456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef012","event_id":"vestrix-20260713T202001Z-node-07-normal-01","model_id":"rf-csi-v1.4.2","node_id":"node-07","pacs_event_status":"not_applicable","record_hash":"456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123","schema_version":"1.0","seq":1206,"sequence_number":4424,"shap_top_feature":"stationary_baseline_similarity","shap_top_value":0.61,"site_id":"hq-karachi","source":"vestrix","ts_utc":"2026-07-13T20:20:01Z","zone_id":"server-room-west"}
rule = 100200
alert = 0
decoder = vestrix
4 changes: 4 additions & 0 deletions integrations/vestrix_integration/sca/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# Security Configuration Assessment

Not applicable — Vestrix is a physical-layer CSI sensor integration, not a
configuration or compliance-assessment source.
4 changes: 4 additions & 0 deletions integrations/vestrix_integration/threat_intel/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# Threat intelligence

Not applicable — Vestrix emits locally classified physical-security events and
does not currently provide or consume a threat-intelligence feed.