|
isn := A+sseq + (count<<COOKIEBITS) + (B+data)&COOKIEMASK
|
反算出count和data。因为攻击者并不知道这里的A和B,因此经过反算出的count和data几乎不可能都合理,因此TCP服务器也几乎不可能为这些ACK包分配存储空间,这也就说明了SYN Cookie达到起到了抵挡SYN Flood攻击的作用。
四 SYN Cookie Firewall
从上面的介绍可以看到,Linux内核中的SYN Cookie机制主要的功能是防止本机遭受SYN Flood攻击的,但是在很多情况下,仅仅实现这样的SYN Cookie机制是不够的。如果我们要考虑的是一个网关模式的防火墙,它不仅要保护本机免受各种网络攻击,还要保护它后面的所有对外有开放TCP端口的主机免受这些攻击。比如一个局域网中有个服务器开放了FTP服务给外界,这个服务器主机就有可能遭受到来自互联网上的SYN Flood攻击。而这时的防火墙会将所有的攻击SYN包转发给受害主机。
一种杜绝这种情况的方法是SYN Cookie Firewall。它是SYN Cookie的一种扩展形式。总的来说,它是利用原来SYN Cookie的原理在内网和外网之间实现TCP三次握手过程的代理(proxy)的机制。
为了方便描述,我们假定一个外在的TCP客户机C希望通过防火墙F连接到局域网中的一个TCP服务器S。
在防火墙收到来自外网的SYN包时,它并不直接进行转发,而是缓存在本地,再按照原来SYN Cookie的机制制作好一个针对这个SYN包的SYN+ACK包,注意,这个SYN+ACK包中的ack顺序号为特制的cookie值c,更重要的是这个包的的源地址被伪造成了S的地址(为了描述方便,我们这里暂时不考虑NAT等其他因素)。这样C会接收到这个SYN+ACK包,并认为是从S反馈回来的。于是C再响应一个ACK包,并认为与S的TCP连接已经建立起来。这时防火墙F收到这个ACK包,按照前面的描述的SYN Cookie原理来检查这个ACK中的ack顺序号。如果认为合法,F将本地缓存的来自C的SYN包发送给S,这时S会响应一个SYN+ACK包到C,其中也携带一个seq号, 我们设为c`。当然这个包不会到达C,而是由防火墙F截取,F根据这个包中的序列号等信息,造一个ACK包响应到S。这时的情况是:C认为自己已经与S建立了TCP连接;S认为自己与C建立了TCP连接。以后的TCP数据内容可以直接穿过防火墙F,在S和C之间交互。
上图是SYN Cookie Firewall的工作原理,它相当于在TCP Server与TCP Client之间实现了对三次握手协议的代理。第一次"三次握手"在TCP Client与防火墙之间进行,第二次"三次握手"在防火墙与TCP Server之间。在第一次"三次握手"时使用前面介绍的SYN Cookie流程。有一个问题在进行两次"三次握手"时出现了:如图所示,进行第一次"三次握手"后,TCP Client认为后续数据包的seq值从c+1开始,而进行第二次"三次握手"后,TCP Server认为后续发来的数据包的seq值从c`+1开始, c是cookie,c`是TCP Server随机产生的。c和c`几乎不可能相等,也就是说在完成上面的两个"三次握手"后,如果不进行其他操作,后续从TCP Client到TCP Server的数据包都将被认为顺序号不对而被丢掉。一种补救方法就是在防火墙本地保存一个值δ
δ = |c - c`| 利用这个差值,在每个数据包经过防火墙时,将其seq值修改一下,这样,后续的数据流量可以完美地在TCP Server和TCP Client之间传输了。
总结
现在普遍使用的IPv4协议带有很多安全上的问题,其中面对SYN Flood攻击的软弱就是一点。在不改变TCP三次握手流程的情况下,TCP Server几乎不可能有效的防范SYN Flood的攻击。要保证完全防范SYN Flood,必须修改三次握手协议。SYN Cookie是一种很有效的方法。它的思想比较简单,主要是如何具体的实现,Linux系统也提供了一种实现。作者通过研读Linux2.4.20内核中的代码,基本了解了Linux内核中实现SYN Cookie的手段,将其总结成文字,与对SYN Cookie同样感兴趣的朋友分享、交流。
共3页: 上一页 [1] [2] 3 下一页
|