Nginx日志
Nginx是一款自由的、开源的、高性能的HTTP服务器和反向代理服务器;同时也是一个IMAP、POP3、SMTP代理服务器;Nginx可以作为一个HTTP服务器进行网站的发布处理,另外Nginx可以作为反向代理进行负载均衡的实现。
正向代理
特点:客户端非常明确要访问的服务器地址,屏蔽或隐藏了真实客户端信息。
流程:客户端 —> 正向代理服务器–> 远程网站、资源
用途:1.访问无法访问资源;2.做缓存;3.对客户端访问授权,上网进行认证;4.代理可以记录用户访问记录(上网行为管理),对外隐藏用户信息
反向代理
特点:反向代理隐藏了服务器的信息
作用:(1)保证内网的安全,通常将反向代理作为公网访问地址,Web服务器是内网;(2)负载均衡,通过反向代理服务器来优化网站的负载
Nginx日志
日志位置
默认在 /usr/local/nginx/logs
目录下
access.log
访问日志
error.log
错误日志
nginx.conf
配置文件
nginx.conf
日志格式
1 | log_format main '$remote_addr - $remote_user [$time_local] "$request" ' |
这里是通达OA中的默认配置
$remote_addr:请求服务器的客户端IP
$remote_user:客户端用户名称,此项是用来记录用户HTTP的身份验证信息。如果某些网站要求用户进行身份验证,那么这一项就是记录用户的身份信息;
$time_local: 请求的时间与时区;
$request: 用来记录”请求方法/访问路径请求参数/协议”;
$status: 用来记录请求状态;
$body_bytes_sent :记录发送给客户端文件主体内容大小;
$http_referer:用来记录从哪个页面链接访问过来的;
$http_user_agent:记录客户浏览器的相关信息;
$http_x_forwarded_for:用以记录客户端的ip地址;
日志样例
1 | 127.0.0.1 - - [18/Aug/2021:16:09:30 +0800] "GET /inc/new_sms.php?now=1629274170398 HTTP/1.1" 200 33 "http://localhost:88/general/index.php" "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; WOW64; Trident/4.0; SLCC2; .NET CLR 2.0.50727)" "-" |
X-Forwarded-For和 REMOTE_ADDR的区别
REMOTE_ADDR代表着客户端的IP,但是这个客户端是相对服务器而言的,也就是实际上与服务器相连的机器的IP(建立tcp连接的那个),这个值是不可伪造的,如果没有代理的话,这个值就是用户实际的IP值,有代理的话,REMOTE_ADDR会被设置为代理机器的IP值。
正如前面所说,有了代理就获取不了用户的真实IP,由此X-Forwarded-For应运而生,它是一个非正式协议,在请求转发到代理的时候代理会添加一个X-Forwarded-For头,将连接它的客户端IP(也就是你的上网机器IP)加到这个头信息里,这样末端的服务器就能获取真正上网的人的IP了。
🌰🌰🌰
假设用户的请求顺序如下:
网民电脑ip->代理服务器1–>代理服务器2–>目标服务器
REMOTE_ADDR 就是: 代理服务器2的IP值
**X-Forwarded-For **就是:网民电脑IP,代理1的IP,代理2的IP
在这里只有REMOTE_ADDR是可信的,其他从客户端获取的数据都是不可信的,都是可伪造的。
🥚💦
服务器端开了nginx反向代理的时候,每次获取的都是反向代理的IP,需要nginx在配置反向代理的时候做一定设置并且修改代码。
1 | proxy_set_header Host $host; |
反向代理nginx的配置中将REMOTE_ADDR赋给了X-Real-IP,从X-Real-IP中来获取用户的IP
nginx获取post数据
$request_body是nginx的内置变量,可以记录post的数据
1 | 192.168.79.132 - - [25/Aug/2021:14:06:38 +0800] "POST /logincheck.php HTTP/1.1" 200 1000 "http://192.168.77.175:8668/" "Mozilla/5.0 (Windows NT 10.0; WOW64; rv:52.0) Gecko/20100101 Firefox/52.0" "-" "UNAME=admin&PASSWORD=&encode_type=1" |
日志分析
GoAccess
安装
1 | sudo apt-get install goaccess |
安装好的版本是1.4的,够用了后续用centos搭建的时候,再补充编译安装吧。
使用定义好的日志格式在终端输出
1 | goaccess oa.access.log -c |
预定义的选项包括:通用日志格式,联合日志格式,包含虚拟主机,W3C 格式以及亚马逊 CloudFront(分布式下载)。
空格选中,回车继续,q退出,选择通用日志格式(CLF)
终端输出:
终端热键:
F1 或 h主帮助页面。
F5重绘主窗口。
q退出程序,当前窗口或者崩溃了的模块。
o 或 ENTER扩展选中的模块或打开窗口。
0-9 和 Shift + 0激活选中的模块。
c设置或者改变配色方案。
滚动功能:
j在已扩展模块中向下滚动。
k在已扩展模块中向上滚动。
^ f在当前模块中向下滚动一页。
^ b在当前模块中向上滚动一页。
TAB切换模块(向后)。#和官网手册上写的不一样
SHIFT + TAB切换模块(向后)。 #测试无效
g移动到第一个选项或者屏幕顶部。
G移动到第最后一个选项或者屏幕底部。
s给活跃模块的选项排序。
**/**在所有模块中搜索(支持正则)。
n找到下次发生事件的位置。
自定义 日志/日期 格式
GoAccess 可以解析虚拟的任意 Web 日志格式。
配置文件位于:%sysconfdir%/goaccess.conf
或者 ~/.goaccessrc
time-format 参数 time-format 后跟随一个空格符,指定日志的时间格式,包含普通字符与特殊格式说明符的任意组合。他们都由百分号 (%)开始。参考 man strftime
。 %T
或者 %H:%M:%S
.
date-format 参数 date-format 后跟随一个空格符,指定日志的日期格式,包含普通字符与特殊格式说明符的任意组合。他们都由百分号 (%)开始。参考 man strftime
。
log-format 参数 log-format 后跟随一个空格符或者制表分隔符(\t
),用于指定日志字符串格式。
朋友发给我一个他自己写的配置🤡
1 | log_format access_json_log escape=json '{"@timestamp":"$time_local",' |
看起来是个狠人
那就写个配置文件练习一下
1 | time-format %H:%M:%S |
我感觉我这种做法太笨蛋🤓🤓,其实最后一个XFF按照官网手册应该是
~h
的,但不知道为什么写上去就报错,后续再研究一下吧。
特殊格式说明符
%x 匹配 time-format 和 date-format 变量的日期和时间字段。用于使用时间戳来代替日期和时间两个独立变量的场景。
%t 匹配 time-format 变量的时间字段。
%d 匹配 date-format 变量的日期字段。
%v 根据 canonical 名称设定的服务器名称(服务区或者虚拟主机)。
%e 请求文档时由 HTTP 验证决定的用户 ID。
%h 主机(客户端IP地址,IPv4 或者 IPv6)。
%r 客户端请求的行数。这些请求使用分隔符(单引号,双引号)引用的部分可以被解析。否则,需要使用由特殊格式说明符(例如:**%m**, %U, %q 和 %H)组合格式去解析独立的字段。
- 注意: 既可以使用 **%r** 获取完整的请求,也可以使用 **%m**, **%U**, **%q** and **%H** 去组合你的请求,但是不能同时使用。
%m 请求的方法。
%U 请求的 URL。
- 注意: 如果查询字符串在 **%U**中,则无需使用 **%q**。但是,如果 URL 路径中没有包含任何查询字符串,则你可以使用 **%q** 查询字符串将附加在请求后面。
%q 查询字符串。
%H 请求协议。
%s 服务器回传客户端的状态码。
%b 回传客户端的对象的大小。
%R HTTP 请求的 “Referer” 值。
%u HTTP 请求的 “UserAgent” 值。
%D 处理请求的时间消耗,使用微秒计算。
%T 处理请求的时间消耗,使用带秒和毫秒计算。
%L 处理请求的时间消耗,使用十进制数表示的毫秒计算。
%^ 忽略此字段。
%~ 继续解析日志字符串直到找到一个非空字符(!isspace)。
~h 在 X-Forwarded-For (XFF) 字段中的主机(客户端 IP 地址,IPv4 或者 IPv6)。
针对 XFF, GoAccess 使用了一个特殊符号,即由一个波浪号+主机说明符构成,然后紧跟由大括号封装起来的 XFF 限定字段(例:**~h{,"}
**)。
举例如下,
~h{," }
用于解析 “11.25.11.53, 17.68.33.17” 字段由一对双引号,一个逗号和一个空格限定。
输出HTML页面
静态:
1 | sudo goaccess access.log -p .goaccessrc -o /var/www/html/report.html |
这里输出路径开了kali2021,Apache服务。
-p
:指定要使用的自定义配置文件
-o
:输出到指定扩展名文件中(Html、Json、CSV)
动态:
1 | sudo goaccess access.log -p .goaccessrc -o /var/www/html/report.html --real-time-html |
生成实时 HTML 报告的过程和生成静态报告的过程非常相似。实时报告仅仅需要使用参数
--real-time-html
输出结果:
Linux 命令分析
常用命令
xargs
命令的作用,是将标准输入转为命令行参数。
具体用法详见:xargs 命令教程
cut
命令从文件的每一行剪切字节、字符和字段并将这些字节、字符和字段写至标准输出。
- -d :自定义分隔符,默认为制表符。
- -f :与-d一起使用,指定显示哪个区域。
sort
将文本文件内容加以排序。
- [-k field1[,field2]] 按指定的列进行排序。
- -r 以相反的顺序来排序。
uniq
用于检查及删除文本文件中重复出现的行列
-c或–count 在每列旁边显示该行重复出现的次数。
wc
将计算指定文件的行数、字数,以及字节数
- -l或–lines 显示行数。
定位具体的IP地址或文件名
1 | find . access.log | xargs grep "ip" |
查找文件名包含
access.log
以后,对每个文件搜索一次是否包含字符串的内容顺便一说:奇安信的《网络安全应急响应》这里好像写错了
IP驱动
查看访问次数最多的前10个IP
1 | cat oa.access.log | cut -f1 -d " " | sort | uniq -c | sort -k 1 -rn |head -10 |
先把IP字段提取出来,去重排列,计数根据计数结果也就是第一列排序。
顺便再一说:奇安信的《网络安全应急响应》这里少了个
n
参数。
查看每一个IP访问量:
1 | awk '{++S[$1]} END {for (a in S) print a,S[a]}' oa.access.log |
查看特定的ip访问的url
1 | rep ^127.0.0.1 oa.access.log| awk '{print $1,$7}' |
时间驱动
查看xxx时间点这一个小时内IP访问量:
1 | awk '{print $4,$1}' oa.access.log | grep 23/Aug/2021:15 | awk '{print $2}'| sort | uniq | wc -l |
目的驱动(访问的url等)
去掉搜索引擎统计当天的页面:
1 | awk '{print $12,$1}' oa.access.log | grep ^\"Mozilla | awk '{print $2}' |sort | uniq| wc -l |
统计日志文件中的爬虫
1 | grep -E 'Googlebot|Baiduspider' log_file | awk '{ print $1 }' | sort | uniq |
统计相关扫描器
1 | cat log_file | grep -v -E 'python|java|awvs' | sort | uniq -c | sort -r -n | head -n 100 |
统计HTTP状态码
1 | cat log_file |awk '{print $9}'|sort|uniq -c|sort -rn|more |
访问URL统计
1 | cat log_file |awk '{print $7}'|sort|uniq -c|sort -rn|more |
URL访问量统计
1 | cat log_file | awk '{print $7}' | egrep '\?|&' | sort | uniq -c | sort -rn | more |