简介:
越来越多公司使用ELK来管理日益繁多的日志和数据,其中的kibana非常适合可视化和查询数据,Elastalert就是kibana的辅助工具,用来对数据中的异常(CPU利用率异常,数据尖峰等)进行报警。
ElastAlert 的设计遵循以下几个原则:
-
它应该易于理解并且易于阅读。为此,我们选择了具有直观选项名称的YAML格式。
-
它应该能够抵抗中断。它记录了它所做的每个查询,并且可以在重新打开时准确地从上次查询的地方开始。
-
我们将其设计为模块化。可以通过实现基类来导入或自定义主要组件,规则类型,增强功能和警报。
ElastAlert被设计为可靠,高度模块化,并且易于设置和配置。
它通过将Elasticsearch与两种类型的组件(规则类型和警报)结合使用。定期查询Elasticsearch,并将数据传递到规则类型,该规则类型确定何时找到匹配项。发生匹配时,将为该警报提供一个或多个警报,这些警报将根据匹配采取行动。
这是由一组规则配置的,每个规则定义一个查询,一个规则类型和一组警报。
ElastAlert包含几种具有常见监视范例的规则类型:
-
“匹配Y时间有X个事件的地方”(
frequency type
) -
“当事件发生率增加或减少时进行匹配”(
spike type
) -
“在Y时间内少于X个事件时进行匹配”(
flatline type
) -
“当某个字段与黑名单/白名单匹配时匹配”(
blacklist
和whitelist type
) -
“匹配与给定过滤器匹配的任何事件”(
any type
) -
“当某个字段在一段时间内具有两个不同的值时进行匹配”(
change type
)
建立规则
每个规则都定义要执行的查询,触发匹配的参数以及每个匹配要触发的警报列表。我们将以变更规则为例:
Type: frequency
-在给定时间范围内至少有一定数量的事件时,此规则匹配。这可以基于每个查询键进行计数:
#如果在1小时内有50多个带有some_field == some_value的文档,请发送电子邮件至elastalert@example.com
# ES的ip和端口号
es_host: elasticsearch.example.com
es_port: 14900
# 规则名称
name: Example rule
type: frequency
# ES索引
index: logstash-*
num_events: 50
timeframe:
hours: 4
filter:
- term:
some_field: "some_value"
alert:
- "email"
email:
- "elastalert@example.com"
已配置的字段如下:
-
es_host和
es_port
应指向我们要查询的Elasticsearch集群。 -
name
:此规则的唯一名称。如果两个规则共享相同的名称,则ElastAlert将不会启动。 -
type
:每个规则具有不同的类型,可能采用不同的参数。频率类型表示“在时间范围内发生超过num_event个事件时发出警报。” -
index
:要查询的索引的名称。如果您使用的是Logstash,则默认情况下索引将匹配“ logstash- * ”。 -
num_events
:此参数特定于频率类型,并且是触发警报时的阈值。 -
timeframe
是必须发生num_events的时间段。 -
filter
是用于过滤结果的Elasticsearch过滤器列表。在这里,我们为带有some_field匹配some_value的文档提供了一个单项过滤器。如果不需要过滤器,则应将其指定为空列表:filter:[] -
alert
是在每次比赛中运行的警报的列表。电子邮件警报要求使用SMTP服务器发送邮件。默认情况下,它将尝试使用localhost。可以使用smtp_host选项进行更改。 -
email
是警报将发送到的地址列表。
所有文档都必须有一个时间戳字段。ElastAlert默认情况下将尝试使用@timestamp,但是可以使用timestamp_field选项更改它。默认情况下,ElastAlert使用ISO8601时间戳,尽管设置timestamp_type支持Unix时间戳。
Type: change
-此规则将监视特定字段,并在该字段更改时匹配。对于具有相同query_key的最后一个事件,该字段必须更改。
#当document之间的某些字段发生变化时发出警报
#此规则将在类似于以下不同的document上发出警报:
# {'username': 'john', 'country_code': 'JPN', '@timestamp': '2016-11-17T09:00:00'}
# {'username': 'john', 'country_code': 'UK', '@timestamp': '2016-11-17T07:00:00'}
#因为用户(query_key)john在同一天(时间范围)从不同国家(compare_key)登录
#类型:更改
# Type change
name: New country login
type: change
index: logstash-*
compare_key: country_code
ignore_null: true
query_key: username
timeframe:
days: 1
filter:
- query:
query_string:
query: "document_type: login"
alert:
- "email"
email:
- "elastalert@example.com"
除频率类型规则字段外,以下是已配置的其他字段:
该规则需要三个附加选项:
-
compare_key
:要监视更改的字段名称。 -
ignore_null
:如果为true,则没有compare_key字段的事件将不会计为更改。 -
query_key
:此规则适用于每个query_key。在所有检查的事件中都必须存在此字段。
还有一个可选字段:
-
timeframe
:两次更改之间的最长时间。在这段时间之后,ElastAlert将忘记compare_key字段的旧值。
Type: spike
-当给定时间段内的事件spike_height
量大于或小于前一个时间段时,此规则匹配。它使用两个滑动窗口比较事件的当前频率和参考频率。我们将这两个窗口称为“ 参考 ”和“ 当前 ”。
#当事件量突然增加或匹配文档的数量在一小时内增加两倍时发出警报。将触发警报的最小事件数设置为5。
# Type SPIKE
name: Event spike
type: spike
index: logstash-*
threshold_cur: 5
timeframe:
hours: 1
spike_height: 3
spike_type: "up"
filter:
- query:
query_string:
query: "field: value"
- type:
value: "some_doc_type"
alert:
- "email"
email:
- "elastalert@example.com"
除频率规则类型字段外,以下是一些已配置的重要附加字段:
-
spike_height
:点击时将触发警报的最后一个时间范围与前一个时间范围中的事件数之比。 -
spike_type
:“上”,“下”或“两者”。“向上”表示仅当事件数为“ spik_height”高倍时,该规则才会匹配。“向下”表示参考编号比当前编号高穗高。“两者”将匹配。 -
timeframe
:该规则将平均出该时间段内的事件发生率。例如,hours:1表示“当前”窗口将从当前到一小时前,而“参考”窗口将从一小时前到两小时前。
还有一个可选的配置字段:
-
threshold_cur
:要触发警报,当前窗口中必须存在的最少事件数。例如,如果spike_height: 3
和threshold_cur: 60
,则如果当前窗口中有60个以上的事件,而参考窗口中的事件少于三分之一,则将发出警报。
配置规则过滤器
过滤器是用于查询Elasticsearch的Elasticsearch查询DSL过滤器的列表。ElastAlert将使用格式{'filter':{'bool':{'must':[config.filter]}}}}以及附加的时间戳范围过滤器查询Elasticsearch。使用这些过滤器的所有查询结果都将传递到RuleType进行分析。本节介绍如何为规则配置文件创建过滤器节。
规则中使用的过滤器是Elasticsearch查询DSL的一部分。我们将在这里列出一小部分特别有用的过滤器。
过滤器部分完全按照以下方式传递给Elasticsearch:
filter:
and:
filters:
- [filters from rule.yaml]
与这些过滤器匹配的每个结果都将传递到规则进行处理。
常用过滤器类型:
query_string
-该QUERY_STRING类型遵循Lucene的查询格式,并且可以用于向多个字段的部分或全部匹配。
filter:
- query:
query_string:
query: "username: john"
- query:
query_string:
query: "_type: auth_logs"
- query:
query_string:
query: "field: value OR otherfield: othervalue"
- query:
query_string:
query: "this: that AND these: those"
term
-字词类型允许完全匹配的字段:
filter:
- term:
name_field: "john"
- term:
_type: "auth_logs"
terms
-术语可轻松组合多个术语过滤器:
filter:
- terms:
field: ["value1", "value2", "value3"]
使用该 minimum_should_match
选项,您可以定义一组术语过滤器,其一定数目必须匹配:
- terms:
fieldX: ["value1", "value2"]
fieldY: ["something", "something_else"]
fieldZ: ["foo", "bar", "baz"]
minimum_should_match: 2
range -对于字段范围:
filter:
- range:
status_code:
from: 100
to: 199
negation, and, or
-任何过滤器都可以嵌入not和and和or中:
filter:
- or:
- term:
field: "value"
- wildcard:
field: "foo*bar"
- and:
- not:
term:
field: "value"
- not:
term:
_type: "some_type"
监控警报
在以下警报和监视示例中,我们将省略警报配置,而将重点放在模式和规则类型配置上。可以通过多种方式自定义警报,以满足我们的需求。
身份验证:SSH和其他登录
让我们从一条简单的规则开始,该规则在SSH身份验证失败时提醒我们。我们将假定log _type为ssh_logs,并且还包含响应,成功或失败以及用户名。
#警报 当任何SSH故障发生
filter:
- term:
_type: ssh_logs
- term:
response: failure
type: any
该any
类型将在与过滤器匹配的任何文档上发出警报。我们可以将类型更改frequency
为仅在发生多个SSH故障时发出警报。我们可以通过使用query_key
用户名对事件进行分组来进一步完善它。这将使我们仅在给定用户发生一定数量的故障时发出警报。
#按用户名分组并在1小时内单个用户发生5次SSH故障时发出警报
filter:
- term:
_type: ssh_logs
- term:
response: failure
type: frequency
num_events: 5
timeframe:
hours: 1
query_key: username
如果有人试图强行执行SSH登录,这将提醒您,但是如果攻击者已经获取了您的凭据怎么办?我们还有其他一些事情需要考虑,例如同一用户是否已通过多个IP地址连接?
#当单个用户在一天的时间范围
filter:
- term:
_type: ssh_logs
- term:
response: success
type: cardinality
max_cardinality: 1
cardinality_field: ip_address
timeframe:
days: 1
query_key: username
在此示例中,我们正在警告ip_address
字段的基数username
在一天之内是否大于一个。也可以使用更改规则类型来完成此特定警报,但是基数可为您提供更大的灵活性,并可用于多种其他目的。
日志记录:成功和错误日志
我们假设错误消息的解析方式为包含error_code
。您可以type: any
在每条错误消息上使用并发出警报。但是,这可能无法很好地扩展。设定明确的阈值通常很困难,因为基线正常值可能会随时间变化。我们可以使用spike
类型来处理:
#如果错误数量在一小时内加倍,则发出警报
filter:
- term:
_type: error_logs
type: spike
spike_height: 2
spike_type: up
threshold_ref: 50
timeframe:
hours: 1
top_count_keys:
- error_code
使用此规则,我们正在比较最后一个小时与之前一个小时的错误数量。如果当前时间包含前一个小时的2倍以上,并且前一个小时至少包含50个事件,它将发出警报。如果这太敏感,则增加timeframe
可以有效地使平均错误率平滑。通过设置top_count_keys
,警报将包含该峰值内发生的最常见类型的细分。
如果我们不在乎向我们发送警报的常见错误,那么这一切都很好,但是严重的错误消息仍然可以溜走。我们可以采取的另一种方法是仅在出现新的,从未见过的错误代码时发送警报。
#一个新的错误类型时
filter:
- term:
_type: error_logs
query_key: error_code
type: new_term
include:
- traceback
这些只是一些可能的用例。使用自定义规则类型或警报,一切皆有可能。如果您可以将其放入Elasticsearch,则可以对其进行监视和警报。有关功能的完整列表以及入门指南,请查看文档并在Github上找到源。