# Logstash + Filebeat 설치
Logstash 설치
https://www.elastic.co/guide/en/logstash/current/installing-logstash.html
GPG Key 가져오기
# rpm --import https://artifacts.elastic.co/GPG-KEY-elasticsearch
yum 저장소 등록
# vi /etc/yum.repos.d/logstash.repo
[logstash-8.x]
name=Elastic repository for 8.x packages
baseurl=https://artifacts.elastic.co/packages/8.x/yum
gpgcheck=1
gpgkey=https://artifacts.elastic.co/GPG-KEY-elasticsearch
enabled=1
autorefresh=1
type=rpm-md
설치
# yum install logstash
데이터 전송할때 사용할 역할 생성 (Kibana를 통해서 진행했다!)
ElasticSearch로 보내기위한 계정을 생성하고 역할을 생성한다.
(Logstash데이터를 받기위해 Elasticsearch에 계정생성하는 작업이다)
역할먼저 생성한 과정
특정 index에 대한 지정을 할때는 해당 인덱스만 영향을 받으므로 *로 처리해도 문제는 없다. (위와같이 할경우 index가 nginx*, logstash* 항목에 대해서만 작업이 가능)
데이터 전송할때 사용할 계정 생성
아까 만들었던 역할의 권한을 부여하여 계정 생성
이제 logstash 설정 부분을 수정하러 간다.
logstash.yml
# cat /etc/logstash/logstash.yml
path.data: /var/lib/logstash # Logstash 데이터 저장 경로
path.config: /etc/logstash/conf.d/*.conf # 읽어들일 conf 파일들 지정
path.logs: /var/log/logstash # Logstash log 저장 경로
위 파일은 수정할건 없었다.
Logstash 데몬에 대한 설정
Config 파일 구조
Logstash 설정은 input, filter, output 3가지로 분류된다.
input - 데이터를 수집하는 역할
filter - 데이터를 변환하는 역할
output - 데이터를 내보내는 역할
모든 역할을 한파일로 관리해도되지만 여러개의 conf 파일로 저장하여 관리도 가능하다.
예시)
# ll /etc/logstash/conf.d/
-rw-r--r--. 1 root root 1281 Mar 21 11:54 filter_nginx.conf # nginx 관련 filter 내용 정리
-rw-r--r--. 1 root root 2581 Mar 21 15:32 filter_syslog.conf # syslog 관련 filter 내용 정리
-rw-r--r--. 1 root root 65 Mar 20 14:19 input_filebeat.conf # filebeat으로 들어오는 input 관련 내용 정리
-rw-r--r--. 1 root root 543 Mar 20 14:35 output_nginx.conf # nginx 관련 output 내용 정리
-rw-r--r--. 1 root root 516 Mar 20 15:46 output_syslog.conf # syslog 관련 output 내용 정리
필자는 간단하게 설명하고자 하나의 파일로 담아서 설명 드립니다!
test.conf
# vi /etc/logstash/conf.d/test.conf
## 데이터를 받아오는곳에 대한 정의
input {
beats {
port => 5044 ## input으로 받아올 포트 지정
type => "filebeat" ## type 설정 (위 input으로 들어오는 데이터는 필드값이 type : filebeat 으로 지정된다)
}
}
## 데이터를 grok 언어를 통해 파싱하기.
## if문 사용 가능 (filebeat 설정의 tags 값에 harulife-nginx-server 가 들어있으면 진행)
## grok 언어에 대한 설명은 다음항목에서 설명진행. (grok, ruby등 다양한 언어사용가능)
## mutate 설정은 grok로 쪼개놓은 필드값을 묶어서 필드화 시키는 작업
## remove_field 설정은 쪼개놓은 필드값을 보여주지 않게 설정하는 작업
filter {
grok {
if "harulife-nginx-server" in [tags] {
grok {
match => {
"message" => [
"%{WORD:month} %{NUMBER:day} %{NUMBER:hour}:%{NUMBER:minute}:%{NUMBER:second} %{HOSTNAME:hostname} %{DATA:sys_service}\[%{NUMBER:PID}\]: %{GREEDYDATA:message}",
"%{WORD:month} %{NUMBER:day} %{NUMBER:hour}:%{NUMBER:minute}:%{NUMBER:second} %{HOSTNAME:hostname} %{DATA:sys_service}: %{GREEDYDATA:message}"
]
}
}
mutate {
add_field => {
"time" => "%{month} %{day} %{hour}:%{minute}:%{second}"
}
remove_field => ["month", "day", "hour", "minute", "second"]
}
}
}
}
## 데이터를 보낼곳에 대한 정의
## hosts - 보낼곳에 대한 정의
## index - index는 어떤 index에 넣을지 지정 (없으면 생성함)
## cacert - https 통신임으로 통신할때 사용할 인증서 지정
## user - elasticsearch에 데이터를 쌓을수있는 권한을 가진 계정 설정
## password - 계정에 대한 패스워드
output {
elasticsearch {
hosts => ["https://localhost:9200"]
index => "nginx-%{+YYYY.MM.dd}"
cacert => "/etc/logstash/certs/http_ca.crt"
user => "logstash_writer"
password => "asdfqwer1234"
}
}
Grok에 대한 설명
https://grokdebugger.com/ 를 통해 로그를 Debug 가능
grok {
match => {
"message" => [
"%{WORD:month} %{NUMBER:day} %{NUMBER:hour}:%{NUMBER:minute}:%{NUMBER:second} %{HOSTNAME:hostname} %{DATA:sys_service}\[%{NUMBER:PID}\]: %{GREEDYDATA} %{IPV4:remote_ip}%{GREEDYDATA} %{NUMBER:Port}%{GREEDYDATA}",
"%{WORD:month} %{NUMBER:day} %{NUMBER:hour}:%{NUMBER:minute}:%{NUMBER:second} %{SYSLOGHOST:hostname} sshd\[%{NUMBER:pid}\]: error: kex_exchange_identification: client sent invalid protocol identifier \"%{GREEDYDATA:invalid_protocol_identifier}\""
]
}
}
- grok로 파싱할때 사용할 로그 형태
2024/03/18 19:37:56 [error] 26349#0: *568 open() "/usr/share/nginx/html/pftp" failed (2: No such file or directory), client: 79.110.62.195, server: _, request: "GET /pftp HTTP/1.1", host: "43.202.65.196" 2024/03/18 19:37:56 [error] 26349#0: *569 open() "/usr/share/nginx/html/sh" failed (2: No such file or directory), client: 79.110.62.195, server: _, request: "GET /sh HTTP/1.1", host: "43.202.65.196" 2024/03/18 19:37:57 [error] 26349#0: *570 open() "/usr/share/nginx/html/sshd" failed (2: No such file or directory), client: 79.110.62.195, server: _, request: "GET /sshd HTTP/1.1", host: "43.202.65.196" 2024/03/18 19:37:57 [error] 26349#0: *571 open() "/usr/share/nginx/html/tftp" failed (2: No such file or directory), client: 79.110.62.195, server: _, request: "GET /tftp HTTP/1.1", host: "43.202.65.196" 2024/03/18 20:20:55 [error] 26349#0: *573 open() "/usr/share/nginx/html/.env" failed (2: No such file or directory), client: 185.254.196.173, server: _, request: "GET /.env HTTP/1.1", host: "43.202.65.196" 2024/03/18 21:25:28 [error] 26349#0: *579 open() "/usr/share/nginx/html/.env" failed (2: No such file or directory), client: 177.54.158.94, server: _, request: "GET /.env HTTP/1.1", host: "43.202.65.196" 2024/03/18 22:02:43 [error] 26349#0: *583 open() "/usr/share/nginx/html/aaa9" failed (2: No such file or directory), client: 137.184.226.250, server: _, request: "GET /aaa9 HTTP/1.1", host: "43.202.65.196"
- grok로 파싱할때 grok 코드
%{YEAR:year}/%{MONTHNUM:month}/%{MONTHDAY:day} %{HOUR:hour}:%{MINUTE:minute}:%{SECOND:second} \[%{LOGLEVEL:level}\] %{NUMBER:pid}#%{NUMBER}: \*%{NUMBER} %{GREEDYDATA:message}, client: %{IPORHOST:client}, server: %{DATA:server}, request: "%{WORD:http_method} %{URIPATHPARAM:request} HTTP/%{NUMBER:http_version}\", host: \"%{IPORHOST:host}\"
- grok 코드로 파싱하고 난뒤 결과값
[ { "year": 2024, "month": 3, "day": 18, "hour": 19, "minute": 37, "second": 56, "level": "error", "pid": 26349, "message": "open() \"/usr/share/nginx/html/pftp\" failed (2: No such file or directory)", "client": "79.110.62.195", "server": "_", "http_method": "GET", "request": "/pftp", "http_version": 1.1, "host": "43.202.65.196" }, { "year": 2024, "month": 3, "day": 18, "hour": 19, "minute": 37, "second": 56, "level": "error", "pid": 26349, "message": "open() \"/usr/share/nginx/html/sh\" failed (2: No such file or directory)", "client": "79.110.62.195", "server": "_", "http_method": "GET", "request": "/sh", "http_version": 1.1, "host": "43.202.65.196" }, { "year": 2024, "month": 3, "day": 18, "hour": 19, "minute": 37, "second": 57, "level": "error", "pid": 26349, "message": "open() \"/usr/share/nginx/html/sshd\" failed (2: No such file or directory)", "client": "79.110.62.195", "server": "_", "http_method": "GET", "request": "/sshd", "http_version": 1.1, "host": "43.202.65.196" }, { "year": 2024, "month": 3, "day": 18, "hour": 19, "minute": 37, "second": 57, "level": "error", "pid": 26349, "message": "open() \"/usr/share/nginx/html/tftp\" failed (2: No such file or directory)", "client": "79.110.62.195", "server": "_", "http_method": "GET", "request": "/tftp", "http_version": 1.1, "host": "43.202.65.196" }, { "year": 2024, "month": 3, "day": 18, "hour": 20, "minute": 20, "second": 55, "level": "error", "pid": 26349, "message": "open() \"/usr/share/nginx/html/.env\" failed (2: No such file or directory)", "client": "185.254.196.173", "server": "_", "http_method": "GET", "request": "/.env", "http_version": 1.1, "host": "43.202.65.196" }, { "year": 2024, "month": 3, "day": 18, "hour": 21, "minute": 25, "second": 28, "level": "error", "pid": 26349, "message": "open() \"/usr/share/nginx/html/.env\" failed (2: No such file or directory)", "client": "177.54.158.94", "server": "_", "http_method": "GET", "request": "/.env", "http_version": 1.1, "host": "43.202.65.196" }, { "year": 2024, "month": 3, "day": 18, "hour": 22, "minute": 2, "second": 43, "level": "error", "pid": 26349, "message": "open() \"/usr/share/nginx/html/aaa9\" failed (2: No such file or directory)", "client": "137.184.226.250", "server": "_", "http_method": "GET", "request": "/aaa9", "http_version": 1.1, "host": "43.202.65.196" } ]
Logstash에 대한 설명은 끝!
Filebeat 설치
https://www.elastic.co/guide/en/beats/filebeat/current/setup-repositories.html
GPG Key 가져오기
# rpm --import https://packages.elastic.co/GPG-KEY-elasticsearch
yum repo 저장소 추가
[elastic-8.x]
name=Elastic repository for 8.x packages
baseurl=https://artifacts.elastic.co/packages/8.x/yum
gpgcheck=1
gpgkey=https://artifacts.elastic.co/GPG-KEY-elasticsearch
enabled=1
autorefresh=1
type=rpm-md
filebeat 설치
# yum install filebeat
filebeat.yml
###### INPUT 설정 ######
filebeat.inputs:
###### nginx_access log 설정 ######
- type: log
enabled: true
paths:
- /var/log/nginx/access.log
fields:
server_name: harulife_web
log_name: nginx_access_log
tags: ["harulife-nginx-server", "nginx_access_log"]
scan_frequency: 5s ## 해당 로그를 5초간격으로 스캔한다.
###### nginx_error log 설정 ######
- type: log
enabled: true
paths:
- /var/log/nginx/error.log
fields:
server_name: harulife_web
log_name: nginx_error_log
tags: ["harulife-nginx-server", "nginx_error_log"]
###### message log 설정 ######
- type: log
enabled: true
paths:
- /var/log/messages
fields:
server_name: harulife_web
log_name: message
tags: ["harulife-nginx-server", "messages"]
###### secure log 설정 ######
- type: log
enabled: true
paths:
- /var/log/secure
fields:
server_name: harulife_web
log_name: secure
tags: ["harulife-nginx-server", "secure"]
###### modules를 사용 여부 설정 ######
## 기본적으로 제공되는 모듈이 있지만 모두다 본인이 파싱해서 사용하겠다면 false 한다.
filebeat.config.modules:
path: ${path.config}/modules.d/*.yml
reload.enabled: false
###### 사용할 shards 수 지정 ######
## 사용빈도가 많다면 해당 값을 늘려준다.
setup.template.settings:
index.number_of_shards: 1
###### OUTPUT 설정 ######
output.logstash:
hosts: ["172.31.28.41:5044"]
processors:
- add_host_metadata:
when.not.contains.tags: forwarded
- add_cloud_metadata: ~
- add_docker_metadata: ~
- add_kubernetes_metadata: ~
## 로컬에서 debug 설정
logging.level: debug
logging.to_files: true
logging.files:
path: /var/log/filebeat
name: filebeat
keepfiles: 7
permissions: 0640
세분화된 설명
- type: log ## Type은 뭘로 할건지 설정
enabled: true ## 실행 할건지 말건지 설정
paths: ## 수집할 로그 paths 설정
- /var/log/nginx/access.log
fields: ## 해당 로그에 대해 fields 설정
server_name: harulife_web ## fields.server_name 이라는 필드가 생성되며 해당 필드값은 harulife_web 이 된다.
log_name: nginx_access_log.
tags: ["harulife-nginx-server", "nginx_access_log"] ## tags가 달린채로 데이터를 넘긴다. (tags 필드도 생김)
scan_frequency: 5s ## 해당 로그를 5초간격으로 스캔한다.
위와같이 설정후 이제 Kibana에서 확인하면된다!
'AWS > EC2' 카테고리의 다른 글
ELK(Elasticsearch + Logstash + Kibana + Filebeat)로그 모니터링 - 3 (0) | 2024.03.25 |
---|---|
ELK(Elasticsearch + Logstash + Kibana + Filebeat)로그 모니터링 - 1 (0) | 2024.03.22 |
Kibana process does not have enough permissions to write to config file (0) | 2024.02.28 |
ERROR: Failed to determine the health of the cluster. Unexpected http status [503], with exit code 65 (0) | 2024.02.21 |
EC2 키 페어 관리 (0) | 2024.02.01 |