网站遭遇CC攻击怎么破?

2021-08-25 14:21:22 浏览数 (1)

最近,有朋友反映自家网站访问速度明显慢了许多,用 top 命令查看发现 CPU 快被占满了,HTTP 连接数不断攀升,愈演愈烈。了解后得知,这已经不是网站第一次遭受 CC 攻击了,之前试过使用 Apache 做反向代理配置,可是 Apache 也没扛住。

一、何为CC攻击

那么,什么是 CC 攻击呢?

这里用一个段子做引,顾客点了份鱼香肉丝没有肉丝,找店家理论,店家矢口否认,于是第二天顾客找了 N 多闲杂人等把小饭馆全部坐满,还不消费,正常顾客无法消费就餐,店主损失巨大。

这,就是店家不懂 CC 攻击的下场。

CC 攻击/Challenge Collapsar 是指攻击者控制某些主机,不断发送大量数据包给网站服务器,造成服务器资源耗尽,直到宕机崩溃。大家或多或少都有过网页访问人数过多导致网页打不开或者打开非常慢的经历,CC 攻击就会造成如此结果。CC 攻击由 DDoS 攻击而生出,是 DDoS 的子集,它的攻击对象是网站页面,会模拟多个用户 (多少线程就是多少用户) 不停地访问那些需要大量数据操作 (意味着需要大量 CPU 时间) 的页面,造成服务器资源浪费,CPU 长时间处于 100% 的状态,处理不尽的连接导致网络拥塞,正常访问便会被中止。

CC攻击的特点

  1. 攻击的 IP 都是真实的、有效的,无法拒绝;
  2. 发送的数据包都是正常的数据包;
  3. 攻击的是网页,服务器可以连接,就是网页访问不了;
  4. 攻击成本低、技术含量低、容易实施,主机影响巨大。

二、如何判断CC攻击

CC 攻击发生时,经常出现带宽资源被严重消耗,网站瘫痪;CPU、内存利用率飙升,主机瘫痪;瞬间快速打击,无法快速响应这些现象。这时,比较简单直接的判断方法就是查看 80 端口的连接数,对比正常情况,如果相差悬殊,甚至无法统计,基本可以断定是 CC 攻击了。

代码语言:txt复制
netstat -an|grep ':80' -c

三、测试&防御

我们使用 Apache 自带的压力测试工具 ab 做并发测试,可以模拟多用户访问。

环境

VMware、CentOS Linux release 7.7、Apache/2.4.38 (event 加载方式) 和 Nginx/1.16.0。

测试 I

模拟 600 个用户同时访问,共访问 10000 次,执行:

代码语言:txt复制
ab.exe -n 10000 -c 600 -r   http://www.cc.com/test.html

ab 返回的结果如下:

代码语言:txt复制
Completed 1000 requests
Completed 2000 requests
Completed 3000 requests
Completed 4000 requests
Completed 5000 requests
Completed 6000 requests
Completed 7000 requests
Completed 8000 requests
Completed 9000 requests
Completed 10000 requests
Finished 10000 requests

Server Software:        Apache/2.4.38
Server Hostname:        10.232.16.55
Server Port:            80

Document Path:          /test.html
Document Length:        24738 bytes
Concurrency Level:      600
Time taken for tests:   56.949 seconds
Complete requests:      10000

Apache 日志:

代码语言:txt复制
10.232.18.53 - - [04/Dec/2019:20:51:04  0800] "GET /test.html HTTP/1.0" 200 24738
10.232.18.53 - - [04/Dec/2019:20:51:05  0800] "GET /test.html HTTP/1.0" 200 24738
10.232.18.53 - - [04/Dec/2019:20:51:05  0800] "GET /test.html HTTP/1.0" 200 24738
10.232.18.53 - - [04/Dec/2019:20:51:06  0800] "GET /test.html HTTP/1.0" 200 24738
10.232.18.53 - - [04/Dec/2019:20:51:07  0800] "GET /test.html HTTP/1.0" 200 24738
10.232.18.53 - - [04/Dec/2019:20:51:07  0800] "GET /test.html HTTP/1.0" 200 24738
10.232.18.53 - - [04/Dec/2019:20:51:08  0800] "GET /test.html HTTP/1.0" 200 24738
10.232.18.53 - - [04/Dec/2019:20:51:10  0800] "GET /test.html HTTP/1.0" 200 24738
10.232.18.53 - - [04/Dec/2019:20:51:10  0800] "GET /test.html HTTP/1.0" 200 24738
10.232.18.53 - - [04/Dec/2019:20:51:10  0800] "GET /test.html HTTP/1.0" 200 24738

可以看到,Apache 可以绰绰有余地应付,访问一切正常。

测试 II

将并发数提高到 900,再来看 Apache 的反应,执行:

代码语言:txt复制
ab.exe -n 10000 -c 900 -r   http://www.cc.com/test.html

ab 返回的结果为:

代码语言:txt复制
Total of 1 requests completed

Apache 错误日志:

代码语言:txt复制
[Wed Dec 04 21:08:25.654731 2019] [mpm_event:error] [pid 46995:tid 139688010909504] AH00484: server reached MaxRequestWorkers setting, consider raising the MaxRequestWorkers setting

这一次的访问量,Apache 已无法应对,页面出现无法访问的情况:

图1图1

Apache 防御模块

Apache 可以通过加载 mod_evasive 模块缓解 CC 攻击。mod_evasive 模块提供多个可选参数,通过简单设置这些参数,可以在遭受攻击期间规避操作,并可通过电子邮件和系统日志工具报告滥用行为,如匹配设定参数则发送 403 响应并记录 IP 地址 。

可选参数:

代码语言:txt复制
<IfModule mod_evasive20.c>
    DOSHashTableSize 3097
    DOSPageCount 2
    DOSSiteCount 50
    DOSPageInterval 1
    DOSSiteInterval 1
    DOSBlockingPeriod 60
    DOSEmailNotify <someone@somewhere.com>
</IfModule>

DOSPageCountDOSSiteCount 是比较温和的两个值,以避免客户端被不必要地阻塞。

DOSPageCount 是对每个 IP 地址单位时间 (通常为 1s) 内对同一个 URL 页面的请求数量限制。超过该时间间隔的阈值,客户端的 IP 地址会自动被加到阻止列表中。

DOSSiteCount 是对每个 IP 地址单位时间 (通常为 1s) 内对整个网站的请求总数限制。可以酌情修改为更大的值。

如下例子中,Apache 配置文件 httpd.conf 中设置以下参数:

代码语言:txt复制
LoadModule evasive20_module /usr/lib64/httpd/modules/mod_evasive24.so 
<IfModule evasive20_module>
    DOSPageCount 2
    DOSSiteCount 100
    DOSLogDir /var/log
</IfModule>

再次测试 900 的并发数,执行 ab.exe-n10000-c900-r http://www.cc.com/test.html,看 Apache 作何反应。在前面完全没有防护措施的场景中,Apache 无法应对这种测试。

Apache 日志:

代码语言:txt复制
[Wed Dec 04 21:52:40.582741 2019] [:error] [pid 49596:tid 139700899661568] [client 10.232.18.53:58234] client denied by server configuration: /usr/local/apache2.4/htdocs/test.html
[Wed Dec 04 21:52:40.583081 2019] [:error] [pid 49596:tid 139700899661568] [client 10.232.18.53:58235] client denied by server configuration: /usr/local/apache2.4/htdocs/test.html
[Wed Dec 04 21:52:40.583323 2019] [:error] [pid 49596:tid 139700899661568] [client 10.232.18.53:58236] client denied by server configuration: /usr/local/apache2.4/htdocs/test.html

可以看出,mod_evasive 模块已生效,阻止同一用户非正常的大量并发访问,而其他用户访问正常。

Nginx 防御模块

当 Web 服务器软件切换为 Nginx,测试内容与 Apache 相同。虽然 Nginx 处理并发的能力远远大过 Apache,但并发量不断增加,同样会耗尽资源。我们不禁会问,Apache 有 mod_evasive 模块,那 Nginx 呢?

Nginx 主要通过 ngx_http_limit_conn_modulengx_http_limit_req_module 这两个内置模块来防御 CC 攻击。

ngx_http_limit_conn_module 可以限制单个 IP 地址的连接数。但并不是所有的连接都会被计数,只有当一个请求的整个请求头都已经被读取并且正在被服务器处理,这个请求所在的连接才会被计数。

ngx_http_limit_req_module 则可以限制单个 IP 每秒请求数。通过漏斗算法,限制每秒固定处理请求数,推迟过多请求。

nginx.conf 中的配置如下:

代码语言:txt复制
http {

    limit_conn_zone $binary_remote_addr zone=cc_conn:10m;
    limit_req_zone $binary_remote_addr zone=cc_req:10m rate=1r/s;
    ...

    server {
        limit_conn cc_test 20;  #同一个ip并发连接数不能超过20个
        ...

        location / {
            limit_req zone=cc_req burst=20 nodelay;  #限制平均每秒不超过一个请求,同时允许超过频率限制的请求数不多于20个,用nodelay参数表示不希望超过的请求被延迟。
            ...
            }
        }
    }

再次测试 1000 的并发数,执行:

代码语言:txt复制
ab.exe -n 10000 -c 1000 http://www.cc.com/test.html

结果是这样的:

代码语言:txt复制
10.232.18.153 - - [05/Dec/2019:22:42:19  0800] "GET /test.html HTTP/1.0" 200 24738 "-" "ApacheBench/2.3"
10.232.18.153 - - [05/Dec/2019:22:42:19  0800] "GET /test.html HTTP/1.0" 503 494 "-" "ApacheBench/2.3"
10.232.18.153 - - [05/Dec/2019:22:42:20  0800] "GET /test.html HTTP/1.0" 503 494 "-" "ApacheBench/2.3"
10.232.18.153 - - [05/Dec/2019:22:42:20  0800] "GET /test.html HTTP/1.0" 503 494 "-" "ApacheBench/2.3"
10.232.18.153 - - [05/Dec/2019:22:42:20  0800] "GET /test.html HTTP/1.0" 503 494 "-" "ApacheBench/2.3"
10.232.18.153 - - [05/Dec/2019:22:42:20  0800] "GET /test.html HTTP/1.0" 503 494 "-" "ApacheBench/2.3"
10.232.18.153 - - [05/Dec/2019:22:42:20  0800] "GET /test.html HTTP/1.0" 503 494 "-" "ApacheBench/2.3"
10.232.18.153 - - [05/Dec/2019:22:42:20  0800] "GET /test.html HTTP/1.0" 503 494 "-" "ApacheBench/2.3"
10.232.18.153 - - [05/Dec/2019:22:42:20  0800] "GET /test.html HTTP/1.0" 503 494 "-" "ApacheBench/2.3"

返回 503 (limit_conn和limit_req 的默认返回码),说明大量非正常并发连接已被拦截。


通过以上测试可以看出,Apache 通过加载 mod_evasive 模块、Nginx 通过加载内置 ngx_http_limit_conn_modulengx_http_limit_req_module 模块都可以实现防御 CC 攻击的效果。当然如果配合 iptables 等机制限制 IP 黑名单,效果会更好。

以上方法都是通过限制并发连接数量的手段,达到防止 CC 攻击的目的。当然还有另外的方法,如接入 CDN,多台做负载均衡,扩大带宽等。(卢岩 | 天存信息)

0 人点赞