시스템 로그를 로그 파일 자체로 보는 것은 어려운 일입니다. 형식 자체가 사람이 읽기에 적합하지 않고, 너무도 많은 양이 생산되기 때문에 필요한 부분을 찾거나 가공하는 것이 쉽지 않습니다. 그래서 이것을 처리해 주는 여러 가지 방법 중에서, php-syslog-ng를 오래전 젠투 박스에서 이용했습니다. 물론 지금도 약간의 변경을 통해서 사용이 가능하지만, 개발이 중단된 툴은 문제가 생겼을 때 도움을 받기가 용이하지 않습니다. 이것을 대체하기 위해서 로그 분석 툴들 중에서 대중적으로 인기가 높은 ELK Stack을 설치해서 사용해 보고자 합니다.
ELK Stack은 Elasticsearch, Logstash, Kibana의 약자로서 Elasticsearch는 Apache의 Lucene을 바탕으로 개발한 실시간 분산 검색 엔진이며, Logstash는 각종 로그를 가져와 JSON형태로 만들어 Elasticsearch로 전송하고 Kibana는 Elasticsearch에 저장된 Data를 사용자에게 Dashboard 형태로 보여주는 Solution입니다. 즉, 여러 서버에서 생성된 로그 파일을 ELK가 설치된 서버로 보내주면 통합적으로 로그를 수집/가공/시각화할 수 있는 방법입니다.
Installing java
데비안에서 자바-8을 지원하지 않고, elasticsearch는 버전마다 지원하는 자바 버전이 정해져 있으므로, 그것에 따라 자바를 먼저 설치해야 합니다.
데비안에서 자바-8을 설치하는 방법은 자바 기사를 참조하시기 바랍니다.
Elasticsearch
설치
- wget -qO - https://packages.elastic.co/GPG-KEY-elasticsearch | sudo apt-key add -
- echo "deb http://packages.elastic.co/elasticsearch/2.x/debian stable main" | sudo tee -a /etc/apt/sources.list.d/elasticsearch-2.x.list
- sudo apt-get update
- sudo apt-get install elasticsearch
설정
/etc/elasticsearch/elasticsearch.yml
# Set the bind address to a specific IP (IPv4 or IPv6):
#
network.host: localhost
서비스 시작
- sudo systemctl restart elasticsearch
- sudo systemctl daemon-reload
- sudo systemctl enable elasticsearch
서비스 확인
- curl localhost:9200
{
"name" : "Sputnik",
"cluster_name" : "elasticsearch",
"cluster_uuid" : "N4R7btIGRMK8fiN56tbXjA",
"version" : {
"number" : "2.4.1",
"build_hash" : "c67dc32e24162035d18d6fe1e952c4cbcbe79d16",
"build_timestamp" : "2016-09-27T18:57:55Z",
"build_snapshot" : false,
"lucene_version" : "5.5.2"
},
"tagline" : "You Know, for Search"
}
Kibana
설치
- echo "deb http://packages.elastic.co/kibana/4.5/debian stable main" | sudo tee -a /etc/apt/sources.list
- sudo apt-get update
- sudo apt-get install kibana
설정
/opt/kibana/config/kibana.yml에 적습니다.
...
# The host to bind the server to.
server.host: localhost
...
서비스 시작
- sudo systemctl daemon-reload
- sudo systemctl enable kibana
- sudo systemctl start kibana
Nginx 설정
현재 시스템의 설정을 남겨두고 외부에서 kibana를 접근하기 위해서는 다른 포트를 사용해야 합니다. 먼저 kibana를 접근하기 위한 사용자와 암호를 만듭니다.
- sudo -v
- echo "kibanaadmin:`openssl passwd -apr1`" | sudo tee -a /etc/nginx/htpasswd.users
이제 nginx의 설정을 만들어서 기동합니다.
/etc/nginx/sites-available/kibana 정도에 적습니다.
server {
listen 8000;
server_name elk_server_name;
auth_basic "Restricted Access";
auth_basic_user_file /etc/nginx/htpasswd.users;
location / {
proxy_pass http://elk_server_ip:5601;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
}
}
설정을 연결하고 nigx를 새롭게 기동합니다.
- cd /etc/nginx/sites-enabled
- sudo ln -sf /etc/nginx/sites-available/kibana .
- sudo systemctl restart nginx
- sudo ufw allow 8000
Logstash
설치
- echo "deb http://packages.elastic.co/logstash/2.3/debian stable main" | sudo tee -a /etc/apt/sources.list
- sudo apt-get update
- sudo apt-get install logstash
SSL 인증서 생성
ELK 서버와 다른 서버와의 데이터 교환에 SSL/TLS를 사용해서 보안을 강화할 수 있습니다. ELK 서버가 다른 서버로부터의 로그를 받을 때 필요한 인증을 위해서 ELK 자신의 key를 보관할 디렉토리와 인증서를 보관할 디렉토리를 만듭니다.
- sudo mkdir -p /etc/pki/tls/certs
- sudo mkdir /etc/pki/tls/private
사설 IP인 경우
내부 네트워크에 ELK가 동작하고 있다면 IP 주소를 가지고 인증서와 key를 생성해야 합니다. Openssl 설정 파일에서 [ v3_ca ] 섹션에 ELK 서버의 ip 주소를 적어줍니다. 파일 /etc/ssl/openssl.cnf을 수정합니다.
subjectAltName = IP: ELK_server_private_IP
이제 인증서와 키를 만듭니다.
- cd /etc/pki/tls
- sudo openssl req -config /etc/ssl/openssl.cnf -x509 -days 3650 -batch -nodes -newkey rsa:2048 -keyout private/logstash-forwarder.key -out certs/logstash-forwarder.crt
FQDN을 가진 경우
ELK 서버에 대한 FQDN이 있어서 자동으로 공인 ip로 바꾸어 줄 경우에는 아래와 같이 인증서와 key를 만듭니다.
- cd /etc/pki/tls
- sudo openssl req -subj '/CN=ELK_server_fqdn/' -x509 -days 3650 -batch -nodes -newkey rsa:2048 -keyout private/logstash-forwarder.key -out certs/logstash-forwarder.crt
만들어진 logstash-forwarder.crt 파일은 ELK 서버의 logstash에 로그를 보내는 모든 서버에 복사를 해 주어야 합니다.
logstash 설정
SSL 인증을 이용할 경우에는 아래의 ssl로 시작하는 줄을 주석(#)을 제거해 주어야 합니다. 또한 방화벽이 켜져 있는 상항에서는 포트를 열어주어야 합니다. 파일 /etc/logstash/conf.d/02-beats-intput.conf을 수정합니다.
input {
beats {
port => 5044
#ssl => true
#ssl_certificate => "/etc/pki/tls/certs/logstash-forwarder.crt"
#ssl_key => "/etc/pki/tls/private/logstash-forwarder.key"
}
}
파일 /etc/logstash/conf.d/10-syslog-filter.conf를 수정합니다.
filter {
if [type] == "syslog" {
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" ]
}
}
}
파일 /etc/logstash/conf.d/30-elasticsearch-output.conf을 수정합니다.
output {
elasticsearch {
hosts => ["localhost:9200"]
sniffing => true
manage_template => false
index => "%{[@metadata][beat]}-%{+YYYY.MM.dd}"
document_type => "%{[@metadata][type]}"
}
}
테스트
- sudo /opt/logstash/bin/logstash --configtest -f /etc/logstash/conf.d/
Configuration OK
서비스 시작
- sudo systemctl restart logstash
- sudo systemctl enable logstash
Load Kibana Dashboards
- cd ~
- curl -L -O https://download.elastic.co/beats/dashboards/beats-dashboards-1.2.2.zip
- unzip beats-dashboards-*.zip
- cd beats-dashboards-*
- ./load.sh
Load Filebeat Index Template in Elasticsearch
- cd ~
- curl -O https://gist.githubusercontent.com/thisismitch/3429023e8438cc25b86c/raw/d8c479e2a1adcea8b1fe86570e42abab0f10f364/filebeat-index-template.json
- curl -XPUT 'http://localhost:9200/_template/filebeat?pretty' -d@filebeat-index-template.json
"acknowledged" : true
Set Up Filebeat (Add Client Servers)
모니터링하고 싶은 어떤 서버에서 진행해야 하는 사항입니다. 여기서는 ELK 서버에 설치해 보겠습니다. 그래서 인증 부분은 제외하고 진행할 것입니다.
FileBeat 설치
- echo "deb https://packages.elastic.co/beats/apt stable main" | sudo tee -a /etc/apt/sources.list.d/beats.list
- wget -qO - https://packages.elastic.co/GPG-KEY-elasticsearch | sudo apt-key add -
- sudo apt-get update
- sudo apt-get install filebeat
FileBeat 설정
파일 /etc/filebeat/filebeat.yml을 수정합니다.
paths:
- /var/log/auth.log
- /var/log/syslog
# - /var/log/*.log
#- c:\programdata\elasticsearch\logs\*
...
# Type to be published in the 'type' field. For Elasticsearch output,
# the type defines the document type these entries should be stored
# in. Default: log
document_type: log
...
### Logstash as output
logstash:
# The Logstash hosts
hosts: ["localhost:5044"]
bulk_max_size: 1024
...
SSL을 사용하시면 tls 섹션을 설정하셔야 합니다.
Filebeat 서비스 시작
- sudo systemctl restart filebeat
- sudo systemctl enable filebeat
FileBeat 테스트
- curl -XGET 'http://localhost:9200/filebeat-*/_search?pretty'
...
"_index" : "filebeat-2016.10.13",
"_type" : "log",
"_id" : "AVfABMDw2dEYhhFABxTh",
"_score" : 1.0,
"_source" : {
"message" : "Oct 14 05:35:37 ubuntu64 barnyard2[848]: Closing spool file '/var/log/snort/snort.u2.1476359549'. Read 1100 records",
"@version" : "1",
"@timestamp" : "2016-10-13T21:48:38.644Z",
...
Connect to Kibana
이제 웹 브라우저를 열어서 http://ELK_server_ip:5601 을 입력합니다. 화면에서 Settings->Indices->filebeat-* 를 선택한 후에 초록색 네모로 감싸진 별표를 눌러줍니다.
이제 Discover를 누르면 데이터를 받은 것이 보일 것입니다.
다음 사항을 시도해 봅니다:
- Search for "root" to see if anyone is trying to log into your servers as root
- Search for a particular hostname (search for host: "hostname")
- Change the time frame by selecting an area on the histogram or from the menu above
- Click on messages below the histogram to see how the data is being filtered
여기까지 하시면 기본 설치/설정은 끝났습니다. 아래부분은 자세한 사용전에 이미 만들어진 보드를 사용해 보기 위한 목적입니다. |
Loading the Packetbeat Index Template
ELK 서버가 설치된 컴퓨터에서 접속해서 실행합니다.
- cd ~
- curl -O https://raw.githubusercontent.com/elastic/beats/master/packetbeat/packetbeat.template-es2x.json
- curl -XPUT 'http://localhost:9200/_template/packetbeat' -d@packetbeat.template-es2x.json
{"acknowledged":true}
Setting Up Packetbeat (Add Client Servers)
인증서 설치
ELK 서버의 SSL 인증서를 내려받아서 설정합니다.
Packetbeat 설치
이전에 filebeat를 가져올 때 패키지를 가진 서버는 PPA에 등록이 되어 있기 때문에 패키지를 가져와서 설치합니다.
- sudo apt-get update
- sudo apt-get install packetbeat
Packetbeat 설정
파일 /etc/packetbeat/packetbeat.yml을 수정합니다.
### Elasticsearch as output
#elasticsearch:
# Array of hosts to connect to.
# Scheme and port can be left out and will be set to the default (http and 9200)
# In case you specify and additional path, the scheme is required: http://localhost:9200/path
# IPv6 addresses should always be defined as: https://[2001:db8::1]:9200
#hosts: ["localhost:9200"]
...
### Logstash as output
logstash:
# The Logstash hosts
hosts: ["localhost:5044"]
...
Packetbeat 서비스 시작
- sudo service packetbeat restart
- sudo systemctl enable packetbeat
Packetbeat 테스트
...
"_index" : "packetbeat-2016.10.14",
"_type" : "dns",
"_id" : "AVfB0WT3p4jzLQI1sNFN",
"_score" : 1.0,
"_source" : {
"bytes_in" : 33,
"method" : "QUERY",
"client_server" : "ubuntu64",
"ip" : "127.0.1.1",
"type" : "dns",
"client_ip" : "127.0.0.1",
"proc" : "",
"transport" : "udp",
"dns" : {
"additionals_count" : 0,
"answers_count" : 0,
"authorities" : [ {
"class" : "IN",
"data" : "nf1.no-ip.com",
"expire" : 604800,
"minimum" : 1800,
"name" : "duckdns.org",
"refresh" : 10800,
"retry" : 1800,
"rname" : "hostmaster.no-ip.com",
"serial" : 2099391725,
"ttl" : 645,
"type" : "SOA"
} ],
...
Visualizing Data with Kibana
http://ELK_server_ip:5601 로 접근하셔서 Settings->Indices->packetbeat-*를 선택합니다.
Discover->packetbeat-*를 누르면 결과를 볼 수 있습니다.
Dashboard->Load Saved Dashboard 에서 Packetbeat Dashbeat를 선택하시면 결과를 볼 수 있습니다.
Loading the Topbeat Index Template Manually
Topbeat 패키지에 있는 인덱스 템플릿을 ELK 서버로 가져와서 아래와 같이 명령해 줍니다.
- curl -XPUT 'http://localhost:9200/_template/topbeat' -d@topbeat.template.json
{"acknowledged":true}
Set Up Topbeat (Add Client Servers)
SSL 인증서 복사하기
ELK 서버의 인증서를 가져와서 설정해 줍니다.
Topbeat 설치
- sudo apt-get update
- sudo apt-get install topbeat
Topbeat 설정
파일 /etc/topbeat/topbeat.yml을 수정합니다.
...
### Elasticsearch as output
#elasticsearch:
# Array of hosts to connect to.
# Scheme and port can be left out and will be set to the default (http and 9200)
# In case you specify and additional path, the scheme is required: http://localhost:9200/path
# IPv6 addresses should always be defined as: https://[2001:db8::1]:9200
#hosts: ["localhost:9200"]
...
### Logstash as output
logstash:
# The Logstash hosts
hosts: ["localhost:5044"]
...
SSL을 이용할 경우 tls section도 적절히 설정해 줍니다.
Topbeat 서비스 시작
- sudo systemctl restart topbeat
- sudo systemctl enable topbeat
Topbeat 테스트
- curl -XGET 'http://localhost:9200/topbeat-*/_search?pretty'
...
}, {
"_index" : "topbeat-2016.10.14",
"_type" : "process",
"_id" : "AVfB7Cf5p4jzLQI1sOcG",
"_score" : 1.0,
"_source" : {
"beat" : {
"hostname" : "ubuntu64",
"name" : "ubuntu64"
},
"@timestamp" : "2016-10-14T06:41:00.546Z",
"type" : "process",
"count" : 1,
"proc" : {
"cpu" : {
"user" : 0,
"user_p" : 0,
"system" : 0,
"total" : 0,
"start_time" : "14:48"
},
"mem" : {
"size" : 0,
"rss" : 0,
"rss_p" : 0,
"share" : 0
},
"name" : "devfreq_wq",
"pid" : 48,
"ppid" : 2,
"state" : "sleeping",
"username" : "root"
},
"@version" : "1",
"host" : "ubuntu64",
"tags" : [ "beats_input_raw_event" ]
}
...
Visualizing Data with Kibana
http://ELK_server_ip:5601 로 접근하셔서 Settings->Indices->topbeat-*를 선택합니다.
Discover->topbeat-*를 누르면 결과를 볼 수 있습니다.
Dashboard->Load Saved Dashboard 에서 Topbeat Dashbeat를 선택하시면 결과를 볼 수 있습니다.
Application: Nginx
Logstash Patterns: Nginx
ELK 서버로 접근해서 nginx에 대한 새로운 패턴을 만듭니다.
- sudo mkdir /opt/logstash/patterns
파일 /opt/logstash/patterns/nginx에 씁니다.
NGUSERNAME [a-zA-Z\.\@\-\+_%]+
NGUSER %{NGUSERNAME}
NGINXACCESS %{IPORHOST:clientip} %{NGUSER:ident} %{NGUSER:auth} \[%{HTTPDATE:timestamp}\] "%{WORD:verb} %{URIPATHPARAM:request} HTTP/%{NUMBER:httpversion}" %{NUMBER:response} (?:%{NUMBER:bytes}|-) (?:"(?:%{URI:referrer}|-)"|%{QS:referrer}) %{QS:agent}
- sudo chown logstash: /opt/logstash/patterns/nginx
Logstash Filter: Nginx
파일 /etc/logstash/conf.d/11-nginx-filter.conf에 씁니다.
filter {
if [type] == "nginx-access" {
grok {
match => { "message" => "%{NGINXACCESS}" }
}
}
}
주목할 것은 형식을 nginx-access로 지정되었다는 점입니다. 검색을 할 때에 사용할 수 있습니다.
- sudo systemctl restart logstash
Filebeat Prospector: Nginx
Nginx가 실행되고 있는 서버에서 설정해야 합니다. 파일 /etc/filebeat/filebeat.yml에 씁니다.
-
paths:
- /var/log/nginx/access.log
document_type: nginx-access
Using Kibana With Shield
반드시 ssl 설정을 먼저해야 합니다. 그렇지 않으면 plugin을 설치할 수 없습니다.
- sudo bin/kibana plugin --install kibana/shield
...
Transfer complete
Extracting plugin archive
Extraction complete
Optimizing and caching browser bundles...
Plugin installation was unsuccessful due to error "unknown export types injectDefaultVars in plugin shield"
External Resources
- http://www.avidtechnologist.com/blog/?p=31
- https://www.digitalocean.com/community/tutorials/how-to-install-elasticsearch-logstash-and-kibana-elk-stack-on-ubuntu-16-04
- http://linoxide.com/ubuntu-how-to/setup-elk-stack-ubuntu-16/
- http://linoxide.com/tools/configure-elasticsearch-logstash-kibana-ubuntu-15-04/
- https://www.digitalocean.com/community/tutorials/how-to-gather-infrastructure-metrics-with-packetbeat-and-elk-on-ubuntu-14-04
- https://www.digitalocean.com/community/tutorials/how-to-gather-infrastructure-metrics-with-topbeat-and-elk-on-ubuntu-14-04
- https://www.elastic.co/guide/en/beats/topbeat/current/topbeat-template.html
- https://www.elastic.co/guide/en/shield/current/kibana.html#kibana4-user-role