最近每天的工作之一就是分析nginx流量,对与我来说分析流量主要能帮助我学习如何分辨什么是真实用户请求,什么是异常请求。并且将异常请求中的恶意ip进行禁封也是我的目的之一。

本篇文章总结了我使用过的web日志分析方法

关键词:nginx 日志 access log

系统环境:ubuntu 22.04

一、goaccess

1.简介

GoAccess 是一款开源的且具有交互视图界面的实时 Web 日志分析工具,通过你的 Web 浏览器或者 Unix 系统下的终端程序(terminal)即可访问。

能为系统管理员提供快速且有价值的 HTTP 统计,并以在线可视化服务器的方式呈现。

2.安装

1.源码安装

  • 1.安装依赖
sudo apt install ncurses-devel -y
  • 2.下载源码,编译,安装
wget https://tar.goaccess.io/goaccess-1.6.3.tar.gz
tar -xzvf goaccess-1.6.3.tar.gz
cd goaccess-1.6.3/
./configure --enable-utf8 --enable-geoip=mmdb
make
make install

configure这一步是选择你要启用的功能

Multiple options can be used to configure GoAccess. For a complete up- to-date list of configure options, run ./configure --help
可以同时使用多种选项,使用以下命令查看所有可用的选项
./configure --help

以下是一些常用的选项

选项说明
--enable-debugdebug编译模式
--enable-utf8启用UTF-8支持
--enable-geoip=<legacy|mmdb>启用GeoIP支持. MaxMind's GeoIP is required. legacy will utilize the original GeoIP databases. mmdb will utilize the enhanced GeoIP2 databases.
--with-getlineDynamically expands line buffer in order to parse full line requests instead of using a fixed size buffer of 4096.
--with-openssl为实时html功能提供https支持

2.apt安装(旧编译版本)

sudo apt install goaccess

添加goaccess官方仓库获得最新的goaccess二进制文件

wget -O - https://deb.goaccess.io/gnugpg.key | gpg --dearmor | sudo tee /usr/share/keyrings/goaccess.gpg >/dev/null
echo "deb [signed-by=/usr/share/keyrings/goaccess.gpg arch=$(dpkg --print-architecture)] https://deb.goaccess.io/ $(lsb_release -cs) main" | sudo tee /etc/apt/sources.list.d/goaccess.list
sudo apt update
sudo apt install goaccess

3.使用

单命令分析

这个是在服务器上安装的软件,安装好后只需要在web日志目录键入如下命令即可让goaccess分析你的日志

goaccess access.log

配置生成动态实时的html报告

goaccess创建一个websoket并监听指定端口,使用web访问即可查看动态html

goaccess /var/log/nginx/access.log -o /usr/share/nginx/html/log/index.html --real-time-html --daemonize

服务端常用参数

参数说明
-addr=
指定绑定的IP
--port=指定监听的端口
--daemonize后台运行 (只有当 --real-time-html 使用时有效)
--user-name=指定运行goaccess websocket的用户,该用户需要有输入输入文件的读写权限,Other groups the user belongs to will be ignored. As such it's advised to run GoAccess behind a SSL proxy as it's unlikely this user can access the SSL certificates
--origin=指明当前请求来自于哪个站点,The specified origin should look exactly to the origin header field sent by the browser. e.g., --origin=http://goaccess.io
--pid-file=<path/goaccess.pid>当--daemonize option启用时把后台运行进程的pid写入文件中
--real-time-html开启实时HTML输出
--ssl-cert=<path/cert.crt>ssl证书路径,用于启用https访问,仅适用于编译时开启了--with-openssl选项
--ssl-key=<path/priv.key>ssl私钥路径,仅适用于编译时开启了--with-openssl选项

检查端口是否成功监听

netstat -ltpn4

使用nginx反向代理goaccess

这个玩法应该也是可以实现的,但是我暂时还没有试过,主要针对的是nginx设置了多个虚拟主机并且日志分散在不同的文件中的情况

比如你有a.abc.com,b.abc.com,c.abc.com三个虚拟站点,并且在nginx中设置为分别记录日志到不同的文件,那你又想同时使用goaccess来监控所有站点的流量情况,那你可以使用goaccess开启多个动态实时的html报告,即为不同的日志文件指定不同的端口,然后在nginx中正常监听80,443端口,当访问指定路径或子域名时将请求反向代理到goaccess的端口上。

评价

程序使用C编写,处理大量数据的速度非常快,但是作为一个每天几乎没有真实访客的小站点来说没有这么多数据需要让他处理

如果你网站流量不小,想使用它来统计你网站的UV,PV,UA等统计参数,那它是一个不错的选择

但是如果你像我一样天天只有机器人访问的话,goaccess应该大材小用了,推荐你直接用第三个excle大法

二、awk 命令

这个命令是一个强大的文本处理工具,支持多种匹配规则,切割,拼接文本等等强大的功能

使用它也可以非常便捷的统计出文件中IP访问频率,那个URL访问的最多,等等指标

这里直接引用这篇文章,写的很好

Nginx Access Log日志统计分析常用命令

IP相关统计

  • 统计IP访问量
awk '{print $1}' access.log | sort -n | uniq | wc -l
  • 查看某一时间段的IP访问量(4-5点)
grep "07/Apr/2017:0[4-5]" access.log | awk '{print $1}' | sort | uniq -c| sort -nr | wc -l
  • 查看访问最频繁的前100个IP
awk '{print $1}' access.log | sort -n |uniq -c | sort -rn | head -n 100
  • 查看访问100次以上的IP
awk '{print $1}' access.log | sort -n |uniq -c |awk '{if($1 >100) print $0}'|sort -rn
  • 查询某个IP的详细访问情况,按访问频率排序
grep '104.217.108.66' access.log |awk '{print $7}'|sort |uniq -c |sort -rn |head -n 100

页面访问统计

  • 查看访问最频的页面(TOP100)
awk '{print $7}' access.log | sort |uniq -c | sort -rn | head -n 100
  • 查看访问最频繁的页面(TOP100)
cat  access.log | awk '{print $7}' | sort |uniq -c | sort -rn | head -n 100 
  • 查看页面访问次数超过100次的页面
cat access.log | cut -d ' ' -f 7 | sort |uniq -c | awk '{if ($1 > 100) print $0}' | less
  • 查看最近1000条记录,访问量最高的页面
tail -1000 access.log |awk '{print $7}'|sort|uniq -c|sort -nr|less

按时间请求量统计

  • 每秒请求量统计

统计每秒的请求数,top100的时间点(精确到秒)

awk '{print $4}' access.log |cut -c 14-21|sort|uniq -c|sort -nr|head -n 100
  • 每分钟请求量统计

统计每分钟的请求数,top100的时间点(精确到分钟)

awk '{print $4}' access.log |cut -c 14-18|sort|uniq -c|sort -nr|head -n 100
  • 每小时请求量统计

统计每小时的请求数,top100的时间点(精确到小时)

awk '{print $4}' access.log |cut -c 14-15|sort|uniq -c|sort -nr|head -n 100

性能分析-请求时间

默认nginx的访问日志格式是没有记录请求时间的,若想要分析请求时间,需要在nginx.conf中在log_format 命令后添加$request_time,这样nginx才会在日志中记录

  • 列出传输时间超过 3 秒的页面,显示前20条
cat access.log|awk '($NF > 3){print $7}'|sort -n|uniq -c|sort -nr|head -20
  • 列出php页面请求时间超过3秒的页面,并统计其出现的次数,显示前100条
cat access.log|awk '($NF > 1 &&  $7~/\.php/){print $7}'|sort -n|uniq -c|sort -nr|head -100

蜘蛛抓取统计

  • 统计蜘蛛抓取次数
grep 'Baiduspider' access.log |wc -l
  • 统计蜘蛛抓取404的次数
grep 'Baiduspider' access.log |grep '404' | wc -l

TCP连接统计

  • 查看当前TCP连接数
netstat -tan | grep "ESTABLISHED" | grep ":80" | wc -l
  • 用tcpdump嗅探80端口的访问看看谁最高
tcpdump -i eth0 -tnn dst port 80 -c 1000 | awk -F"." '{print $1"."$2"."$3"."$4}' | sort | uniq -c | sort -nr

评价

非常灵活,速度也非常块,如果你非常熟悉这些命令的话你可以非常快的在大量数据中筛选出你想要的数据,但是还是有一定的上手难度,终究还是比不上图形化呈现出来的效果,建议和goaccess搭配使用

三、excle

以上两种方法都能很好的实现统计功能,但是对于我来说没有多少数据去统计,分析是我主要的目的

这是我目前正在使用的方案,因为网站访问量比较小,我最近也在为nginx不断更新过滤规则,相当于在做waf防火墙的一部分工作,所以我需要逐条请求分析该请求是否为恶意的,是否被规则拦下,为什么没有被拦截等等。

excle功能就更强大了,筛选功能可以满足我的所有需要,比如我需要昨天googlebot 成功抓取的所有页面,或者我需要完整检查一条恶意请求,自定义规则以筛出所有发送恶意请求的IP等。

我是这样做的

  1. 首先在nginx虚拟主机配置中配置好每个站点的日志,这样我可以用不同的文件来分辨不同的请求指向哪里
  2. 其次我写了一个简单的脚本,使用crontab在每天12:01分执行,具体工作就是
  • 把/var/log/nginx目录中被压缩的旧日志删掉
  • 复制后缀为.1的日志到临时目录(也就是昨天的日志)
  • 把临时目录的日志文件进行压缩,并重命名为当前时间
  • 把压缩文件移动到指定的web目录下

这样我可以每天直接访问指定链接来下载到昨日的日志,导入到excle中后即可开始分析

文章作者:四文鱼Max

本文链接:https://blog.awolon.fun/archives/how-to-analyse-access-log.html

许可协议:CC BY-SA 4.0

标签: access log, nginx

添加新评论