专注 K8S研究
分类: 系统运维
2018-11-15 20:01:35
nginx 使用 ngx_http_limit_req_module和ngx_http_limit_conn_module 来限制对资源的请求
这种方法,对于CC攻击(Challenge Collapsar)or DDOS(分布式拒绝服务)有一定的用处
限制request 事实上就是 the processing rate of requests coming from a single IP address,使用的是漏桶算法(Leaky Bucket)
Traffic Shaping和Traffic Policing
在桶满水之后,常见的两种处理方式为:
1)暂时拦截住上方水的向下流动,等待桶中的一部分水漏走后,再放行上方水
2)溢出的上方水直接抛弃
将水看作网络通信中数据包的抽象,则方式1起到的效果称为Traffic Shaping,方式2起到的效果称为Traffic Policing
由此可见,Traffic Shaping的核心理念是"等待",Traffic Policing的核心理念是"丢弃"。它们是两种常见的流速控制方法
1
2
3
|
Syntax: limit_req zone=name [burst=number] [nodelay];
Default: —
Context: http, server, location
|
示例
1
2
3
4
5
6
|
limit_req_zone $binary_remote_addr zone=one:10m rate=1r/s;
server {
location /search/ {
limit_req zone=one burst=5 nodelay;
}
|
第一个参数:$binary_remote_addr 表示通过remote_addr这个标识来做限制,“binary_”的目的是缩写内存占用量,是限制同一客户端ip地址
第二个参数:zone=one:10m表示生成一个大小为10M,名字为one的内存区域,用来存储访问的频次信息
第三个参数:rate=1r/s表示允许相同标识的客户端的访问频次,这里限制的是每秒1次,还可以有比如30r/m的
第一个参数:zone=one 设置使用哪个配置区域来做限制,与上面limit_req_zone 里的name对应
第二个参数:burst=5,重点说明一下这个配置,burst爆发的意思,这个配置的意思是设置一个大小为5的缓冲区当有大量请求(爆发)过来时,超过了访问频次限制的请求可以先放到这个缓冲区内
第三个参数:nodelay,如果设置,超过访问频次而且缓冲区也满了的时候就会直接返回503,如果没有设置,则所有请求会等待排队
下面这个配置可以限制特定UA(比如搜索引擎)的访问
1
2
3
4
5
|
limit_req_zone $anti_spider zone=one:10m rate=10r/s;
limit_req zone=one burst=100 nodelay;
if ($http_user_agent ~* "googlebot|bingbot|Feedfetcher-Google") {
set $anti_spider $http_user_agent;
}
|
这个模块就是 limit the number of connections from a single IP address
Not all connections are counted. A connection is counted only if it has a request processed by the server and the whole request header has already been read
1
2
3
|
Syntax: limit_conn zone number;
Default: —
Context: http, server, location
|
示例
1
2
3
4
5
6
7
8
9
10
11
12
|
http {
limit_conn_zone $binary_remote_addr zone=addr:10m;
...
server {
...
location /download/ {
limit_conn addr 1;
#带宽限制,对单个连接限数,如果一个ip两个连接,就是500x2k
limit_rate 100k;
}
}
}
|
Sets the shared memory zone and the maximum allowed number of connections for a given key value. When this limit is exceeded, the server will return the 503 (Service Temporarily Unavailable) error in reply to a request
配置完之后,我们可以使用ab或者webbench来测试一下
1
|
ab -n 5 -c 1
|
正常情况下可以这样来配置
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
|
map $remote_addr $rt_filtered_ip {
default $binary_remote_addr;
1.2.3.4 "";
4.4.4.4 "";
}
or
geo $rt_filtered_ip {
default $binary_remote_addr;
127.0.0.1 "";
192.168.1.0/24 "";
10.1.0.0/16 "";
::1 "";
2001:0db8::/32 "";
1.2.3.4 ""
}
limit_conn_zone $binary_remote_addr zone=perip:10m;
limit_conn_zone $server_name zone=perserver:10m;
limit_conn_zone $host$uri zone=peruri:10m;
limit_req_zone $rt_filtered_ip zone=qps:10m rate=1r/s;
server {
location = /wp-login.php {
limit_req zone=qps burst=5 nodelay;
limit_conn perip 10;
limit_conn perserver 100;
limit_rate 500k;
include fastcgi_params;
fastcgi_pass 127.0.0.1:9000;
}
}
ab -n 100 -c 10 example.com/wp-login.php
$binary_remote_addr是限制同一客户端ip地址;
$server_name是限制同一server最大并发数;
limit_conn为限制并发连接数;
limit_rate为限制下载速度;
|
参考