防御DDos攻击之备忘录

前一段时间,本站受到了疯狂的DDOS攻击,近半个月的时间攻击流量超过了30TB,刚开始有点猝不及防,导致网站间歇性的不能访问,对本站多少也造成了一些影响和困扰。本来以为攻击者随便玩玩,没想到他还挺有“毅力”的,持续了差不多一个月了。但后来也不得不认真对待,尝试各种应对方法。简单记录一下,以供自己和读者参考。

一、关于主机的选择

我大部分的网站都放在海外,中文站,包括本站最初放在腾讯云香港区,宽带很小,只有2M,基本上一遭到攻击,ip很快就会进入封堵状态,一个月只有3次自主解封机会,多次封堵后,需要24小时甚至更长时间才能解封。所以,腾讯云香港区正常使用是非常不多的,但是遇到攻击就力不从心了。

然后,我将主机移到了Linode,这个主机商我使用了很多年,性能和服务都是很赞的,而且它自己开发了一个DDOS流量分流服务,利用AI机器学习,自动识别和建立规则,减轻服务器的负担,它对所有的linode用户都是免费的。

二、Cloudflare防护

虽然有一定的效果,但抵抗大流量的ddos攻击,还是会导致服务器卡死,网站很慢。于是只好再加上全球著名的CDN和ddos防护服务:Cloudflare

经过一系列的配置,发现Linode+Cloudflare基本可以缓解绝大部分的ddos攻击了。Cloudflare果然名不虚传,它不但可以提供全球cdn服务,而且在对抗ddos攻击方面功能非常的强大,可以隐藏真实主机的ip地址,可以通过自定义防火墙和规则,阻止攻击性质的请求。例如上一周,就阻止了20多个TB的攻击流量,我真实主机消化的流量其实并不多。

这个月攻击SSL请求数超过了96亿,真的不知道谁这个变态,花这么多的时间和精力来攻击我这个小站。

虽然,对这种流氓和无赖的行径, 没有什么终极的解决方案,但也基本上能够应对了。这已经是我发现的最稳妥有用的方案了。

据说,Cloudflare提供无限的流量和防护,如果有必要,我会考虑它家的付费方案。

三、服务器自身的的一些防护措施

如果攻击量不高,或者不想上CDN(Cloudflare的免费节点都在国外,对于目标国内访客的网站实际上会拖慢速度,这个也是一个缺点),就可以通过优化服务器自身的配置来缓解攻击。

1、服务器安装 DDoS Deflate

DDoS Deflate 是一个轻量级 bash shell 脚本,可以阻止一部分分布式拒绝服务攻击。它利用命令创建连接到服务器的 IP 地址列表,以及它们的总连接数。超过预先设置的连接数量的 IP 地址会在服务器的防火墙中自动加入屏蔽,它可以自动适应诸如 ipfw, iptables, 或者 Advanced Policy Firewall (APF)等防火墙。

主要功能包括:

  • 支援 IPv6,IP段
  • 可以设置ip,hostnames,白名单
  •  IP 地址在一个预先配置的时间限制(默认值: 600秒)之后自动解除屏蔽
  • 可以通过设置自动任务,以选定的频率(例如1分钟),自动执行
  • 当 IP 地址被阻止时,可以收到电子邮件提醒
  • 可以设置连接或通过特定的端口规则
  • 使用 tcpkill 减少攻击者打开的进程数量

安装方法,以(Ubuntu/Debian)为例,首先安装相关依赖:

sudo apt install dnsutils
sudo apt-get install net-tools
sudo apt-get install tcpdump
sudo apt-get install dsniff -y
sudo apt install grepcidr

接着安装脚本:

wget https://github.com/jgmdev/ddos-deflate/archive/master.zip -O ddos.zip
unzip ddos.zip
cd ddos-deflate-master
./install.sh

查看和修改配置文件,命令:nano /etc/ddos/ddos.conf

//脚本和其他文件的路径
# Paths of the script and other files
PROGDIR="/usr/local/ddos"
SBINDIR="/usr/local/sbin"
PROG="$PROGDIR/ddos.sh"  //执行脚本地址
IGNORE_IP_LIST="ignore.ip.list"  //IP地址白名单列表
IGNORE_HOST_LIST="ignore.host.list"  //主机白名单列表
CRON="/etc/cron.d/ddos"  //计划任务文件地址
//防火墙命令地址
APF="/usr/sbin/apf"
CSF="/usr/sbin/csf"
IPF="/sbin/ipfw"
IPT="/sbin/iptables"
IPT6="/sbin/ip6tables"
TC="/sbin/tc"
//第22行,检查DDos时间间隔,默认1分钟
FREQ=1
//第25行,作为一个守护进程时,运行的频率,单位秒
DAEMON_FREQ=5
//第28行,最大连接数,超过该数值后IP就会被禁止,一般默认即可
NO_OF_CONNECTIONS=150
//第33行,为true时仅统计接入连接,会比统计in/out更慢禁止
ONLY_INCOMING=false
//第38行,为true时脚本将会使用tcpdump扫描由CloudFlare服务器发送的CF-Connecting-IP头标签,
//并且禁止使用iptables字符串匹配模块
ENABLE_CLOUDFLARE=false
//第43行,为true时启用PORT_CONNECTIONS,与ONLY_INCOMING相同,但更慢
ENABLE_PORTS=false
//第54行,端口连接检测,为每个端口分配监听规则,格式为“端口(或端口端):最大连接数:禁用时间(单位秒)”
PORT_CONNECTIONS="80:150:600 443:150:600 20-21:150:600"
//第58行,使用的防火墙,包括:auto, apf, csf, ipfw, and iptables
FIREWALL="auto"
//第62行,当ip被屏蔽是给指定邮箱发送邮件
EMAIL_TO="root"
//第65行,IP禁止时间,单位秒
BAN_PERIOD=600
//第71行,要阻止的连接状态,状态之间使用冒号分隔,例如:established:syn-sent:syn-recv:fin-wait-1:fin-wait-2
//该例默认情况下,会阻止监听和关闭之外的所有状态,状态详见:man ss
CONN_STATES="connected"
//第74行,当使用netstat时要阻止的连接状态,状态详见:man netstat。那理论上,上面是使用ss时阻止的连接状态?
CONN_STATES_NS="ESTABLISHED|SYN_SENT|SYN_RECV|FIN_WAIT1|FIN_WAIT2|TIME_WAIT|CLOSE_WAIT|LAST_ACK|CLOSING"
//第78行,是否监控每个ip使用的带宽,超过时降低速率(需要iftop和tc命令)
BANDWIDTH_CONTROL=false
//第82行,触发降速的带宽速率,目前支持kbit和mbit
BANDWIDTH_CONTROL_LIMIT="1896kbit"
//第87行,触发降速时,会在指定时间周期内,速率上限
BANDWIDTH_DROP_RATE="512kbit"
//第91行,降速的时间周期,单位秒,即600秒内会有速率上限
BANDWIDTH_DROP_PERIOD=600
//第95行,如果为true时,仅考虑从客户端接收的数据,而不考虑服务器发给客户端的数据
BANDWIDTH_ONLY_INCOMING=true

需要注意的是:在配置文件中,ENABLE_PORTS(第43行)参数开启时,PORT_CONNECTIONS(第54行)才能使用;BANDWIDTH_CONTROL(第78行)参数开启时,BANDWIDTH_CONTROL_LIMIT(第82行)、BANDWIDTH_DROP_RATE(第87行)、BANDWIDTH_DROP_PERIOD(第91行)、BANDWIDTH_ONLY_INCOMING(第95行)才能使用。

DDoS deflate已支持systemctl命令管理

查看DDoS Deflate状态:

# systemctl status ddos

重启ddos 防御:

# systemctl restart ddos

关闭ddos 防御:

# systemctl stop ddos

可以为搜索引擎蜘蛛配置白名单,配置文件地址:

/etc/ddos/ignore.host.list

加入以下代码,白名单Google的蜘蛛

googlebot.com
my-dynamic-ip.somehost.com

或者编辑文件:

/etc/ddos/ignore.ip.list

加入白名单ip,例如:

12.43.63.13
165.123.34.43-165.123.34.100
192.168.1.0/24
129.134.131.2

更加详细的配置参考页面:

https://github.com/jgmdev/ddos-deflate

2、优化服务器配置(nginx环境)

nginx可以通过limit_conn_zone 和limit_req_zone两个组件来对客户端访问目录和文件的访问频率和次数进行限制,另外还可以善用进行服务安全加固,两个模块都能够对客户端访问进行限制

我一直用的都是lnmp.org配置生成环境的,编辑以下nginx的配置文件:

#nano /usr/local/nginx/conf/nginx.conf

1、在nginx.conf里的http{}里加上如下代码:

limitlimit_conn_zone $binary_remote_addr zone=perip:10m;
limit_conn_zone $server_name zone=perserver:10m;

2、在需要限制并发数和下载带宽的网站配置server{}里加上如下代码:

limit_conn perip 2;
limit_conn perserver 20;
limit_rate 100k;

补充说明下参数:

  • $binary_remote_addr是限制同一客户端ip地址;
  • $server_name是限制同一server最大并发数;
  • limit_conn为限制并发连接数;
  • limit_rate为限制下载速度;

这样可以一定程度上限制非正常的请求,缓解服务器负担。但说真的,这些配置只对小攻击有用,对于大型的攻击,如果硬件不是特别高大上(缺点就是贵),基本上请求一涌过来,还是会堵死,只能说聊胜于无吧。

以上就是遭遇ddos攻击的一些处理经历,希望大家最好不要遇上。