服务器开发的日子 2014-11-14
一:什么是CentOSSYNFlood攻击
CentOSSYNFlood攻击利用的是IPv4中TCP协议的三次握手(Three-WayHandshake)过程进行的攻击。这个协议规定,如果一端想向另一端发起TCP连接,它需要首先发送TCPSYN(synchronize)包到对方。
对方收到后发送一个TCPSYN+ACK包回来,发起方再发送TCPACK(ACKnowledgeCharacter)包回去,这样三次握手就结束了。在上述过程中,还有一些重要的概念。
未连接队列:在三次握手协议中,服务器维护一个未连接队列,该队列为每个客户端的CentOSSYN包(syn=j)开设一个条目,该条目表明服务器已收到CentOSSYN包,并向客户发出确认,正在等待客户的确认包。
这些条目所标识的连接在服务器处于CentOSSYN_RECV状态,当服务器收到客户的确认包时,删除该条目,服务器进入ESTABLISHED状态。或者说TCP服务器收到TCPSYNrequest包时。
在发送TCPSYN+ACK包回TCP客户机前,TCP服务器要先分配好一个数据区专门服务于这个即把形成的TCP连接。一般把收到CentOSSYN包而还未收到ACK包时的连接状态成为半开连接(Half-openConnection)。
Backlog参数:表示未连接队列的最大容纳数目。CentOSSYN-ACK重传次数:服务器发送完CentOSSYN-ACK包,如果未收到客户确认包,服务器进行首次重传,等待一段时间仍未收到客户确认包,进行第二次重传,如果重传次数超过系统规定的最大重传次数。
系统将该连接信息从半连接队列中删除。注意,每次重传等待的时间不一定相同。半连接存活时间:是指半连接队列的条目存活的最长时间,也即服务从收到SYN包到确认这个报文无效的最长时间。
该时间值是所有重传请求包的最长等待时间总和。有时我们也称半连接存活时间为Timeout时间、CentOSSYN_RECV存活时间。在最常见的CentOSSYNFlood攻击中,攻击者在短时间内发送大量的TCPSYN包给受害者,这时攻击者是TCP客户机,受害者是TCP服务器。
根据上面的描述,受害者会为每个TCPSYN包分配一个特定的数据区,只要这些CentOSSYN包具有不同的源地址(这一点对于攻击者来说是很容易伪造的)。这把给TCP服务器系统造成很大的系统负担,最终导致系统不能正常工作。
二:CentOSSYNCookie原理
能够有效防范CentOSSYNFlood攻击的手段之一,就是SYNCookie。SYNCookie原理由D.J.Bernstain和EricSchenk发明。CentOSSYNCookie是对TCP服务器端的三次握手协议作一些修改,专门用来防范CentOSSYNFlood攻击的一种手段。
它的原理是,在TCP服务器收到TCPSYN包并返回TCPSYN+ACK包时,不分配一个专门的数据区,而是根据这个CentOSSYN包计算出一个cookie值。在收到TCPACK包时,TCP服务器在根据那个cookie值检查这个TCPACK包的合法性。
如果合法,再分配专门的数据区进行处理未来的TCP连接。下面分Linux和FreeBSD来说说如何配置内核参数来实现CentOSSYNCookie
三:Linux下设置
如果你的服务器配置不太好,TCPTIME_WAIT套接字数量达到两、三万,服务器很容易被拖死。通过修改Linux内核参数,可以减少服务器的TIME_WAIT套接字数量。
TIME_WAIT可以通过以下命令查看:以下是代码片段:netstat-an|grep"TIME_WAIT"|wc-l在Linux下,如CentOS,可以通过修改/etc/sysctl.conf文件来达到目的。
增加以下几行:以下是代码片段:
net.ipv4.tcp_fin_timeout=30
net.ipv4.tcp_keepalive_time=1200
net.ipv4.tcp_syncookies=1
net.ipv4.tcp_tw_reuse=1
net.ipv4.tcp_tw_recycle=1
net.ipv4.ip_local_port_range=102465000
net.ipv4.tcp_max_syn_backlog=8192
net.ipv4.tcp_max_tw_buckets=5000
net.ipv4.tcp_synack_retries=2
net.ipv4.tcp_syn_retries=2
说明:
net.ipv4.tcp_syncookies=1表示开启CentOSSYNCookies,这是个BOOLEAN。当出现CentOSSYN等待队列溢出时,启用cookies来处理,可防范少量CentOSSYN攻击,默认为0,表示关闭;
net.ipv4.tcp_tw_reuse=1表示开启重用,这是个BOOLEAN。允许将TIME-WAITsockets重新用于新的TCP连接,默认为0,表示关闭;
net.ipv4.tcp_tw_recycle=1表示开启TCP连接中TIME-WAITsockets的快速回收,这是个BOOLEAN,默认为0,表示关闭。
net.ipv4.tcp_fin_timeout=30表示如果套接字由本端要求关闭,这个参数决定了它保持在FIN-WAIT-2状态的时间。单位为秒。
net.ipv4.tcp_keepalive_time=1200表示当keepalive起用的时候,TCP发送keepalive消息的频度。缺省是2小时,改为20分钟。单位为秒。
net.ipv4.ip_local_port_range=102465000表示用于向外连接的端口范围。缺省情况下很小:32768到61000,改为1024到65000。
net.ipv4.tcp_max_syn_backlog=8192表示CentOSSYN队列的长度,默认为1024,加大队列长度为8192,可以容纳更多等待连接的网络连接数。
net.ipv4.tcp_max_tw_buckets=5000表示系统同时保持TIME_WAIT套接字的最大数量,如果超过这个数字,TIME_WAIT套接字将立刻被清除并打印警告信息。
默认为180000,改为5000。对于Apache、Nginx等服务器,上几行的参数可以很好地减少TIME_WAIT套接字数量,但是对于Squid,效果却不大。此项参数可以控制TIME_WAIT套接字的最大数量,避免Squid服务器被大量的TIME_WAIT套接字拖死。
net.ipv4.tcp_synack_retries和net.ipv4.tcp_syn_retries是定义CentOSSYN重试次数。执行以下命令使配置生效:以下是代码片段:/sbin/sysctl-p如果你不想修改/etc/sysctl.conf,你也可以直接使用命令修改:以下是代码片段:/sbin/sysctl-wkey=value
四:FreeBSD下设置
yayu个人学习的观点:FreeBSD中对CentOSSYN的防御和Linux下可能不一样,配置的参数也不完全相同,相关配置和理解可能不对:)TCP链接中有一个MSL(maxsegmentlifetime)的概念,也就是最大生成时间,MSL的值在一般的实现中取30s,有些实现采用2分钟。
在TCP的状态机中的“被动关闭”:从CLOSE_WAIT到LAST_ACK中有一个如下的规则:当TCP执行一个主动关闭,并发回最后一个ACK,该连接必须在TIME_WAIT状态停留的时间为2倍的MSL。这样可让TCP再次发送最后的ACK以防这个ACK丢失(另一端超时并重发最后的FIN)。
存在这个规则导致一个后果就是在这个2*MSL的时间内,该地址上的链接(客户端地址、端口和服务器端的地址、端口)不能被使用。比如我们在建立一个链接后关闭链接然后迅速重启链接,那么就会出现端口不可用的情况。
TIME_WAIT时间是2*MSL。因此可以通过调整net.inet.tcp.msl来减少TIME_WAIT时间。对于Web服务器完全可以将这个值调整为7500或2000(访问一个web,超过4~15秒页面还刷不出来,就可以考虑放弃了-_-)
参数设置参考:
以下是引用片段:net.inet.tcp.syncookies=1防止DOS攻击net.inet.tcp.msl=7500防止DOS攻击,默认为30000net.inet.tcp.blackhole=2接收到一个已经关闭的端口发来的所有包,直接drop,如果设置为1则是只针对TCP包
net.inet.udp.blackhole=1接收到一个已经关闭的端口发来的所有UDP包直接dropFreeBSD下,yayu没看见“/sbin/sysctl-p”这样的命令可以使/etc/sysctl.conf的内容生效,所以直接使用命令了:
以下是代码片段:sysctlnet.inet.tcp.syncookies=1net.inet.tcp.msl=7500net.inet.tcp.blackhole=2net.inet.udp.blackhole=1
五:其他
除了修改服务器的内核参数,还可以修改apache的配置文件中的Timeout、KeepAlive、MaxClients等参数来防止Dos攻击,如果有接口调用,还要注意控制一下调用的时间。请听下文分解。
ACK英文缩写:ACK(ACKnowledgeCharacter)中文译名:确认字符分类:传输与接入解释:在数据通信传输中,接收站发给发送站的一种传输控制字符。它表示确认发来的数据已经接受无误。
NAK是否定应答或者非应答的缩写。它是一个用于数字通信中确认数据受到但是有小错误的信号。有时候NAK信号也叫REJ(拒绝)。
CentOSSYN包(synchronize)
TCP连接的第一个包,非常小的一种数据包。CentOSSYN攻击包括大量此类的包,由于这些包看上去来自实际不存在的站点,因此无法有效进行处理。每个机器的欺骗包都要花几秒钟进行尝试方可放弃提供正常响应。
在黑客攻击事件中,CentOSSYN攻击是最常见又最容易被利用的一种攻击手法。CentOSSYN攻击属于DOS攻击的一种,它利用TCP协议缺陷,通过发送大量的半连接请求,耗费CPU和内存资源。
CentOSSYN攻击除了能影响主机外,还可以危害路由器、防火墙等网络系统,事实上CentOSSYN攻击并不管目标是什么系统,只要这些系统打开TCP服务就可以实施。服务器接收到连接请求(syn=j),将此信息加入未连接队列,并发送请求包给客户(syn=k,ack=j+1),此时进入SYN_RECV状态。
当服务器未收到客户端的确认包时,重发请求包,一直到超时,才将此条目从未连接队列删除。配合IP欺骗,CentOSSYN攻击能达到很好的效果,通常,客户端在短时间内伪造大量不存在的IP地址,向服务器不断地发送syn包,服务器回复确认包,并等待客户的确认。
由于源地址是不存在的,服务器需要不断的重发直至超时,这些伪造的CentOSSYN包将长时间占用未连接队列,正常的CentOSSYN请求被丢弃,目标系统运行缓慢,严重者引起网络堵塞甚至系统瘫痪。
关于CentOSSYN攻击防范技术,人们研究得比较早。归纳起来,主要有两大类,一类是通过防火墙、路由器等过滤网关防护,另一类是通过加固TCP/IP协议栈防范.但必须清楚的是,CentOSSYN攻击不能完全被阻止,我们所做的是尽可能的减轻CentOSSYN攻击的危害,除非将TCP协议重新设计。