一、屏蔽IP
1、从日志查找要屏蔽的IP
logs目录下:awk '{print $1}' access.log |sort |uniq -c|sort -n
可以看到IP的访问次数
2、在conf目录下,添加IP黑名单
-
新建文件:blockip.conf 写入:deny 127.0.0.1;
-
nginx_conf中引入:
location /tb/ { alias html/tb/; index index.html; try_files $uri $uri/ /tb/index.html; include blockip.conf; #黑名单,可以在http, server, location, limit_except语句块 }
3、屏蔽与开放IP
被屏蔽的IP,再次访问时,会显示403
deny 127.0.0.1; #屏蔽单个IP
allow 127.0.0.1; #允许单个IP
deny all; #屏蔽所有IP
allow all; #运行所有IP
4、IP监控脚本
shell脚本分析日志,自动屏蔽恶意IP;摘自网上,可用性未测;
需要分割日志。因为是单位时间内访问过高才仍为是攻击者,而日志是全部的。
nginx可以配置日志切割
#! /bin/bash
log_nginx="/var/log/nginx" # nginx日志文件
blockfile="/usr/local/nginx/conf/website" #ip黑名单那
#取出日志中符合条件的ip写入ip.txt,并过滤掉重复的
grep "app/user/getCode" $log_nginx/access.log | awk '{print $1}' | sort -rn |uniq -c |awk '{print $2}' > /home/shell/ip.txt
for ip in `cat /home/shell/ip.txt`
do
result=$(grep $ip $blockfile/blockip.conf)
#判断ip是否已经被屏蔽
if [ -z "$result" ]; then
#分析ip请求的次数
count=$(grep $ip $log_nginx/access.log|grep "app/user/getCode"|wc -l)
#请求次数大于等于20次就进行屏蔽
if [ $count -ge 20 ]; then
echo "deny $ip;" >> $blockfile/blockip.conf
fi
fi
done
#重启nginx
/usr/local/nginx/sbin/nginx -s reload
二、访问限制模块
1、limit_req_zone:限制每个IP的请求数
http {
#定义一个名为ttlsa_com的请求限制块
#块的容量为10m,使用$binary_remote_addr变量, 可以将每条状态记录的大小减少到64个字节,这样1M的内存可以保存大约1万6千个64字节的记录。
#如果限制域的存储空间耗尽了,对于后续所有请求,服务器都会返回 503
#rete是请求速度,每秒/分钟处理请求数;30r/m,表示2秒处理一个请求。
#超过请求速度的请求将被延迟,直到被延迟的请求超过了定义的阈值,这时请求将被终止并返回503,阈值默认是0
limit_req_zone $binary_remote_addr zone=ttlsa_com:10m rate=1r/s;
limit_req_zone $binary_remote_addr $uri zone=two:3m rate=1r/s; #$uri表示同个ip访问同个uri,才会进入限制
server {
location ^~ /download/ {
#允许超过频率限制的请求数不多于5个。
#burst=5,相当于设置一个大小为5的缓冲区,超过了访问频次的请求会先放到这个缓冲区中等待。
#但是这个缓冲区大小只有5,超过缓冲区的请求会直接503
#nodelay是无延迟的意思,表示请求超过频次时,可提供处理(burst + rate)个请求的能力
#请求超过(burst + rate)的时候就会直接返回503,永远不存在请求需要等待的情况。
#注意:不存在单独使用nodelay的情况。nodelay是和burst配合使用的
limit_req zone=ttlsa_com burst=5 nodelay;
alias /data/www.ttlsa.com/download/;
}
}
}
limit_req_zone:http;定义一个会话区,记录会话状态信息。以$binary_remote_addr为key;也就是说一个IP就是一个会话;
limit_req_conn:;指定一个会话的最大请求数;
limit_req:http, server, location
limit_req_status:http, server, location,设置拒绝请求的响应状态码,默认是503
2、limit_conn_zone:限制每个IP的并发连接数
http{
# $binary_remote_addr是限制同一客户端ip地址;
limit_conn_zone $binary_remote_addr zone=limit:10m;
limit_conn_zone $server_name zone=perserver:10m;
limit_conn_log_level info;
server {
location ^~ /download/ {
limit_conn perserver 1000; #表示该服务提供的总连接数最大不超过1000,超过的请求会被拒绝
limit_conn limit 4; #表示每个IP的最大并发连接数为4
limit_rate 200k; #这里是对连接的限速,不是对IP的限速
alias /data/www.ttlsa.com/download/;
}
}
}
zone:块的意思
limit_conn_zone:http;定义一个会话区,记录会话状态信息。以$binary_remote_addr为key;也就是说一个IP就是一个会话;
limit_conn:http, server, location
limit_rate:http, server, location, if in location;每个连接的速率限制;
limit_conn_status:http, server, location;指定超过限制事返回的状态码,默认是503;
3、白名单
如果 Nginx 前面有 lvs 或者 haproxy 之类的负载均衡或者反向代理,nginx 获取的都是来自负载均衡的连接或请求,这时不应该限制负载均衡的连接和请求,就需要 geo 和 map 模块设置白名单了;
geo $whiteiplist {
default 1;
10.11.15.1610;
}
map $whiteiplist $limit {
1$binary_remote_addr;
0"";
}
limit_req_zone $limit zone=one:10m rate=10r/s;
limit_conn_zone $limit zone=addr:10m;