Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1338077
  • 博文数量: 464
  • 博客积分: 9399
  • 博客等级: 中将
  • 技术积分: 6364
  • 用 户 组: 普通用户
  • 注册时间: 2011-02-19 09:15
文章分类

全部博文(464)

文章存档

2014年(12)

2013年(123)

2012年(173)

2011年(156)

我的朋友

分类: 系统运维

2013-03-22 10:55:36

一、链表

当数据包到达防火墙时,如果MAC地址符合,就会由内核里相应的驱动程序接收,然后会经过一系列操作,从而决定是发送给本地的程序,还是转发给其他机子,还是其他的什么。

先来看一个以本地为目的的数据包,它要经过以下步骤才能到达要接收它的程序:

下文中有个词mangle,我实在没想到什么合适的词来表达这个意思,只因为我的英语太差!我只能把我理解的写出来。这个词表达的意思是,会对数据 包的一些传输特性进行修改,在mangle表中允许的操作是 TOS、TTL、MARK。也就是说,今后只要我们见到这个词能理解它的作用就行了。

Table 3-1. 以本地为目标(就是我们自己的机子了)的包

Step(步骤) Table(表) Chain(链) Comment(注释)
1     在线路上传输(比如,Internet)
2     进入接口 (比如, eth0)
3 mangle PREROUTING 这个链用来mangle数据包,比如改变TOS等
4 nat PREROUTING 这个链主要用来做DNAT。不要在这个链做过虑操作,因为某些情况下包会溜过去。
5     路由判断,比如,包是发往本地的,还是要转发的。
6 mangle INPUT 在路由之后,被送往本地程序之前,mangle数据包。
7 filter INPUT 所有以本地为目的的包都要经过这个链,不管它们从哪儿来,对这些包的过滤条件就设在这里。
8     到达本地程序了(比如,服务程序或客户程序)

注意,相比以前(译者注:就是指ipchain)现在数据包是由INPUT链过,而不是FORWARD链。这样更符合逻辑。刚看上去可能不太好理解,但仔细想想就会恍然大悟的。

现在我们来看看源地址是本地器的包要经过哪些步骤:

Table 3-2. 以本地为源的包

Step Table Chain Comment
1     本地程序(比如,服务程序或客户程序)
2     路由判断,要使用源地址,外出接口,还有其他一些信息。
3 mangle OUTPUT 在这儿可以mangle包。建议不要在这儿做过滤,可能有副作用哦。
4 nat OUTPUT 这个链对从防火墙本身发出的包进行DNAT操作。
5 filter OUTPUT 对本地发出的包过滤。
6 mangle POSTROUTING 这条链主要在包DNAT之后(译者注: 作者把这一次DNAT称作实际的路由,虽然在前面有一次路由。对于本地的包,一旦它被生成,就必须经过路由代码的处理,但这个包具体到哪儿去,要由NAT 代码处理之后才能确定。所以把这称作实际的路由。),离开本地之前,对包 mangle。有两种包会经过这里,防火墙所在机子本身产生的包,还有被转发的包。
7 nat POSTROUTING 在这里做SNAT。但不要在这里做过滤,因为有副作用,而且有些包是会溜过去的,即使你用了DROP策略。
8     离开接口(比如: eth0)
9     在线路上传输(比如,Internet)

在这个例子中,我们假设一个包的目的是另一个网络中的一台机子。让我们来看看这个包的旅程:

Table 3-3. 被转发的包

Step Table Chain Comment
1     在线路上传输(比如,Internet)
2     进入接口(比如, eth0)
3 mangle PREROUTING mangle数据包,,比如改变TOS等。
4 nat PREROUTING 这个链主要用来做DNAT。不要在这个链做过虑操作,因为某些情况下包会溜过去。稍后会做SNAT。
5     路由判断,比如,包是发往本地的,还是要转发的。
6 mangle FORWARD 包继续被发送至mangle表的 FORWARD链,这是非常特殊的情况才会用到的。在这里,包被mangle(还记得mangle的意思吗)。这次mangle发生在最初的路由判断之 后,在最后一次更改包的目的之前(译者注:就是下面的FORWARD链所做的,因其过滤功能,可能会改变一些包的目的地,如丢弃包)。
7 filter FORWARD 包继续被发送至这条FORWARD链。只有需要转发的包才会走到这里,并且针对这些包的所有过滤也在这里进行。注意,所有要转发的包都要经过这里,不管是外网到内网的还是内网到外网的。在你自己书写规则时,要考虑到这一点。
8 mangle POSTROUTING 这个链也是针对一些特殊类型的包(译者注:参考第6步,我们可以发现,在转发包时,mangle表的两个链都用在特殊的应用上)。这一步mangle是在所有更改包的目的地址的操作完成之后做的,但这时包还在本地上。
9 nat POSTROUTING 这个链就是用来做SNAT的,当然也包括Masquerade(伪装)。但不要在这儿做过滤,因为某些包即使不满足条件也会通过。
10     离开接口(比如: eth0)
11     又在线路上传输了(比如,LAN)

就如你所见的,包要经历很多步骤,而且它们可以被阻拦在任何一条链上,或者是任何有问题的地方。我们的主要兴趣是iptables的概貌。注意,对不同的接口,是没有什么特殊的链和表的。所有要经防火墙/ 路由器转发的包都要经过FORWARD链。

三个主要表的概述:

Mangle

主要用来mangle包,可以用mangle匹配来改变包的TOS等特性。

mangle表中仅有的几种操作:

TOS      操作用来设置或改变数据包的服务类型域。这常用来设置网络上的数据包如何被路由等策略。它在Internet上不能使用,而且很多路由器不会注意到这个域值。换句话说,不要设置发往Internet的包,除非你打算依靠TOS来路由,比如用iproute2

TTL      操作用来改变数据包的生存时间域 ,我们可以让所有数据包只有一个特殊的TTL。它的存在有一个很好的理由,那就是我们可以欺骗一些ISP。为什么要欺骗他们呢?因为他们不愿意让我们共享一个。那些ISP会查找一台单独的计算机是否使用不同的TTL,并且以此作为判断连接是否被共享的标志。

MARK 用来给包设置特殊的标记。iproute2能识别这些标记,并根据不同的标记(或没有标记)决定不同的路由。用这些标记我们可以做带宽限制和基于请求的分类。

Nat

此表仅用于NAT,也就是转换包的源或目标地址。

注意,就象我们前面说过的,只有流的第一个包会被这个链匹配,其后的包会自动被做相同的处理。

实际的操作分为以下几类:

DNAT   操作主要用在这样一种情况,你有一个合法的IP地址,要把对防火墙的访问重定向到其他的机子上(比如DMZ)。也就是说,我们改变的是目的地址,以使包能重路由到某台主机。

SNAT   改变包的源地址,这在极大程度上可以隐藏你的本地网络或者DMZ等。如我们知道防火墙的外部地址,但必须用这个地址替换本地网络地址。有了这个操作,防火墙就能自动地对包做SNATDe-SNAT(就是反向的SNAT),以使LAN能连接到Internet

MASQUERADE       的作用和MASQUERADE完全一样,只是计算机的负荷稍微多一点。因为对每个匹配的包,MASQUERADE都要查找可用的IP地址,而不象SNAT用的IP地址是配置好的。当然,这也有好处,就是我们可以使用通过PPP PPPOESLIP等拨号得到的地址,这些地址可是由ISPDHCP随机分配的。

Filter

filter 表用来过滤数据包,我们可以在任何时候匹配包并过滤它们。我们就是在这里根据包的内容对包做DROPACCEPT的。几乎所有的target都可以在这儿使用。

二、跟踪

状态机制是iptables中特殊的一部分,其实它不应该叫状态机制,因为它只是一种连接跟踪机制。但是,很多人都认可状态机制这个名字。文中我也 或多或或少地用这个名字来表示和连接跟踪相同的意思。这不应该引起什么混乱的。连接跟踪可以让Netfilter知道某个特定连接的状态。运行连接跟踪的 防火墙称作带有状态机制的防火墙,以下简称为状态防火墙。状态防火墙比非状态防火墙要安全,因为它允许我们编写更严密的规则。

在iptables里,包是和被跟踪连接的四种不同状态有关的。它们是NEWESTABLISHEDRELATEDINVALID。后面我们会深入地讨论每一个状态。使用--state匹配操作,我们能很容易地控制 “谁或什么能发起新的会话”。

所有在内核中由Netfilter的特定框架做的连接跟踪称作conntrack(译者注:就是connection tracking 的首字母缩写)。conntrack可以作为模块安装,也可以作为内核的一部分。大部分情况下,我们想要,也需要更详细的连接跟踪,这是相比于缺省的 conntrack而言。也因为此,conntrack中有许多用来处理TCP, UDP或ICMP协议的部件。这些模块从数据包中提取详细的、唯一的信息,因此能保持对每一个数据流的跟踪。这些信息也告知conntrack流当前的状 态。例如,UDP流一般由他们的目的地址、源地址、目的端口和源端口唯一确定。

在以前的内核里,我们可以打开或关闭重组功能。然而,自从iptables和Netfilter,尤其是连接跟踪被引入内核,这个选项就被取消了。 因为没有包的重组,连接跟踪就不能正常工作。现在重组已经整合入 conntrack,并且在conntrack启动时自动启动。不要关闭重组功能,除非你要关闭连接跟踪。

除了本地产生的包由OUTPUT链处理外,所有连接跟踪都是在PREROUTING链里进行处理的,意思就是, iptables会在PREROUTING链里从新计算所有的状态。如果我们发送一个流的初始化包,状态就会在OUTPUT链里被设置为NEW,当我们收到回应的包时,状态就会在PREROUTING链里被设置为ESTABLISHED。如果第一个包不是本地产生的,那就会在PREROUTING链里被设置为NEW状态。综上,所有状态的改变和计算都是在nat表中的PREROUTING链和OUTPUT链里完成的。

包的状态依据IP所包含的协议不同而不同,但在内核外部,也就是用户空间里,只有4种状态:NEWESTABLISHEDRELATEDINVALID。它们主要是和状态匹配一起使用。下面就简要地介绍以下这几种状态:

Table 4-1. 数据包在用户空间的状态

State(状态) Explanation(注释)
NEW NEW说明这个包是我们看到的第一个包。意思就是,这是conntrack模块看到的某个连接第一个包,它即将被匹配了。比如,我们看到一个SYN 包,是我们所留意的连接的第一个包,就要匹配它。第一个包也可能不是SYN包,但它仍会被认为是NEW状态。这样做有时会导致一些问题,但对某些情况是有非常大的帮助的。例如,在我们想恢复某条从其他的防火墙丢失的连接时,或者某个连接已经超时,但实际上并未关闭时。
ESTABLISHED ESTABLISHED已经注意到两个方向上的数据传输,而且会继续匹配这个连接的包。处于ESTABLISHED状态的连接是非常容易理解的。只要发送并接到应答,连接就是ESTABLISHED的了。一个连接要从NEW变为ESTABLISHED,只需要接到应答包即可,不管这个包是发往防火墙的,还是要由防火墙转发的。ICMP的错误和重定向等信息包也被看作是ESTABLISHED,只要它们是我们所发出的信息的应答。
RELATED RELATED是 个比较麻烦的状态。当一个连接和某个已处于ESTABLISHED状态的连接有关系时,就被认为是RELATED的了。换句话说,一个连接要想是 RELATED的,首先要有一个ESTABLISHED的连接。这个ESTABLISHED连接再产生一个主连接之外的连接,这个新的连接就是 RELATED的了,当然前提是conntrack模块要能理解RELATED。ftp是个很好的例子,FTP-data 连接就是和FTP-control有RELATED的。还有其他的例子,比如,通过IRC的DCC连接。有了这个状态,ICMP应答、FTP传输、DCC 等才能穿过防火墙正常工作。注意,大部分还有一些UDP协议都依赖这个机制。这些协议是很复杂的,它们把连接信息放在数据包里,并且要求这些信息能被正确 理解。
INVALID INVALID说明数据包不能被识别属于哪个连接或没有任何状态。有几个原因可以产生这种情况,比如,内存溢出,收到不知属于哪个连接的ICMP 错误信息。一般地,我们DROP这个状态的任何东西。

这些状态可以一起使用,以便匹配数据包。这可以使我们的防火墙非常强壮和有效。以前,我们经常打开1024以上的所有端口来放行应答的数据。现在,有了状态机制,就不需再这样了。因为我们可以只开放那些有应答数据的端口,其他的都可以关闭。这样就安全多了。

tcp 6 117 SYN_SENT src=192.168.1.5 dst=192.168.1.35 sport=1031 dport=23 [UNREPLIED] src=192.168.1.35 dst=192.168.1.5 sport=23 dport=1031 use=1

从上面的记录可以看出,SYN_SENT状态被设置了,这说明连接已经发出一个SYN包,但应答还没发送过来,这可从[UNREPLIED]标志看出。

tcp 6 57 SYN_RECV src=192.168.1.5 dst=192.168.1.35 sport=1031 dport=23 src=192.168.1.35 dst=192.168.1.5 sport=23 dport=1031 use=1

现在我们已经收到了相应的SYN/ACK包,状态也变为SYN_RECV,这说明最初发出的SYN包已正确传输,并且SYN/ACK包也到达了防火墙。 这就意味着在连接的两方都有数据传输,因此可以认为两个方向都有相应的回应。当然,这是假设的。

tcp 6 431999 ESTABLISHED src=192.168.1.5 dst=192.168.1.35 sport=1031 dport=23 src=192.168.1.35 dst=192.168.1.5 sport=23 dport=1031 use=1

现在我们发出了三步握手的最后一个包,即ACK包,连接也就进入ESTABLISHED状态了。再传输几个数据包,连接就是[ASSURED]的了。

udp 17 20 src=192.168.1.2 dst=192.168.1.5 sport=137 dport=1025 [UNREPLIED] src=192.168.1.5 dst=192.168.1.2 sport=1025 dport=137 use=1

从前两个值可知,这是一个UDP包。第一个是协议名称,第二个是协议号,第三个是此状态的生存时间,默认是30秒。接下来是包的源、目地址和端口,还有期待之中回应包的源、目地址和端口。[UNREPLIED]标记说明还未收到回应。

udp 17 170 src=192.168.1.2 dst=192.168.1.5 sport=137 dport=1025 src=192.168.1.5 dst=192.168.1.2 sport=1025 dport=137 use=1

一旦收到第一个包的回应,[UNREPLIED]标记就会被删除,连接就被认为是ESTABLISHED的,但在记录里并不显示 ESTABLISHED标记。相应地,状态的超时时间也变为180秒了。在本例中,只剩170秒了,10秒后,就会减少为160秒。有个东西是不可少的, 虽然它可能会有些变化,就是前面提过的[ASSURED]。要想变为 [ASSURED]状态,连接上必须要再有些流量。

udp 17 175 src=192.168.1.5 dst=195.22.79.2 sport=1025 dport=53 src=195.22.79.2 dst=192.168.1.5 sport=53 dport=1025 [ASSURED] use=1

可以看出来,[ASSURED]状态的记录和前面的没有多大差别,除了标记由[UNREPLIED]变成[ASSURED]。如果这个连接持续不了 180秒,那就要被中断。180秒是短了点儿,但对大部分应用足够了。只要遇到这个连接的包穿过防火墙,超时值就会被重置为默认值,所有的状态都是这样 的。

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