DDOS的特色是分布式,针对带宽和服务×××,即四层流量×××和七层应用×××。对于七层的应用×××,若是前端是Nginx,主要使用nginx的http_limit_conn和http_limit_req模块来防护,经过限制链接数和请求数能相对有效的防护CC×××。html
* ngx_http_limit_req_module:限制单个IP单位时间内的请求数,即速率限制,该模块默认已经安装 * ngx_http_limit_conn_module:限制单个IP同一时间链接数,即并发链接数限制
一个TCP链接能够产生多个请求,例如,一个页面上有不少图片,对客户端来讲只须要发送这个页面的一次请求,而每一个图片实际对应的就是一个链接,因此实际应用中对请求作限制比对链接作限制的效果更好。前端
ngx_http_limit_req_module:限制每秒请求数node
* http字段中定义触发条件,能够有多个条件; * server、location段中定义达到触发条件时nginx所要执行的动做。
例如:nginx
[root@localhost sbin]# vim /app/OpenResty/nginx/conf/nginx.conf ...... http { ...... limit_req_zone $binary_remote_addr zone=two:100m rate=50r/s; ...... server { ...... listen 80; ...... limit_req zone=two burst=20 nodelay; ...... } }
对限流起做用的配置就是rate=50r/s和burst=20这两个配置,假如同一秒有55个请求到达nginx,其中50个请求被处理,另外的5个请求被放到burst缓冲队列里,因为配置了nodelay,第51-55个请求依然会被处理,可是会占用burst缓冲队列的5个长度,若是下一秒没有新的请求过来,这5个长度的空间会被释放,不然会继续占用burst缓冲队列5个长度,若是后面每秒请求都超过50个,那么多余的请求虽然会被处理可是会占用burst缓冲队列长度,直到达到设定的burst=20,后面的每秒第51个请求开始会被nginx拒绝,并返回503错误,被拒绝的请求在nginx的日志中能够看到被那个zone拒绝的。c++
二、limit_req_log_level
语法: limit_req_log_level info | notice | warn | error;
默认值: limit_req_log_level error;
配置段: http, server, location
设置日志级别,当服务器由于频率太高拒绝或者延迟处理请求时能够记下相应级别的日志。 延迟记录的日志级别比拒绝的低一个级别; 若是设置“limit_req_log_level notice”, 延迟的日志就是info级别。web
ngx_http_limit_conn_module:限制IP链接数apache
ngx_http_limit_conn_module的模块也有2部分:vim
* http字段中定义触发条件,能够有多个条件; * server、location段中定义达到触发条件时nginx所要执行的动做。
http段:
语法:limit_conn_zone key zone=name:memory_max_size;
实例:limit_conn_zone $binary_remote_addr zone=one:10m;
说明:limit_conn_zone模块只能配置在http字段中进行定义,该指令描述会话状态存储区域。主要用来定义变量、zone名称、共享内存大小,键的状态中保存了当前链接数,键的值能够是特定变量的任何非空值(空值不会被考虑)。size 定义各个键共享内存空间大小,若是共享内存空间被耗尽,服务器将会对后续全部的请求返回 503 (Service Temporarily Unavailable) 错误。从Nginx 1.1.8版本后limit_conn升级为limit_conn_zone。链接数限制不是全部的链接都计算在内;只有那些已请求该服务器并当前正在处理的请求(请求头已充分阅读的)。windows
[root@localhost sbin]# vim /app/OpenResty/nginx/conf/nginx.conf ...... http { ...... limit_conn_zone $binary_remote_addr zone=one:10m; ...... server { ...... listen 80; ...... limit_conn one 20; ...... } }
还能够叠加使用,同时限制访问的虚拟主机:后端
[root@localhost sbin]# vim /app/OpenResty/nginx/conf/nginx.conf ...... http { ...... limit_conn_zone $binary_remote_addr zone=perip:100m; limit_conn_zone $server_name zone=perserver:100m; ...... server { ...... listen 80; ...... limit_conn perip 50;; #同一个IP限制连接20个 limit_conn perserver 20;; #同一主机名连接限制在100个 ...... } }
*二、 limit_conn_log_level
语法: limit_conn_log_level info | notice | warn | error;
默认值: limit_conn_log_level error;
使用环境: http, server, location
设置触发最大限制后记录日志的级别,默认为error级别,该指令在 0.8.18版后新增
*三、 limit_conn_status
语法: limit_conn_status code;
默认值: limit_conn_status 503;
使用环境: http, server, location
当超出最大同时链接数的时候,对于新增链接返回的错误代码,默认503. 该指令在 1.3.15版本后新增,
*四、 limit_rate
语法:limit_rate rate
默认值:0
实例:limit_rate 200k;
配置段:http, server, location, if in location
对每一个链接的速率限制。参数rate的单位是字节/秒,设置为0将关闭限速。 按链接限速而不是按IP限制,所以若是某个客户端同时开启了两个链接,那么客户端的总体速率是这条指令设置值的2倍。
白名单设置
http_limit_conn和http_limit_req模块限制了单ip单位时间内的并发和请求数,如前端若是有作LVS或反代,对于后端的ningx来讲过来的请求都是lvs或者反代的IP,而咱们后端启用了该模块功能,那不是很是多503错误了?这样的话,就须要geo和map模块设置白名单:
geo $whiteiplist { default 1; 10.15.43.18 0; } map $whiteiplist $limit { 1 $binary_remote_addr; 0 ""; }
geo模块定义了一个默认值default 1的变量$whiteiplist,当ip在白名单中,变量whiteiplist的值为0(10.15.43.18 0),反之为1
若是在白名单中--> whiteiplist=0 --> $limit="" --> 不会存储到zone对应的内存共享会话状态中 --> 不受限制
反之,不在白名单中 --> whiteiplist=1 --> $limit=二进制远程地址 -->存储进zone对应的内存共享会话状态中 --> 受到限制
iptables设置
单个IP在60秒内只容许新建20个链接访问web的80端口 iptables -I INPUT -i eth1 -p tcp -m tcp –dport 80 -m state –state NEW -m recent –update –seconds 60 –hitcount 20 –name DEFAULT –rsource -j DROP iptables -I INPUT -i eth1 -p tcp -m tcp –dport 80 -m state –state NEW -m recent –set –name DEFAULT –rsource 单个IP的最大并发链接数为20 iptables -I INPUT -p tcp –dport 80 -m connlimit –connlimit-above 20 -j REJECT 每一个IP最多20个初始链接 iptables -I INPUT -p tcp –syn -m connlimit –connlimit-above 20 -j DROP
测试
使用ab命令来模拟CC×××,http_limit_conn和http_limit_req模块要分开测试,同时注意http_limit_conn模块只统计正在被处理的请求(这些请求的头信息已被彻底读入)所在的链接。若是请求已经处理完,链接没有被关闭时,是不会被统计的。这时用netstat看到链接数能够超过限定的数量,不会被阻止。
http { ...... geo $whiteiplist { default 1; 10.15.43.18 0; } map $whiteiplist $limit { 1 $binary_remote_addr; 0 ""; } limit_req_zone $binary_remote_addr zone=one:100m rate=50r/s; limit_conn_zone $binary_remote_addr zone=two:10m; limit_conn_zone $server_name zone=three:10m; ...... server { listen 80; server_name 192.168.100.127; ...... server_tokens off; limit_req zone=one burst=20 nodelay; limit_req_log_level error; limit_req_status 503; limit_conn two 20; limit_conn three 3; limit_conn_log_level error; limit_conn_status 503; limit_rate 200k; ...... location / { root html; index index.html index.htm; } ...... }
ab是针对apache的性能测试工具,在APACHE的bin目录下,也能够只安装ab工具。
[root@localhost ~]# yum install -y httpd-tools [root@localhost ~]# ab -V This is ApacheBench, Version 2.3 <$Revision: 1430300 $> Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/ Licensed to The Apache Software Foundation, http://www.apache.org/ [root@localhost ~]# ab -v ab: option requires an argument -- v ab: wrong number of arguments Usage: ab [options] [http[s]://]hostname[:port]/path Options are: -n requests Number of requests to perform #在测试会话中所执行的请求次数。默认时,仅执行一个请求 -c concurrency Number of multiple requests to make at a time #一次产生的请求个数,即并发数。默认是一次一个 -t timelimit Seconds to max. to spend on benchmarking #测试所进行的最大秒数。其内部隐含值是-n 50000。它可使对服务器的测试限制在一个固定的总时间之内。默认时,没有时间限制。 This implies -n 50000 -s timeout Seconds to max. wait for each response Default is 30 seconds -b windowsize Size of TCP send/receive buffer, in bytes -B address Address to bind to when making outgoing connections -p postfile File containing data to POST. Remember also to set -T #包含了须要POST的数据的文件. -u putfile File containing data to PUT. Remember also to set -T -T content-type Content-type header to use for POST/PUT data, eg. #POST数据所使用的Content-type头信息。 'application/x-www-form-urlencoded' Default is 'text/plain' -v verbosity How much troubleshooting info to print #设置显示信息的详细程度 - 4或更大值会显示头信息, 3或更大值能够显示响应代码(404, 200等), 2或更大值能够显示警告和其余信息。 -V 显示版本号并退出。 -w Print out results in HTML tables #以HTML表的格式输出结果。默认时,它是白色背景的两列宽度的一张表。 -i Use HEAD instead of GET #执行HEAD请求,而不是GET -x attributes String to insert as table attributes -y attributes String to insert as tr attributes -z attributes String to insert as td or th attributes -C attribute Add cookie, eg. 'Apache=1234'. (repeatable) #-C cookie-name=value 对请求附加一个Cookie:行。 其典型形式是name=value的一个参数对。此参数能够重复。 -H attribute Add Arbitrary header line, eg. 'Accept-Encoding: gzip' Inserted after all normal header lines. (repeatable) -A attribute Add Basic WWW Authentication, the attributes are a colon separated username and password. -P attribute Add Basic Proxy Authentication, the attributes are a colon separated username and password. #-P proxy-auth-username:password 对一个中转代理提供BASIC认证信任。用户名和密码由一个:隔开,并以base64编码形式发送。不管服务器是否须要(即, 是否发送了401认证需求代码),此字符串都会被发送。 -X proxy:port Proxyserver and port number to use -V Print version number and exit -k Use HTTP KeepAlive feature -d Do not show percentiles served table. -S Do not show confidence estimators and warnings. -q Do not show progress when doing more than 150 requests -g filename Output collected data to gnuplot format file. -e filename Output CSV file with percentages served -r Don't exit on socket receive errors. -h Display usage information (this message) -Z ciphersuite Specify SSL/TLS cipher suite (See openssl ciphers) -f protocol Specify SSL/TLS protocol (SSL3, TLS1, TLS1.1, TLS1.2 or ALL) root@localhost ~]# ab -n1000 -c10 http://192.168.100.127/index.html #同时处理10个请求,连续1000次 This is ApacheBench, Version 2.3 <$Revision: 1430300 $> Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/ Licensed to The Apache Software Foundation, http://www.apache.org/ Benchmarking 192.168.100.127 (be patient) Completed 100 requests Completed 200 requests Completed 300 requests Completed 400 requests Completed 500 requests Completed 600 requests Completed 700 requests Completed 800 requests Completed 900 requests Completed 1000 requests Finished 1000 requests Server Software: openresty #测试的Web服务器软件名称 Server Hostname: 192.168.100.127 #服务器主机名 Server Port: 80 Document Path: /index.html Document Length: 6110 bytes Concurrency Level: 10 #并发数 Time taken for tests: 0.255 seconds #整个测试持续的时间 Complete requests: 1000 #完成的请求数量 Failed requests: 967 #失败的请求数量 (Connect: 0, Receive: 0, Length: 967, Exceptions: 0) Write errors: 0 Non-2xx responses: 967 Total transferred: 917130 bytes #整个场景中的网络传输量 HTML transferred: 724777 bytes #整个场景中的HTML内容传输量 Requests per second: 3917.94 [#/sec] (mean) #吞吐率,重要指标之一,至关于 LR 中的 每秒事务数 ,后面括号中的 mean 表示这是一个平均值 Time per request: 2.552 [ms] (mean) #用户平均请求等待时间,重要指标之二,至关于 LR 中的 平均事务响应时间 Time per request: 0.255 [ms] (mean, across all concurrent requests) #服务器平均请求处理时间,重要指标之三 Transfer rate: 3509.05 [Kbytes/sec] received #平均每秒网络上的流量,能够帮助排除是否存在网络流量过大致使响应时间延长的问题 Connection Times (ms) #网络上消耗的时间的分解 min mean[+/-sd] median max Connect: 0 0 0.1 0 1 Processing: 1 2 0.7 2 5 Waiting: 1 2 0.7 2 5 Total: 1 2 0.7 2 5 Percentage of the requests served within a certain time (ms) #每一个请求处理时间的分布状况 50% 2 66% 3 75% 3 80% 3 90% 3 95% 5 98% 5 99% 5 100% 5 (longest request) #整个场景中全部请求的响应状况。在场景中每一个请求都有一个响应时间,其中50%的用户响应时间小于2 毫秒,66% 的用户响应时间小于3毫秒,最大的响应时间小于5 毫秒 [root@localhost ~]#
吞吐率(Requests per second)
概念:服务器并发处理能力的量化描述,单位是reqs/s,指的是某个并发用户数下单位时间内处理的请求数。某个并发用户数下单位时间内能处理的最大请求数,称之为最大吞吐率。
计算公式:总请求数 / 处理完成这些请求数所花费的时间,即
Request per second = Complete requests / Time taken for tests
并发链接数(The number of concurrent connections)
概念:某个时刻服务器所接受的请求数目,简单的讲,就是一个会话。
并发用户数(The number of concurrent users,Concurrency Level)
概念:要注意区分这个概念和并发链接数之间的区别,一个用户可能同时会产生多个会话,也即链接数。
用户平均请求等待时间(Time per request)
计算公式:处理完成全部请求数所花费的时间/ (总请求数 / 并发用户数),即
Time per request = Time taken for tests /( Complete requests / Concurrency Level)
若是测试的站点带登录密码,先用帐户和密码登陆后,用开发者工具找到标识这个会话的Cookie值(Session ID)记下来,若是只用到一个Cookie,ab -n 100 -C key=value http://192.168.100.127/index.html,若是须要多个Cookie,就直接设Header:ab -n 100 -H “Cookie: Key1=Value1; Key2=Value2” http://192.168.100.127/index.html
Webbench是知名的网站压力测试工具,它是由Lionbridge公司开发。它能测试处在相同硬件上,不一样服务的性能以及不一样硬件上同一个服务的运行情况。可以统计每秒钟相应请求数和每秒钟传输数据量。webbench既能测试静态页面,还能对动态页面(ASP,PHP,JAVA,CGI)进 行测试。还支持对含有SSL的安全网站进行静态或动态的性能测试。最多能够模拟3万个并发链接去测试网站的负载能力。
官网:http://home.tiscali.cz/~cz210552/webbench.html
webbench会fork出多个子进程,每一个子进程都循环作web访问测试。子进程把访问的结果经过pipe告诉父进程,父进程作最终的统计结果
[root@localhost soft]# yum install ctags wget make apr* autoconf automake gcc gcc-c++ [root@localhost soft]# wget http://home.tiscali.cz/cz210552/distfiles/webbench-1.5.tar.gz [root@localhost soft]# tar -zxvf webbench-1.5.tar.gz [root@localhost soft]# cd webbench-1.5 [root@localhost webbench-1.5]# make [root@localhost webbench-1.5]# make install #这步可能提示/usr/local/man不存在,若是存在检查权限 [root@localhost webbench-1.5]# which webbench /usr/local/bin/webbench [root@localhost webbench-1.5]# webbench --help webbench [option]... URL -f|--force Don't wait for reply from server. #不须要等待服务器相应 -r|--reload Send reload request - Pragma: no-cache. #不发送从新加载请求 -t|--time <sec> Run benchmark for <sec> seconds. Default 30. #运行测试持续时间,单位秒 -p|--proxy <server:port> Use proxy server for request. #使用代理服务器发送请求 -c|--clients <n> Run <n> HTTP clients at once. Default one. #执行并发客户端数量,默认1个 -9|--http09 Use HTTP/0.9 style requests. #使用http/0.9 -1|--http10 Use HTTP/1.0 protocol. #使用HTTP/1.0协议 -2|--http11 Use HTTP/1.1 protocol. --get Use GET request method. --head Use HEAD request method. --options Use OPTIONS request method. --trace Use TRACE request method. -?|-h|--help This information. -V|--version Display program version. [root@localhost webbench-1.5]# webbench -c 10 -t 30 http://192.168.100.127 Webbench - Simple Web Benchmark 1.5 Copyright (c) Radim Kolar 1997-2004, GPL Open Source Software. Invalid URL syntax - hostname don't ends with '/'. [root@localhost webbench-1.5]# webbench -c 10 -t 30 http://192.168.100.127/ Webbench - Simple Web Benchmark 1.5 Copyright (c) Radim Kolar 1997-2004, GPL Open Source Software. Benchmarking: GET http://192.168.100.127/ 10 clients, running 30 sec. Speed=245980 pages/min, 26000094 bytes/sec. #每秒钟响应请求数:245980 pages/min,每秒钟传输数据量26000094 bytes/sec. Requests: 122990 susceed, 0 failed. #122990次返回成功,0次返回失败 [root@localhost soft]# cat webbench.sh #!/bin/bash export LANG="en_US.UTF-8" #export LANG="zh_CN.UTF8" source /etc/rc.d/init.d/functions [ -f /etc/profile ] && . /etc/profile [ -f ~/.bash_profile ] && . ~/.bash_profile for n in `seq 5 5 50`;do echo -n $n " " webbench -c $n -t 60 http://192.168.100.127/ 2>/dev/null | grep Speed | awk '{print $1}' | awk -F= '{print $2}' echo done [root@localhost soft]#
webbench的优势:
1.部署简单,适用于小型网站压力测试,(最多可模拟3万并发);
2.它具备静态页面测试能力也支持动态页面(ASP,PHP,JAVA,CGI)进行测试能力;
3.支持对含有SSL的安全网站如电子商务网站进行动态或静态性能测试;