Elastic stack番外篇之elastalert告警

Elastic stack番外篇之elastalert告警

目前大多數公司都在慢慢的遷移到elastic static 套件(以前我們習慣稱呼為ELK) 實現網站的數據分析, 這幾天一直在搞線上服務的日誌報警功能(主要是在應用的日誌層面來實現的),所以在這裡介紹一下一個非常好用的python報警框架elastalert 結合我們的elastic stack套件

說到報警一般我們要滿足這 3個條件

第一是 : 及時性

第二是:準確性

第三是: 智能報警頻率限制性

那麼這幾個功能這個框架都是滿足的.

​好啦終於輪到我們的主角–ElastAlert出來了,其他的告警工具還有 Alert Management、Elasticsearch watch ,請讀者們自行確定需要使用哪個。

ElastAlert使用python編寫,具有容易上手、文檔全等特點,雖然這個工具擁有如此多的優點,在搭建過程還是遇到了很多很多的未知錯誤,主要原因是網上的資料大多是針對es5.x以前的版本而沒什麼現成的資料可供參考。

1.1 安裝elastalert

 git clone https://github.com/Yelp/elastalert.git 
cd elastalert

python setup.py install //可能需要sudo
Pip install -r requirements.txt //可能需要sudo
cp config.yaml.example config.yaml

​ 具體的功能本文就不一一介紹了,請自行前往官方文檔瞭解

1.2 創建索引

​ 安裝完成後會系統中會自帶三個命令:

​ elastalert-create-index、elastalert-rule-from-kibana 、elastalert-test-rule

​ 使用elastalert-create-index,根據提示設置es後按回車默認即可。

​ 配置完索引及配置文件後,可以使用elastalert-test-rule進行測試。這裡有個bug,如果出現TransportError(400, u'search_phase_execution_exception', u'No mapping found for [alert_time] in order to sort on')之類的錯誤,在確認沒有其他的問題時,可以先刪除索引curl -XDELETE http://localhost:9200/*,再使用elastalert-create-index重新生成索引。

1.3 配置config.yaml

 rules_folder: example_rules
# How often ElastAlert will query Elasticsearch
# The unit can be anything from weeks to seconds
run_every:
seconds: 3 #每三秒向es請求數據
# ElastAlert will buffer results from the most recent
# period of time, in case some log sources are not in real time
buffer_time:
minutes: 15
#日誌會延遲進入es,這裡是配置query的向前的時間範圍,這是15分鐘,即查詢 time[now-15m, now]
# The Elasticsearch hostname for metadata writeback
# Note that every rule can have its own Elasticsearch host
es_host: 188.88.88.88

# The Elasticsearch port
es_port: 9200
# Optional URL prefix for Elasticsearch
#es_url_prefix: elasticsearch
# Connect with TLS to Elasticsearch
#use_ssl: True
# Verify TLS certificates
#verify_certs: True
# GET request with body is the default option for Elasticsearch.
# If it fails for some reason, you can pass 'GET', 'POST' or 'source'.
# See http://elasticsearch-py.readthedocs.io/en/master/connection.html?highlight=send_get_body_as#transport
# for details
#es_send_get_body_as: GET
# Option basic-auth username and password for Elasticsearch
#es_username: someusername
#es_password: somepassword
# The index on es_host which is used for metadata storage
# This can be a unmapped index, but it is recommended that you run
# elastalert-create-index to set a mapping
writeback_index: elastalert_status
# If an alert fails for some reason, ElastAlert will retry
# sending the alert until this time period has elapsed
alert_time_limit:
days: 1

以上各字段的解釋:

Rules_folder:用來加載下一階段rule的設置,默認是example_rules

Run_every:用來設置定時向elasticsearch發送請求

Buffer_time:用來設置請求裡時間字段的範圍,默認是45分鐘

Es_host:elasticsearch的host地址

Es_port:elasticsearch 對應的端口號

Use_ssl:可選的,選擇是否用SSL連接es,true或者false

Verify_certs:可選的,是否驗證TLS證書,設置為true或者false,默認為- true

Es_username:es認證的username

Es_password:es認證的password

Es_url_prefix:可選的,es的url前綴(我的理解是https或者http)

Es_send_get_body_as:可選的,查詢es的方式,默認的是GET

Writeback_index:elastalert產生的日誌在elasticsearch中的創建的索引

Alert_time_limit:失敗重試的時間限制

1.4 告警配置介紹

​ 在example_rules目錄中新建yaml配置文件 webattack_frequency.yaml,下面分開介紹這個配置文件的內容(下個小節將分享我的配置文件,此小節僅解釋其中的必要設置項):

1、告警規則

ElastAlert支持11種告警規則,本文不一一介紹了,為響應web攻擊行為,本文選用的告警規則是frequency。

name: web attack
# (Required)
# Type of alert.
# the frequency rule type alerts when num_events events occur with timeframe time
type: frequency
# (Required, frequency specific)
# Alert when this many documents matching the query occur within a timeframe
num_events: 10
# (Required, frequency specific)

# num_events must occur within this amount of time to trigger an alert
timeframe:
minutes: 1

# (Required)
# Index to search, wildcard supported
index: logstash-* #對應logstash的配置文件中output的elasticsearch index前綴
filter:
- query_string:
# sql insert xss detect
query: "request: select.+(from|limit) OR request: union(.*?)select OR request: into.+(dump|out)file "
上述配置文件的意圖即是:在一分鐘內將匹配query裡面的sql注入規則,若匹配次數達到10次,即進行報警。

2、使用郵箱進行告警

ElastAlert提供了 10 多種通知的類型,本文選用的是郵箱告警,還有微信告警、釘釘告警,若有需要,請自行配置。

smtp_host: smtp.qiye.163.com
smtp_port: 25
smtp_auth_file: /Users/qy/Downloads/work/elastalert/example_rules/smtp_auth_file.yaml
#回覆給那個郵箱
email_reply_to: [email protected]
#從哪個郵箱發送
from_addr: [email protected]
# (Required)
# The alert is use when a match is found
alert:
- "email"
# (required, email specific)
# a list of email addresses to send alerts to
email:
- "[email protected]"
alert_subject: "web attack may be by {} at @{}"
alert_subject_args:
- remote_addr

- time
alert_text_type: alert_text_only
alert_text: |
你好,服務器({})可能正在受到web攻擊,請採取手段阻止!!!!
### 截止發郵件前匹配到的請求數:{}
> 發生時間: {}
> timestamp:{}
> attacker's ip: {}
> request: {}
> status:{}
> UA頭:{}
>>> 參考來源:{}
alert_text_args:
- host
- num_hits
- time
- "@timestamp"
- remote_addr
- request
- status
- http_user_agent
- source

smtp_auth_file.yaml的配置內容會在下個小節給出,在這個配置中,我自定義了 alert 的內容,更為精確地突出了攻擊者ip、受攻擊的服務器、攻擊事件等信息。

3、減少重複告警的頻率

在實際的使用中,若使用上述的配置,受到攻擊的時候郵箱將不斷地收到郵件,而這些郵件都對應著同一個攻擊實例,根本沒必要重複收取,於是,我使用瞭如下的配置:

 # 用來區分報警,跟 realert 配合使用,在這裡意味著,
# 5 分鐘內如果有重複報警,那麼當 name 不同時,會當做不同的報警處理,可以是數組
query_key:
- name
# 5 分鐘內相同的報警不會重複發送
realert:
minutes: 5
# 指數級擴大 realert 時間,中間如果有報警,
# 則按照 5 -> 10 -> 20 -> 40 -> 60 不斷增大報警時間到制定的最大時間,
# 如果之後報警減少,則會慢慢恢復原始 realert 時間
exponential_realert:
hours: 1

在本人實際測試的攻擊場景中,發現使用了exponential_realert後,會錯過很多告警(這些告警並不是同一個攻擊實例),暫時不確定原因,還請讀者們自行確定是否開啟該設置。

1.5webattack_frequency.yaml及smtp_auth_file.yaml配置文件內容

上述的1.4小節中對每個配置都作了簡單的介紹,這裡就直接放出web攻擊預警的配置文件供各位讀者參考。

webattack_frequency.yaml:

# Alert when the rate of events exceeds a threshold
# (Optional)

# Elasticsearch host
#es_host: 188.88.88.88
# (Optional)
# Elasticsearch port
#es_port: 9200
# (OptionaL) Connect with SSL to Elasticsearch
#use_ssl: True
# (Optional) basic-auth username and password for Elasticsearch
#es_username: someusername
#es_password: somepassword
# (Required)
# Rule name, must be unique
name: web attack
realert:
minutes: 5
# (Required)
# Type of alert.
# the frequency rule type alerts when num_events events occur with timeframe time
type: frequency
# (Required)
# Index to search, wildcard supported
index: logstash-*
# (Required, frequency specific)
# Alert when this many documents matching the query occur within a timeframe
num_events: 10
# (Required, frequency specific)
# num_events must occur within this amount of time to trigger an alert
timeframe:
#hours: 4
minutes: 1
# (Required)
# A list of Elasticsearch filters used for find events
# These filters are joined with AND and nested in a filtered query
# For more info: http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/query-dsl.html
#filter:
#- term:
# some_field: "some_value"
filter:
- query_string:
# sql insert xss detect
query: "request: select.+(from|limit) OR request: union(.*?)select OR request: into.+(dump|out)file OR
request: (base64_decode|sleep|benchmark|and.+1=1|and.+1=2|or%20|exec|information_schema|where%20|union%20|%2ctable_name%20|cmdshell|table_schema) OR
request: (iframe|script|body|img|layer|div|meta|style|base|object|input|onmouseover|onerror|onload) OR
request: .+etc.+passwd OR http_user_agent:(HTTrack|harvest|audit|dirbuster|pangolin|nmap|sqln|-scan|hydra|Parser|libwww|BBBike|sqlmap|w3af|owasp|Nikto|fimap|havij|PycURL|zmeu|BabyKrokodil|netsparker|httperf|bench) OR
status: (400|404|500|501)
NOT (request:_health.html OR remote_addr:222.222.222.222 )
"
smtp_host: smtp.qiye.163.com
smtp_port: 25
smtp_auth_file: /Users/qy/Downloads/work/elastalert/example_rules/smtp_auth_file.yaml

#回覆給那個郵箱
email_reply_to: [email protected]
#從哪個郵箱發送
from_addr: [email protected]
# (Required)
# The alert is use when a match is found
alert:
- "email"
# (required, email specific)
# a list of email addresses to send alerts to
email:
- "[email protected]"
alert_subject: "web attack may be by {} at @{}"
alert_subject_args:
- remote_addr
- time
alert_text_type: alert_text_only
alert_text: |
你好,服務器({})可能正在受到web攻擊,請採取手段阻止!!!!
### 截止發郵件前匹配到的請求數:{}
> 發生時間: {}
> timestamp:{}
> attacker's ip: {}
> request: {}
> status:{}
> UA頭:{}
>>> 參考來源:{}
alert_text_args:
- host
- num_hits
- time
- "@timestamp"
- remote_addr
- request
- status
- http_user_agent
- source

smtp_auth_file.yaml:

user: [email protected]
password: password

1.6 運行elastalert

在成功配置完ElastAlert後將生成三個配置文件:
config.yaml、webattack_frequency.yaml、smtp_auth_file.yaml
啟動elastalert服務,監聽elasticsearch:
nohup python -m elastalert.elastalert --verbose --rule webattack_frequency.yaml >/dev/null 2>&1 &
為實現守護進程的作用,可以配合supervisor進行使用,本文不再闡述。

1.7 運行效果:

當匹配到自定義攻擊規則的時候,ElastAlert將會以郵件方式發送告警信息:

web attack may be by 104.38.13.21 at @[13/Jan/2018:16:06:58 +0800]
xxx 發給 shystartree
你好,服務器(199.222.36.31)可能正在受到web攻擊,請採取手段阻止!!!!
### 截止發郵件前匹配到的請求數:20
> 發生時間: [13/Jan/2018:16:06:58 +0800]
> timestamp:2018-01-13T08:07:04.930Z
> attacker's ip: 184.233.9.121
> request: GET /dbadmin/scripts/setup.php HTTP/1.0
> status:200
> UA頭:ZmEu
>>> 參考來源:/log/localhost_access_log.2018-01-13.txt

五、總結

ElastAlert除了本文介紹的告警web攻擊行為外,還能進行異常告警等。使用了frequency的規則後,基本能達到識別web攻擊的目的。在實際的使用中,elastalert能穩定運行,且能根據自定義配置文件精確告警,缺點是告警的格式不夠美觀和需要頻繁地修改配置文件。

至於目前比較主流告警----微信告警,大家可以訪問我的github項目,裡面介紹了詳細的使用方法項目地址: https://github.com/Hello-Linux/elastalert_wechat_plugin

Elastic stack番外篇之elastalert告警

最後說一句重要的話: 記得關注我一下 關注 關注 關注


分享到:


相關文章: