本文首发自河南CISP,安全内参转载。

阅读说明:DDoS攻击确实是很多企业头疼的事。就攻击本身而言,并没有太大的技术含量,而防御则基本靠花钱。做DDoS防御之前,我们还是要剖析攻击方法,才能做到准确防护,让企业把钱用在刀刃上。本篇抛砖引玉谈谈DDoS攻击方法及防御,希望对您的企业安全建设有所帮助。

DDoS的梦魇

DDoS(Distributed Denial of Service,分布式拒绝服务)攻击的主要目的是让指定目标无法提供正常服务,或被迫关闭。DDoS似乎是很多行业的噩梦。这种没有技术含量的攻击,却拖累着我们脆弱的互联网,成为一块心病。在2016年10月的某天,美国遭受着有史以来最大的DDoS攻击,GitHub、Twitter、Airbnb、Reddit等大量站点都因此受到影响。Dyn(一家DNS提供商)公司宣称,这次攻击来源超过千万IP。意味着至少有0.4%的IPv4地址参与了攻击行为。

就在2019年1月的某天,我放在互联网上的Honey Pot(蜜罐节点)也在遭受着总流量超过30G的DDoS攻击。攻击者在我的蜜罐玩了几个月,最终发现是个蜜罐(求攻击者心理阴影),气急败坏发动DDoS攻击。总量30G并不高,但毕竟那是一台VPS,总出口带宽也只不过20M。把攻击行为日志备份好了之后,最后只能关闭那台VPS主机。

DDoS的可恶,相信很多朋友都深有体会。不过嘛~~

1

我们先讨论DDoS的攻击方式,不过要记住一句话:DDoS没有直接的制止手段,一切手段都只能缓解!

从攻击方式来看,DDoS可以粗旷的分为两大类: 流量型攻击和资源型攻击(CC攻击就是其中典型的资源型攻击代表)。其中,流量型攻击又可以分为,直接流量攻击反射流量攻击。直接流量包括了ICMP FLOOD/UDP FLOOD/SYN FLOOD,这种直接攻击目前已经不多见了(SYN FLOOD除外),但在20年前,几乎一打一个准。大概是下图这样子。

(补充:这里的攻击者,是指被控攻击终端)

直到最近几年,反射攻击逐步走入了视野。反射型拒绝服务攻击,又称DRDoS攻击。是由攻击者伪造被攻击服务器的IP地址,向互联网上大量开放特定服务的服务器发起请求,收到请求的那些主机根据被伪造的源IP地址将响应数据包返回给被攻击者。大概如下图

那么,还有一类是资源型攻击,即利用业务的漏洞或业务特点,发送消耗资源较大的请求,从而耗尽服务器资源。我把CC与Slowloris,HASH冲突列在一起,它们均需要特定的场景才能触发

我粗旷的分类,就是下面的样子,毕竟一图胜千言。

接下来,我们继续介绍最具代表性的攻击,并探讨这些攻击的防御方式。

2

SYN FLOOD

熟悉TCP/IP的朋友都知道,当然你不熟悉也马上就知道。

一个正常的TCP连接需要经过3次握手操作:

首先第一步,由发送端向接收端发送一个带有SYN标记的TCP数据报文,SYN即同步(Synchronize),这个报文会指明发送端使用的端口以及TCP连接的初始序号;

然后第二步,接收端在收到这个SYN报文后,分配一个控制块(可以理解为内存空间),并返回(响应)一个SYN+ACK(确认Acknowledgement)报文,表示发送端的请求被接受,同时TCP初始序号自动加1;

最后第三步,发送端在收到这个SYN+ACK报文后,也会返回一个确认报文ACK给发送端,同样TCP序号再自动加1。

这样就完成了传说中的三次握手。

可是,如果在第二步之后,接收端一直等啊等,没有等到发送端最终的ACK确认报文,此时接收端的这条TCP连接会处于半开状态(SYN_RECV)。直到接收到ACK确认报文或TCP连接因time-to-live(TTL)计时器设置而超时。这时,事先分配的控制块将被释放。如果攻击者有意一直向目标服务器发送TCP SYN 报文,同时不向接收端应答ACK确认报文。这样,接收端服务器就产生了大量的SYN_RECV状态的连接。可惜的是,我们的服务器或者网络设备或者PC,通常资源都是有限的。当SYN_RECV状态超过可接受极限时,就不再接受新的SYN报文。这时候,就攻击者就实现了让目标服务器拒绝服务(拒绝新的TCP连接)。

UDP FLOOD

说起UDP FLOOD 就不得不祭出一个神器——UDP Flooder 我最早接触到这个神器还是在1999年的某天。(这里可以透露一点,还记得2001年号称8万红颜色客户打白色宫殿的事情吗?当时提供的就是下图这个工具。)

首先,UDP协议是没有连接状态的,如果我们把TCP比作打电话(需要拨号,接听),则UDP可以理解为发短信(发送即可)。因此可以发送大量的UDP包到某个端口,如果是个正常的UDP应用端口,则可能干扰正常应用;如果没有正常应用,接收端要返回ICMP报文,这样就消耗了接收端的处理资源,同时很容易阻塞上行链路的带宽。早期常见攻击者发送大量UDP小包打防火墙/Radius认证服务(PPPOE服务端)/流媒体服务器等,现在多数的IDC机房屏蔽了来自公网的UDP协议,所以已经不多见了(题外话:某公有云厂商内网很热闹)。

反射流量型攻击 (DRDoS)

反射拒绝服务攻击又称DRDoS(Distribute Reflection Denial of Service)。简单的说,攻击者首先伪造数据包来源IP为被攻击主机,于此同时,攻击者向中转反射的服务发送的请求包小于中转反射服务的应答包也就实现了攻击者的攻击流量放大。基于这个特性,有的文章称其为“流量放大攻击”。

攻击者常用的放大攻击服务包括但不限于 DNS服务、NTP服务、SNMP服务、CharGEN服务、NetBIOS服务等等。

其中,利用NTP服务的放大攻击效果最好,其放大效果超过500倍。换言之,假设攻击者发起 10Mbps的请求流量,经过NTP服务放大,被攻击主机接收到的应答流量至少是 10Mbps*500 即 5000Mbps ,想想是一件恐怖的事。

CC攻击

聊到CC攻击,同样要追溯到古老的历史,CC 即 Challenge Collapsar 意为 挑战黑洞。"黑洞" 是安全厂绿盟科技的一款抗D产品,有篇 《CC攻击竟然是源于一个误会》的文章在网络上流传,想了解这些故事,可以找找这篇文章。

最早的CC工具,就是下面这个样子。也就是传说中的FatBoy,默认的攻击目标即 绿盟科技 的官网。

这真不是我PS的,关键我不会ps

CC如何把网站打瘫呢?

打个比方说: 网站打开首页只需要 1ms (1毫秒) ,而执行网站查询需要 200ms(相对消耗资源),很多论坛关闭或限制了查询,就是防CC的措施。那么攻击者首先需要找到网站占用资源较大的应用功能请求(就比如查询),然后通过大量的肉鸡或代理服务,向被攻击的网站发送应用功能请求。1个查询请求耗时 200ms,1000个肉鸡做代理,每个主机开100线程,服务器的请求处理时间就会大大增加,服务器处理请求的延迟秒数就是 1000*100/(1000ms/200 ms) = 20,000 S(秒) 。你算吧,1小时3600秒,服务器早就挂了 。正常用户也会使用网站提供的合法功能。这个请求几乎不可能被拦截。这也是CC难以防御之处。

Slowloris 攻击

与CC攻击相似Slowloris也是针对Web业务进行攻击的一种方式,CC利用的是Web应用程序缺陷。那么Slowloris则是利用Web Server程序的缺陷。Slowloris最早在2009年由安全专家RSnake提出的一种攻击方法(其实在他提出之前,已经有攻击者利用这种方式实施攻击了),在2012年的OWASP大会上Wong Onn Chee和 Tom Brennan共同展示了HTTP Post 方式的 Slowloris攻击。

其原理是:对已开放HTTP访问的Web服务器,建立一个连接,指定一个较大的Content-length,然后以非常低的速度发包,比如1-10s发送1字节,以此来维持这个连接不断开。如果客户端持续建立这样的连接,那么服务器上可用的连接将一点一点被占满,从而无法接受新的连接请求,导致拒绝服务。

攻击者以单线程方式建立大量无用连接的代价非常低廉,实际测试中,任何一台普通的PC都可以轻松建立3000个以上的无用连接,这对普通的Web Server都是致命打击,更不要说分布式攻击了。

3

DDoS的目的是让被攻击业务宕机,难道遇到DDoS就真的束手无策吗?不幸的是,对有些低成本没预算的业务来说,是这样的!

对于企业而言,业务不能停,既然抗D要花钱,那么怎样把钱用在刀刃上,才是关键问题!

确认攻击流量,这是实施防御的关键。遭受攻击量的大小,采取的对策也不同(追求成本合理化)。

先说 1G流量之内的防护方式,大致的预算 1万元/每月 以内

以SYN FLOOD为例,这种类型的攻击大量消耗被攻击服务器的CPU/内存资源,并打满SYN等待队列。我们可以通过修改内核参数来缓解。

主要有:

net.ipv4.tcp_synack_retries = 2

net.ipv4.tcp_max_syn_backlog = 8192

net.ipv4.tcp_syncookies = 1

分别为 设置SYN+ACK最大重试次数/设置SYN最大队列长度/启用syn Cookie

设置 net.ipv4.tcp_synack_retries 的目的是降低服务器SYN+ACK报文重试次数,尽快释放等待资源。

设置 tcp_max_syn_backlog 则是为了使用服务器的内存资源,以此获得更大的等待队列长度,让攻击数据报文不致塞满所有连接,而导致正常用户无法完成连接。

设置 net.ipv4.tcp_syncookies 的作用,是为了缓解服务器的资源压力。在启用之前,服务器接收到SYN数据包后,将立即分配存储空间,并随机化一个数字作为SYN号发送SYN+ACK数据包,然后保持连接并等待发送方确认。启用之后,则不再分配存储空间,而通过基于时间种子的随机数设置一个SYN号,替代完全随机的SYN号。发送完SYN+ACK确认报文后,清空资源不保存任何状态信息,直到服务器接收到最终的ACK包,通过检验算法鉴定是否与服务器发出的SYN+ACK报文序列号匹配,匹配则完成握手,否则丢弃。

当然,如果是SYN混合ACK的攻击方法,则是对syncookies的反制,其优劣由硬件配置决定。

还有一种更优化的方案,则是通过TCP Proxy实现。开源我推荐HAProxy,没有之一。可以使用其做多机负载均衡,从而分流压力。网上有一篇《HAProxy压测及参数调优》可以研究一下,这里就不贴出了。

再谈谈遇到反射型攻击的场景,反射型攻击通常攻击量都很高,至少大于 10Gbps。这时,软件防护类的就.......我只知道服务器上不去了。

这时候,防护取决于带宽的大小,与防护软件没有毛线关系

你也许会说,有些机房提供高防IP。是的,基本上与你付出的钱成正比。

机房防护如下图

攻击超过一定量,超过检测设备阀值,自动执行路由切换规则(有些则给你丢空路由),然后再进行流量清洗过程,清洗完毕再发送回你的主机去。

不过,你要明白,每家IDC机房都有一个总带宽,如果攻击流量过大影响了机房的正常生意,自然会屏蔽你的服务器IP。不要问为什么,机房才有最终解释权。

这时候,云端防护就凸显出其价值。但同样攻击流量即防护成本。值得庆幸的是, 百度云加速提供了5Gbps的免费抗D防护。百度联合电信的云堤,国外的CF(一家CDN供应商)实现了联合抗D。

对于大多数的云抗D来说,实现思路如下:

云主机供应商首先自建或合作IDC机房,机房有基础流量清洗硬防(因为成本低),这号称本地一滤;云端二洗,则是在攻击量过大时,切换到高防IP或走高防设备,进行分流和流量清洗(成本高,付费用户才享);源端三封,说的也是近源封锁,换句话说,如果有来自河南电信的攻击流量,河南电信作为运营商,在流量走到主干出口(省出口)的时候,直接封锁掉,这号称源端三封。

如果遇到CC攻击,总不能把网站功能关闭了吧? 怎么办?

此时,还真由不得你关不关。通常防御CC,Web程序中设置3档(比如Discuz)。分别为:1,限制两次请求时间,即用户刷新时间;2,第1档功能 + 部分功能验证码;3,第1、2档功能 + 全站全请求验证码。不得不说,验证码是没有办法的办法

对于Web站点而言,通常,能做静态的要尽量做静态化。这样,前端CDN可以很好的分流和代理请求,不过有些CDN碰到DDoS,直接回源。

第一种方案:对于全站更新不频繁,或较不频繁。除了静态化和前端CDN,还需要生成全站缓存,把本来需要数据库交互的请求交给前端缓存处理。比如使用Varnish自建CDN并生成全站缓存,用户第一次访问即请求真实内容,第二次访问则从缓存读取,从而降低Web后端压力。当然还可以用国产Kangle,也是优秀的反带服务器。这里不建议使用Squid,相比Varnish,我已经踩过坑了。这种方案好处在于,只需要运维人员参与,不需要开发人员。

第二种方案:对于全站更新频繁,则需要开发人员参与。在每次请求插入生成的随机hash,并在第二次请求时,验证上一次生成的hash,再生成新的hash传递过去,存储这个hash可以放在浏览器Cookie或请求参数中。这种方式虽然增加了CPU的开支,但是可以很好地防止重放攻击。在一定程度上,对CC也是有效的。

第三种方案:除了上述的方案一、二外。再除了Web 服务程序的安全配置外。还需要在前端CDN位置开启验证码校验用户请求。这样一来,实际到达后端数据库的访问压力其实很小。从而在很大程度上缓解了CC攻击带来的压力。

第四种方案在公众号后台留言,我在等你!

对于蜜罐类的主机,直接关闭或许就是明智的选择,大不了换个IP嘛~~哈哈~

后记:

所谓抗D,都是拿带宽流量堆起来的,本文剖析常见DDoS原理及防护手段。有些成本省不掉,关键还是要把钱用在刀刃上。相信读完本文的您,已经对DDoS的手段及防护有所了解,如果您有意见或建议,欢迎您留下宝贵的意见及建议。

声明:本文来自河南CISP,版权归作者所有。文章内容仅代表作者独立观点,不代表安全内参立场,转载目的在于传递更多信息。如有侵权,请联系 anquanneican@163.com。