摘要: 本文介绍了如何配置DDoS日志分析功能,结合实际场景详细介绍了如何使用日志对DDoS访问与攻击日志进行分析与图形化操作。
概述
本文介绍了如何配置DDoS日志分析功能,结合实际场景详细介绍了如何使用日志对DDoS访问与攻击日志进行分析与图形化操作。
前提配置
刚进入DDoS高防控制台的全量日志下,在界面引导下开通日志服务并授权操作后。就可以给特定的网站启用日志分析功能了。
分析界面介绍
当选择某一个网站点击日志分析
时,会展示基于这个网站的日志分析界面:
这个查询界面大致可以划分为如下几个功能区域:
1. 日志库与项目信息
当为特定DDoS的防护网站打开了日志分析的功能时, DDoS会实时将相关网站的访问和防护日志导入到您拥有的日志服务的专属日志库中。默认打开日志分析的网站的日志都会集中放到这一个日志库中。
专属的日志库名字是ddos-pro-logstore
,存放于日志服务的项目ddos-pro-project-阿里云账户ID
中。国内项目在杭州区域,国外项目在香港区域。
当选择特定网站时,区域#4查询框
会自动填入特定的查询语句,如:
matched_host: aliyun.com
来展示属于这个网站的日志。关于查询语句框的具体信息可以参考后面内容。
2. 日志时间范围选择器
点击这里可以选择要分析的日志的时间范围,可以是相对时间,也可以使整点时间,或者特定时间:
注意:可以查询的最久日志由日志库的周期决定,日志库默认的周期是3天(3天前的日志会自动删除),默认情况下只能查询到过去3*24小时的日志。如果需要查询更长时间的日志,可以参考这里。
对于选择器的每个选项的更详细的介绍,可以参考这里
3. 辅助配置工具栏
这里是查询操作后的一些辅助工具。包括:
另存为快速查询:将当前区域#4查询框
的内容保存并赋予名字,以便复用(如何如何需要在日志服务的高级管理界面中操作)。也可以用于配置告警时使用。
另存为告警:这里是配置告警的控制界面,基于某一个已经保存的快速查询
进行报警配置,具体请参考这里。
4. 查询语句输入框
这里基于已经配置的时间范围内,对日志进行搜索。如果保留空白或者输入*
表示不做任何过滤,查询选择时间范围内的所有日志。
默认选择一个网站的分析日志
时,会自动输入当前选择的网站(例如aliyun.com)的查询条件:
matched_host: aliyun.com
这里可以按照语法自由输入,进行全文搜索或者基于字段的搜索,查询框支持换行(Ctrl + Enter)、语法高亮和提示功能等。
4.1 全文搜索
全文搜索,不需要指定特定的字段,直接输入关键字(可以用双引号括起来),多个关键字以空格(或and)分隔即可,
示例1:多关键字查询
这里搜索包含所有www.aliyun.com
和error
的日志。例如:
www.aliyun.com error
也可以是:
www.aliyun.com and error
示例2:多关键字或
条件查询
这里搜索所有包含www.aliyun.com
并且包含error
或者404
的日志。例如:
www.aliyun.com and (error or 404)
示例3:前缀查询
这里搜索所有包含www.aliyun.com
并且包含failed_
开头关键字。例如:
www.aliyun.com and failed_*
注意:查询只支持后缀加*
,不支持前缀*
,如:*_error
。
4.2 字段搜索
基于特定字段的更精准的搜索,并且支持数值类型字段的比较,主要形式是字段:值
或者字段 >= 值
这种形式,之间用and
、or
等进行组合。也可以和全文搜索组合使用(也是通过and
、or
等连接)。
示例1:多字段查询
这里搜索所有www.aliyun.com
被CC攻击的日志:
matched_host: www.aliyun.com and cc_blocks: 1
如果要搜索某个客户端1.2.3.4
对网站www.aliyun.com
的所有错误404的访问日志,可以这样:
real_client_ip: 1.2.3.4 and matched_host: www.aliyun.com and status: 404
注意:这里使用的字段matched_host
、cc_blocks
、real_client_ip
和status
等都是DDoS访问与攻击日志的字段,详细的字段列表和信息,可以参考这里
示例2:数值字段查询
这里搜索所有慢请求日志(响应时间超过5秒):
request_time_msec > 5000
也支持区间查询,查询响应时间大于5秒且小于等于10秒(左开右闭)的日志:
request_time_msec in (5000 10000]
等价于:
request_time_msec > 5000 and request_time_msec <= 10000
示例3:字段存在与否查询
针对特定字段的存在与否进行查询:
- 查询存在
ua_browser
字段的日志:ua_browser: *
- 查询不能存在
ua_browser
字段的日志:not ua_browser: *
4.3 完整字段
DDoS网站访问日志和攻击日志具体有哪些字段可以进行查询,它们的含义、类型、格式以及可能的值有哪些,可以参考这里
4.4 详细的查询语法
关于完整的查询语法,例如操作符关键字、优先级、如何查询包含引号的字符等,可以参考这里
5. 符合条件的日志分布
这里一目了然的展示了符合查询时间和查询语句的日志的时间分布。以时间为横轴,数量纵轴的柱状图形式展示。下方展示了查询的日志总数。
注意:可以在柱状图上滑动以选择更小范围的时间区域,时间选择器
会自动更新为选择的时间范围,并刷新结果。
6. 分页的日志详细信息
这里以分页的形式展示了每一条日志的详细内容,包括时间、内容以及其中的各个字段。可以对列进行排序、对当前页进行下载,也可以点击#6.1 下载与展示列调整
中齿轮按钮,选择特定的字段进行展示等。
注意:可以在页面中点击相应字段的值(或者分词),那么会自动在#4 查询语句输入框
中自动加入相应的搜索条件。
例如鼠标点击request_method: GET
中的值GET
,会自动给搜索框加入如下语句:
原来的搜索语句 and request_method: GET
7. 字段列表
字段列表展示了日志库的所有字段,它们的含义、类型、格式以及可能的值有哪些,可以参考这里。
点击每一个字段旁的眼睛按钮,可以展开对这个字段的各个值的分布。例如点击content_type
将会展示来自当前查询下请求内容类型的分布:
可以点击链接approx_distinct
,展示这个字段有多少个唯一的值。也可以点击上图的小图标,展示具体的分布信息。
如果选择的是数值型的字段,如status
,则提供最大最小等值的快捷统计方式:
注意:以上操作会切换查询界面为统计界面并展示结果,我们会在后面内容介绍。
统计界面介绍
当在查询界面中的#7. 字段列表
中点击某一个字段的快捷统计,会将当前查询界面切换为统计界面,同时注意到,#4. 查询语句输入框
也会动被修改一个较长的语句。
以查询界面中的#6. 字段列表
中选择某一列如content_type
点击approx_distinct
链接展示的统计为例,如下:
这个统计界面大致可以划分为如下几个功能区域:
可以看到,与查询界面相比,主要的变化部分就是:#4. 查询与统计语句与输入框
以及6#. 统计工具栏
和#7. 统计图表展示区
。
其他部分并没有变化。
查询与统计语句输入框
以查询界面中的#6. 字段列表
中选择某一列如content_type
点击approx_distinct
链接展示的统计为例。查询语句会从原来的查询语句如:
matched_host: "www.aliyun.com"
变成:
matched_host: "www.aliyun.com" | select count(1) as pv , content_type from log group by content_type order by pv desc limit 10
换行展示为:
matched_host: "www.aliyun.com" |
select count(1) as pv , content_typegroup by content_typeorder by pv desc limit 10
可以看到,这里用一个|
进行分割,前面部分是查询,后面部分是统计。这里的逻辑是:先对选择时间范围内的日志进行查询,满足条件的日志再会根据统计语句的进行统计。
其中查询的部分的用法可以参考前面的内容。这里着重介绍统计的部分。
这里统计的语法其实是一个近乎标准的SQL/92语法。以这里的例子为例,其实就是对字段content_type
进行分组group by
,计算各种值的总数,按照个数排序,并展示前10个。
统计SQL的一些特殊约定
约定1:from log
这里可以看到,并没有SQL标准里面的from 表格名
语句,其实可以写上:from log
,但一般省略:
matched_host: "www.aliyun.com" |
select count(1) as pv , content_typefrom log -- 一般这行可以不写group by content_typeorder by pv desc limit 10
约定2:limit 100
这里可以看到有一个limit 10
,表示获取前10条,如果不写,那么默认其实是返回前100条,也就相当于自动写上了limit 100
日志时间的操作
每一条DDoS日志都有一个字段time
表示日志的时间,其格式如2018-05-31T20:11:58+08:00
。分别是年-月-日T时:分:秒+时区
,这里的时区是UTC+8
区,也就是北京时间。
同时,每条日志都有一个内置字段:__time__
,也表示这条日志的时间,以便在统计时进行基于时间的计算。其格式为Unix时间戳,本质是一个自从1970-1-1 0:0:0 UTC时间开始的累计过去的秒数。因此实际使用时,经过可选的计算后,还是要经过格式化才可以展示。
示例1:选择并展示时间
这里在特定时间范围内,选择网站www.aliyun.com
被CC攻击的最新10条日志,展示其中时间、来源IP以及访问客户端,直接使用字段time
:
matched_host: www.aliyun.com and cc_blocks: 1
| select time, real_client_ip, http_user_agentorder by time desclimit 10
示例2:计算时间
如果想要知道CC攻击已经过去几天了,可以使用__time__
进行计算:
matched_host: www.aliyun.com and cc_blocks: 1
| select time, round((to_unixtime(now()) - __time__)/86400, 1) as "days_passed", real_client_ip, http_user_agentorder by time desclimit 10
结果如下:
SQL说明:这里用round((to_unixtime(now()) - __time__)/86400, 1)
,先用to_unixtime
将now()
获取的时间转化为Unix时间戳,再与内置时间字段__time__
相减,获得已经过去的时间秒数,最后/86400
(一天的总秒数),再用函数round(data, 1)
圆整为小数点后1位数的值。就得到了每条攻击日志,距离现在已经过去了几天。
示例3:基于特定时间分组统计
如果想知道特定时间范围内,某个网站每天被CC攻击的趋势如何,使用如下SQL:
matched_host: www.aliyun.com and cc_blocks: 1
| select date_trunc('day', __time__) as dt, count(1) as PV group by dt order by dt
得到如下的结果:
然后可以在图标工具栏
中选择线图
将结果以折线图的形式展示:
SQL说明:这里使用计算的内置时间字段__time__
,传给函数date_trunc('day', ..)
进行时间按天对齐,将每条日志分组到了其所属的天的分区中进行统计总数(count(1)),并按照分区时间块排序。
函数date_trunc
第一个参数提供更多其他单位进行对齐,包括second
、miniute
、hour
、week
、month
、year
等,更多请参考这里
图表说明:这里配置分组的时间为X轴,各个分组内总数的值为Y轴即可。
示例4:基于时间分组统计
如果想知道更灵活的分组下时间规律,例如某个网站每5分钟被CC攻击的趋势如何,就需要进行数学计算,可以使用如下SQL:
matched_host: www.aliyun.com and cc_blocks: 1
| select from_unixtime(__time__ - __time__% 300) as dt, count(1) as PV group by dt order by dt limit 1000
得到如下的结果:
然后可以在图标工具栏
中选择线图
将结果以折线图的形式展示:
SQL说明:这里使用计算的内置时间字段计算__time__ - __time__% 300
(同时使用函数from_unixtime
做了格式化),将每条日志分组到了一个5分钟(300秒)的分区中进行统计总数(count(1)),并按照分区时间块排序,获得前1000条(相当于选择时间内的前83小时的数据)。
图表说明:这里配置分组的时间为X轴,各个分组内总数的值为Y轴即可。
更多时间相关的函数
更多关于时间解析的函数,例如将一个时间格式转化为另外一个格式,需要使用date_parse
与date_format
,可以参考这里
客户端IP相关的统计
DDoS日志中有反映真实客户端IP的字段real_client_ip
,但某些情况下无法拿到用户真实IP时(例如用户通过代理并跳转头中IP有误的情况),可以直接使用直连客户端IP的字段remote_addr
来代替。
示例1:攻击者国家分布
这里对某个网站进行CC攻击的来源国家分布:
matched_host: www.aliyun.com and cc_blocks: 1
| SELECT ip_to_country(if(real_client_ip='-', remote_addr, real_client_ip)) as country, count(1) as "攻击次数" group by country
得到结果:
在图标工具栏中选择地图,并配置好域后,可以得到一张基于世界地图的分布图:
SQL说明:这里先用函数if(condition, option1, option2)
来选择字段real_client_ip
或者real_client_ip
(当real_client_ip
为-
时)。然后对结果IP传给函数ip_to_country
得到这个IP对应的国家信息。
图表说明:这里选择世界地图
,并配置国家对应的统计结果字段为country
,反应颜色深度的列是攻击次数
即可。
示例2:访问者省份分布
如果期望获得更细腻度的基于省份的分布,可以使用另外一个函数ip_to_province
,例如:
matched_host: www.aliyun.com and cc_blocks: 1
| SELECT ip_to_province(if(real_client_ip='-', remote_addr, real_client_ip)) as province, count(1) as "攻击次数" group by province
得到结果:
在图标工具栏中选择地图
后选中国地图
,可以得到:
SQL说明:这里使用了另外一个IP函数ip_to_province
来获得一个IP的所属省份。注意:如果是国外的IP,依然会尝试转化为其国家所属省份(州),但在选择中国地图展示时,会无法展示出来。
示例3:攻击者热力分布
如果期望获得一张攻击者的热力图,可以使用另外一个函数ip_to_geo
,例如:
matched_host: www.aliyun.com and cc_blocks: 1
| SELECT ip_to_geo(if(real_client_ip='-', remote_addr, real_client_ip)) as geo, count(1) as "攻击次数" group by geolimit 10000
得到结果:
然后配置地图可以得到:
SQL:这里使用了另外一个IP函数ip_to_geo
来获得一个IP的所在经纬度,并获取前1万条。
图表说明:这里选择地图
后选高德地图
,配置对应属性后,选择显示热力图
即可。
更多IP地理函数
基于IP的更多解析功能,例如获得IP所属运营商ip_to_provider
、判断IP是内网还是外网ip_to_domain
等,可以参考这里。
更多SQL统计操作
更多关于SQL的统计操作,例如更多SQL函数(字符串、正则表达式等)、分组(group by)、分组后查询(having)等,可以参考这里。
图表操作介绍
上面已经介绍如何在SQL统计结果上,选择表格
(默认)展示结果;选择线图
展示趋势;选择地图
展示分布。日志服务还提供更多丰富的图表进行展示,包括如下:
关于每个图表如何具体配置,可以参考这里
日志字段
字段 | 名称 | 例子 | 备注 |
---|---|---|---|
__topic__ | 主题 | 固定为ddos_access_log | |
body_bytes_sent | 请求发送Body的大小(字节) | 2 | |
content_type | 内容类型 | application/x-www-form-urlencoded | |
host | 源网站 | api.zhihu.com | |
http_cookie | 请求cookie | k1=v1;k2=v2 | |
http_referer | 请求referer | http://xyz.com | 没有则为- |
http_user_agent | 请求User Agent | Dalvik/2.1.0 (Linux; U; Android 7.0; EDI-AL10 Build/HUAWEIEDISON-AL10) | |
http_x_forwarded_for | 通过代理跳转IP | - | |
https | 是否https | true | 可能值:true、false |
matched_host | 匹配的配置的源站(可能是泛域名) | *.zhihu.com | 未匹配则为- |
real_client_ip | 访问客户的真实IP | 1.2.3.4 | 获取不到时为- |
isp_line | 线路信息 | 电信 | BGP、电信、联通等 |
remote_addr | 请求连接的客户端IP | 1.2.3.4 | |
remote_port | 请求连接的客户端端口号 | 23713 | |
request_length | 请求长度(字节) | 123 | |
request_method | 请求的HTTP方法 | GET | |
request_time_msec | 请求时间(微秒) | 44 | |
request_uri | 请求路径 | /answers/377971214/banner | |
server_name | 匹配到的host名 | api.abc.com | 没有匹配到则为default |
status | HTTP状态 | 200 | |
time | 时间 | 2018-05-02T16:03:59+08:00 | |
cc_action | CC防护策略行为 | close | 可能的值: none、challenge、pass、close、captcha、wait、login、n等 |
cc_blocks | 表示CC防护是否阻止 | 1 | 1-阻止,其他表示通过 |
cc_phase | CC防护策略 | server_ip_blacklist | 可能的值:seccookie、server_ip_blacklist、static_whitelist、 server_header_blacklist、server_cookie_blacklist、server_args_blacklist、qps_overmax等 |
ua_browser | 浏览器 | ie9 | |
ua_browser_family | 浏览器系列 | internet explorer | |
ua_browser_type | 浏览器类型 | web_browser | |
ua_browser_version | 浏览器版本 | 9.0 | |
ua_device_type | 客户端设备类型 | computer | |
ua_os | 客户端操作系统 | windows_7 | |
ua_os_family | windows | ||
upstream_addr | 回源地址列表 | 1.2.3.4:443 | IP:Port,多个地址用逗号分隔 |
upstream_ip | 实际回源地址IP | 1.2.3.4 | |
upstream_response_time | 回源响应时间(秒) | 0.044 | |
upstream_status | 回源请求HTTP状态 | 200 | |
user_id | 12345678 |
本文为云栖社区原创内容,未经允许不得转载。