nginx简单的防DDos攻击-网络安全机制 有更新!

  Bob

1. HttpLimitReqModul限制某一段时间内同一ip访问数实例

http{
...
#定义一个名为allips的limit_req_zone用来存储session,大小是10M内存,
#以$binary_remote_addr 为key,限制平均每秒的请求为20个,
#1M能存储16000个状态,rete的值必须为整数,
#如果限制两秒钟一个请求,可以设置成30r/m
limit_req_zone $binary_remote_addr zone=allips:10m rate=20r/s;
...
server{
...
location {
...
#限制每ip每秒不超过20个请求,漏桶数burst为5
#brust的意思就是,如果第1秒、2,3,4秒请求为19个,
#第5秒的请求为25个是被允许的。
#但是如果你第1秒就25个请求,第2秒超过20的请求返回503错误。
#nodelay,如果不设置该选项,严格使用平均速率限制请求数,
#第1秒25个请求时,5个请求放到第2秒执行,
#设置nodelay,25个请求将在第1秒执行。
limit_req zone=allips burst=5 nodelay;
...
}
...
}
...
}

2.HttpLimitZoneModule限制并发连接数实例

limit_zone只能定义在http作用域,limit_conn可以定义在http server location作用域

http{
...#定义一个名为one的limit_zone,大小10M内存来存储session,

#以$binary_remote_addr 为key
#nginx 1.18以后用limit_conn_zone替换了limit_conn
#且只能放在http作用域
limit_conn_zone one $binary_remote_addr 10m;
...
server{
...
location {
...
limit_conn one 20; #连接数限制#带宽限制,对单个连接限数,如果一个ip两个连接,就是500x2k

limit_rate 500k;...

}
...
}
...
}

3.nginx白名单设置

以上配置会对所有的ip都进行限制,有些时候我们不希望对搜索引擎的蜘蛛或者自己测试ip进行限制,

1.对于特定的白名单ip我们可以借助geo指令实现。

http{
geo $limited{
default 1;
#google
64.233.160.0/19 0;
65.52.0.0/14 0;
66.102.0.0/20 0;
66.249.64.0/19 0;
72.14.192.0/18 0;
74.125.0.0/16 0;
209.85.128.0/17 0;
216.239.32.0/19 0;
#M$
64.4.0.0/18 0;
157.60.0.0/16 0;
157.54.0.0/15 0;
157.56.0.0/14 0;
207.46.0.0/16 0;
207.68.192.0/20 0;
207.68.128.0/18 0;
#yahoo
8.12.144.0/24 0;
66.196.64.0/18 0;
66.228.160.0/19 0;
67.195.0.0/16 0;
74.6.0.0/16 0;
68.142.192.0/18 0;
72.30.0.0/16 0;
209.191.64.0/18 0;
#My IPs
127.0.0.1/32 0;
123.456.0.0/28 0; #example for your server CIDR
}

geo指令定义了一个白名单$limited变量,默认值为1,如果客户端ip在上面的范围内,$limited的值为0

2.使用map指令映射搜索引擎客户端的ip为空串,如果不是搜索引擎就显示本身真是的ip,这样搜索引擎ip就不能存到limit_req_zone内存session中,所以不会限制搜索引擎的ip访问

map $limited $limit {
1 $binary_remote_addr;
0 "";
}

3.设置limit_req_zone和limit_req

  1. limit_req_zone $limit zone=foo:1m rate=10r/m;
  2. limit_req zone=foo burst=5;

4. allow和deny--允许ip和限制ip

allow 
语法:allow address |CIDR|unix:|all: 
默认值:None 
区间:http,server,location,limit_except 
允许一个ip或者ip段访问

deny 
语法:deny address |CIDR|unix:|all: 
默认值:None 
区间:http,server,location,limit_except 
禁止一个ip或者ip段访问

为什么最后会有斜杠呢,其实这是表示ip段的意思

#屏蔽单个IP的命令是
deny 192.168.1.1
#封整个段即从123.0.0.1到123.255.255.254的命令
deny 123.0.0.0/8
#封IP段即从123.45.0.1到123.45.255.254的命令
deny 124.45.0.0/16
#封IP段即从123.45.6.1到123.45.6.254的命令是
deny 123.45.6.0/24

也就是说,如果最后的斜杠后的数值: 

8:匹配后三位最大值的 

16:匹配后两位最大值的 

24:匹配后一位最大值的

简单一点举例说明:
ip段:10.0.0.1-10.0.0.255            的表示方法:10.0.0.0/24
ip段:10.0.0.1-10.0.255.255        的表示方法:10.0.0.0/16
ip段:10.0.0.1-10.255.255.255      的表示方法:10.0.0.0/8

 

5. 阻止特定用户代理(UA)

#大小写无关的匹配

server {
     ...

    if($http_user_agent ~*(netcrawl|npbot|malicious)){
        return403;
    }

  ...

}

在运维的配置上我是以以下形式配置:

server {

    # Load configuration files for the default server block.
    include /etc/nginx/default.d/*.conf;

    ....

}

把下面这段放到/etc/nginx/default.d/deny.conf文件里

if($http_user_agent ~*(netcrawl|npbot|malicious)){
        return403;
}

6. 用户认证配置( Basic HTTP authentication)

ngx_http_auth_basic_module模块实现让访问着,只有输入正确的用户密码才允许访问web内容。

语法:     auth_basic string | off;
默认值:     auth_basic off;
配置段:     http, server, location, limit_except
默认表示不开启认证,后面如果跟上字符,这些字符会在弹窗中显示。
语法:     auth_basic_user_file file;
默认值:     —
配置段:     http, server, location, limit_except


用户密码文件,文件内容类似如下:

ttlsauser1:password1

ttlsauser2:password2:comment

server{
  server_name bob.kim;
  location /
  {
    auth_basic "nginx basic http for bob.kim";
    auth_basic_user_file /etc/nginx/htpasswd;
    autoindex on;
  }
}

生成密码
可以使用htpasswd,或者使用openssl

# printf "ttlsa:$(openssl passwd -crypt 123456)\n" >>conf/htpasswd
# cat conf/htpasswd
ttlsa:xyJkVhXGAZ8tM

账号:ttlsa
密码:123456

 

案例:

限制只允许一分钟内只允许一个ip访问60次配置,也就是平均每秒1次
首先我们准备一个test.php脚本放在根目录$document_root下。

http{
...
limit_req_zone $binary_remote_addr zone=allips:10m rate=60r/m;
...
server{
...
location {
...
limit_req zone=allips;
...
}
...
}
...
}

如果我们未设置brust和nodelay,则可以看到该配置只允许每秒访问1次,超出的请求会返回503错误:

现在我们设置一下brust和nodelay,结果如下:

http{
...
limit_req_zone $binary_remote_addr zone=allips:10m rate=60r/m;
...
server{
...
location {
...
limit_req zone=allips burst=1 nodelay;
...
}
...
}
...
}

可以看出,设置了brust=1和nodelay后,第1秒可以处理两个请求。

另外,我还测试出HttpLimitReqModul在移动4G网下无法访问的问题,具体原因待查。

 

 

阻止用户代理测试

[test@izj6cgiyyob8z default.d]# wget --user-agent "netcrawl" https://bob.kim

 

--2018-04-01 09:57:13-- https://bob.kim/
Resolving bob.kim (bob.kim)... 47.75.83.131
Connecting to bob.kim (bob.kim)|47.75.83.131|:443... connected.
HTTP request sent, awaiting response... 403 Forbidden
2018-04-01 09:57:13 ERROR 403: Forbidden.

 


如有疑问或同行交流欢迎加群讨论:铂金信息技术交流群 151258054