nginx可以通过limit_conn_zone 和limit_req_zone两个组件来对客户端访问目录和文件的访问频率和次数进行限制,另外还可以善用进行服务安全加固,两个模块都能够对客户端访问进行限制,具体如何使用要结合公司业务环境进行配置。
如能善用此模块能够对 cc、ddos等此类的攻击进行有效的防御。
先来看下我们的配置文件
geo $addr_req_whitelist {
ranges;
default 0;
111.206.171.51-111.206.171.51 1; #360 bjmd proxy
180.149.134.10-180.149.134.10 1; #weibo.com verification peer
# --- 百度免流IP段 2018-03-13 --- #
180.97.106.0-180.97.106.255 1;
}
map $http_x_forwarded_for $clientRealIp {
"" $remote_addr;
~^(?P<firstAddr>[0-9\.]+),?.*$ $firstAddr;
}
map $clientRealIp $clientRealIp2C {
~^(?P<ip2c>[0-9]+\.[0-9]+\.[0-9]+)\.[0-9]+$ $ip2c;
}
map $http_user_agent $dirtyUserAgent {
default $msec;
~^.*(?P<userAgent>Mb2345Browser/9.0).*$ $userAgent;
~^.*(?P<userAgent>LieBaoFast/4.51.3).*$ $userAgent;
~^.*(?P<userAgent>OPPO\sA33\sBuild/LMY47V).*$ $userAgent;
~^.*(?P<userAgent>MicroMessenger/6.5.16).*$ $userAgent;
~^.*(?P<userAgent>UpdateRankQ0003).*$ $userAgent;
}
map $http_user_agent $test_map {
default $clientRealIp;
~^.*(?P<userAgent>KHTML,\slike\sGecko).*$ $userAgent;
}
limit_req_whitelist geo_var_name=addr_req_whitelist geo_var_value=1;
#这是白名单用户
limit_conn_zone $clientRealIp zone=addr_conn_whitelist:10m;
limit_req_zone $clientRealIp zone=addr_req_whitelist:10m rate=4r/s;
#如果这个ip属于白名单里边那么可以执行 rate=4r/s(每秒4个请求)
#定义一个名为 addr_req_whitelist 的limit_req_zone用来存储session,大小是10M内存,
#注释 zone=addr_req_whitelist 中的 addr_req_whitelist 和
#1M能存储16000个状态,rete的值必须为整数,
limit_req_zone $clientRealIp $request_uri zone=addr_request_uri_req_whitelist:10m rate=2r/s;
limit_req_zone $clientRealIp2C zone=addr2c_req_whitelist:10m rate=4r/s;
limit_req_zone $dirtyUserAgent zone=user_agent_req_whitelist:10m rate=3r/m;
然后找资料理解这段配置
nginx限速配置指令
指令 limit_zone
语法:limit_conn_zone $variable zone=name:size;
默认值:no
使用字段:http
指令描述会话状态存储区域。
会话的数目按照指定的变量来决定,它依赖于使用的变量大小和memory_max_size的值。
指令 limit_conn (和上边的limit_conn_zone合起来用)
语法:limit_conn zone_name(limit_conn_zone $variable zone=name:size;就是这个里边的 zone=name) max_clients_per_ip
默认值:no
使用字段:http, server, location
指令指定一个会话的最大同时连接数,超过这个数字的请求将被返回”Service unavailable” (503)代码。
对上边的总结
limit_zone: 是针对每个IP定义一个存储session状态的容器.这个示例中定义了一个10m的容器,按照32bytes/session, 可以处理320000个session。
limit_conn one 1:限制每个IP只能发起一个并发连接。
limit_rate 300k: 对每个连接都产生限速300k. 注意,这里是对连接限速,而不是对IP限速。如果一个IP允许两个并发连接,那么这个IP就是限速limit_rate×2。(这里就能理解百度云盘了,,他对每个链接限速<100k,你不买会员就只能是一个链接给你下载,你买会员了,哈哈,那就可以多给你分点链接,你就下载的快了)
nginx限制访问频率配置指令
http {
limit_req_zone $binary_remote_addr zone=one:10m rate=1r/s;
server {
...
location /search/ {
limit_req zone=one burst=5;
#限制每ip每秒不超过1个请求,漏桶数burst为5,也就是队列.
#nodelay,如果不设置该选项,严格使用平均速率限制请求数,超过的请求被延时处理.
#举个栗子:
#设置rate=20r/s每秒请求数为20个,漏桶数burst为5个,
#brust的意思就是,如果第1秒、2,3,4秒请求为19个,第5秒的请求为25个是被允许的,可以理解为20+5
#但是如果你第1秒就25个请求,第2秒超过20的请求返回503错误.
#如果区域存储空间不足,服务器将返回503(服务临时不可用)错误
#速率在每秒请求中指定(r/s)。如果需要每秒少于一个请求的速率,则以每分钟的请求(r/m)指定。
#也可以这么,理解---上面的参数会让nginx 每个IP一秒钟只处理一个请求,但是仍然会有很多还在队列里面等待处理,这样也会占用很多tcp连接,从上面那条命令的结果中就能看得出来。如果加上nodelay就会立即丢弃 limit_req zone=one burst=10 nodelay;
}
指令 limit_req_zone
语法:limit_req_zone $session_variable zone=name:size rate=rate
默认值:none
上下文:http
命令解析:为session会话状态分配一个大小为size的内存存储区,限制了每秒(分、小时)只接受rate个IP的频率。
指令 limit_req (和上边的limit_req_zone合起来用)
语法:limit_req zone=name burst=burst [nodelay]
默认值:none
使用字段:http、server、location
命令解析:该指令用于指定使用的内存存储区(zone)名称,以及最大的突发请求数(burse)。如果请求的速率超过了limit_req_zone指令中设置的速率,这些请求将被延迟处理,在这种情况下,请求获得服务不可用信息,返回503状态码。
指令 limit_conn_log_level
语法: limit_conn_log_level info | notice | warn | error
默认值: error
使用字段: http, server, location
指定当连接数超过设定的最大连接数,服务器限制连接时的日志等级。