为什么写了一个bloomfilterr就出现503错误

&http://www.6san.com/1149/
限制向客户端传送响应数据的速度,可以用来限制客户端的下载速度。参数rate的单位是字节/秒,0为关闭限速。
nginx按连接限速,所以如果某个客户端同时开启了两个连接,那么客户端的整体速度是这条指令设置值的2倍。
nginx限速示例:
location /flv/ {
limit_rate_after 500k; & & #当传输量大于此值时,超出部分将限速传送
limit_rate 50k;
limit_rate_
默认值: limit_rate_after 0;
上下文: http, server, location, if in location
这个指令出现在版本 0.8.0。当传输量大于此值时,超出部分将限速传送,小于设置值时不限速。
nginx其它两种限速方法
也可以利用$limit_rate变量设置流量限制。如果想在特定条件下限制响应传输速率,可以使用这个功能:
if ($slow) {
set $limit_rate 4k;
此外,也可以通过&X-Accel-Limit-Rate&响应头来完成速率限制。 这种机制可以用proxy_ignore_headers指令和 fastcgi_ignore_headers指令关闭。
http://www.cuplayer.com/player/PlayerCode/Nginx/71.html
Nginx(著名的高性能http服务器和反向代理服务器)的模块开发,在此分享nginx的限速实现核心代码。
Nginx的http核心模块ngx_http_core_module中提供limit_rate这个指令可以用于控制速度,limit_rate_after用于设置http请求传输多少字节后开始限速。
另外两个模块ngx_http_limit_conn_module和ngx_http_limit_req_module分别用于连接数和连接频率的控制。
限制速度的配置指令简单易懂,限速支持固定的数值
location&/flv/&{&
&&&&limit_rate_after&500k;&
&&&&limit_rate&&&&&&&50k;&
查 看nginx源代码,可以发现ngx_http_write_filter_module.c源文件具体实现了速度的控制,nginx的特点是高度模块 化,从名字可以看出这个文件其实也是一个filter模块(nginx中的模块分handler,filter,upstream等三类),这个模块属于 filter类别。
static&ngx_int_t&
ngx_http_write_filter_init(ngx_conf_t&*cf)&
&&&&ngx_http_top_body_filter&=&ngx_http_write_&
&&&&return&NGX_OK;&
模块挂载了一个函数在filter的顶端(经过编译链接后此模块即被&压&到filter&链表&的尾部),用于控制数据的输出,这个函数里面就包含了速度的控制。
&&&&limit&=&r-
&&&&&&&&&&&&-&(c-
&&&&if&(limit&
&&&&&&&&c-
&&&&&&&&ngx_add_timer(c-
&&&&&&&&&&&&&&&&&&&&&&(ngx_msec_t)&(-&limit&*&1000&/&r-
&&&&&&&&c-
&&&&&&&&return&NGX_AGAIN;&
&&&&if&(clcf-
&&&&&&&&&&&(off_t)&clcf-
&&&&&&&&limit&=&clcf-
上面代码的逻辑是:如果配置文件设置了限速(limit_rate是速度值,size_t类型,0表示不限速)
当c-&sent&clcf-&limit_rate_after时,说明还没有到需要限速的阈值,计算limit值大于0(下一次应该传输位置偏移量),不必限速
当c-&sent&clcf-&limit_rate_after时,需要控制限速,分两种情况:
r-&limit_rate * (ngx_time() & r-&start_sec + 1)&(c-&sent & clcf-&limit_rate_after) & & &理论传输量&实际传输量,不必控制(传得慢了)
r-&limit_rate * (ngx_time() & r-&start_sec + 1)&(c-&sent & clcf-&limit_rate_after) & & &理论传输量&实际传输量,需要设置延时(传得快了)
chain = c-&send_chain(c, r-&out, limit);
通过上面的c-&send_chain函数异步发送数据,nginx在处理完上面send_chain函数后做了延时的微调,倘若进行到下面
之前异步IO使得c-&sent增加了,则按照增加量添加延时时间delay,因为一般情况这段时间c-&sent应该不会来得及改变的。所
以如果异步IO改变了数据传输量,也应该及时做速度限制的调整,看得出来nginx对这些细节上的处理非常仔细啊,保证一个准确度。
&&&&nsent&=&c-
&&&&if&(clcf-
&&&&&&&&sent&-=&clcf-
&&&&&&&&if&(sent&
&&&&&&&&&&&&sent&=&0;&
&&&&&&&&}&
&&&&&&&&nsent&-=&clcf-
&&&&&&&&if&(nsent&
&&&&&&&&&&&&nsent&=&0;&
&&&&&&&&}&
&&&&delay&=&(ngx_msec_t)&((nsent&-&sent)&*&1000&/&r-
&&&&if&(delay&
&&&&&&&&limit&=&0;&
&&&&&&&&c-
&&&&&&&&ngx_add_timer(c-
接下来nginx还做了点延时的微调,不过这个是涉及到sendfile_max_chunk指令,而不是limit_rate指令的,所以不做分析。
if&(limit&
&&&&ngx_add_timer(c-
总之,可以看出nginx是通过使用ngx_add_timer函数实现对write event的控制,进而实现速度上限的控制。
题外话:nginx 对于速度的限制不止是通过limit_rate设置阈值,在upstream模块中通过获取上游服 务器返回的响应头headers[&X-Accel-Limit-Rate&]的值也可来动态调整limit_rate的具体数值,这个可以用来实现变化 的速度控制。
=============================
http://yunwei.blog.51cto.com/0046
基于模块:
注意事项:
1.由两个指令共同完成limit_rate和limit_rate_after
2.limit_rate
&& 是指定向客户端传输数据的速度,单位是每秒传输的字节数
&&&该限制只针对一个连接的设定,如果同时两个连接数,那么速度是设置值的两倍
3.limit_rate_after
&& 当一个客户端连接后,将以最快的速度下载多大文件,然后在以限制速度下载文件
&& 该指令是下载字节量的大小值,而不是时间值
4.作用范围:http,server,location,if inlocation
配置实例:
最后综合以上两条指令的意思是:
当一个客户端连接后,将以最快的速度下载3M,然后再以大约1024k的速度下载
本文出自 && 博客,请务必保留此出处
...........................
http://www.cszhi.com//nginx-limit_conn-limit_rate.html
在配置文件nginx.conf的http{}添加:
limit_zone
$binary_remote_addr
在location url重写配置里添加:
limit_conn one 5;
limit_rate 50k;
.............
limit_zone
$binary_remote_addr
#添加这一行
..............
.................
location {
limit_conn one 5;
#连接数限制(线程)
limit_rate 50k;
.................
.............
&http://blog.itpub.net//viewspace-732626/
对于提供下载的网站,肯定是要进行流量控制的,例如BBS、视频服务,还是其它专门提供下载的网站。在nginx中我们完全可以做到限流,由Core模块提供了limit_rate、limit_rate_after命令。
&&& 通过以下两条命令来完成限制流量。
指令名称:limit_rate
功&&& 能:该指令用于指定向客户端传输数据的速度,速度的单位是每秒传输的字节数。需要明白的一点是该限制只是针对一个连接的设定,就是说如果同时有两个连接那么它的速度将会是该指令设置值的2倍,
如果需要在server级别对某些客户端限制速度,对于这种情况&&这个指令可能并不适合,但是可设置$limit_rate变量,可以为该变量传递相应的值来实现,例如:
& if ($slow) {
&&& set $limit_rate& 4k;
&&& 当然也可以通过设置X-Accel-Limit-Rate头(来自于NginxXSendfile模块)来控制由proxy_pass(来自于HttpProxyModule模块)返回的响应数据的速率,而没有使用X-Accel-Redirect头。
语&&& 法: limit_rate speed
默 认 值: no
使用环境: http, server, location, if in location
指&&& 令:limit_rate_after
功能:,这个命令中的&&提示了我们,可以这样理解&在后再限制速率为&,没错,就是这个意思,它的语法为:这是官方威客上的语法,它的意思是以最大的速度下载时长后,但是在实际的使用中发现命令的参数是一个下载字节量的大小值,而不是时间值,因此上面的命令&&解释为:以最大的速度下载后。
语&&& 法:limit_rate_after size
默 认 值:limit_rate_after 1m
使用字段:http, server, location, location中的if字段
&&& 看下面的配置,这是一个视频服务器上的配置片断,通过这两条命令限制了访问者的下载速度:
&& location /download {
&&&& &&limit_rate_after 3m;
&&&&&& limit_rate 512k;
我们看一下这两条命令:
&&& limit_rate,相对于limit_rate_after命令,这个命令已经开始限速了,它的语法为:limit_rate speed,它表示限制为的速率。该指令可以用在http, server, location以及location中的if区段,没有默认值。
&http://elastos.org/redmine/issues/10141
nginx 限制ip并发数,也是说限制同一个ip同时连接服务器的数量。如何Nginx限制同一个ip的连接数,限制并发数目,限制流量/限制带宽? 通过下面nginx模块的使用,我们可以设置一旦并发链接数超过我们的设置,将返回503错误给对方。这样可以非常有效的防止CC攻击。在配合 iptables防火墙,基本上CC攻击就可以无视了。Nginx限制ip链接数,Nginx如何限制并发数,同1个IP,nginx怎么限制流量/限制带宽?请看下文:
nginx 限制ip并发数,nginx限制IP链接数的范例参考:
limit_zone
ctohome_zone
$binary_remote_addr
limit_req_zone
$binary_remote_addr
zone=ctohome_req_zone:20m
rate=2r/s;
server_name
www.ctohome.com .ctohome.
location / {
proxy_pass http://1.2.3.4;
include vhosts/conf.proxy_
location ~ .*\.(php|jsp|cgi|phtml|asp|aspx)?$
limit_conn
ctohome_zone
zone=ctohome_req_zone
proxy_pass http://4.3.2.1;
include vhosts/conf.proxy_no_
如何Nginx限制同一个ip的连接数,限制并发数目
1.添加limit_zone
这个变量只能在http使用
vi /usr/local/nginx/conf/nginx.conf
limit_zone ctohome_zone $remote_addr 10m;
2.添加limit_conn
这个变量可以在http, server, location使用
我只限制一个站点,所以添加到server里面
vi /usr/local/nginx/conf/host/www.ctohome.com.conf
limit_conn
ctohome_zone 2;
3.重启nginx
killall -HUP nginx
Nginx限制流量/限制带宽?
关于limit_zone:http://wiki.nginx.org/NginxHttpLimitZoneModule
关于limit_rate和limit_conn:http://wiki.nginx.org/NginxHttpCoreModule
nginx可以通过HTTPLimitZoneModule和HTTPCoreModule两个组件来对目录进行限速。
limit_zone
$binary_remote_addr
location /download/ {
limit_conn
ctohome_zone 2;
limit_rate 300k;
limit_zone,是针对每个IP定义一个存储session状态的容器。这个示例中定义了一个10m的容器,按照32bytes/session,可以处理320000个session。
limit_conn ctohome_zone 2;
限制每个IP只能发起2个并发连接。
limit_rate 300k;
对每个连接限速300k. 注意,这里是对连接限速,而不是对IP限速。如果一个IP允许两个并发连接,那么这个IP就是限速limit_rate&2。
ngx_http_limit_zone_module
&=========================
http://www.21ops.com/linux/30416.html
下nginx服务器限制带宽的几种方法
第一种方法,限制nginx带宽。
&&&limit_rate&25k;&&
&&&limit_zone&to_vhost&$server_name&1m;&
&&&limit_conn&to_vhost&30;&
第二种方法,用Nginx做下载服务时,可能会做下载速度限制,这个Nginx可以做到:
首先,在http{}的配置中添加一条:
limit_zone&one&$binary_remote_addr&10m;
然后,在server{}的配置中添加:
location&/&{
limit_conn&one&1;&限制线程
limit_rate&100k;&限制速度
表示限速100K每个客户端只允许一个线程
客户端最终速度=rate * conn,这样就可以完美的实现限制带宽的设置了。
详细的官方规则:
http://wiki.nginx.org/NginxChsHttpLimit_zoneModule
第三种方法,nginx限制带宽。
在nginx.conf的http{}添加:
limit_zone&one&$binary_remote_addr&10m;
然后,在虚拟机中添加:
location&/&{
&&limit_conn&one&1;&线程
&&limit_rate&100k;&速度
表示限速100K每个客户端只允许一个线程
客户端最终速度=rate * conn,这样即可实现限制带宽的设置了。
&===============
http://blog.51yip.com/apachenginx/1400.html
今天有个人问我,nginx怎么限制ip连接数,突然想不起来了,年龄大了,脑子不怎么好使了。还要看一下配置才想起了。那个人又问我,你 测试过的吗?一下子把我问蒙了,我真没测试过了,也不知道启作用了没有。下面我做了一下测试。以前用apache的时候到是做过测试,apache怎么限 制ip数,请参考:
1,配置nginx.conf
.............&&
limit_zone&&&one&&$binary_remote_addr&&10m;&&
..............&&
&server{&&
&.................&&
&location&{&&
&.........&&
&limit_conn&one&20;&&&&&&&&&&
&limit_rate&500k;&&&&&&&&&&&&
&........&&
&.................&&
.............&&
[root@localhost&nginx]#&/etc/init.d/nginx&reload&
2,测试限制ip连接数
[root@localhost&nginx]#&&webbench&-c&100&-t&2&http:
Webbench&-&Simple&Web&Benchmark&1.5&&
Copyright&(c)&Radim&Kolar&,&GPL&Open&Source&Software.&&
Benchmarking:&GET&http:
100&clients,&running&2&sec.&&
Speed=429959&pages/min,&2758544&bytes/sec.&&
Requests:&14332&susceed,&0&failed.&&
[root@localhost&nginx]#&cat&/var/log/nginx/access.log|grep&503&|more&&&
127.0.0.1&-&-&[25/Apr/:21&+0800]&"GET&/index.php&HTTP/1.0"&503&213&"-"&"WebBench&1.5"&-&&
127.0.0.1&-&-&[25/Apr/:21&+0800]&"GET&/index.php&HTTP/1.0"&503&213&"-"&"WebBench&1.5"&-&&
127.0.0.1&-&-&[25/Apr/:21&+0800]&"GET&/index.php&HTTP/1.0"&503&213&"-"&"WebBench&1.5"&-&&
127.0.0.1&-&-&[25/Apr/:21&+0800]&"GET&/index.php&HTTP/1.0"&503&213&"-"&"WebBench&1.5"&-&&
127.0.0.1&-&-&[25/Apr/:21&+0800]&"GET&/index.php&HTTP/1.0"&503&213&"-"&"WebBench&1.5"&-&&
127.0.0.1&-&-&[25/Apr/:21&+0800]&"GET&/index.php&HTTP/1.0"&503&213&"-"&"WebBench&1.5"&-&&
127.0.0.1&-&-&[25/Apr/:21&+0800]&"GET&/index.php&HTTP/1.0"&503&213&"-"&"WebBench&1.5"&-&&
127.0.0.1&-&-&[25/Apr/:21&+0800]&"GET&/index.php&HTTP/1.0"&503&213&"-"&"WebBench&1.5"&-&&
..............................................................................................&&
通过以上测试,可以得出限制ip连接数是没有问题的,但是限制带宽看不出来,说实话这个不好测试,所以就没测试了。
转载请注明作者:海底苍鹰地址:
...............................
&http://www.jbxue.com/article/2900.html
设置 nginx 流量限制,供大家学习参考。
流量限制,供大家学习参考。
昨天刚把论坛迁移到我新准备的服务器上,新的服务器我的的是nginx++php+memache+squid, 按理说应该不错了。
当今天上班的时候,刚到公司老总就说网站很慢,我就奇怪了怎么会呢?
我查看了流量,很大。但是正常的,访问已经升到几千了。
我想会不会机房的交换机有问题了。之前出现过网站访问很慢,热插拔网卡就ok了。
同样我也做了 效果不佳。主站流量很小。大部分都在论坛上。
我感觉可能论坛人数一多把带宽占满了。
&1、首先我限制并发数了
& -A INPUT& -p tcp --dport 80 -m limit --limit 6/s -j ACCEPT
&将每个用户限制在每秒6个请求
&但效果不明显。
&2、然后我开始设置nginx的流量请求
&修改配置文件
复制代码 代码如下:
&&&&& limit_zone one $binary_remote_addr 10m;
&&&&& limit_conn one 5;
&&&& #&&& limit_req_zone $binary_remote_addr zone=one2:10m rate=5r/s;
&&&& #&&& limit_req zone=one2 burst=5;
&& .................
&& .................
&&& 在server {
&&&&&&&&&&&& ....
&&&&&&&&&&& .....
&&&&&&&&&&& location / {
&&&&&&&& #limit zone
&&&&&&&&&& limit_conn one 10;
&&&&&&&&&&& limit_rate 10k;
&&&&&&&&&&&& }
&&&&&&&&& }
#这个代码是限制速率和并发连接数
:limit_zone(limit_conn) 来限制并发数,limit_rate来限制下载的速率
当然,这些都可以在好一点的交换机上去分配带宽,如果您手上的有相关的设备那是再好不过了。
========================
http://www.nginx.cn/2212.html
lnmp已经成为比较流行的网站服务器端技术配备。越来越多的人开始不满足于能使用nginx,更多人开始关注如何能优化nginx的处理能力。
使用nginx的目的就是为了提高并发处理能力,但是看到有部分人本机部署lanmp,在同一台机器上使用nginx方向代理apache,就有种脱裤子放屁的感觉。
在window下运行nginx,还要跑出好的效果,同样是个伪命题,windows下的select模型注定nginx效率不会太高。
最近看了篇,结合自己理解,写给大家看看吧。
优化nginx包括两方面:
1.是自己重写nginx代码(比如tengine)、本身nginx的代码已经足够优秀,如果不是每秒几千的请求,就忽略这个部分吧。
2.另一个就是和优化nginx的配置,这是中小型网站可以重点优化的部分。
nginx的配置文件是一种声明式定义,控制nginx的每一个细节。
所谓负载调优,就是提高单台机器处理效率,降低单台机器的负载。
为了提高单台机器的处理效率,cpu的处理速度是足够快的,我们能解决的就是降低磁盘I/O、网络I/O,减少内存使用。
降低单台机器的负载我们能做的就是负载均衡,把流量打到多台机器处理。
nginx推荐优化内容:
1.open files数量优化
ulimit -a查看系统参数
open files (-n) 1024
表示系统同时最多能打开的文件数,linux下的所有设备都可以认为是文件,包括网络连接,如果同时超过1024个连接,那么nginx的日志就会报&24: Too many open files&
多以优化的第一步就是设置open files为ulimit
修改/etc/profile,增加
ulimit -n 65535
2.Worker Processes数量优化
通常来说设置一个cpu核心对应一个worker processer,最多不超过4个,提高worker process的值是为了提高计算能力,但一般在越到cpu瓶颈前,你会遇到别的瓶颈(如网络问题)。
只有当你要处理大量静态文件的磁盘I/O时,worker进程是单线程的,所以这个读取文件的阻塞IO会降低CPU的处理速度,这是可以增加worker进程数量,其它情况是不需要的。
3.worker进程连接数优化(Worker Connections)
默认情况下这个值是worker_connections 1024,也就是说考虑到keep-alive超时65秒,每个浏览器平均消耗两个链接(chrome会同时打开多个连接来提到加载速度)。
那么默认情况下nginx平均每秒能处理=8,那么8*86440=64w,差不多相当于每天有60万ip。
多以普通网站默认值就可以了,如果你的流量一直提升,可以考虑增加这个值为2048或者更高。
3. CPU Affinity
用来设置worker进程使用哪个cpu核心处理请求并且一直使用这个cpu核心。如果你不知道cpu调度,最好别碰这个,操作系统比你更懂如何调度。
4. Keep Alive
Keep alive
没有数据传输的情况下保持客户端和服务端的连接,也就是保持空连接一段时间,避免重现建立链接的时间消耗。nginx处理空连接的效率非常高,1万个空连
接大约消耗2.5M内存。如果流量非常大的网站,减少建立连接的时间开销是非常客观的。keep alive的值设置在10-20s之间比较合理。
5. tcp_nodelay 和 tcp_nopush优化
这两个指令影响nginx的底层网络,它们决定操作系统如何处理网络层buffer和什么时候把buffer内容刷新给终端用户。如果你不懂,就可以保持这两个指令默认不变,对nginx性能影响不明显。
6. access日志优化
默认情况下,access日志会记录所有请求到日志文件,写操作会增加IO操作,如果不需要统计信息,可以使用百度统计或者cnzz统计,完全可以关闭日志,来减少磁盘写,或者写入内存文件,提高IO效率。
7. Error日志优化
错误日志会记录运行中的错误,如果设置的太低,会记录的信息太多,会产生大量IO,推荐设置为warn,这样可以记录大部分信息,而不会有太多IO
8. Open File Cache
nginx会读文件系统的许多文件,如果这些文件的描述符能够缓存起来,那么会提高处理效率。详见http://wiki.nginx.org/HttpCoreModule#open_file_cache
9. Buffers size优化
buffer的大小是你需要调优最重要参数。如果buffer size太小就会到导致nginx使用临时文件存储response,这会引起磁盘读写IO,流量越大问题越明显。
client_body_buffer_size 处理客户端请求体buffer大小。用来处理POST提交数据,上传文件等。client_body_buffer_size 需要足够大以容纳如果需要上传POST数据。
fastcgi_buffers,proxy_buffers 处理后端(PHP,
That to used sensitive just
lung however
job that tension
hair because. That shower... Comes
A after. Well
that taking. Head
these is it you
would it. I'm
for had accidentally
this of oil
adult it just. Others
Myself expensive adjustment
supposed highly brush. Out
probably I last costumes.
Apache)响应。如果这个buffer不够大,同样会引起磁盘都系IO。需要注意的是它们有一个上限值,这个上限值受 fastcgi_max_temp_file_size 、 proxy_max_temp_file_size控制。
如果能把数据全放到内存,不使用磁盘就可以完全去掉磁盘IO。 默认情况下操作系统也会缓存频繁访问的数据以降低IO。所以预算足够的情况加,加大内存。
假设我们没有了磁盘IO,所有数据都在内存,那么我们的读IO大概有3-6gbps。这种情况下,如果你网络差,一样会很慢。所以尽可能提高网络带宽,压缩传输数据。
网络带宽买你能买的起的最大带宽,nginx的gzip模块可以用来压缩传输数据,通常gzip_comp_level 设为 4-5,再高就是浪费cpu了。同时也可以采用css,js压缩技术,当然这些技术就与nginx优化无关了。。
如果你还想提高nginx处理能力,只能祭出大杀器了。别优化了,加机器吧。一点点优化是没有用的,不如扩展机器来的快些。
说道系统的扩展性通常有scale、和extension,区别是前者是数量上扩展,后者是功能上扩展。
=========================
&http://www.111cn.net/sys/nginx/56066.htm
http://drops.wooyun.org/tips/734
大家好,我们是OpenCDN团队的Twwy。这次我们来讲讲如何通过简单的配置文件来实现nginx防御攻击的效果。
其实很多时候,各种防攻击的思路我们都明白,比如限制IP啊,过滤攻击字符串啊,识别攻击指纹啦。可是要如何去实现它呢?用守护脚本吗?用PHP在 外面包一层过滤?还是直接加防火墙吗?这些都是防御手段。不过本文将要介绍的是直接通过nginx的普通模块和配置文件的组合来达到一定的防御效果。
0x01 验证浏览器行为
我们先来做个比喻。
社区在搞福利,在广场上给大家派发红包。而坏人派了一批人形的机器人(没有语言模块)来冒领红包,聪明工作人员需要想出办法来防止红包被冒领。
于是工作人员在发红包之前,会给领取者一张纸,上面写着&红包拿来&,如果那人能念出纸上的字,那么就是人,给红包,如果你不能念出来,那么请自觉。于是机器人便被识破,灰溜溜地回来了。
是的,在这个比喻中,人就是浏览器,机器人就是攻击器,我们可以通过鉴别cookie功能(念纸上的字)的方式来鉴别他们。下面就是nginx的配置文件写法。
if ($cookie_say != "hbnl"){
&&&&add_header Set-Cookie "say=hbnl";
&&&&rewrite .* "$scheme://$host$uri"
让我们看下这几行的意思,当cookie中say为空时,给一个设置cookie say为hbnl的302重定向包,如果访问者能够在第二个包中携带上cookie值,那么就能正常访问网站了,如果不能的话,那他永远活在了302中。 你也可以测试一下,用CC攻击器或者webbench或者直接curl发包做测试,他们都活在了302世界中。
当然,这么简单就能防住了?当然没有那么简单。
仔细的你一定会发现配置文件这样写还是有缺陷。如果攻击者设置cookie为say=hbnl(CC攻击器上就可以这么设置),那么这个防御就形同虚设了。我们继续拿刚刚那个比喻来说明问题。
坏人发现这个规律后,给每个机器人安上了扬声器,一直重复着&红包拿来,红包拿来&,浩浩荡荡地又来领红包了。
这时,工作人员的对策是这样做的,要求领取者出示有自己名字的户口本,并且念出自己的名字,&我是xxx,红包拿来&。于是一群只会嗡嗡叫着&红包拿来&的机器人又被撵回去了。
当然,为了配合说明问题,每个机器人是有户口本的,被赶回去的原因是不会念自己的名字,虽然这个有点荒诞,唉。
然后,我们来看下这种方式的配置文件写法
if ($cookie_say != "hbnl$remote_addr"){
&&&&add_header Set-Cookie "say=hbnl$remote_addr";
&&&&rewrite .* "$scheme://$host$uri"
这样的写法和前面的区别是,不同IP的请求cookie值是不一样的,比如IP是1.2.3.4,那么需要设置的cookie是 say=hbnl1.2.3.4。于是攻击者便无法通过设置一样的cookie(比如CC攻击器)来绕过这种限制。你可以继续用CC攻击器来测试下,你会 发现CC攻击器打出的流量已经全部进入302世界中。
不过大家也能感觉到,这似乎也不是一个万全之计,因为攻击者如果研究了网站的机制之后,总有办法测出并预先伪造cookie值的设置方法。因为我们 做差异化的数据源正是他们本身的一些信息(IP、user agent等)。攻击者花点时间也是可以做出专门针对网站的攻击脚本的。
那么要如何根据他们自身的信息得出他们又得出他们算不出的数值?
我想,聪明的你一定已经猜到了,用salt加散列。比如md5("opencdn$remote_addr"),虽然攻击者知道可以自己IP,但是 他无法得知如何用他的IP来计算出这个散列,因为他是逆不出这个散列的。当然,如果你不放心的话,怕cmd5.com万一能查出来的话,可以加一些特殊字 符,然后多散几次。
很可惜,nginx默认是无法进行字符串散列的,于是我们借助nginx_lua模块来进行实现。
rewrite_by_lua '
&&&&local say = ngx.md5("opencdn" .. ngx.var.remote_addr)
&&&&if (ngx.var.cookie_say ~= say) then
&&&&&&&&ngx.header["Set-Cookie"] = "say=" .. say
&&&&&&&&return ngx.redirect(ngx.var.scheme .. "://" .. ngx.var.host .. ngx.var.uri)
通过这样的配置,攻击者便无法事先计算这个cookie中的say值,于是攻击流量(代理型CC和低级发包型CC)便在302地狱无法自拔了。
大家可以看到,除了借用了md5这个函数外,其他的逻辑和上面的写法是一模一样的。因此如果可以的话,你完全可以安装一个nginx的计算散列的第三方模块来完成,可能效率会更高一些。
这段配置是可以被放在任意的location里面,如果你的网站有对外提供API功能的话,建议API一定不能加入这段,因为API的调用也是没有浏览器行为的,会被当做攻击流量处理。并且,有些弱一点爬虫也会陷在302之中,这个需要注意。
同时,如果你觉得set-cookie这个动作似乎攻击者也有可能通过解析字符串模拟出来的话,你可以把上述的通过header来设置cookie的操作,变成通过高端大气的js完成,发回一个含有doument.cookie=...的文本即可。
那么,攻击是不是完全被挡住了呢?只能说那些低级的攻击已经被挡住而来,如果攻击者必须花很大代价给每个攻击器加上webkit模块来解析js和执 行set-cookie才行,那么他也是可以逃脱302地狱的,在nginx看来,确实攻击流量和普通浏览流量是一样的。那么如何防御呢?下节会告诉你答 案。
0x02 请求频率限制
不得不说,很多防CC的措施是直接在请求频率上做限制来实现的,但是,很多都存在着一定的问题。
那么是哪些问题呢?
首先,如果通过IP来限制请求频率,容易导致一些误杀,比如我一个地方出口IP就那么几个,而访问者一多的话,请求频率很容易到上限,那么那个地方的用户就都访问不了你的网站了。
于是你会说,我用SESSION来限制就有这个问题了。嗯,你的SESSION为攻击者敞开了一道大门。为什么呢?看了上文的你可能已经大致知道 了,因为就像那个&红包拿来&的扬声器一样,很多语言或者框架中的SESSION是能够伪造的。以PHP为例,你可以在浏览器中的cookie看到 PHPSESSIONID,这个ID不同的话,session也就不同了,然后如果你杜撰一个PHPSESSIONID过去的话,你会发现,服务器也认可 了这个ID,为这个ID初始化了一个会话。那么,攻击者只需要每次发完包就构造一个新的SESSIONID就可以很轻松地躲过这种在session上的请 求次数限制。
那么我们要如何来做这个请求频率的限制呢?
首先,我们先要一个攻击者无法杜撰的sessionID,一种方式是用个池子记录下每次给出的ID,然后在请求来的时候进行查询,如果没有的话,就 拒绝请求。这种方式我们不推荐,首先一个网站已经有了session池,这样再做个无疑有些浪费,而且还需要进行池中的遍历比较查询,太消耗性能。我们希 望的是一种可以无状态性的sessionID,可以吗?可以的。
rewrite_by_lua '
&&&&local random = ngx.var.cookie_random
&&&&if(random == nil) then
&&&&&&&&random = math.random(999999)
&&&&local token = ngx.md5("opencdn" .. ngx.var.remote_addr .. random)
&&&&if (ngx.var.cookie_token ~= token) then
&&&&&&&&ngx.header["Set-Cookie"] = {"token=" .. token, "random=" .. random}
&&&&&&&&return ngx.redirect(ngx.var.scheme .. "://" .. ngx.var.host .. ngx.var.uri)
大家是不是觉得好像有些眼熟?是的,这个就是上节的完美版的配置再加个随机数,为的是让同一个IP的用户也能有不同的token。同样的,只要有nginx的第三方模块提供散列和随机数功能,这个配置也可以不用lua直接用纯配置文件完成。
有了这个token之后,相当于每个访客有一个无法伪造的并且独一无二的token,这种情况下,进行请求限制才有意义。
由于有了token做铺垫,我们可以不做什么白名单、黑名单,直接通过limit模块来完成。
&&&&limit_req_zone $cookie_token zone=session_limit:3m rate=1r/s;
然后我们只需要在上面的token配置后面中加入
limit_req zone=session_limit burst=5;
于是,又是两行配置便让nginx在session层解决了请求频率的限制。不过似乎还是有缺陷,因为攻击者可以通过一直获取token来突破请求频率限制,如果能限制一个IP获取token的频率就更完美了。可以做到吗?可以。
&&&&limit_req_zone $cookie_token zone=session_limit:3m rate=1r/s;
&&&&limit_req_zone $binary_remote_addr $uri zone=auth_limit:3m rate=1r/m;
location /{
&&&&limit_req zone=session_limit burst=5;
&&&&rewrite_by_lua '
&&&&&&&&local random = ngx.var.cookie_random
&&&&&&&&if (random == nil) then
&&&&&&&&&&&&return ngx.redirect("/auth?url=" .. ngx.var.request_uri)
&&&&&&&&end
&&&&&&&&local token = ngx.md5("opencdn" .. ngx.var.remote_addr .. random)
&&&&&&&&if (ngx.var.cookie_token ~= token) then
&&&&&&&&&&&&return ngx.redirect("/auth?url=".. ngx.var.request_uri)
&&&&&&&&end
location /auth {
&&&&&&&&limit_req zone=auth_limit burst=1;
&&&&&&&&if ($arg_url = "") {
&&&&&&&&&&&&return 403;
&&&&&&&&access_by_lua '
&&&&&&&&&&&&local random = math.random(9999)
&&&&&&&&&&&&local token = ngx.md5("opencdn" .. ngx.var.remote_addr .. random)
&&&&&&&&&&&&if (ngx.var.cookie_token ~= token) then
&&&&&&&&&&&&&&&&ngx.header["Set-Cookie"] = {"token=" .. token, "random=" .. random}
&&&&&&&&&&&&&&&&return ngx.redirect(ngx.var.arg_url)
&&&&&&&&&&&&end
&&&&&&&&';
我想大家也应该已经猜到,这段配置文件的原理就是:把本来的发token的功能分离到一个auth页面,然后用limit对这个auth页面进行频率限制即可。这边的频率是1个IP每分钟授权1个token。当然,这个数量可以根据业务需要进行调整。
需要注意的是,这个auth部分我lua采用的是access_by_lua,原因在于limit模块是在rewrite阶段后执行的,如果在 rewrite阶段302的话,limit将会失效。因此,这段lua配置我不能保证可以用原生的配置文件实现,因为不知道如何用配置文件在 rewrite阶段后进行302跳转,也求大牛能够指点一下啊。
当然,你如果还不满足于这种限制的话,想要做到某个IP如果一天到达上限超过几次之后就直接封IP的话,也是可以的,你可以用类似的思路再做个错误 页面,然后到达上限之后不返回503而是跳转到那个错误页面,然后错误页面也做个请求次数限制,比如每天只能访问100次,那么当超过报错超过100次 (请求错误页面100次)之后,那天这个IP就不能再访问这个网站了。
于是,通过这些配置我们便实现了一个网站访问频率限制。不过,这样的配置也不是说可以完全防止了攻击,只能说让攻击者的成本变高,让网站的扛攻击能 力变强,当然,前提是nginx能够扛得住这些流量,然后带宽不被堵死。如果你家门被堵了,你还想开门营业,那真心没有办法了。
然后,做完流量上的防护,让我们来看看对于扫描器之类的攻击的防御。
0x03 防扫描
这个是一个不错的waf模块,这块我们也就不再重复造轮子了。可以直接用这个模块来做防护,当然也完全可以再配合limit模块,用上文的思路来做到一个封IP或者封session的效果。
本文旨在达到抛砖引玉的作用,我们并不希望你直接单纯的复制我们的这些例子中的配置,而是希望根据你的自身业务需要,写出适合自身站点的配置文件。
阅读(...) 评论() &

我要回帖

更多关于 java filter 的文章

 

随机推荐