
比如:A端为DDOS攻击,B端为服务器
A端向B端发送SYN
B端接收后回复SYN+ACK
此时A端不再回复,使这条连接成为半连接。而服务端认为A端没能成功接收SYN+ACK包,便会不断地重新发送 直到请求超时。
若A端数量为N或者不断发送半连接 则服务器休矣■ SYN cookies技术 我们知道,TCP协议开辟了一个比较大的内存空间backlog队列来存储半连接条目,当SYN请求不断增加,并这个空间,致使系统丢弃SYN连接。为使半连接队列被塞满的情况下,服务器仍能处理新到的SYN请求,SYN cookies技术被设计出来。 SYN cookies应用于linux、FreeBSD等 *** 作系统,当半连接队列满时,SYN cookies并不丢弃SYN请求,而是通过加密技术来标识半连接状态。 在TCP实现中,当收到客户端的SYN请求时,服务器需要回复SYN+ACK包给客户端,客户端也要发送确认包给服务器。通常,服务器的初始序列号由服务器按照一定的规律计算得到或采用随机数,但在SYN cookies中,服务器的初始序列号是通过对客户端IP地址、客户端端囗、服务器IP地址和服务器端囗以及其他一些安全数值等要素进行hash运算,加密得到的,称之为cookie。当服务器遭受SYN攻击使得backlog队列满时,服务器并不拒绝新的SYN请求,而是回复cookie(回复包的SYN序列号)给客户端, 如果收到客户端的ACK包,服务器将客户端的ACK序列号减去1得到cookie比较值,并将上述要素进行一次hash运算,看看是否等于此cookie。如果相等,直接完成三次握手(注意:此时并不用查看此连接是否属于backlog队列)。 在RedHat linux中,启用SYN cookies是通过在启动环境中设置以下命令来完成: # echo 1 > /proc/sys/net/ipv4/tcp_syncookies ■ 增加最大半连接数 大量的SYN请求导致未连接队列被塞满,使正常的TCP连接无法顺利完成三次握手,通过增大未连接队列空间可以缓解这种压力。当然backlog队列需要占用大量的内存资源,不能被无限的扩大。 WIN2000:除了上面介绍的TcpMaxHalfOpen, TcpMaxHalfOpenRetried参数外,WIN2000 *** 作系统可以通过设置动态backlog(dynamic backlog)来增大系统所能容纳的最大半连接数,配置动态backlog由AFDSYS驱动完成,AFDSYS是一种内核级的驱动,用于支持基于window socket的应用程序,比如ftp、telnet等。AFDSYS在注册表的位置:HKLM\\System\\CurrentControlSet\\Services\\AFD\\ParametersEnableDynamicBacklog值为1时,表示启用动态backlog,可以修改最大半连接数。 MinimumDynamicBacklog表示半连接队列为单个TCP端囗分配的最小空闲连接数,当该TCP端囗在backlog队列的空闲连接小于此临界值时,系统为此端囗自动启用扩展的空闲连接(DynamicBacklogGrowthDelta),Microsoft[s:148]该值为20。 MaximumDynamicBacklog是当前活动的半连接和空闲连接的和,当此和超过某个临界值时,系统拒绝SYN包,Microsoft[s:148]MaximumDynamicBacklog值不得超过2000。 DynamicBacklogGrowthDelta值是指扩展的空闲连接数,此连接数并不计算在MaximumDynamicBacklog内,当半连接队列为某个TCP端囗分配的空闲连接小于MinimumDynamicBacklog时,系统自动分配DynamicBacklogGrowthDelta所定义的空闲连接空间,以使该TCP端囗能处理更多的半连接。Microsoft[s:148]该值为10。 LINUX:Linux用变量tcp_max_syn_backlog定义backlog队列容纳的最大半连接数。在Redhat 73中,该变量的值默认为256,这个值是远远不够的,一次强度不大的SYN攻击就能使半连接队列占满。我们可以通过以下命令修改此变量的值: # sysctl -w netipv4tcp_max_syn_backlog=\"2048\" Sun Solaris Sun Solaris用变量tcp_conn_req_max_q0来定义最大半连接数,在Sun Solaris 8中,该值默认为1024,可以通过add命令改变这个值: # ndd -set /dev/tcp tcp_conn_req_max_q0 2048 HP-UX:HP-UX用变量tcp_syn_rcvd_max来定义最大半连接数,在HP-UX 1100中,该值默认为500,可以通过ndd命令改变默认值: #ndd -set /dev/tcp tcp_syn_rcvd_max 2048 ■缩短超时时间 上文提到,通过增大backlog队列能防范SYN攻击;另外减少超时时间也使系统能处理更多的SYN请求。我们知道,timeout超时时间,也即半连接存活时间,是系统所有重传次数等待的超时时间总和,这个值越大,半连接数占用backlog队列的时间就越长,系统能处理的SYN请求就越少。为缩短超时时间,可以通过缩短重传超时时间(一般是第一次重传超时时间)和减少重传次数来实现。 Win2000第一次重传之前等待时间默认为3秒,为改变此默认值,可以通过修改网络接囗在注册表里的TcpInitialRtt注册值来完成。重传次数由TcpMaxConnectResponseRetransmissions 来定义,注册表的位置是:HKLM\\SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters registry key。 当然我们也可以把重传次数设置为0次,这样服务器如果在3秒内还未收到ack确认包就自动从backlog队列中删除该连接条目。 LINUX:Redhat使用变量tcp_synack_retries定义重传次数,其默认值是5次,总超时时间需要3分钟。 Sun Solaris Solaris 默认的重传次数是3次,总超时时间为3分钟,可以通过ndd命令修改这些默认值。
为什么要有三次握手,因为如果只有两次握手,那么
第一次:客户端发送一个syn包给服务器,里面有一个随机生成的syn,然后客户端处于syn_send状态
第二次:服务端收到客户端发来的syn包之后,确认syn包,也就是生成一个ack=syn+1,然后再自己随机生成一个syn包,即syn+ack包,然后返回给客户端,自己变成syn_recv状态
第三次:客户端收到服务端发来的syn+ack包之后,确认ack是正确的之后,返回一个ack=syn+1给服务端,此包发送完毕,客户端进入了ESTABLISHED状态,服务端收到ack包后也进入ESTABLISHED状态。
SYN攻击,当第二次握手服务端发送了syn+ack包之后,收到客户端发送的ack之前这段时间的tcp链接成为半连接,此时服务端处于syn_recv状态。当大量客户端随机IP疯狂发送tcp链接请求时,客户端以为是不同用户的请求,所以队列中全是半连接,然后导致服务器宕机,正常请求被丢弃。
第一个包发送过程丢失
A会周期性超时重传,直到收到B的确认
第二个包发送过程丢失
B会周期性超时重传,直到收到A的确认
第三个包发送过程丢失
A发送完数据后单方面进入TCP的ESTABLISHED状态,B还处于半链接:
TCP协议为什么需要三次握手?
第一次:客户端发送一个fin给服务端表示自己要断开连接了,然后进入fin_wait_1状态
第二次:服务端收到fin后,发送一个ack=fin+1给客户端,服务端进入close_wait状态,客户端进入fin_wait_2状态
第三次:服务端发送一个fin,用来关闭服务端到客户端的数据传输,服务端进入last_ack状态
第四次:客户端收到fin后,进入time_wait状态,然后发送一个ack=fin+1给服务端,服务端确认后进入close状态,完成四次挥手
TCP协议是一种面向连接的、可靠的、基于字节流的运输层通信协议。TCP是全双工模式,这就意味着,当主机1发出FIN报文段时,只是表示主机1已经没有数据要发送了,主机1告诉主机2,它的数据已经全部发送完毕了;但是,这个时候主机1还是可以接受来自主机2的数据;当主机2返回ACK报文段时,表示它已经知道主机1没有数据发送了,但是主机2还是可以发送数据到主机1的;当主机2也发送了FIN报文段时,这个时候就表示主机2也没有数据要发送了,就会告诉主机1,我也没有数据要发送了,之后彼此就会愉快的中断这次TCP连接。如果要正确的理解四次分手的原理,就需要了解四次分手过程中的状态变化。
答案解析:
浏览器对并发请求的数目限制是针对域名的,即针对同一域名(包括二级域名)在同一时间支持的并发请求数量的限制。如果请求数目超出限制,则会阻塞。因此,网站中对一些静态资源,使用不同的一级域名,可以提升浏览器并行请求的数目,加速界面资源的获取速度。
在 >
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)