zoukankan      html  css  js  c++  java
  • dos攻击与防御

    SYN Flood攻击

    标准的TCP三次握手过程如下:

    客户端发送一个包含SYN标志的TCP报文,SYN即同步(Synchronize),同步报文会指明客户端使用的端口以及TCP连接的初始序号; 
    服务器在收到客户端的SYN报文后,将返回一个SYN+ACK(即确认Acknowledgement)的报文,表示客户端的请求被接受,同时TCP初始序号自动加1; 
    客户端也返回一个确认报文ACK给服务器端,同样TCP序列号被加1。 
    经过这三步,TCP连接就建立完成。TCP协议为了实现可靠传输,在三次握手的过程中设置了一些异常处理机制。第三步中如果服务器没有收到客户端的最终ACK确认报文,会一直处于SYN_RECV状态,将客户端IP加入等待列表,并重发第二步的SYN+ACK报文。重发一般进行3-5次,大约间隔30秒左右轮询一次等待列表重试所有客户端。另一方面,服务器在自己发出了SYN+ACK报文后,会预分配资源为即将建立的TCP连接储存信息做准备,这个资源在等待重试期间一直保留。更为重要的是,服务器资源有限,可以维护的SYN_RECV状态超过极限后就不再接受新的SYN报文,也就是拒绝新的TCP连接建立。

    SYN Flood正是利用了上文中TCP协议的设定,达到攻击的目的。攻击者伪装大量的IP地址给服务器发送SYN报文,由于伪造的IP地址几乎不可能存在,也就几乎没有设备会给服务器返回任何应答了。因此,服务器将会维持一个庞大的等待列表,不停地重试发送SYN+ACK报文,同时占用着大量的资源无法释放。更为关键的是,被攻击服务器的SYN_RECV队列被恶意的数据包占满,不再接受新的SYN请求,合法用户无法完成三次握手建立起TCP连接。也就是说,这个服务器被SYN Flood拒绝服务了。

    SYN Flood防御

    前文描述过,SYN Flood攻击大量消耗服务器的CPU、内存资源,并占满SYN等待队列。相应的,我们修改内核参数即可有效缓解。主要参数如下:

    net.ipv4.tcp_syncookies = 1

    net.ipv4.tcp_max_syn_backlog = 8192

    net.ipv4.tcp_synack_retries = 2

    分别为启用SYN Cookie、设置SYN最大队列长度以及设置SYN+ACK最大重试次数。

    SYN Cookie的作用是缓解服务器资源压力。启用之前,服务器在接到SYN数据包后,立即分配存储空间,并随机化一个数字作为SYN号发送SYN+ACK数据包。然后保存连接的状态信息等待客户端确认。启用SYN Cookie之后,服务器不再分配存储空间,而且通过基于时间种子的随机数算法设置一个SYN号,替代完全随机的SYN号。发送完SYN+ACK确认报文之后,清空资源不保存任何状态信息。直到服务器接到客户端的最终ACK包,通过Cookie检验算法鉴定是否与发出去的SYN+ACK报文序列号匹配,匹配则通过完成握手,失败则丢弃。tcp_max_syn_backlog则是使用服务器的内存资源,换取更大的等待队列长度,让攻击数据包不至于占满所有连接而导致正常用户无法完成握手。net.ipv4.tcp_synack_retries是降低服务器SYN+ACK报文重试次数,尽快释放等待资源。这三种措施与攻击的三种危害一一对应,完完全全地对症下药。但这些措施也是双刃剑,可能消耗服务器更多的内存资源,甚至影响正常用户建立TCP连接,需要评估服务器硬件资源和攻击大小谨慎设置。

    解决方案:

    这部分可以通过设置内核参数来进行防御

    ACK Flood攻击

    ACK Flood攻击是在TCP连接建立之后,所有的数据传输TCP报文都是带有ACK标志位的,主机在接收到一个带有ACK标志位的数据包的时候,需要检查该数据包所表示的连接四元组是否存在,如果存在则检查该数据包所表示的状态是否合法,然后再向应用层传递该数据包。如果在检查中发现该数据包不合法,例如该数据包所指向的目的端口在本机并未开放,则主机操作系统协议栈会回应RST包告诉对方此端口不存在。
    这里,服务器要做两个动作:查表、回应ACK/RST.这种攻击方式显然没有SYN Flood给服务器带来的冲击大,因此攻击者一定要用大流量ACK小包冲击才会对服务器造成影响。按照我们对TCP协议的理解,随机源IP的ACK小包应该会被Server很快丢弃,因为在服务器的TCP堆栈中没有这些ACK包的状态信息。但是实际上通过测试,发现有一些TCP服务会对ACK Flood比较敏感,比如说JSP Server,在数量并不多的ACK小包的打击下,JSP Server就很难处理正常的连接请求。对于Apache或者IIS来说,10kpps的ACK Flood不构成危胁,但是更高数量的ACK Flood会造成服务器网卡中断频率过高,负载过重而停止响应。可以肯定的是,ACK Flood不但可以危害路由器等网络设备,而且对服务器上的应用有不小的影响。

    ACK Flood 防御

    没找到好的方法,一些防火墙应对的方法是:建立一个hash表,用来存放TCP连接“状态”,相对于主机的TCP stack实现来说,状态检查的过程相对简化。例如,不作sequence number的检查,不作包乱序的处理,只是统计一定时间内是否有ACK包在该“连接”(即四元组)上通过,从而“大致”确定该“连接”是否是“活动的”。

    Connection Flood(TCP多连接攻击,CC攻击等通过建立大量连接请求导致拒绝服务的攻击类型的总称)

    典型的并且非常的有效的利用小流量冲击大带宽网络服务的攻击方式,这种攻击方式目前已经越来越猖獗。这种攻击的原理是利用真实的IP地址向服务器发起大量的连接,并且建立连接之后很长时间不释放,占用服务器的资源,造成服务器服务器上残余连接(WAIT状态)过多,效率降低,甚至资源耗尽,无法响应其他客户所发起的连接。

    其中一种攻击方法是每秒钟向服务器发起大量的连接请求,这类似于固定源IP的SYN Flood攻击,不同的是采用了真实的源IP地址。通常这可以在防火墙上限制每个源IP地址每秒钟的连接数来达到防护目的。但现在已有工具采用慢速连接的方式,也即几秒钟才和服务器建立一个连接,连接建立成功之后并不释放并定时发送垃圾数据包给服务器使连接得以长时间保持。这样一个IP地址就可以和服务器建立成百上千的连接,而服务器可以承受的连接数是有限的,这就达到了拒绝服务的效果。

    另外,蠕虫大规模爆发的时候,由于蠕虫代码则比较简单,传播过程中会出现大量源IP地址相同的包,对于 TCP 蠕虫则表现为大范围扫描行为。这是在判断Connection Flood时需要注意的。

    Connection Flood防御

    Connection Flood攻击防御主要通过缓存的方式进行,尽量由设备的缓存直接返回结果来保护后端业务。大型的互联网企业,会有庞大的CDN节点缓存内容。

    当高级攻击者穿透缓存时,清洗设备会截获HTTP请求做特殊处理。最简单的方法就是对源IP的HTTP请求频率做统计,高于一定频率的IP地址加入黑名单。这种方法过于简单,容易带来误杀,并且无法屏蔽来自代理服务器的攻击,因此逐渐废止,取而代之的是JavaScript跳转人机识别方案。

    Connection Flood是由程序模拟HTTP请求,一般来说不会解析服务端返回数据,更不会解析JS之类代码。因此当清洗设备截获到HTTP请求时,返回一段特殊JavaScript代码,正常用户的浏览器会处理并正常跳转不影响使用,而攻击程序会攻击到空处。

    这个地方我们应该可以通过重定向这种实现,即返回给用户一个新的页面,如www.abc.com 自动跳转到www.abc.com/?1881625278=2057455006
    ?1881625278=2057455006

    解决方案:

    这部分攻击基本可以用mod_evasive模块来解决,或者试试新的javascript方法

    <IfModule mod_evasive20.c>
        DOSHashTableSize    3097
        DOSPageCount        5
        DOSSiteCount        50
        DOSPageInterval     1
        DOSSiteInterval     1
        DOSBlockingPeriod   360
    </IfModule>

    相关参数
    DOSHashTableSize 3097:定义哈希表大小。   
    DOSSiteCount 50:允许客户机的最大并发连接。   
    DOSPageCount 2:允许客户机访问同一页的间隔。   
    DOSPageInterval 1:网页访问计数器间隔。   
    DOSSiteInterval 1:全站访问计数器间隔。   
    DOSSiteInterval 60:加入黑名单后拒绝访问时间。   
    DOSEmailNotify xxxx@gmail.com:有IP加入黑名单后通知管理员。   
    DOSSystemCommand "sudo iptables -A INPUT -s %s -j DROP":IP加入黑名单后执行的系统命令。   
    DOSLogDir "/tmp":锁定机制临时目录。   
    DOSWhiteList 127.0.0.1:防范白名单,不阻止白名单IP。

    UDP Flood攻击

    UDP攻击是最容易发起海量流量的攻击手段,而且源IP随机伪造难以追查。但过滤比较容易,因为大多数IP并不提供UDP服务,直接丢弃UDP流量即可。所以现在纯粹的UDP流量攻击比较少见了,取而代之的是UDP协议承载的DNS Query Flood攻击。简单地说,越上层协议上发动的DDoS攻击越难以防御,因为协议越上层,与业务关联越大,防御系统面临的情况越复杂。

    UDP Flood防御

    直接进行阻断或者限制流量

    DNS Query Flood攻击

    DNS Query Flood就是攻击者操纵大量傀儡机器,对目标发起海量的域名查询请求。为了防止基于ACL的过滤,必须提高数据包的随机性。常用的做法是UDP层随机伪造源IP地址、随机伪造源端口等参数。在DNS协议层,随机伪造查询ID以及待解析域名。随机伪造待解析域名除了防止过滤外,还可以降低命中DNS缓存的可能性,尽可能多地消耗DNS服务器的CPU资源。

    DNS攻击防御

    类似HTTP的防御手段,第一方案是缓存。其次是重发,可以是直接丢弃DNS报文导致UDP层面的请求重发,可以是返回特殊响应强制要求客户端使用TCP协议重发DNS查询请求。

    解决方案:

    基本是靠缓存或者是阻断来进行防御

    慢速连接攻击

    提起攻击,第一反应就是海量的流量、海量的报文。但有一种攻击却反其道而行之,以慢著称,以至于有些攻击目标被打死了都不知道是怎么死的,这就是慢速连接攻击,最具代表性的是rsnake发明的Slowloris。

    HTTP协议规定,HTTP Request以 结尾表示客户端发送结束,服务端开始处理。那么,如果永远不发送 会如何?Slowloris就是利用这一点来做DDoS攻击的。攻击者在HTTP请求头中将Connection设置为Keep-Alive,要求Web Server保持TCP连接不要断开,随后缓慢地每隔几分钟发送一个key-value格式的数据到服务端,如a:b ,导致服务端认为HTTP头部没有接收完成而一直等待。如果攻击者使用多线程或者傀儡机来做同样的操作,服务器的Web容器很快就被攻击者占满了TCP连接而不再接受新的请求。

    慢速连接防御

    第一个是统计每个TCP连接的时长并计算单位时间内通过的报文数量即可做精确识别。一个TCP连接中,HTTP报文太少和报文太多都是不正常的,过少可能是慢速连接攻击,过多可能是使用HTTP 1.1协议进行的HTTP Flood攻击,在一个TCP连接中发送多个HTTP请求。

    第二个是限制HTTP头部传输的最大许可时间。超过指定时间HTTP Header还没有传输完成,直接判定源IP地址为慢速连接攻击,中断连接并加入黑名单。

    解决方案:

    Mod_reqtimeout模块可以针对请求头和请求体进行超时时间限制:

    RequestReadTimeout header=10-30,MinRate=500

    Allow at least 10 seconds to receive the request including the headers. If the client sends data, increase the timeout by 1 second for every 500 bytes received. But do not allow more than 30 seconds for the request including the headers:

    RequestReadTimeout header=20-40,MinRate=500 body=20,MinRate=500

    限制每个IP的写进程数量:

    ModSecurity v2.6 introduced a new directive called SecWriteStateLimit, which will place a limit on the concurrent number of threads (per IP address) in a SERVER_BUSY_WRITE state.  This was originally created to help mitigate the Slow Request Body DoS attacks as Apache moves these threads into this state when it is reading request body payloads.  Well, as it turns out, when Apache is sending response body data back to a client, it too moves the threads into the SERVER_BUSY_WRITE state.  This means that we can use the ModSecurity SecWriteStateLimit to set an upper threshold of concurrent threads (per IP address) in this state.  If this threshold is met, then new threads over this limit will be terminated.  The end result is that an attacker will not be able to tie up all available threads and other clients will be able to access the web server.

    SecWriteStateLimit 100

    ICMP相关攻击

    Ping of Death和Pingflood等ping相关攻击基本不需要考虑,应用服务器防火墙可以进行防护

    相关apache模块

    mod_qos

    Limitations on the TCP connection level, e.g., the maximum number of allowed connections from a single IP source address or dynamic keep-alive control.

    Prefers known IP addresses when server runs out of free TCP connections.

    可以在tcp 连接数超过一定限制的时候关闭keep-alive设置

    可以限制单IP的连接数

    可以限制客户端流量???

    http://en.wikipedia.org/wiki/Mod_qos

    如果有一天我们淹没在茫茫人海中,庸碌一生,那一定是我们没有努力活得丰盛
  • 相关阅读:
    02-model设计
    01-开发环境搭建
    04-Uwsgi配置启动Nginx虚拟主机配置
    03-MySQL安装与配置
    02-Nginx配置
    01-Nginx安装
    22-注册、登录、验证登录
    21-django-pure-pagination分页
    (二)windows上使用docker
    Docker在windows7上的安装
  • 原文地址:https://www.cnblogs.com/xiachj/p/4105030.html
Copyright © 2011-2022 走看看