7.2.7. INPUT链
我写的INPUT链大部分是使用其他链来完成这个艰难的工作的。这样做,我们就无需从iptables 装载太多的规则(译者注:这是针对装载INPUT链的规则说的,因为这时其他规则已装载好了),而且他在较慢的机子上也能够工作得很好,但另一方面,这样的机子在高负载时还是会丢弃很多包(译者注:机子慢,就是不行)。之所以能做到这一点,是因为对于大量不同的包,我们通过检查特定的细节来确定他们的类别,再把这些包发送到相应的自定义链去处理。这样,我们能够分割规则集使之包含很少的规则,每个包要经历的规则也就少了。从而,在过滤包时,防火墙的开销也就小多了。
首先,我们要检查进入的tcp包的形态是否是不正常的或我们不想要的。这个工作是这样完成的,我们把任何的tcp包送到bad_tcp_packets链,由其中的规则进行检查,具体的描述在小节bad_tcp_packets链里。
然后,我们开始处理被信任的网络的数据传输。这包括任何来自“连接内网的网卡”的流量,任何来自和发往loopback的流量(要注意,和loopback相对应的IP地址包括了任何分配给防火墙的地址,其中也包括连接Internet的地址)。我们把处理LAN的流量的规则放在防火墙的上部,因为我们的局域网产生的流量要远远多于Internet连接。这样,规则会更有效率,防火墙就能以较小的开销去匹配包,从而网络阻塞的可能性也就减小了,而且也便于我们查看经过防火墙的包主要是什么类型。
下面的一些规则会处理来自Internet的信息,在接触这些规则之前,有一个相关的规则,我们可用他来减少一些开销。这是个处理状态的规则,他允许任何处于状态ESTABLISHED或RELATED且发往 Internet接口的包进入。在allowed链中有一个和此类似的规则(译者注:实在是多余,建议大家把他拿掉吧)。顺序上,当然是INPUT链里的规则先处理包了。然而,在allowed链里保留--state ESTABLISHED,RELATED规则还是有一些原因的,比如,方便某些人想剪切此功能,粘贴到其他地方。
在INPUT链里,我们会把从$INET_IFACE进入的任何TCP包发往tcp_packets链,类似地,把UDP包发往udp_packets链,把 ICMP包发往icmp_packets链。一般说来,防火墙碰到的最多的包是TCP包,其次是 UDP包,最后是ICMP包。但要注意,这只是一般情况,对您可能不适用。相同的规则因为顺序不同,或说逻辑不同,效率会有很大的差别。假如规则集写得不好,即使只有100条规则,而且有100mbit的网卡,就算是Pentium III的机子也会吃不消的。所以您自己写规则集时一定要注意这一点。
这里有一条被注释掉了规则,万一在我们的防火墙外部有一些Microsoft网络,我们能够启用他来解除日志过多的烦恼。Microsoft的客户机有个坏习惯,就是向地址224.0.0.0/8发送大量的多播包。因此我们要有这条规则来阻塞那些包,以免我们的日志被他们填满。还记得吗?udp_packets链里也有两条类似的规则。忘了的话,就到处理UDP的链看看吧。
在其他的包被INPUT链的策略处理之前,我们会把他们记录下来,以便查找可能的问题或bug:他可能就是我们不想允许他进入的那种包,也可能是对我们做了什么坏事的用户,还可能是防火墙的问题,如我们阻塞了应该被放行的包。我们要了解任何的情况,这样问题才能得以解决。我们每分钟最多记录3个包,因为我们可不想让日志里记载的都是废话。为了容易辨别包的来源,我们还对任何的记录配置了前缀。
任何没被上面的规则处理的包都会被策略DROP掉。策略的配置在本章的小节缺省策略的配置里,距离我们已很远喽。
7.2.8. FORWARD链
在本例中,FORWARD链包含的规则很少。首先,我们会把任何的包发往bad_tcp_packets 链。此链我们前面提到过多次,他能够被多条链调用,其实他也就是为这个目的而设计的。
之后就是FORWARD链的主要规则了。第一个允许任何来自$LAN_IFACE的数据通过,没有任何限制,也就是说,我们的LAN可自由地访问Internet。第二个允许ESTABLISHED和RELATED状态的包能通过防火墙。换句话说,就是任何对我们的内网发出的连接的回应都能够返回局域网。为了使我们的内网能访问Internet,这些规则是必须的,因为我们在前面已把FORWARD链的策略设为DROP了。这样配置规则也是很聪明的,因为他在确保局域网能够访问Internet的同时阻止了Internet对局域网的访问。
最后我们也有一个处理日志的规则,用来记录没被上面任何规则匹配的包。这样的包很可能是形态不正常的或是其他问题,比如可能是黑客攻击。这个规则和INPUT链中的那个类似,只是前缀不同,这里用的是:"IPT FORWARD packet died: "。前缀主要用来分离日志的记录,便于我们查找包的来源和包头的一些信息。
7.2.9. OUTPUT链
除了我几乎没有人把防火墙还当作工作站来使用,但正因为这样,我允许几乎任何从防火墙的IP(包括 LOCALHOST_IP,$LAN_IP或$STATIC_IP )出发的数据,而阻塞其他情况。因为其他任何情况都可能被人以某种方式欺骗。最后的规则还是用来记录那些要被策略DROP掉的包。这样,我们就能够了解他们,继而能够对产生的问题(可能是具备威胁性的错误,或是用来进行欺骗的包)采取行动。
7.2.10. PREROUTING链
顾名思义,PREROUTING链(nat表的)是在路由之前做网络地址转换工作的。然后,包再经过路由,就会被送到filter表的INPUT或FORWARD链。我们在这里讨论这个链的唯一原因是,我们觉得有责任再次指出您不应该在此链中做任何过滤。PREROUTING链只会匹配流的第一个包,也就是说,这个流的任何其他的包都不会被此链检查。事实上,在这个脚本中,我们根本没有用到PREROUTING 链。假如您想对一些包做DNAT操作,例如,您把web server放在了局域网内,这里就是您放置规则的地方。有关PREROUTING链的周详信息在章节表和链中。
 | 千万注意,PREROUTING链只能做网络地址转换,不能被用来做任何过滤,因为每个流只有第一个包才会经过此链。 |
7.2.11. POSTROUTING链
我们最后的任务应该是构造网络地址转换,对吧?至少对我来说是的。我们在nat表的 POSTROUTING里只加入了一条规则,他会对任何从Internet接口(对我来说,这是eth0)发出的包进行NAT操作。在任何的例子脚本里,都有一些变量,他们要给以正确的配置。选项-t指定要在那个表里插入规则,这里是nat表。命令-A说明我们要把规则添加到 POSTROUTING链末尾。-o $INET_IFACE指定要匹配任何从接口INET_IFACE出去的包,这里我们使用的是eth0。最后,我们把target配置为SNAT。这样,任何匹配此规则的包都会由SNAT target处理,之后,他们的源地址就是Internet接口的地址了。不要忘了SNAT可是一定要有IP地址的,用--to-source 来配置哦。
在这个脚本中,我们选择SNAT而不用MASQUERADE是有原因的。主要的原因是我们的防火墙有静态IP地址,使用SNAT会更快更有效。更有一个原因是我们要在这个例子中展示他的作用连同怎样使用他。假如您没有静态的IP地址,要想实现SNAT,还是使用MASQUERADE为好,因为他简单易用,而且他能够自动获得IP地址。当然,电脑的消耗会多一点,但假如您使用DHCP,这样做是很值得的。假如您想了解MASQUERADE target的表现,应该看看脚本rc.DHCP.firewall.txt。
Chapter 8. 例子简介
本章的目的是对指南提到的每个脚本都给以简单明了的说明,连同提供一个关于这些脚本的框架,描述他们提供的服务。这些脚本不是任何情况都能用的,他们可能并不符合您的意图。也就是说,为了能满足您的需要,还是要取决于您自己。在这方面,下面的内容可能会给您很大的帮助。第一小节介绍了这些脚本的结构,您会发现我们在这些脚本里使用的处理方式还是比较容易的。
8.1. rc.firewall.txt脚本的结构
本指南任何的脚本都是依据一个特定的结构来写的。理由嘛,就是这样能够使他们彼此相似,便于我们查找不同之处。本章将要对这个结构做一个很好的说明,而且还会简单地阐述这些脚本为什么会按照现在这种样子来写,连同我为什么选择一直使用这种结构。
 | 注意,即使我选择了这种结构,您也不一定非要用他,对您来说,他可能并不是最好的。我选择他只是因为他易读,而且能很好地符合我的逻辑。 |
8.1.1. 脚本结构
这就是本指南任何脚本遵循的脚本结构。假如有不同于此的地方,可能就是我出错了,除非我特意说明为什么要打破这种结构。
Configuration ?? 首先是个配置选项区,里面的变量在脚本中会用到。几乎任何脚本(shell-script)的第一部分都是配置选项区。
Internet ?? 有关Internet连接的配置。假如我们没有任何Internet连接,这一部分就能够跳过去。注意,相比我们列出来的,这一部分可能会包含更多小节,虽然我们这里只有了了几个,但足够应对我们已有的各种Internet连接了。
DHCP ?? 假如脚本用到了DHCP,我们就要在此添加相应的配置。
PPPoE ?? 假如想把脚本用于PPPoE连接,就要在此添加相应的配置。
LAN ?? 假如防火墙后有局域网,就要使用这里的配置了。大部分情况下都会用到这儿,因为局域网几乎总是存在的。
DMZ ?? 对非军事区(DMZ zone)的配置。大部分脚本不会用到这个配置,因为这些脚本针对的主要是一些普通的家庭网络,或小企业的网络。
Localhost ?? 本地(local-host)的有关配置。虽然我把他们写成变量的形式,但一般不会被改变,也不应该有什么理由要改变他们。
iptables ?? 有关iptables的配置。大部分情况下,这里只配置一个变量,用来指向iptables程式的位置。
Other ?? 假如更有什么信息,首先应该把他们放在相应的小节里,实在没有相应的小节,就放这儿吧。
Module loading ?? 脚本应该维护一个模块列表。他分为两部分,第一部分包含必需的模块,同时第二部分要包含不必要的模块的列表。
 | 注意,这些模块可能会提高安全性,或为管理者、客户添加某些服务,更有一些模块不是必需的,但他们可能也被加入了列表。但是,在本例中,我已注意了这个问题。 |
Required modules ?? 这里装载的是必要的模块,他们可能会提高安全性或为管理者、客户增加某些服务。
Non-required modules ?? 这里列出的是不必要的模块,所以他们都被注释掉了。假如您用到了他们提供的功能,就能够启用他们。
proc configuration ?? 这儿关心的是有关proc系统的配置。假如一些选项是必须的,我们就启用他,假如不是,就把他注释掉。大部分有用的proc配置都列在这儿了,但远远不是全部的。
Required proc configuration ?? 包含了使脚本能正常工作的任何必需的proc配置,他也能够包含一些能提高安全性或为管理者、客户增加特定服务的选项。
Non-required proc configuration ?? 这里提到的选项不是必需的,虽然他们可能很有用。因此,我把他们都注释掉了。当然,这里并没有包括任何这样的选项。
rules set up ?? 现在,应该添加规则了。我把任何的规则都明确地分配到了和表、链相应的小节里。任何自定义的规则都写在系统内建的链之前(译者注:当然要写在前面了,因为后面要调用他们哦)。另外,我是按照命令iptables -L输出的顺序来安排此脚本里表和链的出现顺序的(译者注:这样,便于我们查看哦)。
Filter table ?? 首先是filter表,而且我们先要配置策略。
Set policies ?? 为任何系统内建的链配置策略。通常,我会配置 DROP,对于允许使用的服务或流会在后面明确地给以ACCEPT。这样,我们就能够方便地排除任何我们不想让人们使用的端口。
Create user specified chains ?? 在这里创建任何以后会用到的自定义链。假如没有事先建立好,后面是不能使用他们的,所以我们要尽早地建立这些链。
Create content in user specified chains ?? 建立自定义链里使用的规则。其实您也能够在后面的某个地方写这些规则,之所以写在这儿,唯一的原因是这样做规则和链会离得近些,便于我们查看。
INPUT chain ?? 创建INPUT链的规则。
 | 从这里开始,我就是遵循iptables -L的输出格式来创建规则的,这样做的唯一原因就是为了便于阅读,避免混淆。 |
FORWARD chain ?? 为FORWARD链创建规则。
OUTPUT chain ?? 为OUTPUT链创建规则。其实,在这里要建的规则很少。
nat table ?? 在处理完filter表之后,该配置nat表了。我们这样做是有一定原因的。首先,我们不想太早地打开转发机制(译者注:注意,filter表设定的是过滤机制,而不是转发)和NAT功能,因为他们可能导致数据会在错误的时间(也就是这样的时刻:我们打开了NAT,但过滤规则还没有运行)通过防火墙。更有,我把nat表看作是围绕filter表的一个层。也就是说,filter表是核心, nat表是他外部的一个层,mangle表是第二层。从某些观点来看,这可能有点不对,但也八九不离十了。
Set policies ?? 和filter相同,我们先来配置策略。一般说来,缺省的策略,即ACCEPT,就很好。这个表不应该被用来做任何过滤,而且我们也不应该在这儿丢弃任何包,因为对我们假设的网络情况来说,可能会发生一些难以应付的事情。我把策略设为ACCEPT,因为没有什么原因不这样做。
Create user specified chains ?? 在这儿创建nat表会用到的自定义链。一般情况下,我没有任何规则要在这儿建立,但我还是保留了这个小节,以防万一罢了。注意,在被系统内建链调用之前一定要建好相应的自定义链。
Create content in user specified chains ?? 建立自定义链的规则。
PREROUTING chain ?? 要对包做DNAT操作的话,就要用到此链了。大部分脚本不会用到这条链,或是把里面的规则注释掉了,因为我们不想在不了解他的情况下就在防火墙上撕开一个大口子,这会对我们的局域网造成威胁。当然,也有一些脚本默认使用了这条链,因为那些脚本的目的就是提供这样的服务。
POSTROUTING chain ?? 假如使用SNAT操作,就要在此建立规则。您可能有一个或多个局域网需要防火墙的保护,而我就是依据这样的情况来写此脚本的,所以这个脚本中使用的 POSTROUTING链是相当实用的。大部分情况下,我们会使用SNAT target,但有些情况,如PPPoE,我们不得不使用MASQUERADE target。
OUTPUT chain ?? 不管什么脚本都几乎不会用到这个链。迄今为止,我还没有任何好的理由使用他,假如您有什么理由用他了的话,麻烦您把相应的规则也给我一份,我会把他加到本指南里的。
mangle table ?? 最后要做的就是处理mangle表了。通常,我不会使用这个表,因为一般情况下,他不会被任何人要到,除非他们有什么特别的需要,比如为了隐藏一条连接后的多台机子,我们要统一配置TTL或TOS等。在这个脚本里,此表是空白的。但在此指南中还是有个小小的例子说明了mangle表的用处。
Set policies ?? 配置策略。这里的情形和nat表几乎完全相同。这里不应该做过滤,也不应该丢弃任何包。在任何脚本里我都不会把mangle表的策略设为其他的值,也不鼓励您这样做。
Create user specified chains ?? 建立自定义链。我几乎不会用到这个链,所以没有建立任何规则。保留此小节,只是已备后用。
Create content in user specified chains ?? 建立自定义链的规则。
PREROUTING ?? 本指南的任何脚本都未在此链建立规则。
INPUT chain ?? 本指南的任何脚本都未在此链建立规则。
FORWARD chain ?? 本指南的任何脚本都未在此链建立规则。
OUTPUT chain ?? 本指南的任何脚本都未在此链建立规则。
POSTROUTING chain ?? 本指南的任何脚本都未在此链建立规则。
这应该能够较周详地解释每个脚本的结构是怎样的连同他们为什么要使用这个结构了。
 | 注意,上面的描述其实还是很简单的,应该被看作一个摘要,他简要地解释了脚本为什么要按照这种松散的结构来写。千万注意,我可没有说过这种结构是唯一的、最好的。 |