基于Opensearch的监控:使用fluentbit采集nginx日志

2022-06-15 Views OPENSEARCH FLUENTBIT

背景

小站点刚部署上去,需要做监控,站点配置强制要通过域名访问的,没有通过域名访问的会给500异常。

监控的内容:

  1. 异常访问,比如是否有在试图爆破站点
  2. 异常提醒

站点的部署情况:nginx监听80和443端口,然后转发给后端的wordpress服务。

监控方案

对外暴露的只有nginx,因此只需要监听nginx日志即可。

因为已经搭建有个opensearch && opensearch dashboards应用,所以打算基于opensearch做监控。

nginx日志到opensearch使用的是fluentbit,filebeat也是存在部分版本兼容可以直接输出到opensearch,综合评估后使用的是fluentbit,这里就不做展开。

PS

opensearch 从elasticsearch 7.10.x版本fork出来的一个分支,采用的是Apache License 2.0 开源许可协议,相对于elasticsearch最新的协议更自由。

**使用****opensearch的主要原因**

elasticseach配套的kibana里面的告警及通知功能是额外需要license才能使用的,opensearch配到的opensearch dashboards完全开源免费,个人挺喜欢这两个功能点的,故选择opensearch。

但实际上就目前来说,elasticseach生态会更丰富些。

配置

docker-compose配置

version: "3.7"

services:
  fluent-bit:
    image: fluent/fluent-bit
    volumes:
      - ./fluent-bit.conf:/fluent-bit/etc/fluent-bit.conf
      - ./parsers.conf:/fluent-bit/config/parsers.conf
      - ./GeoLite2-City.mmdb:/fluent-bit/mmdb/GeoLite2-City.mmdb
      - /var/log/nginx/:/var/log/nginx/
    network_mode: host

fluent-bit配置

[SERVICE]
    Flush        5
    Daemon       Off
    Log_Level    info
    Parsers_File parsers.conf

[INPUT]
    name  tail
    path  /var/log/nginx/*.log
    Parser  nginx
    tag  nginx.*

[FILTER]
    Name geoip2
    Match *
    Database /fluent-bit/mmdb/GeoLite2-City.mmdb
    Lookup_key remote
    Record location.lat  remote %{location.latitude}
    Record location.lon  remote %{location.longitude}

[FILTER]
    Name nest
    Match *
    Operation nest
    Wildcard location.*
    Nest_under geo
    Remove_prefix location.      

[OUTPUT]
    Name  opensearch
    Match *
    Host  10.0.0.1
    Port  9200
    Index fluentbit.nginx.log
    Type  _doc
    http_User XXXXXX
    http_Passwd XXXXXX
    tls.verify false
    tls on

上面定义了数据的流转,

  1. 数据从[INPUT]采集并以nginx日志的形式进行解析
  2. 然后第一个[FILTER]分别是将remote字段解析成location.lat和location.lon经纬度,第二个[FILTER]是将经纬度合并成一个能opensearch解析的geo格式
  3. 将最后解析出来的日志输出到opensearch中

parsers配置

这个文件内容官网上的仓库有,做了精简。

参考链接:https://github.com/fluent/fluent-bit/blob/master/conf/parsers.conf

[PARSER]
    Name   nginx
    Format regex
    Regex ^(?<remote>[^ ]*) (?<host>[^ ]*) (?<user>[^ ]*) \[(?<time>[^\]]*)\] "(?<method>\S+)(?: +(?<path>[^\"]*?)(?: +\S*)?)?" (?<code>[^ ]*) (?<size>[^ ]*)(?: "(?<referer>[^\"]*)" "(?<agent>[^\"]*)")
    Time_Key time
    Time_Format %d/%b/%Y:%H:%M:%S %z

这个是定义了nginx日志的格式,使得fluentbit知道如何去解析

图上还有另外一个GeoLite2-City.mmdb文件,用于将ip解析成geo地理位置。主要用于在地图上可视化展示请求来源,需要搭配所用模板才能生效。

opensearch索引模板内容如下:

PUT _index_template/fluentbit_nginx_log
{
  "index_patterns": ["fluentbit.nginx.log"],
  "template": {
    "settings": {
      "number_of_shards": 1
    },
    "mappings": {
      "properties": {
        "geo": {
            "type": "geo_point"
        }
      }
    }
  }
}

总结

效果图如下:

结论

  1. Geo图: 除了国内的请求,还有不少是海外ip进行请求的
  2. 状态分布图:2XX是正常访问,3XX应该是强制走了https的转跳,500这个通过IP请求被nginx拦截了,4XX这个是异常流量
  3. agent分布图:agent为-或者curl的这些的都是异常流量,占比还是有的

参考

geoip2-filter使用

https://docs.fluentbit.io/manual/pipeline/filters/geoip2-filter

https://github.com/fluent/fluent-bit/issues/3109

nest filter使用

https://docs.fluentbit.io/manual/pipeline/filters/nest#example-usage-nest

elastic使用geo

https://www.elastic.co/guide/en/elasticsearch/reference/current/geo-point.html