设为首页 友情链接
在线留言 发表文章
加入收藏 广告联系

刺猬首页

| 专案技术 | 网络技术 | 图形图象 | 网络编程 | 网页设计 | 操作系统 | 服务器 | 技术白皮书 | 在线实验室 | 刺猬论坛 |
小说专版  | 数据库 | 设计赏析 | 存储频道 | 网络安全 | 私服架设 |  Solaris | 网站评估 | PC维护技巧 | 下载中心 | 博 客 |
专   题: | Linux | java | cisco | 防病毒 | 刀片 | SOA | iscsi | ASP.NET | SQL | Oracle |
您现在的位置: IT公社 IT community >> Linux专题 >> 内核研究 >> 教程正文 用户登录 新用户注册
专 题 栏 目
最 新 热 门
最 新 推 荐
相 关 文 章
使用synergy在多台电脑间…
busybox 制作tiny linux
經由 VNC 安裝 Redhat L…
用apt+synaptic 在线安装…
Fedora 软件包管理器sys…
基于LINUX蜜网(Honeynet…
动态iptables防火墙dynf…
微软WinCE6.0过高授权费…
Unisys改变企业战略定位…
FREEBSD下使用crunch集成…
  SYN Cookie原理及在Linux内核中的实现         
SYN Cookie原理及在Linux内核中的实现
 

概述

在目前以IPv4为支撑的网络协议上搭建的网络环境中,SYN Flood是一种非常危险而常见的DoS攻击方式。到目前为止,能够有效防范SYN Flood攻击的手段并不多,而SYN Cookie就是其中最著名的一种。SYN Cookie原理由D. J. Bernstain和 Eric Schenk发明。在很多操作系统上都有各种各样的实现。其中包括Linux。本文就分别介绍一下SYN Flood攻击和SYN Cookie的原理,更重要的是介绍Linux内核中实现SYN Cookie的方式。最后,本文给出一种增强目前Linux中SYN Cookie功能的想法。

一 SYN Flood攻击

SYN Flood攻击是一种典型的拒绝服务型(Denial of Service)攻击。所谓拒绝服务型攻击就是通过进行攻击,使受害主机或网络不能够良好的提供服务,从而间接达到攻击的目的。

SYN Flood攻击利用的是IPv4中TCP协议的三次握手(Three-Way Handshake)过程进行的攻击。大家知道协议规定,如果一端想向另一端发起TCP连接,它需要首先发送TCP SYN 包到对方,对方收到后发送一个TCP SYN+ACK包回来,发起方再发送TCP ACK包回去,这样三次握手就结束了。我们把TCP连接的发起方叫作"TCP客户机(TCP Client)",TCP连接的接收方叫作"TCP服务器(TCP Server)"。值得注意的是在TCP服务器收到TCP SYN request包时,在发送TCP SYN+ACK包回TCP客户机前,TCP服务器要先分配好一个数据区专门服务于这个即将形成的TCP连接。一般把收到SYN包而还未收到ACK包时的连接状态成为半开连接(Half-open Connection)。

在最常见的SYN Flood攻击中,攻击者在短时间内发送大量的TCP SYN包给受害者,这时攻击者是TCP客户机,受害者是TCP服务器。根据上面的描述,受害者会为每个TCP SYN包分配一个特定的数据区,只要这些SYN包具有不同的源地址(这一点对于攻击者来说是很容易伪造的)。这将给TCP服务器系统造成很大的系统负担,最终导致系统不能正常工作。

二 SYN Cookie原理

SYN Cookie是对TCP服务器端的三次握手协议作一些修改,专门用来防范SYN Flood攻击的一种手段。它的原理是,在TCP服务器收到TCP SYN包并返回TCP SYN+ACK包时,不分配一个专门的数据区,而是根据这个SYN包计算出一个cookie值。在收到TCP ACK包时,TCP服务器在根据那个cookie值检查这个TCP ACK包的合法性。如果合法,再分配专门的数据区进行处理未来的TCP连接。

从上面的介绍可以看出,SYN Cookie的原理比较简单。到实际的应用中,它有多种不同的实现方式。

三 Linux内核中的SYN Cookie实现

Linux内核中对SYN Flood有很好的防护。以下的讨论都是针对Linux2.4.20内核进行的。在每一个sock都有一个tcp_opt即这个sock的TCP选项。在tcp_opt其中有一个tcp_listen_opt,这里存储的是这个sock在LISTEN状态下时保存的一些选项,其中有一个open_request结构的数组,数组长度为TCP_SYNQ_HSIZE(512)。所有这些表示在一个sock,最多可以同时开启512个半开连接(这是在不考虑其他约束条件时的最大值,实际情况中不会达到这个值)。当这个数组满了时,新来的open_request会顶替掉一个老的open_request。这样,即使没有启动SYN Cookie,也能够在SYN Flood发生时保护系统免于瘫痪。问题是这种处理方法会在面对SYN Flood攻击时丢掉正常的TCP连接请求。SYN Cookie的作用恰恰是保证在面对SYN Flood攻击时,一方面能够拒绝非法的TCP连接请求,一方面正常连接可以被建立。

Linux内核对TCP流程的处理主要在tcp_ipv4.c文件中的函数实现。具体的,当处理TCP SYN包时,系统进入tcp_v4_conn_request函数。其中调用cookie_v4_init_sequence生成一个ISN(Initial Sequence Number)。Linux内核把它作为SYN Cookie流程中的cookie。

cookie_v4_init_sequence函数在syncookies.c文件中定义,它又调用random.c文件中的secure_tcp_syn_cookie函数。cookie的实质计算是在这个函数中进行的。

在random.c文件里给出secure_tcp_syn_cookie函数的定义之前给出两个宏,它们的定义分别为:

#define COOKIEBITS 24

  #define COOKIEMASK (((__u32)1 << COOKIEBITS) - 1)

  

COOKIEBITS表示cookie的比特长度;COOKIEMASK是一个COOKIEBITS长的比特串,所有比特都是1。

还有两个比特串,被定义成一个__u32的二维数组:

 static __u32 syncookie_secret[2][16-3+HASH_BUFFER_SIZE];

其中所有的比特值在secure_tcp_syn_cookie中被随机的赋予,用get_random_bytes函数。它们成为制作cookie的密钥。这两个被随机产生的比特串是整个SYN Cookie实现方案的关键。另外还有一个开关syncookie_init控制对这两个密钥的改动。

还需要指出,在文件syncookies.c中定义有一个__u16组成的表static __u16 const msstab[],这个表中保存的是一些可能的MSS(Maximum Segment Size)值。

secure_tcp_syn_cookie函数的返回值就是计算得到的ISN值,即cookie。为了描述方便,我们给出如下定义:

tmp1 := saddr + daddr + ((sport<<16)+dport) + syncookie_secret[0]

   tmp2 := saddr + daddr + ((sport<<16)+dport) + syncookie_secret[1]

   tmp11 := HASH_TRANSFORM(tmp1[16], tmp1)

   tmp22 := HASH_TRANSFORM(tmp2[16], tmp2)

  A := tmp11[0][17]

   B := tmp22[1][17]

sseq := ntohl(skb->h.th->seq) 这里的skb是携带TCP SYN的那个skb,count1 := jiffies/(HZ*60) 当前时间的分钟值,data1 := msstab, 从前往后最后一个小于skb中携带的MSS值的值的索引(值得注意的是两个密钥在第一次被初始化后,就不会再有改动,直到系统重新启动。因此可以认为它是一个常值。)

有了上面的定义我们可以得到cookie等于:

    isn := A+sseq + (count1<<COOKIEBITS) + (B+data1)&COOKIEMASK

   

这个isn被赋予返回的TCP SYN+ACK包中,作为其中的ISN值。这就是cookie 的产生过程。在这个过程中,没有在本地为这个连接请求分配任何存储空间。

在TCP服务器收到TCP ACK包时,相应的要进行SYN Cookie的检查。这个检查过程在函数tcp_v4_hnd_req中的cookie_v4_check函数开始。cookie_v4_check调用cookie_check函数,cookie_check函数调用check_tcp_syn_cookie函数。

check_tcp_syn_cookie函数在random.c中定义,是与前面介绍的secure_tcp_syn_cookie函数对应的函数,检查从TCP ACK中提取出的ISN值。

在check_tcp_syn_cookie中假定ISN的值如下:

isn := A+sseq + (count2<<COOKIEBITS) + (B+data2)&COOKIEMASK

    
 

这里的A、B都是根据当前这个skb中的地址信息和syncookie_secret算出来的;sseq是根据这个skb中的seq值算出的。

有了上面这些值,TCP服务器就可以反算出count2和data2。理论上来说,只要这个isn是原来那个isn,应该有:

count2 == count1 

  data2 == data1

但是这种结论仅仅是一个理论情况。因为在TCP服务器端并没有保存原来的count1和data1,因此不能直接进行比较。TCP服务器采取的方法是:

1)计算出当前的分钟值

count3 := jiffies/(HZ*60)用count3与count2比较,如果差值超过COUNTER_TRIES(4)分钟,则认为这 个ACK包不合法。

2)看data2是不是一个合法的msstab的索引,也就是说是不是小于NUM_MSS, 即(sizeo(msstab)/sizeof(msstab[0]) - 1)。如果小于,则认为这个ACK 合法,否则认为非法。

上面介绍的就是Linux内核Linux2.4.20中对SYN Cookie的实现方式。下面讨论一下它的合理性。希望得到的结论是这种方案可以有效的实现一般TCP的连接,同时可以防止SYN Flood攻击。

从上面的介绍来说,合法的TCP连接请求一定可以通过SYN Cookie流程。 另一方面我们看SYN Cookie在系统受到各种SYN Flood攻击时会采取的行为。 最一般的SYN Flood攻击方式是攻击者作为TCP客户机发送大量TCP SYN包而不再发送其他的包。这时SYN Cookie会为每个SYN包计算出相应的ISN值,并返回SYN+ACK包,而在本地将不分配任何存储空间,因此不会被成功攻击。

根据SYN Cookie的原理,攻击者有可能直接发送大量ACK包。这时SYN Cookie提取出每个包的isn值,并假定它有下面的格式:

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包转发给受害主机。

Linux联盟收集整理

频道声明:本频道的文章除部分特别声明禁止转载的专稿外,可以自由转载.但请务必注明出出处和原始作者 文章版权归本频道与文章作者所有.对于被频道转载文章的个人和网站,我们表示深深的谢意。

原始作者:佚名 录入时间:2007-1-2 4:02:49
信息来源:不详 投稿信箱:itqoo@126.com
教程录入:itqoo    责任编辑:itqoo 
  • 上一个教程:

  • 下一个教程:
  • 【字体: 】【发表评论】【加入收藏】【告诉好友】【打印此文】【关闭窗口
      网友评论:(只显示最新10条。评论内容只代表网友观点,与本站立场无关!)
    - 关于我们 - 合作伙伴 - 友情链接 - 广告刊登 - 投稿热线 - 在线留言版权声明联系方式 -
    IT公社版权所有 粤ICP备05127012号
    Copyrigh@2005-2006 itqoo.com.Inc All Rights Reserved  推荐分辨率 1024*768
    联系站长:E-Mail:itqoo@126.com     MSN:urchincc@hotmail.com    QQ:点击这里给我发消息
    特别感谢:亿太网络提供空间支持