Alert Templates
Capsule8 was designed to let users decide which data they need to best serve their workflows. As such, we support custom formatting of Alerts through Alert Templates. Alerts may be translated to a UTF-8 string via a Go template instead of the default JSON format.
Alert Templates are strings set in either the template
field of the individual outputs listed in the outputs
section of the analytics config or at the top level under alert_output
which will apply the template to any output that does not have a template set. This allows an operator to set a global Alert Template that can optionally be overridden for a given output. When dispatching alerts the template will be populated with alert data before being sent to the alert output. If the populated template is entirely empty, the alert will not be sent; this can be used as a basic form of alert filtering.
This guide will cover basic usage as well as some common scenarios. See the Go template documentation for a complete overview.
Alert Template Examples
To create an Alert Template, first select the names of the Alert fields you wish to include in your Alert output. See the Alert Template Schema for a complete reference of all the available fields. Alert fields are selected using the Go template {{.FieldName}}
syntax. The syntax is similar to Mustache templates, but the Go template language is much more powerful. For example, to log the name of an Alert’s Policy Name, Thread Group ID, and Program Name you could do the following:
template: '{{.StrategyName}} - {{.ProcessInfo.Tgid}} {{.ProcessInfo.Program.Path}}'
This will produce an Alert that looks like the following string:
WGET - Blacklist 6620 /usr/bin/wget
This template selected the nested TGID value from the Alert’s ProcessInfo
struct. Note that everything except the template parameters was passed through as plain text. This allowed us to add a hyphen between the Policy Name and the rest of the log statement for clarity. Taking this one step further, we could even format the Alert as JSON:
template: '{"policy_name":"{{.StrategyName}}","process_tgid":"{{.ProcessInfo.Tgid}}"}'
This would produce the following JSON string:
{"policy_name":"Blacklist wget","process_tgid":"22144"}
Should you need to wrap the full Alert JSON in another JSON object for compatibility with another system, a helper function called AlertJSON
is provided. This example creates a new JSON object with an id
field, a timestamp
field, and the full Alert payload assigned to a field called payload
:
template: '{"id":"{{.UUID}}","timestamp":"{{.Timestamp}}","payload":{{AlertJSON .}}}'
Note that you should always test the output of new templates before deploying to ensure that the formatting of your output is what you expect! This is especially important for formats like JSON that are intended to be parsed by another system. This example was intentionally compacted onto one line to avoid introducing multi-line output which is not compatible by default with most logging systems.
Overall, Alert Templates are a powerful and flexible way to extend the Alert format to better integrate into your existing workflows. When combined with the Alert Webhook feature, this is a powerful way to easily integrate Capsule8 with other systems. When the sensor starts, any templates that are set are compiled and silently tested with a test Alert which allows the sensor to verify not only that the templates are syntactically correct but also that they can successfully be applied to an Alert without error. No output is generated from this process.
Filtering with Alert Templates
It is possible using go template if statements to send alerts to specific output locations. This works because the Capsule8 sensor will not send empty alerts to an output. For example, it is possible to send high priority alerts to a slack channel and all alerts to the capsule8 console:
alert_output:
outputs:
# Write the Alert to AWS S3 authed through access keys
- type: blobstorage
enabled: true
create_bucket: true
bucket_name: capsule8-alerts
provider: aws
aws_access_key_id: $ACCESS_KEY_ID
aws_secret_access_key: $SECRET_ACCESS_KEY
aws_region: us-east-2
aws_acl: "bucket-owner-full-control"
# Send Alerts to Slack using their webhook JSON format - type: webhook enabled: true url: https://hooks.slack.com/services/123ABC/ab914B12eeigVh2xZ template: |
{{- if eq .Priority 4 -}}
{"text": "🌶 New Capsule8 Alert {{.PolicyType}} {{.Description}}"}
{{- end -}}
# Send all Alerts except for Heartbeat alerts
- type: webhook
enabled: true
url: https://hooks.slack.com/services/123ABC/ab914B12eeigVh2xZ
template: |
{{- if ne (print .PolicyType) "Heartbeat" -}}
{"data": {{AlertJSON .}}}
{{- end -}}
Note: the "-" in the above template tells go to ignore any whitespace before and after the template. This is important to prevent empty new lines from displaying around the alert JSON.
More information on if statements in go templates can be found here. For more information on available boolean and comparison functions see this godoc.
Alert Template Enums
Capsule8 alerts make use of enums for many fields which have a set number of possible values. For usability these enums are converted to strings when alerts are generated but when referencing the value in templates the integer value must be used. For example in order to only generate high priority alerts:
{{if eq .Priority 4 -}} {"text": "Alert {{.PolicyType}} {{.StrategyName}}"} {{- end}}
A full reference can be found in the alert schema reference.
Functions In Alert Templates
Alert Templating expose several functions that can make formatting easier.
AlertJSON
Outputs the entire alert json. This can be useful for wrapping the alert json when other systems have a required input format IE. Console Web Hooks, Splunk ect.
To use the function:
template: '{"uuid": "{{.UUID}}", "data": {{AlertJSON}}}'
This will generate the expected output of:
{"uuid": "2fb9e1fd-cd9b-4dbc-adca-70c29446f808", "data": {"timestamp":"2020-07-29T19:35:57.440109088Z","scope":"Process","priority":"Low","confidence":"Max","comments":"Alerts when an command is executed by a valid system user via SSH.","alert_labels":{},"notifications":[{"timestamp":"2020-07-29T19:35:57.440109088Z",
....
,"name":"Shell Command Executed","categories":["C8.Abnormal Activity.System Activity","MITRE.Execution.Command-Line Interface","MITRE.Execution.User Execution","MITRE.Initial Access.Valid Accounts"]}}
RFC3339Date, RFC3339NanoDate, and ToSeconds
These functions allow for easy formatting the date in alerts. This allows for the output alerts to display the date in whatever format the destination expects.
RFC3339Date displays the date in YYYY-MM-DDTHH:mm:SSZ
format
RFC3339NanoDate displays the date in YYYY-MM-DDTHH:mm:SS.NNNNNNNNNZ
ToSeconds converts the Unix Nano Seconds to a Unix Timestamp in seconds
To use these functions:
template: |
{{.UUID}} .Timestamp {{.Timestamp}}
{{.UUID}} RFC3339Date .Timestamp {{RFC3339Date .Timestamp}}
{{.UUID}} RFC3339NanoDate .Timestamp {{RFC3339NanoDate .Timestamp}}
{{.UUID}} ToSeconds .Timestamp {{ToSeconds .Timestamp}}
Which will output:
9dae63f9-110f-40d0-9dfe-ebac85b9433f .Timestamp 1596053056936135157
9dae63f9-110f-40d0-9dfe-ebac85b9433f RFC3339Date .Timestamp 2020-07-29T20:04:16Z
9dae63f9-110f-40d0-9dfe-ebac85b9433f RFC3339NanoDate .Timestamp 2020-07-29T20:04:16.936135157Z
9dae63f9-110f-40d0-9dfe-ebac85b9433f ToSeconds .Timestamp 1596053056
Alert Template Errors
If the template
value is not a syntactically valid template, it is treated as a fatal error and will prevent the Capsule8 Sensor from starting. Included in the output is a line number, e.g. template:1
, to indicate the error is on the first line.
root@peterm:~# ./capsule8-sensor
Capsule8 Sensor version 1.1.0+563aff9-dirty (Build: )
INFO[0000] fetching metadata
INFO[0000] fetched metadata
INFO[0001] Starting Embedded Analytics
FATA[0001] Unable to start analytics: template: error: template: template:1: unexpected"}" in operand
If the template is syntactically valid but an invalid Alert field is specified, this will result in a non-fatal error on Alerts.
For example, if you had the following template
with the Path
field misspelled as Pathx
like:
template: |
{{.StrategyName}} {{.ProcessInfo.Tgid}} {{.ProcessInfo.Program.Pathx}}
you would get the following error:
ERRO[0005] template: template:1:53: executing "template" at <.ProcessInfo.Program...>: can't evaluate field Pathx in type *processtree.ProgramInfo
To resolve this, you will need to update the template and restart the Capsule8 Sensor.
Comments
0 comments
Please sign in to leave a comment.