DDoS 攻击
什么是 DDoS 攻击
DDoS 全称 Distributed Denial of Service,中文意思为“分布式拒绝服务”,就是利用大量合法的分布式服务器对目标发送请求,从而导致正常合法用户无法获得服务。比喻一个饭店有 50 个位,当 50 个位都坐满之后,再想有客人进来点餐,必须等到在吃的客人吃完结账离开才行。但是在座的客人一直不离开,新来的客人只得不停地排队或者离开,餐厅相当于过载,这就是“拒绝服务”。
网络骗子无处不在,其中一种诈骗方式就是钓鱼网站。笔者曾在某 IT 论坛上见过一名网友的经历自述,该网友收到含有钓鱼网站链接的诈骗信息,但他是个搞技术的人,并没中招,反而自行编写了一个能够以高速发送网络请求的 phython 程序,针对该钓鱼网站进行打击,不一会就将其击溃了。连续攻击几天后,骗子不得不修改了域名。
DDoS 攻击的特点
不同于其它劫持类攻击或篡改数据类攻击,DDoS 攻击简单粗暴,可以达到直接摧毁目标的目的,只要是面向大众的服务就需要对外接口,只要有对外接口就能发起 DDoS 攻击。另外,相对其他攻击手段 DDoS 的技术要求和发动攻击的成本很低,只需要购买部分服务器权限或控制一批肉鸡即可,而且攻击相应速度很快,攻击效果可视。另一方面,DDoS 具有易攻难守的特征,服务提供商为了保证正常客户的需求需要耗费大量的资源才能和攻击发起方进行对抗。这些特点使得 DDoS 成为黑客们手中的一把很好使的利剑,而且所向霹雳。
DDoS 的攻击方式
从 DDoS 的危害性和攻击行为来看,我们可以将 DDoS 攻击方式分为以下几类:
资源消耗类攻击
资源消耗类是比较典型的 DDoS 攻击,最具代表性的包括:Syn Flood、Ack Flood、UDP
Flood。这类攻击的目标很简单,就是通过大量请求消耗正常的带宽和协议栈处理资源的能力,从而达到服务端无法正常工作的目的。其中 Syn Flood 最为经典,其被发现于 1996 年,但至今仍然保持着强大的生命力。Syn Flood 利用 TCP 协议设计中的致命缺陷,而 TCP/IP 协议是整个互联网的基础,这也是 Syn Flood 如此猖獗的原因。
图 1.DDoS 攻击示意图
在正常情况下,TCP 三次握手过程如下:
(1)客户端向服务器端发送一个 SYN 包,包含客户端使用的端口号和初始序列号 x;
(2)服务器端收到客户端发送来的 SYN 包后,向客户端发送一个 SYN 和 ACK 都置位的 TCP 报文,包含确认号 x+1 和服务器端的初始序列号 y;
(3)客户端收到服务器端返回的 SYN+ACK 报文后,向服务器端返回一个确认号为 y+1、序号为 x+1 的 ACK 报文,一个标准的 TCP 连接完成。
而 SYN flood 在攻击时,首先伪造大量的源 IP 地址,分别向服务器端发送大量的 SYN 包,此时服务器端会根据各个 SYN 包中的 IP 地址发送 SYN/ACK 包,因为源地址是伪造的,所以伪造的 IP 并不会应答,服务器端没有收到伪造 IP 的回应,会重试 3 ~ 5 次并且等待一个 SYN Time,如果超时则丢弃这个连接。攻击者大量发送这种伪造源地址的 SYN 请求,服务器端将会消耗非常多的资源来处理这种半连接,同时还要不断地对这些 IP 进行 SYN+ACK 重试,导致服务器资源枯竭,无暇理睬正常的连接请求,这就是拒绝服务。
服务消耗性攻击
相比资源消耗类攻击,服务消耗类攻击不需要太大的流量,它主要是针对服务的特点进行精确定点打击,如 web 的 CC,数据服务的检索,文件服务的下载等。这类攻击往往不是为了拥塞流量通道或协议处理通道,它们是让服务端始终处理高消耗型的业务的忙碌状态,进而无法对正常业务进行响应。
CC 攻击全称 Challenge Collapasar,CC 攻击的原理非常简单,就是对一些消耗资源较大的应用页面不断发起正常的请求,以达到消耗服务端资源的目的。在 Web 应用中,查询数据库、读/写硬盘文件等操作,相对都会消耗比较多的资源,例如一般的站点中都有搜索服务,CC 攻击可以不断地发起搜索请求来使用搜索服务,大量的搜索服务使得服务器不得不挪用资源去处理,当请求量达到一定程度时就可能导致服务过载。
反射类攻击
反射攻击也叫放大攻击,该类攻击以 UDP 协议为主,一般请求回应的流量远远大于请求本身流量的大小。反射攻击有很多种,包括 Smurf 攻击、NTP 反射攻击、SSDP 反射攻击和 DNS 反射攻击等。下面来看看 DNS 攻击:
DNS 服务是整个互联网的基础服务,在我们链接互联网的时候,需要通过 DNS 解析将域名转化成对应的 IP 地址。理论上来说 ISP 的 DNS 服务器只响应来自它自己客户 IP 的 DNS Query 响应,但事实上互联网上大量 DNS 服务的默认配置缺失,导致了会响应所有 IP 的 DNS Query 请求。同时,DNS 大部分使用 UDP 协议,UDP 协议没有握手过程让其去验证请求的源 IP。综合以上两点,攻击者控制傀儡机发送大量伪造了 IP 的请求给 DNS 服务器,因为 UDP 协议的原因 DNS 服务器不会去验证 IP 的真伪,直接照单全收,将请求加工包裹后反射给受害者(攻击目标服务器),而这个加工包裹正是流量放大的关键。
图 2.DNS 反射攻击
下面再来看一下 DNS 如何将请求数据包进行放大,输入(x.x.x.x 为 DNS 服务器 IP):
1 | dig ANY @x.x.x.x |
返回结果,这里为了节约篇幅,我们省略了大部分的响应内容。我们可以看到,响应的内容远远大于请求的数据包内容,这里就产生了放大的效果。
; <<>> DiG 9.7.3 <<>> ANY @x.x.x.x
;; global options: +cmd
;; Got answer:
………………………………….此处省略具体请求内容…………………………………………
isc.org. 484 IN RRSIG A 5 2 7200 20121125230752 20121026230752 4442 isc.org. ViS+qg95DibkkZ5kbL8vCBpRUqI2/M9UwthPVCXl8ciglLftiMC9WUzq Ul3FBbri5CKD/YNXqyvjxyvmZfkQLDUmffjDB+ZGqBxSpG8j1fDwK6n1 hWbKf7QSe4LuJZyEgXFEkP16CmVyZCTITUh2TNDmRgsoxrvrOqOePWhp 8+E=
DDoS 防御手段
限制请求频率
最常见的针对应用层 DDOS 攻击的防御措施,是在应用中针对每个“客户端”做一个请求频率的限制。它的思路很简单,通过 IP 地址与 Cookie 定位一个客户端,如果客户端的请求在一定时间内过于频繁,则对之后来自该客户端的所有请求都重定向到一个出错页面。从架构上看,这段代码需要放在业务逻辑之前,才能起到保护后端应用的目的,可以看做是一个“基层”的安全模块。
然而这种防御方法并不完美,因为它在客户端的判断依据上并不是永远可靠的。这个方案中有两个因素用以定位一个客户端:一个是 IP 地址,另一个是 Cookie。但用户的 IP 地址可能会发生改变,而 Cookie 又可能会被清空,如果 IP 地址和 Cookie 同时都发生了变化,那么就无法再定位到同一个客户端了。比如使用代理、傀儡机来让 IP 地址发生变化。
应对代理与傀儡机
Yahoo 为我们提供了一个解决思路。因为发起应用层 DDOS 攻击的 IP 地址都是真实的,所以在实际情况中,攻击者的 IP 地址其实也不可能无限制增长。假设攻击者有 1000 个 IP 地址发起攻击,如果请求了 10000 次,则平均每个 IP 地址请求同一页面达到 10 次,攻击如果持续下去,单个 IP 地址的请求也将变多,但无论如何变,都是在这 1000 个 IP 地址的范围内做轮询。为此 Yahoo 实现了一套算法,根据 IP 地址和 Cookie 等信息,可以计算客户端的请求频率并进行拦截。Yahoo 设计的这套系统也是为 Web Server 开发的一个模块,但在整体架构上会有一台 master 服务器集中计算所有 IP 地址的请求频率,并同步策略到每台 WebServer 上。因此,我们也可以借助这样的一个思想实现代理、傀儡机 DDoS 防御机制。
验证码
验证码是互联网中常用的技术之一,它的英文简称是 CAPTCHA(Completely AutomatedPublic Turing Test to Tell Computers and Humans Apart,全自动区分计算机和人类的图灵测试)。在很多时候,如果可以忽略对用户体验的影响,那么引入验证码这一手段能够有效地阻止自动化的重放行为。但如果用户体验比较重要,就不得不考虑放弃验证码。验证的的核心思想是识别人与机器,因此我们可以通过一段 JavaScript 来区分当前客户端是人为控制的浏览器,还是机器脚本,原理很简单,大部分的脚本都是直接构造 HTPP 包来完成请求的,例如 Phython,而不是通过浏览器发送的请求,所有从服务器发送一段 JS 脚本至客户端并给出正确结果,如果客户端是浏览器则这段 JS 脚本能正常运行并且运行结果与来自服务器的一致,但客户端是非浏览器环境的则无法执行 JS,由此可以判断客户端到底是不是浏览器。不过,有些自动话脚本是 JS 编写,内挂至浏览器运行的,那就没办法了。
利用 Web Server 的防御手段
在某些 Web Server 容器中,可以通过调整一些选项的值来达到一定程度的防御效果,比如 Apache,在 Apache 的配置文件中,有一些参数可以缓解 DDOS 攻击。比如调小 Timeout、KeepAliveTimeout 值,增加 MaxClients 值。
Apache 提供的模块接口为我们扩展 Apache、设计防御措施提供了可能。目前已经有一些开源的 Module 全部或部分实现了针对应用层 DDOS 攻击的保护。“mod_qos”就是 Apache 的一个 Module,它可以帮助缓解应用层 DDOS 攻击。比如 mod_qos 的下面这些配置就非常有价值。
小结
DDoS 不论在过去还是现在都是一个深受关注的课题,互联网的特性决定了它不会轻易地消失。DDoS 本质是对有限资源的无限制滥用所造成的。所以,解决这个问题的核心思路就是限制每个不可信任的资源使用者的配额。