脚本编程

CCKiller:Linux轻量级CC攻击防御工具,秒级检查、自动拉黑和释放

Jager · 9月28日 · 2015年 · · · 18818次已读

张戈博客很久以前分享过一个CC 攻击的防御脚本,写得不怎么样,不过被 51CTO 意外转载了。博客从此走上了经常被人拿来练手的不归之路。

当然,还是有不少朋友在生产环境使用,并且会留言询问相关问题。根据这些问题的需求,我花了一些时间重新写了一个比较满意的轻量级 CC 攻击防御脚本,我给它取了一个比较形象的名字:CCKiller,译为 CC 终结者。

CCKiller:Linux轻量级CC攻击防御工具,秒级检查、自动拉黑和释放

一、功能申明

分享之前我必须先申明一下,众所周知,DDoS 攻击指的是分布式拒绝服务。而 CC 攻击只是 DDoS 攻击的一种,本文所阐述的 CC 攻击,指的是单个 IP 达到我们设定好的阈值并发请求,而非海量 IP 的低并发攻击!对于个人低配服务器,除了使用 CDN 来防护,至少我是没有想到如何抵挡海量 IP 攻击的!因为每个 IP 都模拟正常的用户浏览器请求,并不会触发防御阈值,同时来 1000 个,甚至上万个,个人低配服务器的带宽在第一时间就会被占满,就无法继续提供服务了。

当然,用脚本也是无法防御 DDoS 大流量攻击的,因为所有机房的防御带宽是有限的,当攻击的流量超过了机房的防御带宽,要么机房把你的服务器 IP 拉黑洞,要么就一起死。因此,如果你的服务器正遭受大流量攻击,比如几十 G 上百 G,一般机房或 CDN 节点都是扛不住的,脚本也无能为力了,赶紧换高防服务器吧!

二、功能介绍

通过以上申明,也就大致给 CCKiller 一个定位:CCKiller 是用于个人低配服务器的轻量级 CC 攻击防御,可以抵挡单个 IP 产生的高并发攻击。

目前设计的功能特性如下:

①、秒级检查

很多人写的防御脚本都是使用了 Linux 系统的计划任务 crontab 来定时检查的。而 crontab 的最细颗粒是 1 分钟,也就是说脚本最快也只能 1 分钟检查一次。对于一些强迫症来说就会很不爽。

所以,我还是按照以前分享的思路,利用 while 循环实现秒级检查,实现更细的颗粒。当然,CCKiller 更是被我写成了系统服务,更加灵活稳定。

②、拉黑时长

CCKiller 可以设置拉黑时长,默认为 10 分钟。当发现有恶意请求时,会自动拉黑目标 IP,并在拉黑时长结束后自动释放,这个功能算是对我之前写的脚本的一个大的改进。

③、并发阈值

CCKiller 可以设定单个 IP 的最高请求数,如果某个 IP 同时请求数超过了设定的阈值,就会被暂时拉黑一段时间。

④、邮件发送

这个功能没啥好说的,意义并不大。而且发送成功率和服务器的环境也有很大关系。

⑤、并发显示

安装后,直接运行 cckiller 会列出当前系统的请求排行,可以清晰的看到当前请求 IP 和并发数。使用-s 参数还可以继续定制需求,比如 cckiller -s 10 就能显示当前并发数排行前 10 名的 IP。

⑥、手动拉黑

支持手动拉黑,执行后会立即检查,将并发请求超过 n 的 IP 拉黑一段时间,比如 cckiller -k 100 就会将目前超过 100 个请求的 IP 拉黑一段时间,如果没有则不会执行任何拉黑操作。

三、工具安装

①、在线安装

由于我可能经常会更新一些功能,或修复一些 BUG,所以仅提供在线安装,以保证脚本是最新的。

安装非常简单,执行如下命令就能进入配置步骤了:

curl -ko install.sh --connect-timeout 300 --retry 5 --retry-delay 3 https://zhangge.net/wp-content/uploads/files/cckiller/install.sh?ver=1.0.8 && sh install.sh -i

2017-12-13 补充:Ubuntu 系统请参考 joviqiao 的版本=>传送门

2017-09-06 补充:CCKiller 代码早已提交到 Github,有网友问到,就来补充说明下 =>传送门

②、工具配置

因为每个服务器的情况可能不一样,所以有一个自定义配置的过程。

CCKiller:Linux轻量级CC攻击防御工具,秒级检查、自动拉黑和释放

执行上述安装命令后,将会进入自选配置部分,如图:

CCKiller:Linux轻量级CC攻击防御工具,秒级检查、自动拉黑和释放

提示否使用脚本默认配置,如果选择是(y),那么显示默认配置,并询问是否继续:

默认配置如下:

The Time interval : 20 s       #每 20s 检查一次系统请求情况

The Forbidden Time: 600 s  #拉黑时长设为 10 分钟

Adminstrator Email: root@localhost   #邮件对象设置为 root@localhost(即关闭邮件发送)

Connections Allow: 100      #单个 IP 并发限制为 100

如果不符合你的需求,你可以使用 ctrl + c 组合键终止脚本,或者先继续安装,因为工具设计了配置修改的功能,所以无需着急。

CCKiller:Linux轻量级CC攻击防御工具,秒级检查、自动拉黑和释放

如果不使用默认配置(n),则会要你输入参数来自定义配置:

CCKiller:Linux轻量级CC攻击防御工具,秒级检查、自动拉黑和释放

如图,我将参数依次定义为每 10 秒进行检查,拉黑时长为 300 秒,发件人设置为博客邮箱,并发限制设置为 60,回车后会弹出一个提示,让你检查,如果没问题你直接回车就会安装并启动:

③、服务控制

安装后,会将 cckiller 注册成系统服务,这时你就可以使用 service 来控制 cckiller 了。

使用标准的 service 定义,支持 start | stop | restart | status 四个参数。所以,你可以使用

service cckiller stop 来停止 cckiller,也可以使用 service cckiller status 来查看状态。

 ④、集成命令

成功安装后,系统还会多出一个 cckiller 的命令,这个命令现有功能如下:

cckiller -h 可以调出帮助信息:

CCkiller version 1.0.0 Author: Jager <[email protected]>
Copyright ©2015 zhang.ge. All rights reserved. 
Usage: cckiller [OPTIONS] [N]
N : number of tcp/udp   connections (default 100)
OPTIONS:
-h | --help: Show       this help screen
-k | --kill: Block the offending ip making more than N connections
-s | --show: Show The TOP "N" Connections of System Current

我蹩脚的英文也能凑合解释一下功能了吧~

-k 是拉黑功能,需要在后面带上你想拉黑的并发数,比如 cckiller -k 100 就会拉黑当前请求数大于 100 的 IP 一段时间(和拉黑时长一致)

-s 是显示并发排名,也需要在后面带上数字,比如 cckiller -s 10 就能显示当前并发数排行前 10 名的 IP。

⑤、文件结构

如上图所示,脚本安装目录为/usr/local/cckiller,其结构如下:

cckiller/
├── cckiller       #主程序
├── log/           #日志目录(ver 1.0.1 新增特性)
├── ck.conf        #配置文件
├── ignore.ip.list #白名单
└── install.sh     #安装和卸载脚本

0 directories, 5 files

很简单也比较规范的的结构,当然,后续功能如果越来越多,此结构可能会有所更新,这是后话。

如果你熟悉 vim 的话,只要编辑 ck.conf 就可以定义工具参数了:

##### Paths of the script and other files
PROGDIR="/usr/local/cckiller"
PROG="/usr/local/cckiller/cckiller"
LOGDIR="/usr/local/cckiller/log"
IGNORE_IP_LIST="/usr/local/cckiller/ignore.ip.list"
IPT="/sbin/iptables"
DKName=CCkiller
DKVer=1.0.5
##### SLEEP_TIME 设定检查频率,单位为秒
SLEEP_TIME=10
##### NO_OF_CONNECTIONS 设定并发限制
NO_OF_CONNECTIONS=60
##### EMAIL_TO 设定邮件的发送对象(请改为自己的邮箱地址)
EMAIL_TO="[email protected]" 
##### BAN_PERIOD 设定拉黑时长,单位为秒
BAN_PERIOD=300
##### 设置忽略端口,比如 21,2121,8000 (默认不忽略)
IGNORE_PORT=

##### 定义日志级别 INFO,DEBUG,WARNING,OFF (默认 INFO)
LOG_LEVEL=INFO

如果不熟悉也没关系。你还可以执行 ./install.sh -c 进行工具初始化,重新设定所有参数,过程和首次安装时一致,这里就不赘述了。

⑥、白名单

工具安装时会默认将系统所有 IP 都加入白名单,避免自己把自己给拉黑的尴尬。如果你还有其他要加白的 IP,可以将 IP 加入到 cckiller 安装目录下的 ignore.ip.list 文件中,每行一个。

Ps:目前白名单还不支持 IP 段,敬请期待后续更新。

⑦、卸载工具

有心的朋友可能注意到了 install.sh 是可以带参数的。我写代码的时候已经设计了几个常用的安装卸载功能,具体如下:

#直接执行./install.sh 将会显示如下帮助信息
###################################################################
#  CCkiller version 1.0.5 Author: Jager <[email protected]>          #
#  For more information please visit https://zhang.ge/5066.html #
#-----------------------------------------------------------------#
#  Copyright @2015 zhang.ge. All rights reserved.              #
###################################################################

Usage: configure.sh [OPTIONS]

OPTIONS:
-h | --help : Show help of CCkiller
-u | --update : update Check for CCkiller [not available now]
-c | --config : Edit The configure of CCkiller again
-i | --install : install CCkiller version 1.0.0 to This System
-U | --uninstall : Uninstall cckiller from This System

其中:

-u 参数用来升级工具,不过目前由于没时间还没写,所以不可用(Ver 1.0.2 已支持在线更新)

-i  参数用来安装工具,如果已安装则会提示并终止

-c 参数用来配置工具,方便安装后随时修改工具配置

-U 参数用来卸载工具,注意是大写哦!

因此,我们可以使用 ./install.sh -U  如图卸载 CCKiller:

CCKiller:Linux轻量级CC攻击防御工具,秒级检查、自动拉黑和释放

四、攻防测试

成功安装并启用 CCKiller 之后,我们可以使用压力测试工具来测试拉黑和释放效果,比如 webbench 或 ab 等。

假如 CCKiller 设定的并发限制为 100,检查间隔为 10s,使用 webbench 如下测试:

webbench -c 101 -t 60 http://www.yourwebsite.com/

启动测试后,你可以立即去服务器上查看防火墙

iptables -nvL

多刷几下,就可以看到 webbench 所在服务器 IP 已经在 DROP 规则中了。

确定已被拉黑之后,你等个 10 分钟再来看防火墙,可以发现 webbench 所在服务器 IP 已经消失了,成功释放!

CCKiller:Linux轻量级CC攻击防御工具,秒级检查、自动拉黑和释放

Ps:如果邮件发送功能无误,那么应该也收到了工具发来的告警邮件,比如有一个饱受 CC 攻击煎熬的站长给我发来的反馈:

五、更多说明

①、配置并发限制

CCKiller 配置最大连接数限制时,建议根据单个网页产生的并发数来判断。

情况 A: 你网站做了动静分离,那么静态的请求就到另一个域名了(假设静态资源托管在另一台服务器或是 CDN),单个 IP 请求一个页面可能就只会产生若干并发(假设 5 个),我们假设某个用户很猛,他喜欢快速拖拽打开你网站的多个网页,比如同时打开 10 个,那么正常用户的正常最大并发你也可以基本确定了吧?即并发限制:10x5=50。如果有人同时刷新你几十个页面,要说没恶意你也不相信吧?

情况 B: 如果没有做动静分离,那么一个页面产生的并发可能就比较多了,每个 css、js、图片都会产生一次请求。所以,在这种情况下就需要稍微计算一下你网站单个页面产生的并发请求,比如一个单页面会产生 30 个请求,那么你也需要考虑用户可能会连续拖拽多个页面的情况,假设我允许用户可以同时刷新 10 页面,那么并发限制就可以设置为 300 了,依此类推。

容错:从 A 和 B 来看,CCKiller 其实是有一个盲点的,那就是如果用户 IP 是某个公司的统一出口,也就是代理上网 IP,那么工具就容易误杀无辜了。所以,除了 A 和 B,你还得考虑你网站的受众人群类型。比如,我就一个个人博客,同一时刻被一个公司的多名同时多窗口拖拽访问,这种情况也不多吧?如果可能存在这种受众人群,那么这个并发限制可以设置大一些,避免错杀无辜。当然,拉黑也就 10 分钟而已,也不至于“一失足成千古恨”。。。

当然,不管哪种情况,并发限制都可以比预估设置高那么一些,这个自行斟酌吧!

②、不足与完善

CCKiller 是我最近利用闲暇时间,匆忙之作,难免会有各种问题。也没时间进行测试和完善。不过目前还是有数位站长在使用,暂未反馈异常。当然, 我分享的是在线安装方式,也是为后续的更新提供方便。不过对比我以前写的防御脚本,CCKiller 算是有了长足的进步了,很简单的安装,更强大的功能!

功能计划:

A. 在线升级功能

这个不用多说,现有的工具已经预留了,后面可能会加入版本判断和更新的功能。

B. 加入其他安全防护设置

目前工具其实是赶鸭子上架一样,直接就检查,也没有对系统环境做一些初始化的设置。比如网站通用的 iptables 设置、sync 洪水攻击防御等。后续会在安装的时候会作为一个可选功能。

C. 集成傻瓜式的防火墙控制功能

并不是每个站长都会熟练操作 iptables,所以可能考虑给 cckiller 这个命令集成一个 ban 和 unban ip 的功能,比如禁止一个 ip,执行 cckiller -D $ip 即可,降低 iptables 的使用门槛。

另外,值得说明是,CCKiller 只适合裸奔的网站,而不适合使用 CDN 的网站,因为使用 CDN 之后,请求过来的 IP 都是 CDN 节点,你总不能把 CDN 节点也拉黑了吧?(Ps:其实也可以用,你把并发限制稍微设置高一些就好了,就算拉黑 CDN 节点也就拉黑 10 分钟而已,不至于影响过大

针对这个问题,后续我会找时间研究下直接从 Nginx 日志里面取得真实来源 IP 来拒绝访问。目前已经有了阶段性的进展了,敬请期待!

附录:更新记录


2015-09-23 Ver 1.0.1:

  • 支持白名单为 IP 段,格式为 IP 段通用格式,比如 192.168.1.0/24;
  • 新增拉黑改为判断 iptables 是否已存在操作 IP 的判断方式;
  • 增加日志记录功能,每天一个日志文件,位于安装目录下的 log 文件内;
  • 集成手动拉黑 IP 和解封 IP 功能,使用 cckiller -b IP 拉黑,使用 cckiller -u IP 解封。

2015-11-29 Ver 1.0.2:

  • 新增在线更新功能,执行 ./install.sh -u 即可检测是否有新版本:
CCKiller:Linux轻量级CC攻击防御工具,秒级检查、自动拉黑和释放

如果发现有新版本则显示更新内容,并提示是否执行更新。选择之后将会更新到新版本,需要重新配置,但是 IP 或端口白名单会保持不变。

  • 新增端口白名单功能
CCKiller:Linux轻量级CC攻击防御工具,秒级检查、自动拉黑和释放

应网友需求,新增了这个端口白名单功能。在配置 CCKiller 的最后一项会提示输入端口白名单:

如果需要排除某些端口,请如图最后一行所示,输入端口并已逗号分隔,比如 21,2121,8000

本次更新为非必须功能,在用的朋友可以按需更新,当然新增了在线更新这个功能,也强力推荐更新一下,方便后续检测 CCKiller 是否是最新版本。

更新难免存在不可意料的纰漏,使用中存在任何问题请留言告知,谢谢!

2016-06-20 Ver 1.0.3:

  • 增加“永久”拉黑时长

有网友反馈,需要设置更长的拉黑时间。原先的机制来看,如果设置拉黑时间过长,那么可能会产生很多后台释放黑名单脚本,占用系统资源。

CCKiller:Linux轻量级CC攻击防御工具,秒级检查、自动拉黑和释放

因此,1.0.3 版本加入永久拉黑设置。只要在安装的时候,设置拉黑时长为 0,则 CCKiller 不会再产生后台释放脚本,也不会释放已拉黑的 IP 了:

但是,考虑到灵活性问题,并没有在新版中加入 service iptables save 的保存命令,所以当你重启系统或者重启 iptables,这些拉黑的 IP 都将得到释放。当然,如果你真的想永久拉黑,请手动执行 service iptables save 即可。

  • 注册开机启动

新版本已将 CCKiller 服务注册到了开机启动服务列表,重启系统不用在担心未启动 CCKiller 了。

  • 兼容 Centos 7

目前博客运行在 Centos 7 系统,所以将 CCKiller 也做了一下兼容,其实就是在 Centos 7 上安装了 iptables。并且修复了 Centos7 系统对已拉黑 IP 的判断问题。

Ps:以上功能如果你觉得有用,可以执行 install.sh -u 进行在线更新,记得是小写 u 哦。

2016-10-09 Ver 1.0.4:

  • BUG 修复

根据网友反馈,发现攻防测试中一个 IP 不能被拉黑,经过分析发现命中了白名单。而实际上白名单中并没有 IP 段,只因 IP 同属于一个网段。因此,在是否属于 IP 段的判断中,加入对斜杠的筛选,也就是说只判断白名单中存在斜杠(/)的条目,简单粗暴!

2017-05-20 Ver 1.07 (中间漏记了 2 个小版本,也不记得修复了啥)

  • 日志级别、开关

根据网友建议,新增日志控制开关,参数为 LOG_LEVEL,支持 INFO、DEBUG 和 OFF 3 个参数,其中 INFO 表示仅记录拉黑和释放 IP,DEBUG 记录全部日志,包括拉黑、释放的报错信息,OFF 表示关闭日志。

如果需要使用该功能,可以执行 ./install.sh -u 在线更新或直接重新安装。

2019-07-11 Ver 1.0.8

  • 支持 IPv6 检查;
  • 优化在线安装脚本,减少下载失败几率;
  • 基于/proc/net 检查,替换 netstat,避免在高并发时 netstat 导致 CPU 高负载的问题,感谢 Late Winter 留言指出,统计代码来自 DDoS-Defender-v2.1.0。
259 条回应
  1. 银色乐航 2020-7-2 · 17:06

    老板,1.0.8在最新centos7上面失效:
    [root@xxxx cckiller]# service cckiller start
    /etc/init.d/cckiller: line 1: html: No such file or directory
    /etc/init.d/cckiller: line 2: syntax error near unexpected token `<' 'etc/init.d/cckiller: line 2: `520 Origin Error

    centos7版本:Linux cvm8820 5.5.7-1.el7.elrepo.x86_64 #1 SMP Fri Feb 28 12:21:58 EST 2020 x86_64 x86_64 x86_64 GNU/Linux

    • avatar
      Jager 2020-8-2 · 16:58

      你这个是因为下载失败了,下到了HTML内容。。。你将下载地址改为 zhangge.net 看看

  2. 嚣张 2020-7-17 · 20:56

    这个文章能不能转载到自己博客?

    • avatar
      Jager 2020-8-2 · 16:49

      可以啊,请备注下原文出处即可。

  3. centos8用户 2020-8-1 · 12:06

    centos8上面自动拉黑不起效果,cckiller -k 100不起效果,cckiller -s 10没有任何输出,iptables是正常的。
    使用cckiller -b IP 拉黑,使用 cckiller -u IP 解封都正常。
    能不能花点时间兼容下centos8,感谢。

    • 古哥 2020-11-2 · 19:08

      对的,我也发现了。而且cckiller查看当前请求ip。只有连接ssh的自己ip和一些共享ip,比如:
      1 100.100.30.26
      1 100.100.21.100
      所以,这个软件应该是检测不到centos8系统上的请求状况了。

  4. 嘻嘻哈哈 2020-10-9 · 16:17

    时间我设置了 20秒检测一次,并发数为300。我模拟请求的是1秒请求10次,这样算下来20秒才请求200次,可是ip被封了。是不是计数有问题

  5. 嘻嘻哈哈 2020-10-9 · 16:23

    在ck.conf 中配置的是600秒拉黑时长,不到5分钟就解封了。。。

    [2020-10-09 16:12:26][INFO]: 114.215.131.172 Was Baned successfully.
    [2020-10-09 16:12:26][INFO]: Banned 114.215.131.172 with 310 connections
    [2020-10-09 16:16:42][INFO]: 114.215.131.172 is Unbaned successfully.

  6. 嘻嘻哈哈 2020-10-9 · 16:26

    20秒检测一次,并发数设置的是300。我模拟请求一秒10次,20秒是200次,还没有达到条件ip就被防火前拦截了

  7. feiji 2020-11-29 · 0:24

    这个对https 剩下么 我安装后 设置并发60 用网页批量打开 和火车头测试采集 都没有被封IP
    用上面webbench指令测试http就正常被封 webbench貌似不能测试https

  8. 三分热度 2020-12-8 · 14:46

    非常感谢您的脚本,
    但是非常困惑的是,原来可以正常使用,只是邮件不能发送。
    我重新卸载,安装后 就不能自动拉黑攻击的IP了。这样应该如何检查排除故障呢?

  9. hym8 2020-12-27 · 16:27

    非常好用,希望作者可以持续维护更新,变得更好用

  10. 啧啧啧 2020-12-28 · 19:10

    centos5 用了很多年了最近升级到centos7.8 安装好iptables防火墙后cckiller好像依旧不行
    [root@localhost ~]# service cckiller status
    ● cckiller.service - SYSV: CCKiller Service
    Loaded: loaded (/etc/rc.d/init.d/cckiller; bad; vendor preset: disabled)
    Active: active (running) since 一 2020-12-28 05:31:05 CST; 13h ago
    Docs: man:systemd-sysv-generator(8)
    Process: 1861 ExecStart=/etc/rc.d/init.d/cckiller start (code=exited, status=0/SUCCESS)
    Tasks: 2
    CGroup: /system.slice/cckiller.service
    ├─ 1883 /bin/sh /usr/local/cckiller/cckiller --process
    └─17283 sleep 60

    12月 28 05:31:05 localhost.localdomain systemd[1]: Starting SYSV: CCKiller S...
    12月 28 05:31:05 localhost.localdomain cckiller[1861]: Starting cckiller ......
    12月 28 05:31:05 localhost.localdomain systemd[1]: Started SYSV: CCKiller Se...
    Hint: Some lines were ellipsized, use -l to show in full.

  11. 夏目贵志 2021-1-1 · 16:42

    我用curl wget 下载都是下载失败 html文件

    然后我windows 手动下载正常 在传到服务器 才安装成功!!

    • xyz 2021-10-19 · 15:10

      跟你本身网络有关系.

  12. 兄弟 2021-1-21 · 23:58

    我知道为什么IPT在某些环境为空了,因为没有安装which建议增加自动安装命令
    yum -y install which

  13. ximeng 2021-6-29 · 11:52

    可否运行于Centos6.10版本?
    我多台服务安装后,自动拉黑不起效果,cckiller -k 100不起效果,cckiller -s 10没有任何输出,iptables是正常的。
    使用cckiller -b IP 拉黑,使用 cckiller -u IP 解封都正常。

  14. aceells 2022-7-4 · 12:27

    你好,我想问下为什么我输入./install.sh -U会自动断开ssh连接呢?输入./install.sh也是一样,我想测试卸载。我的系统是:Alibaba Cloud Linux 3.2104 LTS 64位

    • avatar
      Jager 2022-7-5 · 20:32

      理论上不会导致ssh断开,可以使用 bash -x install.sh -U 看看过程。

  15. MJ 2022-12-4 · 15:10

    [root@iZuf6je77js~]# cckiller -s 10
    -bash: cckiller: command not found
    大神,有没有详细点的命令说明,按不出来。。