-[ELK System Dashboard 바로가기](https://elk-demo.hongsnet.net/app/dashboards#/view/eb4eeb10-8b7e-11eb-8686-cb443298d4ed?_g=(filters:!(),refreshInterval:(pause:!t,value:0),time:(from:now-24h,to:now))&_a=(description:'',filters:!(),fullScreenMode:!f,options:(hidePanelTitles:!f,useMargins:!t),query:(language:kuery,query:''),timeRestore:!f,title:'www.hongsnet.net%20DBMS%20%EC%9A%B4%EC%9A%A9%ED%98%84%ED%99%A9',viewMode:view))
위의 MariaDB audit LOG 설정에 따라 다음과 같이 로그를 Logstash에 전송할 Filebeats 설정을 진행해야 한다.
```bash
# cat /etc/filebeat/filebeat.yml
logging.level: error
logging.to_files: true
logging.files:
path: /var/log/filebeat
name: filebeat
keepfiles: 7
permissions: 0644
filebeat.inputs:
- type: log
enabled: true
paths:
- /var/lib/mysql/server_audit.log
tags: ["db_audit"]
- type: log
enabled: true
paths:
- /var/lib/mysql/slow-query.log
tags: ["db_slow"]
output.logstash:
hosts: ["172.16.0.228:5444"]
```
-**Logstash 설정**
```bash
# cat /etc/logstash/conf.d/logstash.conf
input {
beats {
port => 5444
host =>"0.0.0.0"
client_inactivity_timeout =>"1200"
type=>"filebeats"
}
udp {
port => 514
host =>"0.0.0.0"
type=>"syslog"
}
}
filter {
if[type]=="messages"{
grok {
match =>{"message"=>"%{SYSLOGTIMESTAMP:syslog_timestamp} %{SYSLOGHOST:syslog_hostname} %{DATA:syslog_program}(?:\[%{POSINT:syslog_pid}\])?: %{GREEDYDATA:syslog_message}"}
add_field =>["received_at", "%{@timestamp}"]
add_field =>["received_from", "%{host}"]
}
syslog_pri {}
date{
match =>["syslog_timestamp", "MMM d HH:mm:ss", "MMM dd HH:mm:ss"]
}
}else if[type]=="syslog"{
if"Received disconnect"in[message] {
drop {}
}else if"Disconnected from"in[message] {
drop {}
}else if"Removed slice User Slice of"in[message] {
match =>{"message"=>"Failed %{WORD:sshd_auth_type} for %{USERNAME:sshd_invalid_user} from %{IPORHOST:sshd_client_ip} port %{NUMBER:sshd_port} %{GREEDYDATA:sshd_protocol}"}
}
grok {
add_tag =>["sshd_fail2"]
match =>{"message"=>"Failed %{WORD:sshd_auth_type} for invalid user %{USERNAME:sshd_invalid_user} from %{IPORHOST:sshd_client_ip} port %{NUMBER:sshd_port} %{GREEDYDATA:sshd_protocol}"}
}
grok {
add_tag =>["sshd_accept"]
match =>{"message"=>"%{DATA:syslog_program}(?:\[%{POSINT:syslog_pid}\])?: Accepted password for %{USERNAME:sshd_invalid_user} from %{IPORHOST:sshd_client_ip} port %{NUMBER:sshd_port} %{GREEDYDATA:sshd_protocol}"}
}
grok {
add_tag =>["HDD_SMART_CHECK_ERROR"]
match =>{"message"=>"Error updating SMART data: Error sending ATA command CHECK"}
}
grok {
add_tag =>["DISK_ERROR"]
match =>{"message"=>"Buffer I/O error"}
}
mutate {
convert =>{"geoip.city_name"=>"string"}
}
geoip {
source=>"sshd_client_ip"
}
}else if[type]=="filebeats"{
if"ZABBIXDB"in[message] {
drop {}
}else if"ZABBIX_DEMO"in[message] {
drop {}
}else if"zabbix"in[message] {
drop {}
}
grok {
add_tag =>["db_conn"]
match =>{"message"=>"%{YEAR:year}%{MONTHNUM:month}%{MONTHDAY:day} %{TIME:time},%{GREEDYDATA:host},%{GREEDYDATA:username},%{GREEDYDATA:client_hostname},%{INT:connection_id},%{INT:query_id},%{GREEDYDATA:operation},%{GREEDYDATA:schema},%{GREEDYDATA:object},%{INT:return_code}"}
}
grok {
match =>["message", "^# User@Host: %{USER:query_user}(?:\[[^\]]+\])?\s+@\s+%{HOSTNAME:query_host}?\s+\[%{IP:query_ip}?\]"]
}
grok {
match =>["message", "^# Thread_id: %{NUMBER:thread_id:int}\s+Schema: %{USER:schema}\s+Last_errno: %{NUMBER:last_errno:int}\s+Killed: %{NUMBER:killed:int}"]