在CentOS7上用Elasticsearch、Logstash、Kibana、Filebeat、nginx搭建系统日志监控

在CentOS7上用Elasticsearch、Logstash、Kibana、Filebeat、nginx搭建系统日志监控

文章目录

  • 在CentOS7上用Elasticsearch、Logstash、Kibana、Filebeat、nginx搭建系统日志监控
    • 0、环境说明
    • 1、安装配置Elasticsearch
    • 2、安装配置Kibana
    • 3、安装配置Logstash
    • 4、安装配置Filebeat
    • 5、查看Kibana的仪表板
    • 6、总结
    • 7、参考文献

0、环境说明

4核CPU,8G内存
CentOS7.7,建立elasticsearch用户并加入sudoer,启动firewalld。
Java1.8.0_221,在\etc\profile中配置$JAVA_HOME和$CLASSPATH
Elasticsearch 7.4.2, Kibana 7.4.2, Logstash 7.4.2, Filebeat 7.4.2
nginx 1.16

注意:如果准备在互联网上使用ELK对接有价值的数据,一定要做好防护,比如给域名加上SSL认证(可以通过Let’s Encrypt,免费且很方便),配置访问端口并绑定主机,通过nginx和htpasswd给Kibana加上登录密码,等等。

1、安装配置Elasticsearch

第一步,安装Elasticsearch的GPG-KEY

sudo rpm --import https:\\artifacts.elastic.co\GPG-KEY-elasticsearch

第二步,添加Elasticsearch的yum库,先用vi打开库文件

sudo vi \etc\yum.repos.d\elasticsearch.repo

再输入以下内容并保存

[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

第三步,安装Elasticsearch

sudo yum install elasticsearch

第四步,编辑Elasticsearch的配置文件

注意:Elasticsearch的配置文件是YAML格式,缩进非常重要,编辑时一定要注意各行的前导空格

sudo vi \etc\elasticsearch\elasticsearch.yml

找到network.host并修改其值为localhost后保存,避免未经授权的外部访问。然后在此文件最后添加JAVA_HOME变量,与环境准备中的内容一致。

network.host: localhost
JAVA_HOME: \usr\java\jdk1.8.0_221

第五步,启动Elasticsearch并设置为开机启动

sudo systemctl start elasticsearch
sudo systemctl enable elasticsearch

第六步,最后用curl检查一下Elasticsearch能否正确响应http请求,如果一切正常Elasticsearch会返回一条JSON消息

curl -X GET "localhost:9200"

2、安装配置Kibana

安装很简单,之前第一部分已经添加过elasticsearch的源,所以此时只要安装和启用kibana即可。

sudo yum install kibana
sudo systemctl enable kibana
sudo systemctl start kibana

接下来是配置,第一步,创建kibana远程访问用户(openssl的参数apr1中1是数字1),按提示输入远程访问密码,openssl会自动给密码加密,存进htpasswd.users文件。

echo "kibanaadmin:`openssl passwd -apr1`" | sudo tee -a \etc\nginx\htpasswd.users

第二步,配置nginx,如果是yum安装的nginx可以打开\etc\nginx\conf.d\default.conf配置文件,并将监听80端口的server替换成如下内容,其中example.com应换成自己的域名或公网IP,保存后重启nginx。

server {
    listen 80;

    server_name example.com;

    auth_basic "Restricted Access";
    auth_basic_user_file \etc\nginx\htpasswd.users;

    location \ {
        proxy_pass http:\\localhost: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;
    }
}

第三步,配置SELinux。默认情况下SELinux是不允许nginx连接kibana的,需要配置如下开关。

sudo setsebool httpd_can_network_connect 1 -P

SELinux配置很复杂,感兴趣的话可以参考这篇文章An Introduction to SELinux on CentOS 7 – Part 1: Basic Concepts | DigitalOcean。遇到nginx的SELinux配置问题也可以通过sudo cat \var\log\audit\audit.log |grep nginxsudo cat \var\log\audit\audit.log |grep nginx|grep denied还有getsebool -a|grep httpd查看出错日志、分析运行情况。
第四步,通过远程地址访问kibana,比如http:\\your_server_ip\status,在弹出框中输入刚才配置的远程用户名和密码,即可登录并查看kibana的仪表板。

3、安装配置Logstash

Logstash可以从不同的数据源收集数据,转换为统一格式,然后输出给另一种数据库。安装Logstash只需要一条命令

sudo yum install logstash

我们可以把Logstash想成一个管道,从源端取得数据,用某种方法处理数据,再把数据传输到目标端,比如Elasticsearch。一个Logstash管道有两个必需元素(或称“插件”)input和output,还有一个可选元素filter。如前所述,input插件从源端消费数据,filter插件处理数据,output插件把数据写入目标端。以下是具体的配置过程。
第一步,创建input的配置文件02-beats-input.conf,准备对接Filebeat。

sudo vi \etc\logstash\conf.d\02-beats-input.conf

把以下内容添加到这个配置文件,用于在TCP端口5044上监听beats

input {
  beats {
    port => 5044
  }
}

第二步,创建filter配置文件10-syslog-filter.conf,给系统日志syslogs添加过滤器

sudo vi \etc\logstash\conf.d\10-syslog-filter.conf

输入以下syslog过滤器配置项,内容来源是官方的Use Logstash pipelines for parsing | Logstash Reference [6.7] | Elastic,这个过滤器可以解析系统日志,把日志格式化,以供Kibana的预定义仪表板使用。

input {
  beats {
    port => 5044
    host => "0.0.0.0"
  }
}
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" ]
      }
    }
  }
}
output {
  elasticsearch {
    hosts => localhost
    manage_template => false
    index => "%{[@metadata][beat]}-%{[@metadata][version]}-%{+YYYY.MM.dd}"
  }
}

第三步,创建output的配置文件30-elasticsearch-output.conf

sudo vi \etc\logstash\conf.d\30-elasticsearch-output.conf

output配置文件的内容见下边的代码列表。这个output把Logstash配置为先读取Beats数据,并建立使用Beats后命名的索引,然后存入运行在localhost:9200上的Elasticsearch中。这个教程中使用的Beat是Filebeat。

output {
  elasticsearch {
    hosts => ["localhost:9200"]
    manage_template => false
    index => "%{[@metadata][beat]}-%{[@metadata][version]}-%{+YYYY.MM.dd}"
  }
}

如果需要为其他应用程序添加以Filebeat为输入端的过滤器,应注意命名filter配置文件时确保这些文件排在input和output配置文件之间,例如在这个教程中,这些文件应该是以02和30之间的两个数字开头。
现在可以用以下测试一下Logstash的配置。

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

如果配置文件中没有语法错误, 过几秒output会显示Configruation OK。如果没看到这句话,就需要回头检查output的配置文件,改正错误并更新配置。
如果配置文件测试通过了,就可以启动Logstash并配置成开机启动,如下所示。

sudo systemctl start logstash
sudo systemctl enable logstash

到这里Logstash就配置完毕并能成功运行了,接下来安装Filebeat。

4、安装配置Filebeat

Elastic技术栈使用一些称作Beats的轻量级数据装载工具来从各种源头收集数据,然后传输到Logstash或Elasticsearch。Beats包括Filebeat、Auditbeat、Heartbeat等等,在这个教程中我们用Filebeat把本地的日志传到Elastic。Filebeat的安装命令如下。

sudo yum install filebeat

接下来是配置Filebeat以连接Logstash。第一步,我们将修改Filebeat带的示例配置文件,方法如下。注意,Filebeat的配置文件和Elasticsearch一样也是YAML,空格缩进是关键内容,要确保空格数一致。

sudo vi \etc\filebeat\filebeat.yml

Filebeat支持多种输出 ,但我们一般会直接把事件数据发送到Elasticsearch或Logstash去处理,此例中我们使用Logstash,这样Filebeat就不需要直连Elasticsearch了,所以把Filebeat向Elasticsearch的输出关掉。关闭方法如下,找到output.elasticsearch一节,用#符号注释掉。

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

第二步,打开Filebeat向Logstash的输出,其中5044端口是我们之前在Logstash的input部分指定的。

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

第三步,我们用Filebeat模块来扩展Filebeat的功能,本文使用system模块,它可以收集和解析各种通用Linux系统日志服务生成的日志。system模块启动方法如下。

sudo filebeat modules enable system

还可以用sudo filebeat modules list展示所有启用和禁用的模块,命令输出结果如下。

Enabled:
system

Disabled:
apache2
auditd
elasticsearch
haproxy
icinga
iis
kafka
kibana
logstash
mongodb
mysql
nginx
osquery
postgresql
redis
suricata
traefik

默认配置下,Filebeat会使用默认路径来获取系统日志和认证日志,在这个教程里,我们不需要修改配置文件。我们可以打开system模块的配置文件\etc\filebeat\modules.d\system.yml查看它的参数。
第四步,把索引模板载入Elasticsearch。Elasticsearch索引是一组具有类似特征的文档,索引由名称来识别,在索引上执行各种操作的时候也涉及名称。新索引建立的时候,索引模板会自动应用。以下命令可以载入模板。

sudo filebeat setup --template -E output.logstash.enabled=false -E 'output.elasticsearch.hosts=["localhost:9200"]'

命令执行完后输出如下。

Loaded index template

Filebeat自带Kibana仪表板样例,可用作在Kibana中可视化Filebeat数据。在使用仪表板以前,我们需要创建索引样式并把仪表板载入到Kibana。仪表板载入后,Filebeat会连接到Elasticsearch去检查版本信息。为了在Logstash启用后载入仪表板,我们需要手动禁用Logstash的输出,并启用Elasticsearch的输出,命令如下。

sudo filebeat setup -e -E output.logstash.enabled=false -E output.elasticsearch.hosts=['localhost:9200'] -E setup.kibana.host=localhost:5601

以上命令执行结果和以下文本框的内容类似。

. . .
2018-12-05T21:23:33.806Z        INFO    elasticsearch\client.go:163     Elasticsearch url: http:\\localhost:9200
2018-12-05T21:23:33.811Z        INFO    elasticsearch\client.go:712     Connected to Elasticsearch version 6.5.2
2018-12-05T21:23:33.815Z        INFO    template\load.go:129    Template already exists and will not be overwritten.
Loaded index template
Loading dashboards (Kibana must be running and reachable)
2018-12-05T21:23:33.816Z        INFO    elasticsearch\client.go:163     Elasticsearch url: http:\\localhost:9200
2018-12-05T21:23:33.819Z        INFO    elasticsearch\client.go:712     Connected to Elasticsearch version 6.5.2
2018-12-05T21:23:33.819Z        INFO    kibana\client.go:118    Kibana url: http:\\localhost:5601
2018-12-05T21:24:03.981Z        INFO    instance\beat.go:717    Kibana dashboards successfully loaded.
Loaded dashboards
2018-12-05T21:24:03.982Z        INFO    elasticsearch\client.go:163     Elasticsearch url: http:\\localhost:9200
2018-12-05T21:24:03.984Z        INFO    elasticsearch\client.go:712     Connected to Elasticsearch version 6.5.2
2018-12-05T21:24:03.984Z        INFO    kibana\client.go:118    Kibana url: http:\\localhost:5601
2018-12-05T21:24:04.043Z        WARN    fileset\modules.go:388  X-Pack Machine Learning is not enabled
2018-12-05T21:24:04.080Z        WARN    fileset\modules.go:388  X-Pack Machine Learning is not enabled
Loaded machine learning job configurations

第五步,启动Filebeat并设置其为开机启动。

sudo systemctl start filebeat
sudo systemctl enable filebeat

如果之前的Elastic技术栈配置正确,现在Filebeat应该会开始向Logstash装载系统日志和认证日志的数据了,之后这些数据会被载入到Elasticsearch。下面这条查询Filebeat的命令可以用来验证Elasticsearch确实收到了这些数据。

curl -X GET 'http://localhost:9200/filebeat-*/_search?pretty'

以上命令的执行结果和下边文本框的内容类似。

{
  "took" : 1,
  "timed_out" : false,
  "_shards" : {
    "total" : 3,
    "successful" : 3,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : 3225,
    "max_score" : 1.0,
    "hits" : [
      {
        "_index" : "filebeat-6.5.2-2018.12.05",
        "_type" : "doc",
        "_id" : "vf5GgGcB_g3p-PRo_QOw",
        "_score" : 1.0,
        "_source" : {
          "@timestamp" : "2018-12-05T19:00:34.000Z",
          "source" : "/var/log/secure",
          "meta" : {
            "cloud" : {
. . .

如果命令执行后,输出结果显示命中0条,说明Elasticsearch并没有载入要搜索的索引对应的日志,这时我们就需要检查之前的设置中的错误了。如果我们得到了期望的输出结果,就可以继续本教程的下一步,进一步熟悉Kibana的仪表板

5、查看Kibana的仪表板

第一步,用浏览器打开Elastic服务的地址,输入在第2部分中设置的登录凭证,我们就打开了Kibana的主页。
在CentOS7上用Elasticsearch、Logstash、Kibana、Filebeat、nginx搭建系统日志监控_第1张图片
第二步,点击左边导航条上的Discover链接,在打开的Discover页上选择预定义的filebeat-*索引样式,查看Filebeat的数据,默认情况是展示过去15分钟的所有系统日志,我们能看到一个带日志事件数的直方图,还有一些日志消息。在这里我们可以搜索和浏览这些日志,定制仪表板。此时,因为我们只从自己的Elastic服务器收集了系统日志,所以并没有很多可展示的内容。
在CentOS7上用Elasticsearch、Logstash、Kibana、Filebeat、nginx搭建系统日志监控_第2张图片
第三步,点击左边导航条上的Dashboard链接,在打开的Dashboard页内搜索Filebeat System仪表板,然后就可以打开Filebeat的system模块附带的示例仪表板,比如查看基于系统日志的统计信息。
在CentOS7上用Elasticsearch、Logstash、Kibana、Filebeat、nginx搭建系统日志监控_第3张图片
在此处还可以查看sudo命令的使用情况,SSH登录信息,等等。Kibana还有许多其他功能,比如图形化、过滤,可以随意探索。

6、总结

通过这个教程,我们学习了在服务器上安装和设置Elastic技术栈,还用这个Elastic服务器收集并分析了系统日志。
最后提个建议:为了提高Beats传送到Logstash的数据(各种类型的日志、建立过索引的文档等)的可用性,我们应该用Logstash的过滤器解析并结构化这些数据,把它们转换成一致的格式,以利Elasticsearch的读取。

7、参考文献

1.How To Install Elasticsearch, Logstash, and Kibana (Elastic Stack) on CentOS 7 | DigitalOcean
2.Elasticsearch Reference | Elastic

你可能感兴趣的:(ELK,运维)