監控告警之elastalert部署及配置全解


一、安裝elastalert

環境

  • CentOS:7.4
  • Python:3.6.9
  • pip:19.3
  • elastalert:0.2.1
  • elk:7.3.2

2、配置Python3.6.9環境

安裝依賴包

yum -y install wget openssl openssl-devel gcc gcc-c++ 

下載包

wget https://www.python.org/ftp/python/3.6.9/Python-3.6.9.tgz 

安裝

tar xf Python-3.6.9.tgz cd Python-3.6.9./configure --prefix=/usr/local/python --with-openssl make && make install 

配置

mv /usr/bin/python /usr/bin/python_old ln -s /usr/local/python/bin/python3 /usr/bin/python ln -s /usr/local/python/bin/pip3 /usr/bin/pip pip install --upgrade pip 

注意,所有依賴python2的腳本或者命令,需要更改為python2.7,因為現在默認的python版本為3.6,例如

sed -i '1s/python/python2.7/g' /usr/bin/yum sed -i '1s/python/python2.7/g' /usr/libexec/urlgrabber-ext-down 

驗證

$ python -V Python 3.6.9 $ pip -V pip 19.3 from /usr/local/python/lib/python3.6/site-packages/pip (python 3.6) 

3、安裝elastalert

下載包

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

安裝

pip install "elasticsearch<7,>6" pip install -r requirements.txt python setup.py install 

安裝成功后可以看到四個命令

ll /usr/local/python/bin/elastalert* /usr/local/python/bin/elastalert /usr/local/python/bin/elastalert-create-index /usr/local/python/bin/elastalert-rule-from-kibana /usr/local/python/bin/elastalert-test-rule 

軟連接到/usr/bin下,方便使用

ln -s /usr/local/python/bin/elastalert* /usr/bin 
  • elastalert 報警執行的命令,會根據報警規則執行相應操作。
  • elastalert-create-index會創建一個索引,ElastAlert會把執行記錄存放到這個索引中,默認情況下,索引名叫elastalert_status。其中有4個_type,都有自己的@timestamp字段,所以同樣也可以用kibana來查看這個索引的日志記錄情況。
  • elastalert-rule-from-kibana從Kibana3已保存的儀表盤中讀取Filtering設置,幫助生成config.yaml里的配置。不過注意,它只會讀取filtering,不包括queries。
  • elastalert-test-rule測試自定義配置中的rule設置。

二、使用

官方文檔:https://elastalert.readthedocs.io

規則文檔:https://elastalert.readthedocs.io/en/latest/ruletypes.html

1、主配置文件

首先是主配置文件的模板為config.yaml.example,生成全局配置
vim config.yaml

# 用來加載rule的目錄,默認是example_rules rules_folder: rules # 用來設置定時向elasticsearch發送請求,也就是告警執行的頻率 run_every:  seconds: 30 # 用來設置請求里時間字段的范圍 buffer_time:  seconds: 30 # elasticsearch的host地址,端口 es_host: node01 es_port: 9200 # elastalert產生的日志在elasticsearch中的創建的索引 writeback_index: elastalert_status writeback_alias: elastalert_alerts # 失敗重試的時間限制 alert_time_limit:  days: 2 

2、創建告警索引

執行elastalert-create-index命令在ES創建索引,這不是必須的步驟,但是強烈建議創建。因為對於審計和測試很有用,並且重啟ES不影響計數和發送alert。

Elastic Version: 7.3.2 Reading Elastic 6 index mappings: Reading index mapping 'es_mappings/6/silence.json' Reading index mapping 'es_mappings/6/elastalert_status.json' Reading index mapping 'es_mappings/6/elastalert.json' Reading index mapping 'es_mappings/6/past_elastalert.json' Reading index mapping 'es_mappings/6/elastalert_error.json' New index elastalert_status created Done! 

看到這個輸出,就說明創建成功了,也可以請求一下看看:

curl 127.0.0.1:9200/_cat/indices?v

health status index uuid pri rep docs.count docs.deleted store.size pri.store.size green open elastalert_status_status lh8LL4iCQeSn0afyzxBX7w 1 1 0 0 460b 230b green open elastalert_status i7B7IfCuSb2Sex8U5KoTZg 1 1 0 0 460b 230b green open elastalert_status_past et2aF44VR4WQnxB8T7zD4Q 1 1 0 0 460b 230b green open elastalert_status_silence lhXHEsuUQeGZaW3cRLp5pQ 1 1 0 0 460b 230b green open elastalert_status_error zykwk4KtSyyOY7ckxQTrkA 1 1 0 0 460b 230b 

3、Rule配置

所有的告警規則,通過在rule目下創建配置文件進行定義,這里簡單創建一個來作為演示。

首先我已經在elk集群中配置了一個NGINX日志采集的流水線,現在去kibana中利用檢索規則,過濾出我想要的告警內容,比如我想讓狀態碼是404的請求,觸發告警通知,就用如下語句進行查詢:

response: 404 

其中group是kafka里邊定義的組,后邊是狀態碼,還可以寫更多條件進行匹配。

然后來到服務器添加一條規則:

vim nginx_404.yaml

name: Nginx_err use_strftine_index: true index: nginx_info* type: any aggregation: seconds: 10 filter: - query: query_string: query: "response: 404" alert: - "email" email: - "test@qq.com" smtp_host: smtp.163.com smtp_port: 25 smtp_auth_file: /opt/elastalert/smtp_auth_file.yaml from_addr: test01@163.com email_reply_to: teast02@163.com 

注意里邊在配置郵件通知的時候,還需要引用外部的一個文件,這個文件里用於存放對應郵箱的用戶名密碼。

vim /opt/elastalert/smtp_auth_file.yaml

user: "test01@163.com" password: "xxxxxxx" 

4、規則測試

剛剛已經添加了一條規則,現在可以用自身的命令測試一下剛剛添加的規則。

elastalert-test-rule --config config.yaml nginx_404.yaml

INFO:elastalert:Note: In debug mode, alerts will be logged to console but NOT actually sent. To send them but remain verbose, use --verbose instead. Didn't get any results. INFO:elastalert:Note: In debug mode, alerts will be logged to console but NOT actually sent. To send them but remain verbose, use --verbose instead. 1 rules loaded ......... elastalert_status - {'rule_name': 'Nginx_err', 'endtime': datetime.datetime(2020, 1, 11, 7, 30, 59, 793352, tzinfo=tzutc()), 'starttime': datetime.datetime(2020, 1, 10, 7, 30, 59, 793352, tzinfo=tzutc()), 'matches': 0, 'hits': 0, '@timestamp': datetime.datetime(2020, 1, 11, 7, 31, 0, 76042, tzinfo=tzutc()), 'time_taken': 0.24003815650939941} 

如果沒有報錯,則說明可用。

5、啟動

啟動方式有兩種

(1)指定規則文件路徑

python -m elastalert.elastalert --verbose --config config.yaml --rule rules/nginx_404.yaml 

(2)在全局路徑config.yaml下,配置規則存放在加載規則rules目錄下

python -m elastalert.elastalert --verbose 

6、驗證

服務啟動之后,日志能夠很清晰看到整個過程,此時可以在剛剛的索引原點請求幾個不存在的接口,造一些404狀態,過一會兒應該可以看到日志中的說明,有告警發出,郵箱應該也能收到了。

三、優化

1、啟動方式

上邊的啟動命令只是在前台啟動,並不給力,可以使用nohup啟動,或者是通過supervisord管理,會更加方便。
supervisord如何安裝就不說了.

創建配置文件:

$cat /etc/supervisord.d/elastalert1.ini
[program:elastalert1] directory=/data/elastalert1/ command=python -m elastalert.elastalert --verbose --config /data/elastalert1/config.yaml process_name=elastalert1 autorestart=true startsecs=15 stopsignal=INT stopasgroup=true killasgroup=true redirect_stderr=true stdout_logfile=/data/log/elastalert1.log stdout_logfile_maxbytes=5MB 

然后啟動即可

supervisorctl update supervisorctl start elastalert1 

2、報警方式

elastalert的報警方式有很多種,像郵件、微信、釘釘、post等等,我們主要介紹以下幾種常用的

(1)郵件報警

alert: - "email" email: - "test@qq.com" smtp_host: smtp.163.com smtp_port: 25 smtp_auth_file: /opt/elastalert/smtp_auth_file.yaml from_addr: test01@163.com email_reply_to: teast02@163.com 

修改/opt/elastalert/smtp_auth_file.yaml信息

(2)微信機器人報警

微信報警模板

git clone https://github.com/anjia0532/elastalert-wechat-plugin.git cp elastalert-wechat-plugin/elastalert_modules/* elastalert_modules/ 

添加報警方式

 alert:
 - "elastalert_modules.wechat_qiye_alert.WeChatAlerter"
#后台登陸后【設置】->【權限管理】->【普通管理組】->【創建並設置通訊錄和應用權限】->【CorpID,Secret】 #設置微信企業號的appid corp_id: xxx #設置微信企業號的Secret secret: xxx #后台登陸后【應用中心】->【選擇應用】->【應用id】 #設置微信企業號應用id agent_id: xx #部門id party_id: xx #用戶微信號 user_id: xx # 標簽id,多個用 | 分隔 

(3)釘釘報警方式

釘釘報警模板

git clone https://github.com/xuyaoqiang/elastalert-dingtalk-plugin.git cp elastalert-dingtalk-plugin/elastalert_modules/dingtalk_alert.py elastalert_modules/ 

添加報警方式

alert: - "elastalert_modules.dingtalk_alert.DingTalkAlerter" dingtalk_webhook: "https://oapi.dingtalk.com/robot/send?access_token=fb6500f4c85b8cfe66fa9586870f3ce16c848eab1e1cb23110388d6d443f1e" dingtalk_msgtype: text 

3、報警頻率

#限定時間內,發生事件次數 num_events: 3 #與上面參數結合使用,表示在2分鍾內發生3次就報警 timeframe:  minutes: 2 

4、避免重復告警

避免一定時間段中重復告警,可以配置realertexponential_realert這兩個選項:

# 5分鍾內相同的報警不會重復發送 realert: minutes: 5 # 指數級擴大 realert 時間,中間如果有報警, # 則按照5->10->20->40->60不斷增大報警時間到制定的最大時間, # 如果之后報警減少,則會慢慢恢復原始realert時間 exponential_realert: hours: 1 

5、聚合相同告警

# 根據報警的內容將相同的報警按照 name 來聚合 aggregation_key: name # 聚合報警的內容,只展示 name 與 message summary_table_fields: - name - message 

6、告警內容格式化

可以自定義告警內容,內部是使用Pythonformat來實現的。

alert_subject: "Error {1} @{2}" alert_subject_args: - name - "@timestamp" alert_text_type: alert_text_only alert_text: | > Name: {1} > Message: {2} > Host: {3} ({4}) alert_text_args: - name - message - hostname - host 

最后,整理了比較全的配置文件

name: test_err use_strftine_index: true index: filebeat-7.3.2-* type: any #將多個匹配項匯總到一個警報中。每次找到匹配項時,ElastAlert將等待該aggregation時間段,並將特定規則在該時間段內發生的所有匹配項一起發送。 aggregation: seconds: 10 #限定時間內,發生事件次數 num_events: 3 #與上面參數結合使用,在幾分鍾內 timeframe: minutes: 2 realert: # 5分鍾內相同的報警不會重復發送 minutes: 5 # 指數級擴大 realert 時間,中間如果有報警, # 則按照5->10->20->40->60不斷增大報警時間到制定的最大時間, # 如果之后報警減少,則會慢慢恢復原始realert時間 exponential_realert: hours: 1 filter: - query: query_string: query: "404" alert: - "email" #在郵件正文會顯示你定義的alert_text alert_text: "You have a err message!" #用戶認證文件,需要user和password兩個屬性 smtp_host: smtp.163.com smtp_port: 25 smtp_auth_file: /opt/elastalert/smtp_auth_file.yaml #從哪個郵箱發送 from_addr: test@163.com #回復給那個郵箱 email_reply_to: test@163.com email: #接收報警郵件的郵箱 - "test04@163.com" 

四、示例

1、監控日志Web攻擊行為

1.1 修改nginx日志格式

log_format logstash_json '{"time": "$time_local", ' '"remote_addr": "$remote_addr", ' '"remote_user": "$remote_user", ' '"request": "$request", ' '"status": "$status", ' '"body_bytes_sent": "$body_bytes_sent", ' '"http_referer": "$http_referer", ' '"http_user_agent": "$http_user_agent", ' '"http_x_forwarded_for": "$http_x_forwarded_for", ' '"request_time": "$request_time", ' '"request_length": "$request_length", ' '"host": "$http_host"}'; 

1.2 編寫監控規則

name: web attack realert:  minutes: 5 index: logstash-* type: frequency num_events: 10 timeframe:  minutes: 1 query_key:  - name realert:  minutes: 5 exponential_realert:  hours: 1 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: /opt/elastalert/smtp_auth_file.yaml email_reply_to: xxx@163.com from_addr: xxx@163.com alert: - "email" email: - "shystartree@163.com" alert_subject: "web attack may be by {0} at @{1}" 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 

2、五分鍾內流量總和超過200M就發郵件

run_every:  minutes: 5 name: flow type: metric_aggregation index: nginx_info buffer_time:  minutes: 5 metric_agg_key: body_bytes_sent metric_agg_type: sum max_threshold: 209715200 use_run_every_query_size: true alert_text_type: alert_text_only alert_subject: "Alter 最近五分鍾流量超200M,請注意!!!" alert_text: | 最近五分鍾總流量: {0} B kibana url: http://xxxxx alert_text_args:  - metric_body_bytes_sent_sum smtp_host: smtp.qq.com smtp_port: 25 smtp_auth_file: /opt/elastalert/smtp_auth_file.yaml from_addr: "xxxx@qq.com" alert: - "email" email: - "xxxx@qq.com" 

3、對后端請求超過3秒的發送郵件

es_host: 192.168.20.6 es_port: 9200 run_every:  seconds: 30 name: xxx_reponse_time index: n-xxx-* type: whitelist compare_key: "request" ignore_null: true whitelist:  - /index.html  - /siteapp/ecsAuthentication/hasAuthentication type: frequency num_events: 1 timeframe:  seconds: 30 filter: - query_string:  query: "upstream_response_time: >3 " alert_text_type: alert_text_only alert_subject: "Alter {0} 接口后端處理超過3秒!!!" alert_subject_args: - _index html_table_title: "<h2>This is a heading</h2>" alert_text: |  timestamp: {0}  request_method: {1}  request: {2}  request_body: {3}  request_time: {4} s  upstream_response_time: {5} s  body_bytes_sent: {6} B  status: {7}  remote_addr: {8}  http_x_forwarded_for: {9}  upstream_addr: {10}  agent: {11} alert_text_args:  - timestamp  - request_method  - request  - request_body  - request_time  - upstream_response_time  - body_bytes_sent  - status  - remote_addr  - http_x_forwarded_for  - upstream_addr  - agent smtp_host: smtp.qq.com smtp_port: 25 smtp_auth_file: /opt/elastalert/rule_templates/smtp_auth_file.yaml from_addr: "xxx@qq.com" alert: - "email" email: - "xxxxx@qq.com"


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM