Server

Giới thiệu Elastic Stack

Elastic Stack (ELK Stack) - là một nhóm phần mềm nguồn mở, dựa trên Elastic nó cho phép tìm kiếm, phân tích, thể hiện trực quan các log thu thập được từ các nguồn, các log này là bất kỳ định dạng nào, ELK là trung tâm phân tích log. Trung tâm log này hữu ích khi trợ giúp xác định các vấn đề phát sinh trên các server, các ứng dụng mà bạn không cần truy cập trực tiếp vào log của từng server, từng ứng dụng. Thường để xây dựng nên trung tâm này dùng đến ELK với các thành phần chính gồm:

  • Elasticsearch - máy chủ lưu trữ và tìm kiếm dữ liệu
  • Logstash - thành phần xử lý dữ liệu, sau đó nó gửi dữ liệu nhận được cho Elasticsearch để lưu trữ
  • Kibana - ứng dụng nền web để tìm kiếm và xem trực quan các logs
  • Beats - gửi dữ liệu thu thập từ log của máy đến Logstash

Cài đặt Elastic Stack (ELK) trên CentOS

Server cài đặt ở đây thực hiện trên CentOS 7, trước tiên cần đảm bảo cài đặt Java (openjdk)

yum update -y
yum install java-1.8.0-openjdk-devel -y
# kiểm tra bằng lệnh
java -version

Bước 1) Cài đặt Elasticsearch CentOS

Thực hiện lệnh:

# thêm repo
echo '[elasticsearch-7.x]
name=Elasticsearch repository for 7.x packages
baseurl=https://artifacts.elastic.co/packages/7.x/yum
gpgcheck=1
gpgkey=https://artifacts.elastic.co/GPG-KEY-elasticsearch
enabled=1
autorefresh=1
type=rpm-md
' > /etc/yum.repos.d/elasticsearch.repo
# cài đặt
yum install elasticsearch -y

# kích hoạt dịch vụ
systemctl enable elasticsearch.service
systemctl start elasticsearch.service
# Mở firewall cổng 9200 cho Es nếu cần
firewall-cmd --permanent --add-port=9200/tcp
firewall-cmd --permanent --add-port=9300/tcp
firewall-cmd --reload

# kiểm tra ES
curl -XGET localhost:9200

Bước 2) Cài đặt Kibana CentOS

Kibana là ứng dụng nền web, nó lắng nghe các truy vấn http gửi đến cổng mặc định 5601, phần này sẽ cấu hình truy cập trực tiếp đến cổng 5601 (cấu hình server.host ở dưới), nếu triển khai thực tế có thể bạn cần một proxy (ví dụ Nginx) để đảm bảo bảo mật, kiểm tra được user có quền truy cập Kibana

yum install kibana -y
systemctl enable kibana

# cấu hình truy cập được từ mọi IP
echo 'server.host: 0.0.0.0' >> /etc/kibana/kibana.yml

systemctl start kibana

firewall-cmd --permanent --add-port=5601/tcp
firewall-cmd --permanent --add-port=5601/tcp
firewall-cmd --reload

Kiểm tra Kibana bằng cách truy cập đến địa chỉ IP server với cổng là 5601, ví dụ máy server đang có địa chỉ 192.168.1.104 thì truy cập đến http://192.168.1.104

Bước 3) Cài đặt Logstash CentOS

Logstash là nơi nhận dữ liệu đầu vào, nó xử lý sau đó chuyển lưu tại Elasticseach. Luồng làm việc của nó phải được cấu hình gồm cấu hình đầu vào input và đầu ra output. Trước tiên cài đặt bằng lệnh:

yum install logstash -y

Cấu hình input: file cấu hình tại /etc/logstash/conf.d/02-beats-input.conf, phần này sẽ cấu hình để nó nhân đầu vào do Beats gửi đến cổng beats, thực hiện lệnh sau để tạo file 02-beats-input.conf

echo 'input {
  beats {
    host => "0.0.0.0"
    port => 5044
  }
}' > /etc/logstash/conf.d/02-beats-input.conf

Cấu hình đầu ra, file cấu hình tại /etc/logstash/conf.d/30-elasticsearch-output.conf, phần này sẽ cấu hình sau khi Logstash nhận dữ liệu đầu vào từ Beats, nó xử lý rồi gửi đến Elasticsearch (localhost:9200). Thực hiện lệnh để tạo file 30-elasticsearch-output.conf

echo 'output {
  elasticsearch {
    hosts => ["localhost:9200"]
    manage_template => false
    index => "%{[@metadata][beat]}-%{[@metadata][version]}-%{+YYYY.MM.dd}"
  }
}' > /etc/logstash/conf.d/30-elasticsearch-output.conf

Ngoài ra nếu muốn lọc các log, định dạng lại các dòng log ở dạng dễ đọc, dễ hiểu hơn thì cấu hình filter tại file /etc/logstash/conf.d/10-syslog-filter.conf, ví dụ sau là cấu hình định dạng lại cấu trúc system log, lấy theo hướng dẫn tại document của Logstash

echo 'filter {
  if [fileset][module] == "system" {
    if [fileset][name] == "auth" {
      grok {
        match => { "message" => ["%{SYSLOGTIMESTAMP:[system][auth][timestamp]} %{SYSLOGHOST:[system][auth][hostname]} sshd(?:\[%{POSINT:[system][auth][pid]}\])?: %{DATA:[system][auth][ssh][event]} %{DATA:[system][auth][ssh][method]} for (invalid user )?%{DATA:[system][auth][user]} from %{IPORHOST:[system][auth][ssh][ip]} port %{NUMBER:[system][auth][ssh][port]} ssh2(: %{GREEDYDATA:[system][auth][ssh][signature]})?",
                  "%{SYSLOGTIMESTAMP:[system][auth][timestamp]} %{SYSLOGHOST:[system][auth][hostname]} sshd(?:\[%{POSINT:[system][auth][pid]}\])?: %{DATA:[system][auth][ssh][event]} user %{DATA:[system][auth][user]} from %{IPORHOST:[system][auth][ssh][ip]}",
                  "%{SYSLOGTIMESTAMP:[system][auth][timestamp]} %{SYSLOGHOST:[system][auth][hostname]} sshd(?:\[%{POSINT:[system][auth][pid]}\])?: Did not receive identification string from %{IPORHOST:[system][auth][ssh][dropped_ip]}",
                  "%{SYSLOGTIMESTAMP:[system][auth][timestamp]} %{SYSLOGHOST:[system][auth][hostname]} sudo(?:\[%{POSINT:[system][auth][pid]}\])?: \s*%{DATA:[system][auth][user]} :( %{DATA:[system][auth][sudo][error]} ;)? TTY=%{DATA:[system][auth][sudo][tty]} ; PWD=%{DATA:[system][auth][sudo][pwd]} ; USER=%{DATA:[system][auth][sudo][user]} ; COMMAND=%{GREEDYDATA:[system][auth][sudo][command]}",
                  "%{SYSLOGTIMESTAMP:[system][auth][timestamp]} %{SYSLOGHOST:[system][auth][hostname]} groupadd(?:\[%{POSINT:[system][auth][pid]}\])?: new group: name=%{DATA:system.auth.groupadd.name}, GID=%{NUMBER:system.auth.groupadd.gid}",
                  "%{SYSLOGTIMESTAMP:[system][auth][timestamp]} %{SYSLOGHOST:[system][auth][hostname]} useradd(?:\[%{POSINT:[system][auth][pid]}\])?: new user: name=%{DATA:[system][auth][user][add][name]}, UID=%{NUMBER:[system][auth][user][add][uid]}, GID=%{NUMBER:[system][auth][user][add][gid]}, home=%{DATA:[system][auth][user][add][home]}, shell=%{DATA:[system][auth][user][add][shell]}$",
                  "%{SYSLOGTIMESTAMP:[system][auth][timestamp]} %{SYSLOGHOST:[system][auth][hostname]} %{DATA:[system][auth][program]}(?:\[%{POSINT:[system][auth][pid]}\])?: %{GREEDYMULTILINE:[system][auth][message]}"] }
        pattern_definitions => {
          "GREEDYMULTILINE"=> "(.|\n)*"
        }
        remove_field => "message"
      }
      date {
        match => [ "[system][auth][timestamp]", "MMM  d HH:mm:ss", "MMM dd HH:mm:ss" ]
      }
      geoip {
        source => "[system][auth][ssh][ip]"
        target => "[system][auth][ssh][geoip]"
      }
    }
    else if [fileset][name] == "syslog" {
      grok {
        match => { "message" => ["%{SYSLOGTIMESTAMP:[system][syslog][timestamp]} %{SYSLOGHOST:[system][syslog][hostname]} %{DATA:[system][syslog][program]}(?:\[%{POSINT:[system][syslog][pid]}\])?: %{GREEDYMULTILINE:[system][syslog][message]}"] }
        pattern_definitions => { "GREEDYMULTILINE" => "(.|\n)*" }
        remove_field => "message"
      }
      date {
        match => [ "[system][syslog][timestamp]", "MMM  d HH:mm:ss", "MMM dd HH:mm:ss" ]
      }
    }
  }
}
' > /etc/logstash/conf.d/10-syslog-filter.conf

Thực hiện lệnh sau để xác định xem cấu hình có lỗi gì không

sudo -u logstash /usr/share/logstash/bin/logstash --path.settings /etc/logstash -t

Có thông báo Config Validation Result: OK. là được

Có thể cần mở cổng 5044 ở trên để nó nhận dữ liệu từ Server khác

firewall-cmd --permanent --add-port=5044/tcp
firewall-cmd --permanent --add-port=5044/tcp
firewall-cmd --reload

Kích hoạt dịch vụ

systemctl enable logstash
systemctl start logstash

Đến đây đã có một ELK hệ thống quản lý logs trung tâm. Việc tiếp theo là cài đặt để các logs từ các Server khác nhau gửi đến trung tâm này.

Bước 4) Cài đặt Beats/Filebeat CentOS

Beats là một nền tảng để gửi dữ liệu vào Logstash, nó có nhiều thành phần nhưu:

  • Packetbeat : lấy / gửi các gói tin mạng
  • Filebeat : lấy / gửi các file log của Server
  • Metricbeat : lấy / gửi các log dịch vụ (Apache log, mysql log ...)
  • ...

Trong phần này sẽ thử dùng Filebeat, thu thập các file log trên Server cài đặt nó, cấu hình để nó gửi tới Logstash

Cài đặt

yum install filebeat -y

File cấu hình tại /etc/filebeat/filebeat.yml, mở ra chỉnh sửa các nội dung sau:

Tìm đến mục Elasticsearch output comment lại để không gửi log thẳng đến Elasticsearch

#output.elasticsearch:
  # Array of hosts to connect to.
  # hosts: ["localhost:9200"]

Tìm đến Logstash output, bỏ các comment để yêu cầu filebeat gửi đến Logstash (địa chỉ dùng là localhost:)

output.logstash:
  # The Logstash hosts
  hosts: ["localhost:5044"]

Ngoài ra tại mục filebeat.inputs: có phần

  paths:
    - /var/log/*.log
    #- c:\programdata\elasticsearch\logs\*

Có nghĩa là nó đang thu thập logs từ các file ở /var/log/*.log, nếu muốn cấu hình thu thập thêm log từ các đường dẫn khác cho các ứng dụng khác không viết log ra /va/log thì tự thêm vào, ví dụ nếu Apache của bạn cài đặt trên máy cấu hình để nó viết log ra /etc/httpd/logs/access_log, để filebeat thu thập thì thêm vào - /etc/httpd/logs/access_log

  paths:
    - /var/log/*.log
    - /etc/httpd/logs/access_log

filebeat có nhiều module tương ứng với loại log nó thu thập, để xem trạng thái các module này thực hiện lệnh

filebeat modules list

Sau đó nếu muốn kích hoạt module nào thì thực hiện theo cú pháp, ví dụ kích hoạt system, apache, mysql ...

filebeat modules enable system
filebeat modules enable apache
filebeat modules enable mysql

Kích hoạt dịch vụ filebeat

systemctl enable filebeat
systemctl start filebeat

Xem log trong Kibana

Đến đây bạn đã có một ELK (một trung tâm quản lý log), nó đang nhận log từ một server gửi đến bằng Filebeat (nếu muốn server khác gửi đến nữa thì cài Filebeat trên server nguồn và cấu hình như trên)

Truy cập vào Kibana theo địa chỉ IP của ELK, ví dụ http://192.168.1.104:5601, nhấn vào phần Discover, chọn mục Index Management của Elasticsearch, bạn sẽ thấy các index có tiền tố là filebeat-*, chính là các index lưu dữ liệu log do Filebeat gửi đến Logstash và Logstash để chuyển lưu tại Elasticsearch. (Nếu có nhiều server gửi đến thì có nhiều index dạng này)

Để truy vấn bằng Kibana ta sẽ tạo các Index patterns, đó là truy vấn thông tin các index có tiền tố là filebeat-, nhấn vào Index patterns của Kibana, bấm vào Create index pattern

Điền filebeat-* vào index pattern, rồi nhấn Next Step

Chọn @timestamp ở mục Time Filter field name, rồi nhấn Create Index Pattern

Cuối cùng, bấm vào Discover, để xem thông tin về các log. Mặc định đang liệt các log 15 phút cuối

Đọc thêm: Cài đặt Filebeat trên Ubuntun

sudo apt update
sudo apt upgrade
wget -qO - https://artifacts.elastic.co/GPG-KEY-elasticsearch | sudo apt-key add -
echo "deb https://artifacts.elastic.co/packages/7.x/apt stable main" | sudo tee /etc/apt/sources.list.d/elastic-7.x.list
sudo apt-get install apt-transport-https
sudo apt update
sudo apt install filebeat
sudo filebeat modules enable system
sudo systemctl start filebeat
sudo systemctl enable filebeat

Sau khi cài đặt, cấu hình để nó gửi log đến Logstash như trên

Tương tự nếu muốn dùng metricbeat thì cài đặt

yum -y install metricbeat

Trong các file cấu hình Beats, có thể thêm vào setup.dashboards.enabled: true để nạp thêm cấu hình thiết lập trực quan cho Kibana

Đăng ký theo dõi ủng hộ kênh