=Start=
缘由:
之前就做过网站访问日志的分析,分别用的是awk和Python,但都比较简单,只是简单选取了IP的维度,还没有区分访问的日期,这样的话如果某个IP在某一天中的访问次数很多,但在其它这一月/年终的其他时候访问次数不多,那在单纯只考虑IP访问次数的情况下是很难确定这样的IP的(而这样的IP又很有可能是爬虫或是攻击者的IP),因此需要加上时间维度,但如果时间维度做的太细,消耗时间太长;如果做的太粗又不容易发现问题;所以,这种情况下需要根据具体情况 & 实际需要来选取粒度。因为我这主要是各人分析用,所以可以使用简单的“以天为单位”来分析,用到了Python和awk进行日志处理,快速方便:
默认的Nginx记录日志的格式为(默认情况下以“空格”为分隔符,但在真实情况下是不利于日志分析的,但这里为了方便起见还是以默认的为示例进行说明):
#log format log_format access '$remote_addr - $remote_user [$time_local] "$request" $status $body_bytes_sent "$http_referer" "$http_user_agent" $http_x_forwarded_for';
从日志中取一些样本进行查看:
# head -3 access.log 120.204.200.21 - - [25/Apr/2015:00:01:04 +0800] "GET /blog/ HTTP/1.1" 200 9082 "-" "DNSPod-Monitor/2.0" - 50.116.30.23 - - [25/Apr/2015:00:01:05 +0800] "GET /blog/feed HTTP/1.1" 304 0 "-" "Superfeedr bot/2.0 http://superfeedr.com - Make your feeds realtime: get in touch - feed-id:128926078" - 209.15.21.92 - - [25/Apr/2015:00:01:26 +0800] "HEAD /blog/ HTTP/1.1" 200 0 "-" "-" -
先用awk取几列看看:
$ cat access.log | awk '$3="-" {print substr($4, 2, 11),$1}' $ cat access.log | awk '$3=="-" {print substr($4, 2, 11),$1}'
用awk对日志进行处理(根据“日期+IP”进行去重):
$ awk '{dict[substr($4, 2, 11)"\t"$1]++}; END{for(item in dict) print item"\t"dict[item]}' access.log
对大公司来说,日志是会按时间段进行切割的(这个几乎是必然的,否则访问日志过大的话容易引起各种问题/隐患),并用处理大数据的方法对日志进行处理(其实这几句话都是废话,我的真实目的是想引出HDFS和简单的Streaming)……
正文:
废话不多说,通过awk对日志进行处理了之后,记录的文件内容格式为:
date IP count
然后通过对处理后的文件再进行分析从而得到我们想要的各种结果:
- #某一天的IP访问总量(PV)
- #某一天的独立IP访问总量(UV)
- #总IP访问量的排序(按IP访问量取top)
- #某一指定IP在每/某一天的访问量(对IP进行去重计数)
- …待添加…
这里需要用到二维数组的知识(如果需要增加更多的分析维度,那就需要多维数组了),但Python里面的二维数组用的少(貌似主要是做科研的用 NumPy 库和一些其他的专用库),去stackoverflow上搜了一堆感觉那种二维数组不是我想要的:
搜索关键字:
- python 二维数组
- python two dimensional array
- python create dynamic two dimensional array
参考链接:
- http://stackoverflow.com/questions/6667201/how-to-define-two-dimensional-array-in-python
- http://stackoverflow.com/questions/3890621/how-does-multiplication-differ-for-numpy-matrix-vs-array-classes/
- http://stackoverflow.com/questions/2397141/how-to-initialize-a-two-dimensional-array-in-python
- http://stackoverflow.com/questions/6673006/how-to-define-a-dynamic-two-dimensional-array-in-python
- Python一维数组转二维数组
- Python创建二维数组
- python的二维数组操作
- 字典推导式 | Stackoverflow about Python
- (译)提高你的Python编码效率
==
之前写另外一个东西的时候用了嵌套的dict代替二维数组(list),挺好用的,这次就依葫芦画瓢,整了个类似的:
#!/usr/bin/env python # coding=utf-8 import sys, re date_ip_x = {} pv_of_date = {} uv_of_date = {} for line in sys.stdin: line = line.strip() res = re.split(" ", line) ip = res[0].strip() date = res[3].strip()[1:12] if date in date_ip_x: if ip in date_ip_x[date]: date_ip_x[date][ip] += 1 else: date_ip_x[date][ip] = 1 else: date_ip_x[date] = {ip:1} for date in date_ip_x: pv_of_date[date] = len(date_ip_x[date]) #pv_of_date = {date:len(date_ip_x[date]) for date in date_ip_x} for date in date_ip_x: uv_of_date[date] = 0 for ip in date_ip_x[date]: uv_of_date[date] += date_ip_x[date][ip] print date_ip_x print pv_of_date print uv_of_date with open("date_ip_count.txt", 'w') as f: for date in date_ip_x: f.write('%s\n' % date) for ip in date_ip_x[date]: f.write('%s\t%d\n' % (ip, date_ip_x[date][ip])) f.write('\n') with open("date_pv_uv.txt", 'w') as f: f.write('\n####PV_of_date####\n') for date in pv_of_date: f.write('%s\t%d\n' % (date, pv_of_date[date])) f.write('\n####UV_of_date####\n') for date in uv_of_date: f.write('%s\t%d\n' % (date, uv_of_date[date]))
根据以上的几个步骤处理了之后,就可以得到我们想要的数据了~~
参考链接:
- python traverse nested dictionary – AOL Search Results
- python – Loop through all nested dictionary values? – Stack Overflow
- dictionary – Iterating over Dictionaries…For Loops in Python – Stack Overflow
- create a double dictionary in python » from the desk of stinkpot
- Generic way to create nested dictionary from flat list in python – Stack Overflow
- Python知识积累_0 | ASPIRE
- 一道思考题_0 | ASPIRE
- Built-in Types — Python 2.7.9 documentation
- Chapter 10. Nested data structures
- data structures – What is the best way to implement nested dictionaries in Python? – Stack Overflow
- dictionary – How to initialize nested dictionaries in Python – Stack Overflow
- nested – Python dictionaries-How to keep the new value from overwriting the previous value? – Stack Overflow
- Sorting dictionary keys in python – Stack Overflow
- Access python nested dictionary items via a list of keys – Stack Overflow
- Python 代码性能优化技巧
- Python高级特性之:List Comprehensions、Generator、Dictionary and set comprehensions
- nested – Python dictionaries-How to keep the new value from overwriting the previous value? – Stack Overflow
- Python Recursive remove nested dict – AOL Search Results
- Some more python recursion examples – SaltyCrane Blog
- Python: How RECURSIVELY remove None values from a NESTED data structure (lists and dictionaries)? – Stack Overflow
- scripting – deleting items from a dictionary while iterating over it – Stack Overflow
- python – Elegant way to remove fields from nested dictionaries – Stack Overflow
- Python nested dict length – AOL Search Results
- recursion – How to get keys from nested dictionary of arbitrary length in Python – Stack Overflow
- python – How to count all elements in a nested dictionary? – Stack Overflow
- Reading/writing a list of nested dictionaries to/from a CSV file (Python) – Stack Overflow
- python – How to write a nested dictionary to json – Stack Overflow
- output – In Python, how do I write the contents of nested dictionaries to a file in a certain format? – Stack Overflow
=END=
《 “用Python和Awk进行日志分析” 》 有 6 条评论
jpcert 的通过追踪事件日志检测横向渗透攻击(第2版)
https://www.jpcert.or.jp/english/pub/sr/Detecting%20Lateral%20Movement%20through%20Tracking%20Event%20Logs_version2.pdf
数据分析指北 – 附录一(数据分析工具漫谈)
https://mp.weixin.qq.com/s/d34k5ArRkiSXF1G8ReEaOg
关于用户画像那些事,看这一文章就够了
https://mp.weixin.qq.com/s/cHinmVC5o9DApFcI5odxNQ
`
用户画像的含义
用户画像的作用
用户画像的内容
用户画像的生产
用户特征的提取即用户画像的生产过程,大致可以分为以下几步:
1. 用户建模,指确定提取的用户特征维度,和需要使用到的数据源。
2. 数据收集,通过数据收集工具,如Flume或自己写的脚本程序,把需要使用的数据统一存放到Hadoop集群。
3. 数据清理,数据清理的过程通常位于Hadoop集群,也有可能与数据收集同时进行,这一步的主要工作,是把收集到各种来源、杂乱无章的数据进行字段提取,得到关注的目标特征。
4. 模型训练,有些特征可能无法直接从数据清理得到,比如用户感兴趣的内容或用户的消费水平,那么可以通过收集到的已知特征进行学习和预测。
5. 属性预测,利用训练得到的模型和用户的已知特征,预测用户的未知特征。
6. 数据合并,把用户通过各种数据源提取的特征进行合并,并给出一定的可信度。
7. 数据分发,对于合并后的结果数据,分发到精准营销、个性化推荐、CRM等各个平台,提供数据支持。
`
访问日志分析脚本(用shell写的)
https://github.com/tabalt/access-log-analysis
MySQL日志安全分析技巧
https://mp.weixin.qq.com/s?__biz=MzA3NzE2MjgwMg==&mid=2448904152&idx=1&sn=1d3c78c678ee7106d4f2a0dd627de903
`
常见的数据库攻击包括弱口令、SQL注入、提升权限、窃取备份等。对数据库日志进行分析,可以发现攻击行为,进一步还原攻击场景及追溯攻击源。
0x01 Mysql日志分析
general query log能记录成功连接和每次执行的查询,我们可以将它用作安全布防的一部分,为故障分析或黑客事件后的调查提供依据。
1、查看log配置信息
show variables like ‘%general%’;
2、开启日志
SET GLOBAL general_log = ‘On’;
3、指定日志文件路径
SET GLOBAL general_log_file = ‘/var/lib/mysql/mysql.log’;
0x02 登录成功/失败
不同的数据库连接工具,它在连接数据库初始化的过程中是不同的。通过这样的差别,我们可以简单判断出用户是通过连接数据库的方式。
另外,不管你是爆破工具、Navicat for MySQL、还是命令行,登录失败都是一样的记录。
在日志分析中,特别需要注意一些敏感的操作行为,比如删表、备库,读写文件等。
关键词:drop table、drop function、lock tables、unlock tables、load_file() 、into outfile、into dumpfile。
敏感数据库表:SELECT * from mysql.user、SELECT * from mysql.func
0x03 SQL注入入侵痕迹
检查方法:
1、检查网站目录下,是否存在一些木马文件:
2、检查是否有UDF提权、MOF提权痕迹
检查目录是否有异常文件
mysql\lib\plugin
c:/windows/system32/wbem/mof/
检查函数是否删除
select * from mysql.func
3、结合web日志分析。
`
30亿日志,检索+分页+后台展示,你是否遇到过更奇葩的需求?
https://mp.weixin.qq.com/s/3CwbmAIqpq8wSYrZaVTqfw