Chinaunix首页 | 论坛 | 博客
  • 博客访问: 502863
  • 博文数量: 119
  • 博客积分: 5054
  • 博客等级: 大校
  • 技术积分: 1305
  • 用 户 组: 普通用户
  • 注册时间: 2010-01-03 13:13
文章分类

全部博文(119)

文章存档

2011年(4)

2010年(115)

我的朋友

分类: 网络与安全

2010-01-06 16:04:16

声明:版权属原作者和译者所有,转载请注明出处

摘自 Chapter 6

本章将详细地讨论如何构件你自己的规则。规则就是指向标,在一条链上,对不同的连接和数据包阻塞或允许它们去向何处。插入链的每一行都是一条规则。我们也会讨论基本的matche及其用法,还有各种各样的target,以及如何建立我们自己的target(比如,一个新的子链)。

基础

我们已经解释了什么是规则,在内核看来,规则就是决定如何处理一个包的语句。如果一个包符合所有的条件(就是符合matche语句),我们就运行target或jump指令。书写规则的语法格式是:

iptables [-t table] command [match] [target/jump]

对于这个句法没什么可说的,但注意target指令必须在最后。为了易读,我们一般用这种语法。总之,你将见到的大部分规则都是按这种语法写的。因此,如果你看到别人写的规则,你很可能会发现用的也是这种语法,当然就很容易理解那些规则了。

如果你不想用标准的表,就要在[table]处指定表名。一般情况下没有必要指定使用的表,因为iptables 默认使用filter表来执行所有的命令。也没有必要非得在这里指定表名,实际上几乎可在规则的任何地方。当然,把表名在开始处已经是约定俗成的标准。

尽管命令总是放在开头,或者是直接放在表名后面,我们也要考虑考虑到底放在哪儿易读。command告诉程序该做什么,比如:插入一个规则,还是在链的末尾增加一个规则,还是删除一个规则,下面会仔细地介绍。

match细致地描述了包的某个特点,以使这个包区别于其它所有的包。在这里,我们可以指定包的来源IP 地址,网络接口,端口,协议类型,或者其他什么。下面我们将会看到许多不同的match。
最后是数据包的目标所在。若数据包符合所有的match,内核就用target来处理它,或者说把包发往 target。比如,我们可以让内核把包发送到当前表中的其他链(可能是我们自己建立的),或者只是丢弃这个包而没有什么处理,或者向发送者返回某个特殊的应答。下面有详细的讨论。

Tables

选项-t用来指定使用哪个表,它可以是下面介绍的表中的任何一个,默认的是 filter表。注意,下面的介绍只是章节表和链的摘要。

Table 6-1. Tables

上面介绍了三个不同的表的最基本的内容。你应该知道它们的使用目的完全不同,还要清楚每一条链的使用。如果你不了解,就可能会在防火墙上留下漏洞,给人以可乘之机。在章节表和链 中,我们已详细地讨论了这些必备的的表和链。如果你没有完全理解包是怎样通过这些表、链的话,我建议你回过头去再仔细看看。

Commands

在这一节里,我们将要介绍所有的command以及它们的用途。command指定iptables 对我们提交的规则要做什么样的操作。这些操作可能是在某个表里增加或删除一些东西,或做点儿其他什么。以下是iptables可用的command(要注意,如不做说明,默认表的是 filter表。):

Table 6-2. Commands

在使用iptables时,如果必须的参数没有输入就按了回车,那么它就会给出一些提示信息:告诉你需要哪些参数等等。iptables的选项-v用来显示iptables的版本,-h给出语法的简短说明。。下面将要介绍的就是部分选项,还有它们的作用。

Table 6-3. Options

Matches

这一节,我们会详细讨论一些matche,我把它们归为五类。第一类是generic matches(通用的匹配),适用于所有的规则;第二类是TCP matches,顾名思义,这只能用于TCP包;第三类是UDP matches,当然它只能用在UDP包上了;第四类是ICMP matches ,针对ICMP包的;第五类比较特殊,针对的是状态(state),所有者(owner)和访问的频率限制(limit)等,它们已经被分到更多的小类当中,尽管它们并不是完全不同的。我希望这是一种大家都容易理解的分类。

通用匹配

无论我们使用的是何种协议,也不管我们又装入了匹配的何种扩展,通用匹配都使可用的。也就是说,它们可以直接使用,而不需要什么前提条件,在后面你会看到,有很多匹配操作是需要其他的匹配作为前提的。

Table 6-4. Generic matches

隐含匹配

这种匹配操作是自动地或隐含地装载入内核的。例如我们使用–protocol tcp 时,不需再装入任何东西就可以匹配只有IP包才有的一些特点。现在有三种隐含的匹配针对三种不同的协议,即TCP matches,UDP matches和 ICMP matches。它们分别包括一套只适用于相应协议的判别标准。相对于隐含匹配的是显式匹配,它们必须使用-m或–match被明确地装载,而不能是自动地或隐含地,下一节会介绍到。

TCP matches

TCP matches只能匹配TCP包或流的细节,它们必须有–protocol tcp作为前提条件。

Table 6-5. TCP matches

UDP matches

UDP matches是在指定–protocol UDP时自动装入的。UDP是一种无连接协议,所以在它打开、关闭连接以及在发送数据时没有多少标记要设置,它也不需要任何类型的确认。数据丢失了,就丢失了(不会发送ICMP错误信息的)。这就说明UDP matches要比TCP matches少多了。即使UDP和ICMP是无连接协议,状态机制也可以很好的工作,就象在TCP上一样,这在前面讨论过。

Table 6-6. UDP matches

ICMP matches

ICMP协议也是无连接协议,ICMP包更是短命鬼,比UDP的还短。ICMP协议不是IP协议的下属协议,而是它的辅助者,其主要作用是报告错误和连接控制。ICMP包的头和IP的很相似,但又有很多不同。这个协议最主要的特点是它有很多类型,以应对不同的情况。比如,我们想访问一个无法访问的地址,就会收到一个ICMP host unreachable信息,它的意思是主机无法到达。在附录ICMP类型里有完整的ICMP类型列表。虽然有这么多类型,但只有一个 ICMP matche,这就足够对付它们了。这个matche是在指定–protocol ICMP时自动装入的。注意所有的通用匹配都可以使用,这样我们就可以匹配ICMP包的源、目地址。

Table 6-7. ICMP matches

显式匹配

显式匹配必须用-m或–match装载,比如要使用状态匹配就必须使用-m state。有些匹配还需要指定协议,有些就不需要,比如连接状态就不要。这些状态是NEW(还未建立好的连接的第一个包), ESTABLISHED(已建立的连接,也就是已经在内核里注册过的),RELATED(由已经存在的、处于已建立状态的连接生成的新连接),等等。有些匹配还处在开发阶段,或者还只是为了说明iptables的强大能力。这说明不是所有的匹配一开始就是实用的,但以后你可能会用到它。随着iptables 新版本的发布,会有一些新的匹配可用。隐含匹配和显式匹配最大的区别就是一个是跟随协议匹配自动装载的,一个是显式装载的。

Limit match

这个匹配操作必须由-m limit明确指定才能使用。有了它的帮助,就可以对指定的规则的日志数量加以限制,以免你被信息的洪流淹没哦。比如,你可以事先设定一个限定值,当符合条件的包的数量不超过它时,就记录;超过了,就不记录了。我们可以控制某条规则在一段时间内的匹配次数(也就是可以匹配的包的数量),这样就能够减少DoS syn flood攻击的影响。这是它的主要作用,当然,还有很多其他作用(译者注:比如,对于某些不常用的服务可以限制连接数量,以免影响其他服务)。limit match也可以用英文感叹号取反,如:-m limit ! –limit 5/s表示在数量超过限定值后,所有的包都会被匹配。

(译者注:为了更好地理解这个匹配操作,我们通过一个比喻来解释一下。原文也做了类似地比喻,但我觉得对于初学者不易理解,故未采用。)limit match的工作方式就像一个单位大门口的保安,当有人要进入时,需要找他办理通行证。早上上班时,保安手里有一定数量的通行证,来一个人,就签发一个,当通行证用完后,再来人就进不去了,但他们不会等,而是到别的地方去(在iptables里,这相当于一个包不符合某条规则,就会由后面的规则来处理,如果都不符合,就由缺省的策略处理)。但有个规定,每隔一段时间保安就要签发一个新的通行证。这样,后面来的人如果恰巧赶上,也就可以进去了。如果没有人来,那通行证就保留下来,以备来的人用。如果一直没人来,可用的通行证的数量就增加了,但不是无限增大的,最多也就是刚开始时保安手里有的那个数量。也就是说,刚开始时,通行证的数量是有限的,但每隔一段时间就有新的通行证可用。limit match有两个参数就对应这种情况,–limit-burst指定刚开始时有多少通行证可用,–limit指定要隔多长时间才能签发一个新的通行证。要注意的是,我这里强调的是“签发一个新的通行证”,这是以iptables的角度考虑的。在你自己写规则时,就要从这个角度考虑。比如,你指定了–limit 3/minute –limit-burst 5 ,意思是开始时有5个通行证,用完之后每20秒增加一个(这就是从iptables的角度看的,要是以用户的角度看,说法就是每一分钟增加三个或者每分钟只能过三个)。你要是想每20分钟过一个,只能写成–limit 3/hour –limit-burst 5,也就是说你要把时间单位凑成整的。

Table 6-8. Limit match options

MAC match

基于包的MAC源地址匹配包。到写这篇文章时,这个match还有一点限制(就是只能匹配MAC源地址匹),但今后定会有所发展,会更有用的。
注意,这个match是由-m mac装入的,而不是一些人想当然的-m mac-source,后者只是前者的选项而已。
Table 6-9. MAC match options

Mark match

以包被设置的mark来匹配包,这个值只能由内核更改。前面曾经提到过,mark比较特殊,它不是包本身的一部分,而是在包穿越计算机的过程中由内核分配的和它相关联的一个字段。它可能被用来改变包的传输路径或过滤。时至今日,在linux里只有一种方法能设置mark,即iptables的MARK target,以前在ipchains里是FWMARK target。这就是为什么在高级路由里我们仍要参照FWMARK的原因。mark字段的值是一个无符号的整数,在32位系统上最大可以是4294967296(就是2的32次方),这足够用的了:)

Table 6-10. Mark match options

Multiport match

多端口匹配扩展使我们能够在一条规则里指定不连续的多个端口,如果没有这个扩展,我们只能按端口来写规则了。其实这只是标准端口匹配的增强版罢了,使我们书写规则更方便而已。
注意:不能在一条规则里同时使用标准端口匹配和多端口匹配,如–sport 1024:63353 -m multiport –dport 21,23,80。这条规则并不能想你想象的那样工作,但也不是不能工作,iptables会使用第一个合法的条件,那么这里多端口匹配就白写了:) 
Table 6-11. Multiport match options

Owner match

基于包的生成者(也就是所有者,或称作拥有者,owner)的ID来匹配包,owner可以是启动进程的用户的ID,或用户所在的组的ID,或进程的ID,或会话的ID。这个扩展原本只是为了说明iptables可以做什么,现在发展到实用阶段了。但要注意,此扩展只能用在OUTPUT中,原因显而易见:我们几乎不可能得到发送端例程的ID的任何信息,或者在去往真正目的地的路上哪儿有路由。甚至在 OUTPUT链里,这也不是十分可靠,因为有些包根本没有owner,比如 ICMP responses,所以它们从不会被这个match抓到:)

Table 6-12. Owner match options

State match

状态匹配扩展要有内核里的连接跟踪代码的协助,因为它是从连接跟踪机制中得到包的状态的。这样我们就可以了解连接所处的状态。它几乎适用于所有的协议,包括那些无状态的协议,如ICMP和UDP。针对每个连接都有一个缺省的超时值,如果连接的时间超过了这个值,那么这个连接的记录就被会从连接跟踪的记录数据库中删除,也就是说连接就不再存在了。这个match必须有-m state作为前提才能使用。状态机制的详细内容在章节状态机制 中。
Table 6-13. State matches

TOS match

根据TOS字段匹配包,必须使用-m tos才能装入。TOS是IP头的一部分,其含义是Type Of Service,由8个二进制位组成,包括一个3 bit的优先权子字段(现在已被忽略),4 bit的TOS子字段和1 bit未用位(必须置0)。它一般用来把当前流的优先权和需要的服务(比如,最小延时、最大吞吐量等)通知路由器。但路由器和管理员对这个值的处理相差很大,有的根本就不理会,而有的就会尽量满足要求。

Table 6-14. TOS matches

TTL match

根据IP头里的TTL (Time To Live,即生存期)字段来匹配包,此必须由-m ttl装入。TTL field是一个字节(8个二进制位),一旦经过一个处理它的路由器,它的值就减去1它的值。当该字段的值减为0时,报文就被认为是不可转发的,数据报就被丢弃,并发送ICMP报文通知源主机,不可转发的报文被丢弃。这也有两种情况,一是传输期间生存时间为0,使用类型为11代码是0的ICMP报文;二是在数据报重组期间生存时间为0,使用类型为11代码是1的ICMP报文。这个match只是根据TTL匹配包,而对其不做任何更改,所以在它之后可使用任何类型的match。

Table 6-15. TTL matches

针对非正常包的匹配

这个匹配没有任何参数,也不需要显式地装载。注意这应该被看作是一个实验性的匹配,它不总是能正常工作的,对有些不正常的包(unclean package,就是所谓的脏包)或问题,它是视而不见的。这个match 试图匹配那些好象畸形或不正常的包,比如包头错或校验和错,等等。它可能常用来DROP错误的连接、检查有错的流,但要知道这样做也可能会中断合法的连接。

Targets/Jumps

target/jump决定符合条件的包到何处去,语法是–jump target或-j target。(译者注:本文中,原作者把target细分为两类,即Target和Jump。它们唯一的区别是jump的目标是一个在同一个表内的链,而target的目标是具体的操作。)我们会先接触到两个基本的target,就是ACCEPT和DROP。

前面提到过用户自定义链要用到-N命令。下面我们在filter表中建一个名为tcp_packets的链:

iptables -N tcp_packets

然后再把它作为jump的目标:

iptables -A INPUT -p tcp -j tcp_packets

这样我们就会从INPUT链跳入tcp_packets链,开始在tcp_packets中的旅行。如果到达了tcp_packets链的结尾(也就是未被链中的任何规则匹配),则会退到INPUT链的下一条规则继续它的旅行。如果在子链中被ACCEPT了,也就相当于在父链中被ACCEPT了,那么它不会再经过父链中的其他规则。但要注意这个包能被其他表的链匹配,过程可查看章节 表和链。

target指定我们要对包做的操作,比如DROP和ACCEPT,还有很多,我们后面会介绍。不同的target有不同的结果。一些target会使包停止前景,也就是不再继续比较当前链中的其他规则或父链中的其他规则,最好的例子就是DROP和ACCEPT。而另外一些target在对包做完操作之后,包还会继续和其他的规则比较,如LOG,ULOG和TOS。它们会对包进行记录、mangle,然后让包通过,以便匹配这条链中的其他规则。有了这样的target,我们就可以对同一个包既改变它的TTL又改变它的TOS。有些target必须要有准确的参数(如TOS需要确定的数值),有些就不是必须的,但如果我们想指定也可以(如日志的前缀,伪装使用的端口,等等)。本节我们会尽可能全面地介绍每一个target。现在我们就来看看有哪几种target。

ACCEPT target

这个target没有任何选项和参数,使用也很简单,指定-j ACCEPT即可。一旦包满足了指定的匹配条件,就会被ACCEPT,并且不会再去匹配当前链中的其他规则或同一个表内的其他规则,但它还要通过其他表中的链,而且在那儿可能会百DROP也说不准哦。

DNAT target

这个target是用来做目的网络地址转换的,就是重写包的目的IP地址。如果一个包被匹配了,那么和它属于同一个流的所有的包都会被自动转换,然后就可以被路由到正确的主机或网络。DNAT target是非常有用的。比如,你的Web服务器在LAN内部,而且没有可在Internet上使用的真实IP地址,那就可以使用这个 target让防火墙把所有到它自己HTTP端口的包转发给LAN内部真正的Web服务器。目的地址也可以是一个范围,这样的话,DNAT会为每一个流随机分配一个地址。因此,我们可以用这个target做某种类型地负载平衡。

注意,DANT target只能用在nat表的PREROUTING和OUTPUT链中,或者是被这两条链调用的链里。但还要注意的是,包含DANT target的链不能被除此之外的其他链调用,如POSTROUTING。

Table 6-16. DNAT target

因为DNAT要做很多工作,所以我要再罗嗦一点。我们通过一个例子来大致理解一下它是如何工作的。比如,我想通过Internet连接发布我们的网站,但是HTTP server在我们的内网里,而且我们对外只有一个合法的IP,就是防火墙那个对外的IP——$INET_IP。防火墙还有一个内网的IP——$LAN_IP,HTTP server的IP是$HTTP_IP (这当然是内网的了)。为了完成我们的设想,要做的第一件事就是把下面的这个简单的规则加入到nat表的PREROUTING链中:

iptables -t nat -A PREROUTING --dst $INET_IP -p tcp --dport 80 -j DNAT  --to-destination $HTTP_IP

现在,所有从Internet来的、到防火墙的80端口去的包都会被转发(或称做被DNAT )到在内网的HTTP服务器上。如果你在Internet上试验一下,一切正常吧。再从内网里试验一下,完全不能用吧。这其实是路由的问题。下面我们来好好分析这个问题。为了容易阅读,我们把在外网上访问我们服务器的那台机子的IP地址记为$EXT_BOX。

1、包从地址为$EXT_BOX的机子出发,去往地址为$INET_IP 的机子。
2、包到达防火墙。
3、防火墙DNAT(也就是转发)这个包,而且包会经过很多其他的链检验及处理。
4、包离开防火墙向$HTTP_IP前进。
5、包到达HTTP服务器,服务器就会通过防火墙给以回应,当然,这要求把防火墙作为HTTP到达$EXT_BOX的网关。一般情况下,防火墙就是HTTP服务器的缺省网关。
6、防火墙再对返回包做Un-DNAT(就是照着DNAT的步骤反过来做一遍),这样就好像是防火墙自己回复了那个来自外网的请求包。
7、返回包好象没经过这么复杂的处理、没事一样回到$EXT_BOX。

现在,我们来考虑和HTTP服务器在同一个内网(这里是指所有机子不需要经过路由器而可以直接互相访问的网络,不是那种把服务器和客户机又分在不同子网的情况)的客户访问它时会发生什么。我们假设客户机的IP为$LAN_BOX,其他设置同上。

1、包离开$LAN_BOX,去往$INET_IP。
2、包到达防火墙。
3、包被DNAT,而且还会经过其他的处理。但是包没有经过SNAT 的处理,所以包还是使用它自己的源地址,就是$LAN_BOX(译者注:这就是IP 传输包的特点,只根据目的地的不同改变目的地址,但不因传输过程中要经过很多路由器而随着路由器改变其源地址,除非你单独进行源地址的改变。其实这一步的处理和对外来包的处理是一样的,只不过内网包的问题就在于此,所以这里交待一下原因)。
4、包离开防火墙,到达HTTP服务器。
5、HTTP服务器试图回复这个包。它在路由数据库中看到包是来自同一个网络的一台机子,因此它会把回复包直接发送到请求包的源地址(现在是回复包的目的地址),也就是$LAN_BOX。
6、回复包到达客户机,但它会很困惑,因为这个包不是来自它访问的那台机子。这样,它就会把这个包扔掉而去等待“真正”的回复包。

针对这个问题有个简单的解决办法,因为这些包都要进入防火墙,而且它们都去往需要做DNAT才能到达的那个地址,所以我们只要对这些包做SNAT操作即可。比如,我们来考虑上面的例子,如果对那些进入防火墙而且是去往地址为$HTTP_IP、端口为80的包做SNAT操作,那么这些包就好象是从$LAN_IP来的了,也就是说,这些包的源地址被改为$LAN_IP了。这样,HTTP服务器就会把回复包发给防火墙,而防火墙会再对包做 Un-DNAT操作,并把包发送到客户机。解决问题的规则如下:

iptables -t nat -A POSTROUTING -p tcp --dst $HTTP_IP --dport 80 -j SNAT  --to-source $LAN_IP

要记住,按运行的顺序POSTROUTING链是所有链中最后一个,因此包到达这条链时,已经被做过DNAT操作了,所以我们在规则里要基于内网的地址$HTTP_IP(包的目的地)来匹配包。

警告:我们刚才写的这条规则会对日志产生很大影响,这种影响应该说是很不好的。因为来自 Internet包在防火墙内先后经过了DNAT和SNAT处理,才能到达HTTP服务器(上面的例子),所以HTTP服务器就认为包是防火墙发来的,而不知道真正的源头是其他的IP。这样,当它记录服务情况时,所有访问记录的源地址都是防火墙的IP而不是真正的访问源。我们如果想根据这些记录来了解访问情况就不可能了。因此上面提供的“简单办法”并不是一个明智的选择,但它确实可以解决“能够访问”的问题,只是没有考虑到日志而已。

其他的服务也有类似的问题。比如,你在LAN内建立了SMTP服务器,那你就要设置防火墙以便能转发SMTP的数据流。这样你就创建了一个开放的SMTP中继服务器,随之而来的就是日志的问题了。

一定要注意,这里所说的问题只是针对没有建立DMZ或类似结构的网络,并且内网的用户访问的是服务器的外网地址而言的。(译者注:因为如果建立了DMZ,或者服务器和客户机又被分在不同的子网里,那就不需要这么麻烦了。因为所有访问的源头都不在服务器所在的网里,所以就没必要做SNAT去改变包的源地址了,从而记录也就不是问题了。如果内网客户是直接访问服务器的内网地址那就更没事了)

较好的解决办法是为你的LAN在内网建立一台单独的DNS服务器(译者注:这样,内网的客户使用网站名访问HTTP服务器时,DNS就可以把它解析成内网地址。客户机就可以直接去访问HTTP服务器的内网地址了,从而避免了通过防火墙的操作,而且包的源地址也可以被HTTP服务器的日志使用,也就没有上面说的日志问题了。),或者干脆建立DMZ得了(这是最好的办法,但你要有钱哦,因为用的设备多啊)。

对上面的例子应该考虑再全面些,现在还有一个问题没解决,就是防火墙自己要访问HTTP服务器时会发生什么,能正常访问吗?你觉得呢:)很可惜,现在的配置还是不行,仔细想想就明白了。我们这里讨论的基础都是假设机子访问的是HTTP服务器的外网地址,但这个外网地址其实就是防火墙对外的地址,所以当防火墙访问这个外网地址时,就是访问它自己。防火墙上如果有HTTP服务,那客户机就会看到页面内容,不过这不是它想看到的(它想要的在DNAT上了),如果没有HTTP服务,客户就只能收到错误信息了。前面给出的规则之所以不起作用是因为从防火墙发出的请求包不会经过那两条链。还记得防火墙自己发出的包经过哪些链吧:)我们要在nat表的OUTPUT链中添加下面的规则:

iptables -t nat -A OUTPUT --dst $INET_IP -p tcp --dport 80 -j DNAT  --to-destination $HTTP_IP

有了最后这条规则,一切都正常了。和HTTP服务器不在同一个网的机子能正常访问服务了,和它在一个网内的机子也可以正常访问服务了,防火墙本身也能正常访问服务了,没有什么问题了。这种心情,套用《大话西游》里的一句话,就是“世界又清净了”。(不要说你不知道什么是《大话西游》)

注意:我想大家应该能明白这些规则只说明了数据包是如何恰当地被DNAT和SNAT的。除此之外,在 filter表中还需要其他的规则(在FORWARD链里),以允许特定的包也能经过前面写的(在POSTROUTING链和 OUTPUT链里的)规则。千万不要忘了,那些包在到达FORWARD链之前已经在PREROUTING链里被DNAT过了,也就是说它们的目的地址已被改写,在写规则时要注意这一点。

DROP target

顾名思义,如果包符合条件,这个target就会把它丢掉,也就是说包的生命到此结束,不会再向前走一步,效果就是包被阻塞了。在某些情况下,这个target会引起意外的结果,因为它不会向发送者返回任何信息,也不会向路由器返回信息,这就可能会使连接的另一方的sockets因苦等回音而亡:) 解决这个问题的较好的办法是使用REJECT target,(译者注:因为它在丢弃包的同时还会向发送者返回一个错误信息,这样另一方就能正常结束),尤其是在阻止端口扫描工具获得更多的信息时,可以隐蔽被过滤掉的端口等等(译者注:因为扫描工具扫描一个端口时,如果没有返回信息,一般会认为端口未打开或被防火墙等设备过滤掉了)。还要注意如果包在子链中被DROP了,那么它在主链里也不会再继续前进,不管是在当前的表还是在其他表里。总之,包死翘翘了。

LOG target

这个target是专门用来记录包地有关信息的。这些信息可能是非法的,那就可以用来除错。LOG会返回包的有关细节,如IP头的大部分和其他有趣的信息。这个功能是通过内核的日志工具完成的,一般是syslogd。返回的信息可用dmesg阅读,或者可以直接查看syslogd的日志文件,也可以用其他的什么程序来看。LOG对调试规则有很大的帮助,你可以看到包去了哪里、经过了什么规则的处理,什么样的规则处理什么样的包,等等。当你在生产服务器上调试一个不敢保证100%正常的规则集时,用LOG代替DROP是比较好的(有详细的信息可看,错误就容易定位、解决了),因为一个小小的语法错误就可能引起严重的连接问题,用户可不喜欢这样哦。如果你想使用真正地扩展日志地话,可能会对ULOG target有些兴趣,因为它可以把日志直接记录到MySQL databases或类似的数据库中。

注意,如果在控制台得到的信息不是你想要的,那不是iptables或Netfilter的问题,而是 syslogd 配置文件的事,这个文件一般都是/etc/syslog.conf。有关这个问题的更多信息请查通过man syslog.conf查看
LOG现在有5个选项,你可以用它们指定需要的信息类型或针对不同的信息设定一些值以便在记录中使用。选项如下:

Table 6-17. LOG target options

MARK target

用来设置mark值,这个值只能在本地的mangle表里使用,不能用在其他任何地方,就更不用说路由器或另一台机子了。因为mark比较特殊,它不是包本身的一部分,而是在包穿越计算机的过程中由内核分配的和它相关联的一个字段。它可以和本地的高级路由功能联用,以使不同的包能使用不同的队列要求,等等。如果你想在传输过程中也有这种功能,还是用TOS target吧。有关高级路由的更多信息,可以查看Linux Advanced Routing and Traffic Control HOW-TO。

Table 6-18. MARK target options

MASQUERADE target

这个target和SNAT target的作用是一样的,区别就是它不需要指定–to-source 。MASQUERADE是被专门设计用于那些动态获取IP地址的连接的,比如,拨号上网、DHCP连接等。如果你有固定的IP地址,还是用SNAT target吧。

伪装一个连接意味着,我们自动获取网络接口的IP地址,而不使用–to-source 。当接口停用时,MASQUERADE不会记住任何连接,这在我们kill掉接口时是有很大好处的。如果我们使用SNAT target,连接跟踪的数据是被保留下来的,而且时间要好几天哦,这可是要占用很多连接跟踪的内存的。一般情况下,这种处理方式对于拨号上网来说是较好的(这有利于已有那连接继续使用)。如果我们被分配给了一个不同于前一次的IP,不管怎样已有的连接都要丢失,但或多或少地还是有一些连接记录被保留了(真是白痴,是吧)。

即使你有静态的IP,也可以使用MASQUERADE,而不用SNAT 。不过,这不是被赞成的,因为它会带来额外的开销,而且以后还可能引起矛盾,比如它也许会影响你的脚本,使它们不能用。

注意,MASQUERADE和SNAT一样,只能用于nat表的 POSTROUTING链,而且它只有一个选项(不是必需的):

Table 6-19. MASQUERADE target

MIRROR target

这个target是实验性的,它只是一个演示而已,不建议你使用它,因为它可能引起循环,除此之外,还可能引起严重的DoS。这个target的作用是颠倒IP头中的源目地址,然后再转发包。这会引起很有趣的事,一个骇客最后攻破的可能就是他自己的机子。看来,使用这个target至少可以使我们的机子更强壮:) 我们如果对机子A的80端口使用了MIRROR,会发生什么呢?假设有来自yahoo.com的机子B 想要访问A的HTTP服务,那他得到的将是yahoo的主页,因为请求是来自yahoo的。

注意,MIRROR只能用在INPUT、 FORWARD、 PREROUTING链和被它们调用的自定义链中。还要注意,如果外出的包是因 MIRROR target发出的,则它们是不会被filter、nat或mangle表内的链处理的,这可能引起循环或其他问题。比如,一台机子向另一台配置了MIRROR且TTL值为255的机子发送一个会被认为是欺骗的数据包,同时这台机子也欺骗自己的数据包,以使它被认为好像是来自第三个使用了MIRROR 的机子。这样,那个包就会不间断地往来很多次,直到TTL为0。如果两台机子之间只有一个路由器,这个包就会往返240-255次。对骇客来说,这是不坏的情况,因为他只要发送一个1500字节的数据(也就是一个包),就可以消耗你的连接的380K字节。对于骇客或者叫做脚本小子(不管我们把他们称作什么)来说,这可是很理想的情况。

QUEUE target

这个target为用户空间的程序或应用软件管理包队列。它是和iptables之外的程序或工具协同使用的,包括网络计数工具,高级的数据包代理或过滤应用,等等。讨论程序的编码已超出了本文的范围。即使讨论,也要花很多时间,而且在这样一篇文章之内也无法说清有关Netfilter和iptables的编程。具体的信息请查看Netfilter Hacking HOW-TO。

REDIRECT target

在防火墙所在的机子内部转发包或流到另一个端口。比如,我们可以把所有去往端口HTTP的包REDIRECT到HTTP proxy(例如squid),当然这都发生在我们自己的主机内部。本地生成的包都会被映射到127.0.0.1。换句话说,这个target把要转发的包的目的地址改写为我们自己机子的IP。我们在做透明代理(LAN内的机子根本不需要知道代理的存在就可以正常上网)时,这个target可是起了很大作用的。

注意,它只能用在nat表的PREROUTING、OUTPUT链和被它们调用的自定义链里。 REDIRECT只有一个选项:

Table 6-20. REDIRECT target

REJECT target

REJECT和DROP基本一样,区别在于它除了阻塞包之外,还向发送者返回错误信息。现在,此target还只能用在INPUT、FORWARD、OUTPUT和它们的子链里,而且包含 REJECT的链也只能被它们调用,否则不能发挥作用。它只有一个选项,是用来控制返回的错误信息的种类的。虽然有很多种类,但如果你有TCP/IP方面的基础知识,就很容易理解它们。

Table 6-21. REJECT target

RETURN target

顾名思义,它使包返回上一层,顺序是:子链——>父链——>缺省的策略。具体地说,就是若包在子链中遇到了RETURN,则返回父链的下一条规则继续进行条件的比较,若是在父链(或称主链,比如INPUT)中遇到了RETURN,就要被缺省的策略(一般是ACCEPT或DROP)操作了。(译者注:这很象C语言中函数返回值的情况)

我们来举个例子说明一下,假设一个包进入了INPUT链,匹配了某条target为–jump EXAMPLE_CHAIN规则,然后进入了子链EXAMPLE_CHAIN。在子链中又匹配了某条规则,恰巧target是–jump RETURN,那包就返回INPUT链了。如果在INPUT链里又遇到了–jump RETURN,那这个包就要交由缺省的策略来处理了。

SNAT target

这个target是用来做源网络地址转换的,就是重写包的源IP地址。当我们有几个机子共享一个Internet 连接时,就能用到它了。先在内核里打开ip转发功能,然后再写一个SNAT规则,就可以把所有从本地网络出去的包的源地址改为Internet连接的地址了。如果我们不这样做而是直接转发本地网的包的话,Internet上的机子就不知道往哪儿发送应答了,因为在本地网里我们一般使用的是IANA组织专门指定的一段地址,它们是不能在Internet上使用的。SNAT target的作用就是让所有从本地网出发的包看起来都是从一台机子发出的,这台机子一般就是防火墙。

SNAT只能用在nat表的POSTROUTING链里。只要连接的第一个符合条件的包被SNAT了,那么这个连接的其他所有的包都会自动地被SNAT,而且这个规则还会应用于这个连接所在流的所有数据包。

Table 6-22. SNAT target

TOS target

TOS是用来设置IP头中的Type of Service字段的。这个字段长一个字节,可以控制包的路由情况。它也是iproute2及其子系统可以直接使用的字段之一。值得注意的是,如果你有几个独立的防火墙和路由器,而且还想在他们之间利用包的头部来传递路由信息,TOS是唯一的办法。前面说过,MARK是不能用来传递这种信息的。如果你需要为某个包或流传递路由信息,就要使用TOS字段,它也正是为这个而被开发的。

Internet上有很多路由器在这一方面并没有做好工作,因此,在发送包之前改变其TOS没有什么大用处。最好的情况是路由器根本不理它,最坏的情况是路由器会根据TOS处理,但都是错误的。然而,如果你是在一个很大的WAN或LAN里,而且有很多路由器,TOS还是能有很好的作为的。总的来说,基于TOS的值给包以不同的路由和参数还是可能的,即使在网络里是受限制的(译者注:大不了不起作用就是了)。

警告:TOS只能用来设置具体的或者说是特定的值(这些预定义的值在内核源码的include文件——Linux/ip.h中),原因是很多的,但不管怎么说,你不要使用其他的值就是了。当然,我们也有办法突破这个限制,就是使用一个名为FTOS的patch,你可在由Matthew G. Marsh维护的站点 Paksecured Linux Kernel patches得到它,但要小心使用哦。除了非常特殊、极端的情况,我们是不应该使用预定义以外的值的。

注意,这个target只能在mangle表内使用。

还要注意,在一些老版(1.2.2或更低)的iptables中包含的这个target在设置了TOS之后,不会调整包的校验和,这样包会被认为是错误的并要求重发。而且,这很可能会导致更多的mangle操作,从而使整个连接无法工作。(译者注:好在我们现在不会再用这么老的版本了:) )

TOS target只有一个选项:

Table 6-23. TOS target

TTL target

TTL可以修改IP头中Time To Live字段的值。它有很大的作用,我们可以把所有外出包的Time To Live值都改为一样的,比如64,这是Linux的默认值。有些ISP不允许我们共享连接(他们可以通过TTL的值来区分是不是有多个机子使用同一个连接),如果我们把TTL都改为一样的值,他们就不能再根据TTL来判断了。

关于任何设置Linux的TTL默认值,请参阅附录其他资源和链接 内的ip-sysctl.txt。

TTL只能在mangle表内使用,它有3个选项:

Table 6-24. TTL target

ULOG target

ULOG可以在用户空间记录被匹配的包的信息,这些信息和整个包都会通过netlink socket被多播。然后,一个或多个用户空间的进程就会接受它们。换句话说,ULOG是至今iptables和Netfilter下最成熟、最完善的日志工具,它包含了很多更好的工具用于包的记录。这个target可以是我们把信息记录到MySQL或其他数据库中。这样,搜索特定的包或把记录分组就很方便了。你可以在ULOGD project page里找到ULOGD用户空间的软件。

Table 6-25. ULOG target

配置参考



阅读(1435) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~