长亭百川云 - 文章详情

日志分析系列(外传二):Nginx日志统一化

bloodzer0

50

2024-07-13

本系列故事纯属虚构,如有雷同纯属巧合

为了完成对Nginx服务器的日志分析,小B对Q公司的Nginx日志做了统一化要求。下面是小B在统一化过程中遇到的一些知识点:

Nginx日志与字段解析

Q公司的Nginx版本信息是:1.17.6,使用编译安装,安装过程如下:

yum install zlib-devel.x86_64 zlib.x86_64 openssl.x86_64 openssl-devel.x86_64 pcre-devel.x86_64 -y
  • Nginx原始日志格式:vim /opt/nginx/conf/nginx.conf
    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
  • 原始Nginx的日志为:tail -n 1 -f /opt/nginx/logs/access.log
10.10.10.1 - - [18/Dec/2019:13:27:27 +0800] "GET / HTTP/1.1" 200 612 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.79 Safari/537.36" "-"

>>>>  Nginx日志字段解析

首先小B需要弄明白Nginx日志中每个字段的含义:

>>>>  Nginx获取body信息

在Q公司目前的架构中,使用GET传递参数的方式已经很少了,为了了解攻击者是否在body中嵌入攻击payload以及了解攻击者获取到了什么结果,小B需要采集body的日志信息。

打印request_body

打印request_body有两种方式:一种是使用nginx的模块;另外一种是使用lua编写脚本,如果需要限制nginx收集request_body的长度,最好使用后者。

  • 使用nginx ngx_http_core模块采集request_body

ngx_http_core模块官网地址 http://nginx.org/en/docs/http/ngx\_http\_core\_module.html 中有一段关于采集request_body的说明,内容如下:

The variable’s value is made available in locations processed by the proxy_pass, fastcgi_pass, uwsgi_pass, and scgi_pass directives when the request body was read to a memory buffer.

# 首先修改配置文件,我这里采集的日志只有request_body字段
    log_format  main    $request_body;

此时Nginx的日志为:

使用ngx_http_core模块收集日志有没有办法限制request_body的长度呢?其实是有的。

在nginx配置文件中的http{}里面添加client_max_body_size 1k;即可。

但是这个配置是不允许用户上传超过1K大小的body内容,如果用户需要上传图片,业务可能就无法正常运行,所以不推荐使用此种方法。

我们在这里测试一下ngx_http_core的内容限制:

# 我这里使用1024个A来测试,我的配置是否有效

此时Nginx正常打印出了request_body。

# 如果我们超过1024个字节,就会报错,注意1024个A后面有一个1

此时Nginx无法打印request_body。

  • 使用lua编写脚本采集request_body
# 修改nginx的配置文件

此时Nginx的日志为:

打印response_body

对于response_body我们只有使用lua编写脚本来采集。

  • 修改nginx的配置:vim /opt/nginx/conf/nginx.conf
    server {

此时Nginx的日志为:

request_body与response_body如果在上传文件或者下载文件时,内容会很大,采集全部内容需要考虑对系统、Nginx性能和日志存储等方面的影响。如果采集的body内容太短,也会导致采取不到我们想要的信息,所以根据业务取一个合理阈值。

>>>>  nginx-->syslog-->logstash

小B在测试中与朋友交流得知,可以将nginx日志直接传输到logstash中而不落盘,但是这种方法传输的日志不可靠,并且会对nginx产生性能影响,可以在测试的时候使用。

  • nginx配置文件:vim /opt/nginx/conf/nginx.conf
    log_format  logstash  '$remote_addr - $remote_user [$time_local] "$request" '
  • logstash配置文件:vim /etc/logstash/conf.d/nginx.conf
input {
  • 执行logstash,并查看效果:/usr/share/logstash/bin/logstash -f /etc/logstash/conf.d

统一Nginx日志格式

在完成了调研之后,小B就开始统一所有的日志字段了,为了方便后续查询分析操作,小B决定所有的字段采用JSON格式存盘,并且添加了运维、安全、研发都关注的字段。

  • 修改配置文件:vim /opt/nginx/conf/nginx.conf
# 完整的nginx配置

此时Nginx的日志为:

>>>>  小结一下

  • 对于timestamp参数,可以不使用time_local而使用time_iso8601。

  • 如果运维对于网络的性能有要求,可以考虑使用$tcpinfo_rtt, $tcpinfo_rttvar, $tcpinfo_snd_cwnd, $tcpinfo_rcv_space这些参数可能需要我们给nginx添加其他模块。

踩坑记录

>>>>  启动nginx报错

  • 由于luajit导致的报错
nginx: [alert] detected a LuaJIT version which is not OpenResty's; many optimizations will be disabled and performance will be compromised (see https://github.com/openresty/luajit2 for OpenResty's LuaJIT or, even better, consider using the OpenResty releases from https://openresty.org/en/download.html)

解决方案:卸载原有的luajit

wget https://github.com/openresty/luajit2/archive/v2.1-20190912.tar.gz
  • 由于lua-nginx-module导致的报错
nginx: [error] lua_load_resty_core failed to load the resty.core module from https://github.com/openresty/lua-resty-core; ensure you are using an OpenResty release from https://openresty.org/en/download.html (rc: 2, reason: module 'resty.core' not found:

解决方案:不要使用v0.10.15,使用14就没有问题了

wget https://github.com/openresty/lua-nginx-module/archive/v0.10.14.tar.gz

 

- 参考资料 -

《Nginx安装Lua支持》:http://1t.click/b6ru[](http://mp.weixin.qq.com/s?__biz=MzA5MDk3MjQ0MQ==&mid=2654903349&idx=1&sn=7dfd67ddf7137784383ab9bae2ac7fe4&chksm=8bc9b443bcbe3d55d096bb1a5725726b48cea802a9ab37aa536e64d03aac3feb33803807e4e1&scene=21#wechat_redirect)

《Nginx安装lua-nginx-module》http://1t.click/b6tw

- HISTORY -

《日志分析系列(一):介绍篇》

《日志分析系列(外传一):Nginx透过代理获取真实客户端IP》

相关推荐
关注或联系我们
添加百川云公众号,移动管理云安全产品
咨询热线:
4000-327-707
百川公众号
百川公众号
百川云客服
百川云客服

Copyright ©2024 北京长亭科技有限公司
icon
京ICP备 2024055124号-2