Events
Overview
Events are specific schemas that represent the construct of a logged event. Event generation is very dynamic and flexible, allowing for nearly any logged event to be easily generated once a SaloEventModel has been created. Once a SaloEventModel is created, logged events can easily be customized via a recipe or, for more advanced use cases, by leveraging Stencils. SALO comes with several Events out of the box, with more being developed and shared regularly.
SaloEventModel leverages pydantic for modeling to ensure strict data validation and
type checking. If creating a new SaloEventModel, it is recommended to have a minimal understanding of pydantic
, though
being an expert is not a requirement.
Model Fields
In order to ensure SaloEventModel
classes can pass along their values to other SaloEventModel
and SaloStencilModel
objects, SALO
heavily relies on pydantic
Field
aliases. For example, Zeek
represents the source ip address as id.orig_h
, while
suricata
represents it as src_ip
. To accomodate the multitude of variations across log schemas, pydantic
Field
aliases
are used to define common Field
names across models.
Example
Events must be a subclass of the SaloEventModel
class. Let’s explore a simple example of a SaloEventModel
.
In this example, we will create a SaloEventModel
that produces a simple log output. Our example log event will
be in JSON:
{"source": "test", "src_ip": "1.1.1.1"}
Let’s build our example event model in salo/events/example.py
:
from pydantic import Field, IPvAnyAddress
from salo import SaloEventModel
class ExampleModel(SaloEventModel):
source: str = Field(default="test")
src_ip: IPvAnyAddress = Field(default="1.1.1.1")
def generate(self, by_alias: bool = True, exclude_none: bool = True):
return self.json(by_alias=by_alias, exclude_none=exclude_none)
Note
The generate
method must exist. In this case, we are returning a JSON result. However, any output can be
returned to include raw text or XML. In some cases, it may be more useful to generate results using a templating
language, such as Jinja2.
Now, we can simply create a new recipe in example.yaml
:
sessions:
- event: salo.events.example.ExampleModel
Once the recipe is executed, salogen.py -r example.yaml
, you should see the exact log output we set out to create:
{"source": "test", "src_ip": "1.1.1.1"}