通过Nginx对CC攻击限流

时间:2024-11-10 12:03:38

最近公司部署到阿里金融云的系统遭受CC攻击,网络访问安全控制仅靠阿里云防火墙保障,在接入层及应用层并未做限流。

攻击者拥有大量的IP代理,只要合理控制每个IP的请求速率(以不触发防火墙拦截为限),仍给后端服务带来了很大的压力。

起缘:

存在一个检查某手机号是否已注册接口。(用户注册或重置密码时提示用户是否已存在)

/mobilePhone/existent?mobilePhone=13261748254

攻击者通过穷举调用,借此刺探出系统已注册的手机号列表。

接入层限流:

在接入层Nginx限制每个IP的并发请求数为10,每秒钟最大请求数为10。需要支持白名单IP,在白名单范围内的,不需要限速。

IP:由于Nginx隐藏在阿里云各种网络设备的后端,所以使用\(remote_addr是取不到客户的真实IP的。
一个思路是通过\)x_forwarded_for,取得代理链上所有的IP,然后解析出客户端IP。

其实阿里云前端的网络设备会把客户的终端地址通过HTTP头x_real_ip传递过来,所以只需要$http_x_real_ip即可取得客户的真实IP。

在nginx的http节点增加以下配置:

map $http_x_real_ip $limit {
default $http_x_real_ip; #self IP
"127.0.0.1" "";
}
limit_conn_zone $limit zone=ipc:20m;
limit_req_zone $limit zone=ipr:20m rate=10r/s;

在location节点增加以下配置:

limit_conn ipc 10;
limit_req zone=ipr burst=5 nodelay;

limit_conn和limit_req命令的详细使用请参考:

http://nginx.org/en/docs/http/ngx_http_limit_req_module.html

http://nginx.org/en/docs/http/ngx_http_limit_conn_module.html#limit_conn_zone_req

注意:

要修改zone名时,nginx -s reload是不会生效的,此时需要重启Nginx。

nginx -t测试通过,但nginx -s reload不生效时,请查看nginx的error日志,默认地址:/usr/local/nginx/logs/error.log

测试

使用Jmeter等压力测试工具,分别在白名单IP和非白名单IP下发起大量请求,默认被拦截请求响应码是503,日志为error

后续:

判断某手机号是否已注册交互增加图片验证码,防止机器暴力调用。