CC 攻击和采集都是同个IP发起大量访问请求,这个会造成大量请求拥堵,导致服务器资源耗尽,CC攻击主要针对特定服务接口,属于实现 DoS 攻击的一种方式。

如果没有套上CDN,那其实防御思路非常简单,识别出访问量大的IP,直接用服务器的iptable防火墙封禁IP就行了,但是如果使用CDN,那所有访客都是通过CDN连接我们的服务器,这种情况下,服务器封禁IP的话,只能封到CDN的IP,无法阻止CDN后面的真实访客访问,对这部分有攻击行为的访客,只能通过CDN的防火墙,导入IP黑名单方式来屏蔽。

虽然服务器级别的封禁IP,在CDN下有难度,但是通过NGINX还是可以识别到单独的访问进程,通过识别出CDN后的真实IP访问,在处理这部分访问的时候,直接转给他502页面,不进行后续网页输出就行。

说一下NGINX 流控,有两种方式:

limit_req_zone:通过“漏桶”算法限制每个 IP 发起的请求频率。

limit_conn_zone:限制每个 IP 发起的连接数。

实践配置

一般NGINX 部分 配置error_log /www/wwwlogs/nginx_error.log error;

这样才能正确显示到被封禁的错误记录出来个FAIL2BAN使用

然后在 http 部分中配置:

 map $http_x_forwarded_for  $clientRealIp
{
    ""    $remote_addr; 
    ~^(?P<firstAddr>[0-9.]+),?.*$    $firstAddr;
}
limit_req_zone $clientRealIp zone=sym:10m rate=5r/s;
limit_conn_zone $clientRealIp zone=conn_sym:10m;    

然后在需要流控的站点的 location 部分配置:

limit_req zone=sym burst=5;
limit_conn conn_sym 10;

宝塔安装的NGINX按下面配置 先将

error_log  /www/wwwlogs/nginx_error.log  crit;

改成

error_log  /www/wwwlogs/nginx_error.log  error;

然后在http部分

include proxy.conf;下面增加 map $http_x_forwarded_for $clientRealIp { "" $remote_addr; ~^(?P[0-9.]+),?.*$ $firstAddr; }

将 limit_conn_zone $binary_remote_addr zone=perip:10m; 改成 limit_conn_zone $clientRealIp zone=perip:10m; 这样才能针对使用代理IP刷你的站的人的真实IP进行计数,达到每秒多少个就封禁访问

然后到需要进行防御的网站点设置-流量限制

这里启用流量限制,并将单IP并发数进行限制,一般如果网站页面不复杂设置为10就行。 接下来重启 NGINX 后当有超流客户端请求时将记录在 www/wwwroot/nginx_error.log(不是宝塔面板的话,NGINX默认错误日志在 /var/log/nginx/error.log) 中看到类似记录:

2018/04/27 14:25:27 [error] 6307#0: *1472746 limiting connections by zone "perip", client: 182.161.35.139, server: 104.153.102.68, request: "GET /index.php?10=8 HTTP/1.1"

此时请求已经被 NGINX 限流。