1. 前言
本文主要讲解如何查询和统计网站或网页访问者的IP归属地。
最终成果:
编写一个shell脚本,用于统计网页访问者的地理位置分布情况。
部署前提条件:
- 带公网IP的服务器
- 熟悉基本的命令行操作
- 配置nginx,输出日志文件
- 具有系统的root账号权限
组件介绍:
- 通用的Linux操作系统
- nginx:Nginx是一款面向性能设计的HTTP服务器,也可以用作反向代理、负载平衡器和HTTP缓存。
- awk,sed,grep: Linux文本处理三剑客。
2. 配置http/https服务器的日志文件输出
本文以nginx为例:
先配置nginx日志:
vim /etc/nginx/conf.d/xxx.conf
开启日志功能,类似以下配置:
access_log /var/log/nginx/xxx_server_access.log main;
3. 提取日志文件信息
我们先看看日志文件
cat /var/log/nginx/xxx_server_access.log
nginx默认的日志格式类似于以下内容:
123.123.123.123 - - [15/Jan/2021:04:31:34 -0500] "GET /software/qq.exe HTTP/2.0" 200 8060334 "https://www.linuxrumen.com/test/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:84.0) Gecko/20100101 Firefox/84.0" "-"
可以发现,第一列的内容为客户端的IP地址。
我们使用awk把第一列打印出来,只统计有效的User-Agent数据,然后再排列去重。
cat /var/log/nginx/xx-access.log |grep -v '\"-\" \"-\" \"-\"' |grep -E 'Mozilla|Windows|AppleWebKit|Safari|Chrome|AppleWebKit' |awk '{print $1}' |sort |uniq
你会看到一大波的IP地址,这些IP地址大部分都是正常访问网站的客户IP(不排除肉鸡的行为,如果还想精确过滤,可以在grep的正则表达式中加入URL或者Host等信息)。
得出IP地址列表,如下图:
4. 查询IP归属地
问题来了,知道了IP地址,如何通过命令行查询归属地呢?
查询IP归属地,图片来源于网络
比如,我要查询150.158.115.xx这个IP的归属地,这里的xx就不显示了,随便举例的一个IP地址,执行以下代码:
curl -s "https://www.ip138.com/iplookup.asp?ip=150.158.115.xx&action=2" -H "Host: www.ip138.com" -H "Connection: keep-alive" -H "Upgrade-Insecure-Requests: 1" -H "User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.141 Safari/537.36" -H "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9" -H "Accept-Encoding: gzip, deflate" -H "Accept-Language: zh-CN,zh;q=0.9,en;q=0.8,zh-TW;q=0.7" -H "Cookie: Hm_lvt_7254fb0edf3ade4dbb48f0262d9deb63=1608791174" --compressed |iconv -fgb2312 -t utf-8 |grep 'ASN' |head -n1 |awk -F \" '{ print $4}'
这段代码大概的意思是,通过curl模拟Windows10+Chrome浏览器,到ip138网站查询归属地,然后把返回的网页内容过滤,只提取归属地部分。
我也是通过访问一个http网页,然后使用Wireshark抓包,抓取本机的HTTP GET请求字段,然后再通过curl模拟完成。
现在我们已经知道原理,接下来的工作很简单了,就是把它写成脚本,自动提取,自动查询。
5. 编写根据变量批量查询IP归属地脚本
脚本内容如下 ,由linuxrumen.com开发。
创建nginx_client_location_log.sh
vi nginx_client_location_log.sh
代码如下,自动查看日志中的IP,并查询归属地。假设已经存在日志文件/var/log/nginx/www-access.log
#!/bin/bash
for ip in `cat /var/log/nginx/www-access.log |grep -v '\"-\" \"-\" \"-\"' |grep -E 'Mozilla|Windows|AppleWebKit|Safari|Chrome|AppleWebKit' |awk '{print 1}' |sort |uniq`
do
IP_LOCATION=`curl -s "https://www.ip138.com/iplookup.asp?ip=ip&action=2" -H "Host: www.ip138.com" -H "Connection: keep-alive" -H "Upgrade-Insecure-Requests: 1" -H "User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.141 Safari/537.36" -H "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9" -H "Accept-Encoding: gzip, deflate" -H "Accept-Language: zh-CN,zh;q=0.9,en;q=0.8,zh-TW;q=0.7" -H "Cookie: Hm_lvt_7254fb0edf3ade4dbb48f0262d9deb63=1608791174" --compressed |iconv -fgb2312 -t utf-8 |grep 'ASN' |head -n1 |awk -F \" '{ print 4}'`
echo "ip" "$IP_LOCATION"
done
添加执行权限并执行:
chmod +x nginx_client_location_log.sh && ./nginx_client_location_log.sh
自动批量查询所有IP地址的归属地,输出如下图:
好了,现在已经可以批量查询nginx日志中客户端IP的归属地了。
6. 总结
通过本文,您应该学习到如何在Linux系统中使用脚本和命令行批量查询nginx客户端所在的地址位置了。如果你有更好的shell的基础,你可以对该脚本进行修改,实现更强大的功能。比如我可以结合ss
命令,实时查询连接本服务器的客户地理位置。当然,如果网站已经做了SEO优化,请到相关后台查看更网页详细的受访数据。如果有更好的看法,欢迎留言。
评论前必须登录!
注册