基於ELK 7.50搭建elastalert 監控報警和權限控制

ELK+監控報警全步驟

需求: 公司要求對出在windows服務器上的日誌進行日誌分析並根據關鍵字進行報警,並配置kibana權限控制。下面爲詳細步驟

環境: centos 7.6 elk版本7.50 (由於7.50版本自帶xpack功能,能夠知足kibana角色權限控制)

1. windows字符集改爲utf8

#建立目錄(有就不用建立)

C:\WINDOWS\SHELLNEW

#建立一個文本文檔(txt) 複製到該目錄:

#命名爲:UTF8.txt

#文件 -> 另存爲…

#選擇編碼格式爲:UTF-8
 
WIN + R  ->regedit

#按如下路徑找到ShellNew項:

HKEY_CLASSES_ROOT\.txt\ShellNew

#新建 -> 字符串

#命名爲:FileName

#雙擊 FileName這項,輸入:UTF8.txt

#按如下路徑找到Notepad項:HKEY_CURRENT_USER\Software\Microsoft\Notepad

#更改如下兩項值爲:1(若是不存在,自行建立:右鍵 -> 新建 -> DWORD)

fSavePageSettings 

fSaveWindowPositions

2. 下載安裝包並安裝

1.1 filebeat
https://artifacts.elastic.co/downloads/beats/filebeat/filebeat-6.6.0-windows-x86_64.zip

#下載安裝包,並解壓至c:\filebeat

#進入c:\filebeat 修改配置文件filebeat.yml

############################################
filebeat.inputs:
- type: log
  enabled: true
  paths:
    - c:\work\*
#  include_lines: ['Errors']
  tags: "ca"
- type: log
  enabled: true 
  paths:
    - d:\work\*
 # json.keys_under_root: true   #若是日誌文件原本就是json格式,須要下面2行參數
 # json.overwrite_keys: true
  tags: "json"
  
output.redis:   
  hosts: ["192.168.2.23:6379"]
  key: "all"

setup.template.name: "nginx"
setup.template.pattern: "nginx_*"
setup.template.enabled: false
setup.template.overwrite: true
############################################


#啓動powershell--> 以管理員身份運行

PowerShell.exe -ExecutionPolicy UnRestricted -File .\install-service-filebeat.ps1 #這是以windows服務形式啓動

cd c:\filebeat

.\filebeat.exe -e -c filebeat.yml #這是以cmd形式啓動,能夠改爲bat文件進行運行


#這邊由於filebeat拉取數據直接給的redis,因此不須要配置elasticsearch的帳號密碼
1.2. redis
#安裝redis

yum install -y redis

#修改配置文件

vim /etc/redis.conf

daemonize yes
bind 192.168.2.23
port 6379

#啓動redis

systemctl start redis

netstat -ltnp |grep 6379

#測試登陸
redis-cli -h 192.168.2.23
192.168.2.23:6379>
1.3 jdk
#下載jdk 8 爲其餘服務提供支持

wget https://download.oracle.com/otn/java/jdk/8u231-b11/5b13a193868b4bf28bcb45c792fce896/jdk-8u231-linux-x64.rpm

#安裝jdk

rpm -ivh jdk-8u231-linux-x64.rpm
1.4. elasticsearch
# 安裝es 7.5 須要安裝openjdk 11(es 7.0以上對jdk版本要求升高了)

#下載安裝包

wget https://download.java.net/java/GA/jdk11/13/GPL/openjdk-11.0.1_linux-x64_bin.tar.gz

#將安裝包解壓到/opt下

tar xf openjdk-11.0.1_linux-x64_bin.tar.gz -C /opt/

#修改配置文件

cd /usr/share/elasticsearch/bin

vi elasticsearch

添加如下下幾行內容

#在後面句子後面添加
#   ES_JAVA_OPTS="-Xms8g -Xmx8g" ./bin/elasticsearch  
#配置本身的jdk11,可是並不影響整個系統的jdk環境變量,共存
export JAVA_HOME=/opt/jdk-11.0.1
export PATH=$JAVA_HOME/bin:$PATH

------------------

#在後面句子前面添加# manual parsing to find out, if process should be detached  
#添加jdk判斷
	if [ -x "$JAVA_HOME/bin/java" ]; then
			JAVA="/opt/jdk-11.0.1/bin/java"
	else
			JAVA=`which java`
	fi

# 修改JDK11支持的垃圾回收器

vim /etc/elasticsearch/jvm.options

#-XX:+UseConcMarkSweepGC  #註釋這個
-XX:+UseG1GC				#添加這個

#修改啓動配置

systemctl edit elasticsearch 

[Service]
LimitMEMLOCK=infinity
systemctl daemon-reload
systemctl restart elasticsearch

# 修改配置文件
grep "^[a-Z]" /etc/elasticsearch/elasticsearch.yml 

node.name: node-1
path.data: /var/lib/elasticsearch
path.logs: /var/log/elasticsearch
bootstrap.memory_lock: true
network.host: 0.0.0.0
http.port: 9200

cluster.initial_master_nodes: ["node-1"]  #將註釋取消,修改成這個   
discovery.type: single-node   #或者是添加這個參數,意思是單節模式

#啓動elasticsearch

systemctl start elasticsearch

########################
#若是啓動失敗,能夠換成./elasticsearch 啓動,可是這邊是有坑的,不能使用root用戶啓動
#把elasticsearch用戶改爲普通可登錄用戶(刪除,從新建立)
#要把相關的文件chown 改爲 elasticsearch 
#把啓動文件加入到bin/elasticsearch中

#[Service]裏面添加下面三行
LimitMEMLOCK=infinity
systemctl daemon-reload
systemctl restart elasticsearch

#配置elasticsearch.yml 文件下面修改成
xpack.security.enabled: true
discovery.type: single-node
node.max_local_storage_nodes: 2

#啓動 elasticsearch 

screen -S elasticsearch

cd /usr/share/elasticsearch/bin/

./elasticsearch

ctrl +a +d 

#驗證是否啓動

netstat -ltnp |grep 9200

=========================

#在web中驗證是否啓動成功,須要安裝es-head

#修改ES配置文件支持跨域

http.cors.enabled: true 

http.cors.allow-origin: "*"

#方法1(通用)

# 使用docker安裝 es-head

yum install docker -y

#下載es-head 

docker pull alivv/elasticsearch-head

#docker運行鏡像

docker run --name es-head -p 9100:9100 -dit elivv/elasticsearch-head

#方法2 (通用)

#安裝各類依賴包

yum install nodejs npm openssl screen -y

#安裝node和npm

node -v

npm  -v

npm install -g cnpm --registry=https://registry.npm.taobao.org

cd /opt/

#拉取git代碼

git clone git://github.com/mobz/elasticsearch-head.git

#安裝cnpm

cd elasticsearch-head/

cnpm install

#啓動es-head

screen -S es-head

cnpm run start

Ctrl+A+D

#方法3 (僅適用於Google瀏覽器)

#右上角 --》 更多工具--》擴展程序 

#下載下來ElasticSearch Head0.1.4

#將下載下來的包改爲es-head-0.1.4_0.crx
1.5 開啓xpack功能
#由於咱們要實現kibana權限控制功能,那麼第一步是要給es設置安全密碼

vim /etc/elasticsearch/elasticsearch.yml

#開啓自帶的xpack的驗證功能,在6.8版本之後,已是自帶xpack功能了,不須要花錢了
xpack.security.enabled: true
 
#配置單節點模式
discovery.type: single-node   #開啓這個要關閉cluster那個選項

#執行程序

cd /usr/share/elasticsearch/bin 

./elasticsearch-setup-passwords interactive #輸入y 輸入密碼,最少6位

#記住各自系統服務的帳號和密碼

#記住elasticsearch的帳號和密碼,由於在logstash、elastalert、kibana中都須要配置elasticsearch帳號和密碼

Changed password for user [apm_system]
Changed password for user [kibana]
Changed password for user [logstash_system]
Changed password for user [beats_system]
Changed password for user [remote_monitoring_user]
Changed password for user [elastic]

#重啓es

#登陸es,發現已經須要輸入帳號密碼了
1.6. logstash
#下載logstash安裝包

wget https://artifacts.elastic.co/downloads/logstash/logstash-7.5.0.rpm

#安裝logstash

rpm -ivh logstash-7.5.0.rpm

#修改配置文件

vim /etc/logstash/conf.d/redis.conf

input {
  redis {
    host => "192.168.2.23"
    port => "6379"
    db => "0"
    key => "all"
    data_type => "list"
  }
}

#filter {
#  mutate {
#    convert => ["upstream_time", "float"]
#    convert => ["request_time", "float"]
#  }
#if "ca" in [message]{   
#   grok {
#	 match => { "message" => "%{TIMESTAMP_ISO8601:DATE_time}\s*%{USER:server_name}\S+\s*%{INT:level}\,(?<SNO>(.*))\,(?<excute_time>(.*))\;\s\S+%{GREEDYDATA:message_value}"
#	}
#        }
#    }
#}

filter {
  if "ca" in [tags]{
  grok {
    match => { "message" => "%{TIMESTAMP_ISO8601:DATE_time}\s*%{USER:server_name}\S+\s*%{INT:level}\,(?<SNO>(.*))\,(?<excute_time>(.*))\;\s\S+%{GREEDYDATA:message_value}" }   
  }
}
  if "json" in [tags]{
  grok {
    match => { "message" => "%{TIMESTAMP_ISO8601:DATE_time}\s*\S+\<(?<MODULE>(.*))\>\s\S+\:\<(?<lv_num>(.*))\,(?<lv_SNO>(.*))\>\s\S+%{GREEDYDATA:message_value}" }
  }
}
}
output {
   stdout {}
   if "ca" in [tags] {
      elasticsearch {
        hosts => "http://192.168.2.23:9200"
        manage_template => false
        index => "ca-%{+yyyy.MM}"
        user => "elastic"
        password => "123456"
      }
    }
   if "json" in [tags] {
      elasticsearch {
        hosts => "http://192.168.2.23:9200"
        manage_template => false
        index => "km-%{+yyyy.MM}"
        user => "elastic"
        password => "123456"
      }
    }
#if "rrors" in [message] {     #mail插件,能夠用來報警發郵件
#email {
#        port           =>    "25"
#        address        =>    "smtp.qq.com"
#        username       =>    "xxxxxxx1@qq.com"
#        password       =>    "xxxxxxxxxxxxxxxxxxxxxx"
#        authentication =>    "plain"
#        use_tls        =>    false
#        from           =>    "xxxxxxxx@qq.com"
#        subject        =>    "日誌中有error信息"
#        to             =>    "xxxxxxxxxxxx@126.com"
#        via            =>    "smtp"
#        body           =>    "錯誤日誌: \n  %{message} "
#    }
#}

}


#安裝screen後臺運行程序

yum install screen -y 

#建立一個logstash的後臺程序

screen -S logstash  

/usr/share/logstash/bin/logstash -f /etc/logstash/conf.d/redis.conf

#退出screen後臺程序

ctrl + a + d

#查看screen後臺程序

screen -ls

#進入指定的後臺

screen -r scrren.id
1.6.1 將kibana的收集時間替換爲系統日誌時間
那如何解決上訴問題呢?請看下面👇👇👇

filter {
###替換@timestamp時間爲日誌真實時間######

#方法1
    grok {
        match => {  "message" => "(?<timestamp>%{TIMESTAMP_ISO8601})"  }
    }
    date {
        match => [ "timestamp", "ISO8601" ]
    }
    mutate {
         remove_field => [ "timestamp" ]
    }
}


#方法2 (本身寫的實際的列子)

  if "json" in [tags]{
  grok {
    match => { "message" => "%{TIMESTAMP_ISO8601:times}\s*\S+\<(?<MODULE>(.*))\>\s\S+\:\<(?<lv_num>(.*))\,(?<lv_SNO>(.*))\>\s\S+%{GREEDYDATA:message_value}" }
  }
  date {
        match => ["times", "ISO8601"]
        locale => "en"                      #下面這兩行是定義時區,比中國時區多了八個小時
        timezone => "+00:00"                #通常不用這兩種
        remove_field => "times"
    }
}
}
1.7. kibana
#下載rpm包

wget https://artifacts.elastic.co/downloads/kibana/kibana-7.5.0-x86_64.rpm

#安裝kibana

rpm -ivh kibana-7.5.0-x86_64.rpm

#編輯配置文件

[root@elk ~]# grep "^[a-Z]" /etc/kibana/kibana.yml
server.port: 5601
server.host: "192.168.2.23"
elasticsearch.hosts: ["http://172.16.1.45:9200"]
kibana.index: ".kibana"
elasticsearch.username: "kibana"
elasticsearch.password: "123456"

#啓動kibana

systemctl daemon-reload  #有的時候,會提示找不到服務,就從新reload一下

systemctl start kibana
1.8. 安裝elastalert報警
#安裝elastalert 首先環境須要替換成python3.6

#安裝python3.6

 yum install python36 -y
 yum install python36-pip -y

#測試,顯示python3.6已經安裝成功,可是默認仍是python2
python --version
 python3 --version
 
 #將默認python 修改成python3
 
 cd /usr/bin
 
 ls python*
python   python2.7         python2-config  python3.6         python3.6m         python3.6m-x86_64-config  python.bak

#從新建立軟連接指向python3.6

rm -f python && ln -s python3.6 python

#修改完成後,測試版本

# python --version
Python 3.6.8

# python2 --version
Python 2.7.5

#可是這個時候,由於將python默認改爲了3.6,因此係統裏面依賴python2的都須要修改配置文件

#將第一行"#!/usr/bin/python" 改成 "#!/usr/bin/python2"便可。
vi /usr/bin/yum

#將第一行"#!/usr/bin/python" 改成 "#!/usr/bin/python2"便可。
vi /usr/libexec/urlgrabber-ext-down

#若是某些服務報錯,須要修改python環境


#安裝依賴包
yum install gcc libffi-devel python-devel openssl-devel4 -y

#安裝pip

yum install python2-pip -y

yum install python3-pip-9.0.3-5.el7.noarch

pip install elastalert

#從github上拉取代碼

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

#安裝模塊

 pip install "setuptools>=11.3"
 
#安裝各類包

cd elastalert

python setup.py install 

echo $? #驗證一下是否正確

#若是es是7.0版本以上,若是提示報錯,那邊把之前的卸載掉,從新安裝

pip uninstall elasticsearch

pip3 install 'elasticsearch>=7.0.0'

#這個時候已經多出來elastalert 幾個命令了

#建立報警索引index_status

#編輯配置文件
cp config.yaml.example config.yaml

#配置文件以下:

# grep -Ev "^$|^#" config.yaml  

rules_folder: example_rules
run_every:
  minutes: 1
buffer_time:
  minutes: 15
es_host: 192.168.2.23
es_port: 9200
es_username: "elastic"
es_password: "123456"
writeback_index: elastalert_status
writeback_alias: elastalert_alerts
alert_time_limit:
  days: 2

#建立報錯索引

elastalert-create-index

提示成功
1.9. 配置elastic報警規則
配置example_rules下面的rules


#這是一個樣本

# grep -Ev "^$|^#" example_rules/test_rule.yaml 
name: 你有一封來自elastalert的日誌報警
type: frequency
index: ca*
num_events: 5
timeframe:
  minutes: 4
filter:
- term:
    level: "3"
alert:
- command
- email
new_style_string_format: true
command: ["/opt/test.sh", "elk nginx warning - freq 500 exceed, domain: {match[domain]}"]
alert_text: "報警來自 http://192.168.2.23:9100"
smtp_host: smtp.qq.com
smtp_port: 25
smtp_auth_file: /usr/local/elastalert/example_rules/smtp_auth_file.yaml
email_reply_to: xxxxxxxx@126.com
from_addr: xxxxxxxxxxxxx@qq.com
email:
- "xxxxxxxxxxxxxxxxx@126.com"

#再啓動一個km的報警規則

#[root@zabbix_server elastalert]# grep -Ev "^$|^#" example_rules/km_test.yaml
es_host: 192.168.2.23
es_port: 9200
name: 你有一封來自elastalert的km日誌報警
type: frequency
index: km*
num_events: 5
timeframe:
  minutes: 4
filter:
- term:
    lv_num: "3"
alert:
- command
- email
new_style_string_format: true
command: ["/opt/test.sh", "elk nginx warning - freq 500 exceed, domain: {match[domain]}"]
alert_text: "報警來自 http://192.168.2.23:9100"
smtp_host: smtp.qq.com
smtp_port: 25
smtp_auth_file: /usr/local/elastalert/example_rules/smtp_auth_file.yaml   #建立此文件,並根據需求受權
email_reply_to: xxxxxxxx@126.com
from_addr: xxxxxxxxxx@qq.com
email:
- "xxxxxxxxxxxx@126.com"

#測試建立的規則語法

elastalert-test-rule example_rules/test_rule.yaml  #若是語法正確會看到hit [num] 字樣

#啓動規則,正式拉取報警信息

screen -S elastalert1

python -m elastalert.elastalert --verbose --rule example_rules/test_rule.yaml 

ctrl +a +d

#再拉取一個guiz
screen -S elastalert2

python -m elastalert.elastalert --verbose --rule example_rules/km_test.yaml

ctrl +a +d

#測試,在服務器日誌上插入報警信息,查看是否能夠雙報警
1.10. 配置短信報警(配置command模塊)
vim python3.py 
from  datetime import datetime
import hashlib
import base64
import requests
import json
class YunTongXin():
    # 生產環境的base_url
    base_url = 'https://app.cloopen.com:8883'
    timestamp = None
    def __init__(self,accountSid,authToken,appId,templateId,notice=''):
        self.accountSid = accountSid  # 開發者主帳戶 ACCOUNT SID
        self.authToken = authToken # 帳戶受權令牌
        self.appId = appId # 應用id
        self.templateId = templateId # 模版id
        self.notice = notice # 提示信息

    # 構造請求url
    def gen_request_url(self,sig):
        self.url = self.base_url + '/2013-12-26/Accounts/{}/SMS/TemplateSMS?sig={}'.format(self.accountSid,sig)
        return self.url

    # 構造請求頭
    def gen_request_header(self,timestamp):
        authorization = self.gen_authorization(timestamp)
        return {
            "Accept":"application/json",
            "Content-Type":"application/json;charset=utf-8",
            "Authorization":authorization
        }

    # 構建請求體
    def gen_request_body(self,phone,code):
        return {
            "to":phone,
            "appId":self.appId,
            "templateId":self.templateId,
            "datas":[code,"3"]
        }

    # 獲取 Authorization
    def gen_authorization(self,timestamp):
        return self.base64_encode(self.accountSid+':'+timestamp)

    # base64加密
    def base64_encode(self,raw):
        return base64.b64encode(raw.encode('utf-8')).decode()


    # 生成簽名文檔
    def gen_sig(self,timestamp):
        return self.md5(self.accountSid+self.authToken+timestamp)

    # 生成時間戳
    def gen_timestamp(self):
        return  datetime.now().strftime('%Y%m%d%H%M%S')

    # md5加密
    def md5(self,raw):
        md5 = hashlib.md5()
        md5.update(raw.encode('utf-8'))
        return md5.hexdigest().upper()

    # 請求雲通訊接口
    def request_yuntongxin_api(self,url,header,body):
        response = requests.post(url,headers=header,data=body)
        return response.text

    # 運行
    def run(self,phone,code):
        # 獲取時間戳
        timestamp = self.gen_timestamp()
        # 生成簽名
        sig = self.gen_sig(timestamp)
        # 請求url
        url = self.gen_request_url(sig)
        # 請求頭
        header = self.gen_request_header(timestamp)
        # 請求體
        body = self.gen_request_body(phone,code)
        #請求雲通訊接口
        data = self.request_yuntongxin_api(url,header,json.dumps(body))
        return data


if __name__ == '__main__':
    config = {
        "accountSid":"8a216da86eb206c4016exxxxxxx", # 主帳戶id,控制檯首頁獲取
        "authToken":"e46b476182d94dc094e8xxxxxx", # 令牌
        "appId":"8a216da86eb206c4016ec46cxxxxxx", # 應用id
        "templateId":"1" # 模版id
    }
    phone = '199xxxxx'  # 手機號,若是是多個手機號用英文的,分割 好比說13200000000,13300000000
    code = '123' # 驗證碼
    yun = YunTongXin(**config)
    res = yun.run(phone,code)
    print(res)
    
    
  #將腳本內容放入command模塊中,後置傳參第一個位置
相關文章
相關標籤/搜索