了解CheckPointFW-1状态表作者:LanceSpitzner(lance@spitzner.net)整理:warning3(warning3@nsfocus.com)主页:日期:2000-08-15*译者:以前关于防火墙状态表,也只是有一个大概的了解,通过看这篇文章,也纠正了一些自己的错误看法,感觉很有收获,因此就把它翻译出来了。由于时间仓促,可能些地方翻的会有问题,如发现错误,请跟我联系。这篇文章的主要目的是帮助你了解FW-1的状态连接表是如何工作的。这张表使FW-1知道谁在做什么,什么连接时是允许通过的...这篇文章是我对最新的FW-14.1版研究的一个继续。为了使你更好的理解你自己的FW-1状态检查表并与我所说的进行验证,我将这篇文章中所用到的源码附在最后。状态检查(StatefulInspection)==============================让我们首先从一个很基本的问题开始我们的讨论。假设你有一个防火墙,它的过滤规则允许所有连接通过(any-any-accept),那么防火墙是否会允许一个用ACK位发起的新TCP连接通过呢?如果防火墙允许任何连接通过,那么似乎任意的包都应当通过。然而,如果从状态检查的工作原理上看,这个包又似乎应当被丢弃。我开始对状态检查(至少是对CheckPointFireWall-1)的理解是这样的:当防火墙收到一个发起TCP连接请求的SYN包时,这个SYN包首先会与防火墙的过滤规则按顺序(从规则0开始)进行比较,如果所有的规则都不允许接受这个包,那它就被拒绝,这个连接就被丢弃或者拒绝(发送RST包给远程主机).然而,如果这个包被接受了,这个连接会话就被加入到防火墙的状态连接表中,这个表在内核空间中分配。后续的每个包(不带SYN标记的包)都会与状态表比较,如果相应的会话已经在表中了,那个这个包就是连接会话的一部分,然后这个包就被接受,允许通过。如果不是,这个包就被丢弃。这将改进系统性能,因为不需要将每个包都与过滤规则集进行比较,而是只对发起连接的SYN包进行比较。所有其它的TCP包都在内核空间中与状态表进行比较,这个速度是很快的。好,现在回到我们开始谈的那个问题上来。如果我们用一个ACK包发起一个会话,防火墙是否会接受这个包呢,即使过滤规则已经允许所有的连接通过?就象我们刚才说的,你可能认为会接受。但现在我们对状态连接表有了更多的认识,可能这个答案会是相反的了。当防火墙收到一个ACK包时,它会先与内核空间中的状态连接表进行比较,而不是过滤规则集。当然防火墙的状态连接表中没有相应的会话记录,因为并没有一个SYN包发起过连接。那么,到底防火墙会不会接受这个包呢?答案-FW-1如何建立一个连接============================答案是令人吃惊的。不仅这个ACK包被接受,它还会被加入到状态表中!我对防火墙状态表的理解并不正确。我所发现的结果是,当防火墙收到一个不在状态表中的包时,它会先与过滤规则进行比较,不管这个包是SYN,ACK或者是其他的什么包。如果过滤规则允许接受这个会话,那么这个会话就被加入到状态连接表中去。这个连接会话的所有后续包都会与状态表进行比较,既然在状态连接表中已经存在了相应的会话,因此这些包就被接受而不再与过滤规则集进行比较。fwtable.pl(ver1.0)将'fwtab-tconnections'得到的结果进行转化,我们得到下面的输出结果:注意:下面看到的这些是我的状态连接表中那些使用ACK包发起的连接。mozart#fwtable----FW-1CONNECTIONSTABLE---Src_IPSrc_PrtDst_IPDst_PrtIP_protKbufTypeFlagsTimeout192.168.7.13110003207.229.143.825601638502ffff002845/3600192.168.7.13110002207.229.143.824601638502ffff002845/3600192.168.7.13110001207.229.143.823601638502ffff002845/3600我们可以看到这三个包都被接受并被加入到防火墙状态表中,但它们都是使用用ACK包发起的连接。同样,对于Null,SYN/ACK,FIN/ACK等类型的包也会被接受。当你使用'ftstop;fwstart'重新启动防火墙时,过程连接表会被清空。如果有并发连接发送ACK包,防火墙看到这些包时,会检查它们是不是符合过滤规则,并重建连接表。所有这些操作对终端用户都是透明的。这就是你为什么那些加密认证的会话连接会中断,因为防火墙没有这些连接的初始状态。同时应当注意的时,对于非SYN包连接缺省连接超时是3600秒,这意味着,你可以将这个会话在连接表中保存60分钟的时间直至超时。这个超时时间可以在控制属性菜单里面调整。注意:有效的FIN或者RST包并不会建立一个会话,因为它们被用来中断一个连接。另外,唯一不会被增加到状态表中去的是'Xmas'包,可以用Fyodor的nmap(-sX开关)来产生。然而这些包会被接受并被记录。这里我了解到的另外一点是,FW-1的状态检查只根据源/目的IP和端口来判断是不是一个会话。它不管序列号,因为我制造了很多不同的序列号,防火墙都认为是一个会话而接受了。当建立连接的时候,FW-1也不维护包类型的状态。当你发送一个SYN包初始化一个会话时,防火墙先与过滤规则集进行比较,如果被接受,就将这个会话增加到状态表中,就象我们前面讨论的那样。这时候,超时时间被设置成60秒。防火墙会等候一个返回包来建立连接。当它看到一个返回包时,超时被设置成3600秒(60分钟).然而防火墙并不在乎返回什么类型的包。我使用SYN发起一个连接,然后只发回一个ACK包,防火墙就将这个包作为连接的一部分接受了(因为IP和端口是匹配的).因此,防火墙并没有智能到能够知道必须返回SYN/ACK的应答包,也不在乎序列号。要维护序列号等状态需要更多的系统资源,可能是为了提高系统性能才这么做的吧。拒绝服务攻击(BugtraqID549):当建立一个连接的时候,如果你使用ACK(或者其他的非SYN包,象Null,FIN/ACK,SYN/ACK等等)来发起连接,连接超时自动被设置成3600秒。这暗示着存在以拒绝服务攻击的可能。既然远程系统并不存在,它们就不会发送RST或者FIN包来中断连接,这将在连接表中留下一个死连接,这个死连接会存在一个小时的时间。通过发送大量ACK包连接包给并不存在的系统,你可以迅速地填满防火墙的连接表。幸运的是,从防火墙外部发动这种攻击比从内部要困难的多。但是,如果你从防火墙后面往外进行扫描时,很容易造对自己的DoS攻击。CheckPoint对这个问题发表了提供了一个解决方法,你可以按照下列步骤来解决这个问题:.CheckPoint已经提供了一个用状态检查的解决方案,但重新装载过滤策略时可能会影响状态表的功能.减少TCP超时时间到15分钟(900秒)。这将减少攻击者填满你的连接表的机会.增大你的连接表。这使填满连接表变得更为困难。.使用更为严格的规则集,限制能进出的连接.JasonRhoads提供了一个PERL程序,fwconwatch.pl,可以为你监视连接表,并按照你定义的规则发出警告.使用Fastpath(forver3.0)或者FastMode(forver4.0)。这将从连接表中去掉TCP连接,但这也会带来其它的安全问题。关于Fastpath/FastMode请看下面更为详细的介绍。.注意:SynDefender并不能保护这种攻击,因为它只被设计来保护SYNflooding攻击,这是另外一种不同的攻击。这种攻击是基于非SYN包的。我喜欢FT-1的一个特点是它对待SYN包的方式。如果你试图冒充一个已经存在的连接,初始化一个新连接,防火墙仍然会先与规则集进行比较。例如,假设你试图建立一个这样的连接:A---FW--B#系统A联往系统B现在,系统B可以发送任意的包给系统A,只要IP和端口匹配(例如,那些属于这个连接会话的包).然而,如果系统试图发送SYN包建立一个新的连接,即使它使用与已存在的那个连接同样的端口,防火墙仍然会认为这个SYN包是一个新会话的一部分,将它与规则集进行比较。就我的观点来说,这是件好事。在上面的例子中,如果我们只允许来自外部系统A的连接,不允许从内部的系统B发往外部的连接。那么系统B与系统A联系的唯一方式就是作为一个已建立的连接的一部分来进行。当系统A连往系统B时,这个连接被加入到防火墙连接检查表中,现在系统B可以发送应答包给系统A了。然而,系统B并不能向A发送任何的SYN包来新建连接,即使IP和端口号是相同的。当防火墙看到SYN包时,它将这个包与规则集进行比较。在上面所说的条件下,这个包将被丢弃,虽然已经存在一个端口和IP都相同的连接。Fastpath:我学到的另外一些东西就是,如果fastpath被使用,那么TCP回话不会被加入到过程连接表中。这是因为Fastpath仅仅检查SYN包,所以不需要将连接会话增加到连接表中。如果一个包中设置了其它的标志,缺省情况下这个包就不会被过滤而是让其通过了。通常fastpatch用来改进性能。它的思路是:如果一个包没有设置SYN标志,那么它肯定是一个已经建立的连接的一部分,因为只有SYN包才能开始一个连接。既然只检查SYN包,所以性能肯定会大大提高。然而,使用faspatch通常并不是一个好的做法,因为这可能让你暴露在多种攻击方式之下。Fastpath在FW-1v3.0中存在,并且只能对所有的TCP包同时起作用。在v4.0中,它又被叫做Fastmode,可以有选择的对不同的TCP服务实施。关闭一个连接=================根据初步的测试结果,FW-1通过设置连接超时时间来关闭连接。当检查模块看到一个连接会话开始交换FIN或者RST包时,它就将超时时间从3600秒改为50秒。如果50秒内没有其它的包发送,连接就被从状态表中删除。如果在超时时间段内又有其它的包发送,那么超时时间会再被设置成50秒...这可以阻止别人通过发送假的RST或者FIN包来进行拒绝服务攻击。在关闭TCP连接会话时,在应答了第二个FIN包后进入的TIME_WAIT状态与这种超时有点类似。UDP====================维护UDP状态更简单,因为它们是无连接的。当过滤规则允许一个UDP包通过防火墙时,这个连接就被增加到连接表中。在超时时间段(缺省是40秒)内,只要源/目的地址和端口匹配的UDP包都允许通过。例如,下面是一个DNS请求:Src_IPSrc_PrtDst_IPDst_PrtIP_protKbufTypeFlagsTimeout192.168.1.101111136.1.1.205317016386ff01ff0034/40192.168.1.101111136.1.1.20017016386ff01ff0034/40你能看到,系统192.168.1.10正在向136.1.1.20做DSN查询。40秒内,那个系统可以返回任意多的UDP包(只要源/目的地址和端口匹配).注意这里有两个表项,区别是目的端口不同,一个是53,另一个是0.我不知道为什么FW-1会创建那个目的端口为0的表项。如果不是过滤所有的UDP数据传输,这种情况很常见。ICMP=======================FW-1对ICMP的处理很令人失望。缺省情况下,FW-1不对ICMP进行状态检查。它永远不会被放到状态连接表中。因此,用户被迫盲目地允许特定的ICMP传输(例如入站ECHO_REPLIES)或者不得不自己修改检查代码().我认为这是FW-1最大的不足。报文分组========================最近我一直在看报文分组,特别是FW-1如何处理分组报文