网站如何防CC攻击--巧用nginx

Linux · Fecmall · 于 1年前 发布 · 1827 次阅读

最近跟大佬练习网站攻防。本来做好了防ddos的准备,没想到大佬花了几分钟就写了个node.js的脚本,直接对我的服务器发起了cc攻击,瞬间服务器cpu跑满,2秒即502。在感叹大佬的技术之外,我也顺便写下了这篇文章,记录一下如何使用node.js进行CC攻击以及如何防范。

转载地址:https://www.xiaoweigod.com/webserver/1545.html?spm=5176.smartservice_service_robot-chat.0.0.619df625i0JfNJ

先来看看CC攻击原理:

攻击者借助代理服务器生成指向受害主机的合法请求,实现DDOS和伪装就叫:CC(ChallengeCollapsar)。

CC主要是用来攻击页面的。大家都有这样的经历,就是在访问论坛时,如果这个论坛比较大,访问的人比较多,打开页面的速度会比较慢,访问的人越多,论坛的页面越多,数据库压力就越大,被访问的频率也越高,占用的系统资源也就相当可观。

一个静态页面不需要服务器多少资源,甚至可以说直接从内存中读出来发给你就可以了,但是论坛就不一样了,我看一个帖子,系统需要到数据库中判断我是否有读帖子的权限,如果有,就读出帖子里面的内容,显示出来——这里至少访问了2次数据库,如果数据库的数据容量有200MB大小,系统很可能就要在这200MB大小的数据空间搜索一遍,这需要多少的CPU资源和时间?如果我是查找一个关键字,那么时间更加可观,因为前面的搜索可以限定在一个很小的范围内,比如用户权限只查用户表,帖子内容只查帖子表,而且查到就可以马上停止查询,而搜索肯定会对所有的数据进行一次判断,消耗的时间是相当的大。

CC就是充分利用了这个特点,模拟多个用户(多少线程就是多少用户)不停的进行访问(访问那些需要大量数据操作,就是需要大量CPU时间的页面).这一点用一个一般的性能测试软件就可以做到大量模拟用户并发。

CC攻击也是DDOS中的一种,传统意义上的DDOS攻击为流量攻击,即通过发送大量的垃圾请求,把你的服务器带宽占满,导致服务器无法对外提供服务。而CC攻击则是通过模拟多线程多用户,对服务器进行访问,直到使服务器的硬件满载,无法提供服务,这时候也就达到了目的,打开网页会返回502。

先看看效果,这是我对自己网站攻击的截图:

攻击开始前,使用 top 命令查看web服务器负载

可以看到,cpu负载0.3%,内存剩余35%左右。

然后我在另一台服务器开始对web服务器进行CC攻击:

直接就564错误了。

我们看看被攻击的时候,web服务器负载:

CPU负载直接飙到96%!并且产生了大量php的进程。

我们再看看发起攻击服务器的资源占用:

只有10%,妥妥的,同配置的服务器,可以一次性攻击9台其他服务器。

CC攻击在web攻击中普遍存在,于是好奇心下友情测试了几个网站(小规模测试,返回500code即停止攻击),发现几个网站基本都没做什么CC防护,2秒就直接瘫痪了。有些服务器配置稍微好一点的,在一台服务器上开了5-6个窗口同时进行攻击,撑了一会儿就502了。

那么怎么防止CC攻击呢?其实服务器的web程序nginx就自带了防CC攻击的模块:limit_conn和limit_req

下面来演示下如何使用这两个模块防止CC攻击。

操作环境:centos7系统,LNMP环境

1.先在nginx中引入这两个模块:

vim /usr/local/nginx/conf/nginx.conf

在 http和server之间加入如下内容:

limit_conn_zone $binary_remote_addr zone=perip:10m;
limit_req_zone $binary_remote_addr zone=allips:10m rate=5r/s;

参数说明:

$binary_remote_addr是限制同一客户端ip地址;

$server_name是限制同一server最大并发数;

limit_conn为限制并发连接数;

limit_rate为限制下载速度;

2.在网站配置文件中加入限制条件

vim /usr/local/nginx/conf/vhost/你的域名.conf

在server下加入如下内容:

limit_conn perip 6;  #每个IP并发连接数量
limit_req zone=allips burst=5 nodelay;  #通过令牌桶限制IP连接

参数说明:

limit_conn perip x; x为单个IP的最大并发连接数量,超过这个数量将不接受连接。

limit_req zone=allips burst=x nodelay; x为最大延迟请求数,如果太过多的请求被限制延迟是不需要的 ,这时需要使用nodelay参数,服务器会立刻返回503状态码。

这几个参数可以根据自己服务器配置改,限制太小的话会影响正常访问,限制太大则会影响防CC的效果。

改完之后重启nginx看看效果:

service nginx restart

3.测试防CC效果

我们再用刚才的脚本来测试攻击。

攻击前服务器负载:

image.png

CPU占用依然为 0.3%

开始攻击:

image.png

我们可以看到服务器返回了大量的503。这是因为访问被拒绝了

被攻击时服务器的负载:

image.png

可以很明显看到,php进程变少了,且CPU负载为23%,不像之前一样满载了。

这时候我们还是可以很顺畅地打开网页:

image.png

4.总结

这个防CC机制是nginx自带的,只能抵御基本的CC攻击。因为是通过限制单个IP访问速度来防CC,所以当攻击者使用大量肉鸡攻击的话,那么基本上就死路一条,甚至连你的nginx程序也会直接崩溃。当然我们这种小站也很难会受到大型的CC攻击,至少先保证不会被随便一台服务器或者家用电脑干掉,那样可真的太丢脸了。

当然,如果要进一步防CC攻击,可以提升服务器的配置,或者使用云服务器商提供的安全防护。另外,也可以通过CDN主备站+nginx反向代理做负载均衡,使用多台服务器来抵御DDOS(包括流量攻击和CC攻击)。这里有张自己作的网站架构图可以给大家参考下,希望大家可以开开心心把网站开到地老天荒!

共收到 4 条回复
Fecmall#11年前 0 个赞

nginx access log(nginx访问日志),进行统计IP次数:

1.查看访问量比较大的IP:

cat /www/web_logs/fecmall-access.log | awk '{print $1}' | sort | uniq -c | sort -k 1 -n -r |head -n 20

2.封IP:

iptables -I INPUT -s 49.233.117.204 -j DROP

3.封禁IP段:

47.104.*.*

120.53.220.*

iptables -I INPUT -s  47.104.0.0/16 -j DROP
iptables -I INPUT -s  120.53.220.0/24  -j DROP
iptables -I INPUT -s  47.105.0.0/16 -j DROP
iptables -I INPUT -s  49.233.0.0/16 -j DROP
iptables -I INPUT -s  49.232.0.0/16 -j DROP
iptables -I INPUT -s  118.190.0.0/16 -j DROP

4.iptables 保存:

service iptables save

备注:

比如您这边厢47.104.0.0-47.104.255.255

这个的话就要在后面跟一个子网掩码

一般分为8,16,24

对应的就是IPV4的四个地址数

比如1.0.0.0/8就是1.255.255.255-1.0.0.0的所有网段

如果是1.0.0.0/16
就是1.0.255.255-1.0.0.0

如果是1.0.0.0/24

就是1.0.0.255-1.0.0.0
Fecmall#21年前 0 个赞

ip查询:https://www.cip.cc/

Fecmall#41年前 0 个赞

贴个半自动封IP代码

1.设置nginx的访问日志,日志文件为: /www/web_logs/fecmall-access.log

2.执行命令行:cat /www/web_logs/fecmall-access.log | awk '{print $1}' | sort | uniq -c | sort -k 1 -n -r |head -n 20

输出为:

1663 39.107.110.239
1620 8.142.99.147
1466 103.142.110.98
1309 121.37.255.79
1301 39.106.69.122
1284 114.115.181.74
1262 47.99.142.165
1258 116.205.189.176
1223 116.205.224.136

左边为ip访问的次数,右边为ip

3.通过php代码,生成iptables封禁ip的代码:

$s = "
          2041 147.226.7.161
   1663 39.107.110.239
   1620 8.142.99.147
   1466 103.142.110.98
   1309 121.37.255.79
   1301 39.106.69.122
   1284 114.115.181.74
   1262 47.99.142.165
   1258 116.205.189.176
   1223 116.205.224.136

        ";
        $ss = explode("\r\n", $s);
        $arrr = [];

        foreach ($ss as $s) {
            $d = trim($s);
            if (empty($d)) {

                continue;
            }
            $arr = explode(' ', $d);
            $ip = $arr[1] ?? '';
            if (!$ip) {
                continue;
            }
            $arrr[] = 'iptables -I INPUT -s '.$ip. ' -j DROP';
        }
        $arrr[] = 'service iptables save';
        echo implode("\r\n", $arrr);exit;

输出结果如下:

iptables -I INPUT -s 147.226.7.161 -j DROP
iptables -I INPUT -s 39.107.110.239 -j DROP
iptables -I INPUT -s 8.142.99.147 -j DROP
iptables -I INPUT -s 103.142.110.98 -j DROP
iptables -I INPUT -s 121.37.255.79 -j DROP
iptables -I INPUT -s 39.106.69.122 -j DROP
iptables -I INPUT -s 114.115.181.74 -j DROP
iptables -I INPUT -s 47.99.142.165 -j DROP
iptables -I INPUT -s 116.205.189.176 -j DROP
iptables -I INPUT -s 116.205.224.136 -j DROP
iptables -I INPUT -s 116.205.242.129 -j DROP
service iptables save

粘贴到linux执行即可封禁IP、

添加回复 (需要登录)
需要 登录 后方可回复, 如果你还没有账号请点击这里 注册
Your Site Analytics