Linux 防火墙 iptables
一次性进群,长期免费索取教程,没有付费教程。
教程列表见微信公众号底部菜单
进微信群回复公众号:微信群;QQ群:16004488
微信公众号:计算机与网络安全
ID:Computer-network
一、iptables 概述
iptables 是在Linux 2.4内核之后普遍使用的防火墙。内核由“filter”表中的以下三个规则开始。这些被称为防火墙链或就叫链。这三个链分别是 INPUT、OUTPUT和FORWARD。iptables 中一个数据包的历程如图1 所示。三个圈代表上面说的三个链,当包到达图中的一个圈,那个链就检查并确定包的命运。如果链决定DROP包,数据包就会被丢弃。但是如果链决定让包ACCEPT,包就继续在图中前进。一个链是规则的列表,如果规则和包不匹配,由链中的下一个规则处理。最后,如果再也没有要进行处理的规则了,内核就根据链的原则(policy,有时称为默认规则)来决定应当如何做。在一个注重安全的系统中,原则通常是让内核丢弃这个包。
图1 iptables 结构
当一个包进入时(就是由以太网卡),内核首先检查包的目的地。这被称作选路。
如果它就是进入本机的,包会向图中的下方移动,到达INPUT链。如果到了这里,任何等待这个包的进程都会收到它。
否则,如果内核未被允许转发,或者不知道该如何转发这个包,它会被丢弃。如果允许转发,而且包的目的地是另一个网络接口(如果有另一个的话),那么包向图中的右边行进,到达 FORWARD链。如果允许通过(ACCEPT),它就被送了出去。
最后,服务器上运行的程序可以发送网络包。这些包马上通过 OUTPUT链。如果被允许(ACCEPT),那么包继续向可以到达它的目的地的网络接口发送。
下面将详细讨论如何构建自己的规则。我们也会讨论基本的matche及其用法,还有各种各样的target,以及如何建立我们自己的target(比如,一个新的子链)。
1、基础
我们已经解释了什么是规则,在内核看来,规则就是决定如何处理一个包的语句。如果一个包符合所有的条件(就是符合matche语句),我们就运行target或jump指令。书写规则的语法格式是:
iptables [-t table] command [match] [target/jump]
注意target指令必须在最后。为了易读,我们一般用这种语法。
如果不想用标准的表,就要在[table]处指定表名。一般情况下没有必要指定使用的表,因为iptables 默认使用filter表来执行所有的命令。也没有必要非得在这里指定表名,实际上几乎可在规则的任何地方。当然,把表名放在开始处已经是约定俗成的标准。
尽管命令总是放在开头,或者是直接放在表名后面,我们也要考虑到底放在哪儿易读。command告诉程序该做什么,比如:插入一个规则,还是在链的末尾增加一个规则,还是删除一个规则,下面会仔细地介绍。
match 细致地描述了包的某个特点,以使这个包区别于其他所有的包。在这里,我们可以指定包的来源 IP 地址、网络接口、端口、协议类型,或者其他什么。
最后是数据包的目标所在。若数据包符合所有的match,内核就用target来处理它,或者说把包发往 target。比如,我们可以让内核把包发送到当前表中的其他链(可能是我们自己建立的),或者只是丢弃这个包而没有什么处理,或者向发送者返回某个特殊的应答。
选项-t用来指定使用哪个表,它可以是表1中的任何一个,默认的是 filter表。
表1 IPTABLES的表
2、其他参数介绍
除了-t 格式之外,iptables 还有很多其他参数格式,用来指定提交的规则要做什么样的操作。这些操作可能是在某个表里增加或删除一些东西,或做点儿其他什么。表2所列是iptables可用的command(要注意,如不做说明,默认表的是 filter表)。
表2 其他命令行参数
在使用 iptables 时,如果必须的参数没有输入就按了回车,那么它就会给出一些提示信息:告诉用户需要哪些参数等等。iptables的选项-v用来显示iptables的版本,-h给出语法的简短说明。
二、表和链
当数据包到达防火墙时,如果 MAC 地址符合,就会由内核里相应的驱动程序接收,然后会经过一系列操作,从而决定是发送给本地的程序,还是转发给其他主机,还是其他的什么。我们先来看一个以本地为目的的数据包,它要经过表3所示的步骤才能到达要接收它的程序:表中mangle的意思就是说在这个表中,会对数据包的一些传输特性进行修改,允许的修改可以是 TOS、TTL、MARK。
表3 以本地为目标的包的处理过程
源地址是本地的包要经过的步骤如表4所示。
表4 以本地为源的包的处理过程
在表5所列的例子中,我们假设一个包的目的是另一个网络中的一台主机。让我们来看这个包的旅程。
表5 被转发的包
如上所述,包要经历很多步骤,而且它们可以被阻拦在任何一条链上,或者是任何有问题的地方。我们的主要兴趣是 iptables 的概貌。注意,对不同的接口,是没有什么特殊的链和表的。所有要经防火墙/路由器转发的包都要经过 FORWARD 链。在上面的情况里,不要在 INPUT 链上做过滤。INPUT 是专门用来操作那些以我们的主机为目的地址的包的,它们不会被路由到其他地方的。
在第一个路由判断处,不是发往本地的包,我们会发送它穿过 FORWARD 链。若包的目的地是本地监听的IP地址,我们就会发送这个包穿过INPUT链,最后到达本地。
值得注意的是,在做NAT的过程中,发往本机的包的目的地址可能会在PREROUTING链里被改变。这个操作发生在第一次路由之前,所以在地址被改变之后,才能对包进行路由。注意,所有的包都会经过图1中的某一条路径。如果把一个包DNAT回它原来的网络,这个包会继续走完相应路径上剩下的链,直到它被发送回原来的网络。
1、mangle表
这个表主要用来处理mangle包,可以使用mangle匹配来改变包的TOS等特性。
以下是mangle表中仅有的几种操作:
TOS
TTL
MARK
TOS操作用来设置或改变数据包的服务类型域。这常用来设置网络上的数据包如何被路由等策略。注意这个操作并不完善,有时得不所愿。它在 Internet 上还不能使用,而且很多路由器不会注意到这个域值。换句话说,不要设置发往 Internet 的包,除非你打算依靠 TOS来路由,比如用iproute2。
TTL操作用来改变数据包的生存时间域,我们可以让所有数据包只有一个特殊的TTL。它的存在主要是为了进行连接共享。有些ISP会查找一台单独的计算机是否使用不同的TTL,并且以此作为判断连接是否被共享的标志。
MARK用来给包设置特殊的标记。iproute2能识别这些标记,并根据不同的标记(或没有标记)决定不同的路由。用这些标记可以做带宽限制和基于请求的分类。
2、nat 表
此表仅用于NAT,也就是转换包的源或目标地址。注意,就像我们前面说过的,只有流的第一个包会被这个链匹配,其后的包会自动被做相同的处理。实际的操作分为以下几类:
DNAT
SNAT
MASQUERADE
DNAT操作主要用在这样一种情况,有一个合法的IP地址,要把对防火墙的访问重定向到其他的主机上(比如DMZ)。也就是说,我们改变的是目的地址,以使包能重路由到某台主机。
SNAT改变包的源地址,这在极大程度上可以隐藏本地网络或者DMZ等。一个很好的例子是我们知道防火墙的外部地址,但必须用这个地址替换本地网络地址。有了这个操作,防火墙就能自动地对包做SNAT和De-SNAT(就是反向的SNAT),以使LAN能连接到Internet。如果使用类似192.168.0.0/24这样的地址,是不会从Internet得到任何回应的。因为IANA定义这些网络(还有其他的)为私有的,只能用于LAN内部。
MASQUERADE的作用和SNAT完全一样,只是计算机的负荷稍微多一点。因为对每个匹配的包,MASQUERADE都要查找可用的IP地址,而不像SNAT用的IP地址是配置好的。当然,这也有好处,就是我们可以使用通过PPP、 PPPOE、SLIP等拨号得到的地址,这些地址可是由ISP的DHCP随机分配的。
3、Filter 表
filter 表用来过滤数据包,我们可以在任何时候匹配包并过滤它们。我们就是在这里根据包的内容对包做DROP或ACCEPT的。当然,也可以预先在其他地方做些过滤,但是这个表才是设计用来过滤的。几乎所有的target都可以在这儿使用。
三、状态机制
状态机制是 iptables 中特殊的一部分,其实它不应该叫状态机制,因为它只是一种连接跟踪机制。但是,很多人都认可状态机制这个名字。连接跟踪可以让Netfilter知道某个特定连接的状态。运行连接跟踪的防火墙称作带有状态机制的防火墙,以下简称为状态防火墙。状态防火墙比非状态防火墙要安全,因为它允许我们编写更严密的规则。
在iptables里,包是和被跟踪连接的四种不同状态有关的。它们是NEW、ESTABLISHED、RELATED 和INVALID。后面我们会深入地讨论每一个状态。使用--state 匹配操作,能很容易地控制“谁或什么能发起新的会话”。
所有在内核中由Netfilter的特定框架做的连接跟踪称作conntrack。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链里完成的。
1、conntrack记录
我们先来看看怎样阅读/proc/net/ip_conntrack里的conntrack记录。这些记录表示的是当前被跟踪的连接。如果安装了ip_conntrack模块,cat/proc/net/ip_conntrack的显示类似:
tcp 6 117 SYN_SENT src=192.168.1.6 dst=192.168.1.9 sport=32775 \
dport=22 [UNREPLIED] src=192.168.1.9 dst=192.168.1.6 sport=22 \
dport=32775 use=2
conntrack模块维护的所有信息都包含在这个例子中了,通过它们就可以知道某个特定的连接处于什么状态。首先显示的是协议,这里是 tcp,接着是十进制的 6(tcp的协议类型代码是6)。之后的117是这条conntrack记录的生存时间,它会有规律地被消耗,直到收到这个连接的更多的包。那时,这个值就会被设为当时那个状态的缺省值。接下来的是这个连接在当前时间点的状态。上面的例子说明这个包处在状态 SYN_SENT,这个值是iptables 显示的,以便我们好理解,而内部用的值稍有不同。SYN_SENT 说明我们正在观察的这个连接只在一个方向发送了一个TCP SYN包。再下面是源地址、目的地址、源端口和目的端口。其中有个特殊的词UNREPLIED,说明这个连接还没有收到任何回应。最后,是希望接收的应答包的信息,它们的地址和端口和前面是相反的。
连接跟踪记录的信息依据IP所包含的协议不同而不同,所有相应的值都是在头文件linux/include/netfilter-ipv4/ip_conntrack*.h中定义的。IP、TCP、UDP、ICMP协议的缺省值是在 linux/include/netfilter-ipv4/ip_conntrack.h 里定义的。具体的值可以查看相应的协议,但我们这里用不到它们,因为它们大都只在conntrack内部使用。随着状态的改变,生存时间也会改变。
当一个连接在两个方向上都有传输时,conntrack记录就删除[UNREPLIED]标志,然后重置。在末尾有[ASSURED]的记录说明两个方向已没有流量。这样的记录是确定的,在连接跟踪表满时,是不会被删除的,没有[ASSURED]的记录就要被删除。连接跟踪表能容纳多少记录是被一个变量控制的,它可由内核中的ip- sysctl函数设置。默认值取决于内存大小,128MB可以包含8192条目录,256MB是16376条。也可以在 /proc/sys/net/ipv4/ip_conntrack_max里查看、设置。
2、数据包在用户空间的状态
就像前面说的,包的状态依据IP所包含的协议不同而不同,但在内核外部,也就是用户空间里,只有4种状态:NEW、ESTABLISHED、RELATED和INVALID。它们主要是和状态匹配一起使用。表6中简要地介绍了这几种状态。
表6 数据包在用户空间的状态
这些状态可以一起使用,以便匹配数据包。这可以使防火墙非常强壮和有效。以前,经常需要打开1024以上的所有端口来放行应答的数据。现在,有了状态机制,就不需再这样了。因为可以只开放那些有应答数据的端口,其他的都可以关闭。这样就安全多了。
3、TCP连接
现在我们来详细讨论这些状态,以及在TCP、UDP和ICMP这三种基本的协议里怎样操作它们。当然,也会讨论其他协议的情况。我们还是从TCP入手,因为它本身就是一个带状态的协议,并且具有很多关于iptables状态机制的详细信息。
一个TCP连接是经过三次握手协商连接信息才建立起来的。整个会话由一个SYN包开始,然后是一个SYN/ACK包,最后是一个ACK包,此时,会话才建立成功,能够发送数据。最大的问题在于连接跟踪怎样控制这个过程,其实非常简单。
默认情况下,连接跟踪基本上对所有的连接类型做同样的操作。如图2所示,我们就能明白在连接的不同阶段,流是处于什么状态的。就如你看到的,连接跟踪的代码不是从用户的观点来看待TCP连接建立的流程的。连接跟踪一看到SYN包,就认为这个连接是NEW状态,一看到返回的SYN/ACK包,就认为连接是ESTABLISHED状态。如果仔细想想第二步,应该能理解为什么。有了这个特殊处理,NEW和ESTABLISHED包就可以发送出本地网络,且只有ESTABLISHED的连接才能有回应信息。如果把整个建立连接的过程中传输的数据包都看作NEW,那么三次握手所用的包都是NEW状态的,这样就不能阻塞从外部到本地网络的连接了。因为即使连接是从外向内的,但它使用的包也是 NEW 状态的,而且为了其他连接能正常传输,不得不允许NEW状态的包返回并进入防火墙。更复杂的是,针对TCP连接内核使用了很多内部状态,它们的定义在 RFC 793中。但好在用户空间用不到。
图2 TCP连接状态图
以用户的观点来看,这是很简单的。但是,从内核的角度看这一块还有点困难的。下面来看一个例子。认真考虑一下在/proc/net/ip_conntrack里,连接的状态是如何改变的。
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]的了。
下面介绍TCP连接在关闭过程中的状态。在发出最后一个ACK包之前,连接(指两个方向)是不会关闭的。注意,这只是针对一般的情况。连接也可以通过发送关闭,这用在拒绝一个连接的时候。在RST包发送之后,要经过预先设定的一段时间,连接才能断掉。
连接关闭后,进入TIME_WAIT状态,缺省时间是2分钟。之所以留这个时间,是为了让数据包能完全通过各种规则的检查,也是为了数据包能通过拥挤的路由器,从而到达目的地。
如果连接是被RST包重置的,就直接变为CLOSE了。这意味着在关闭之前只有10秒的默认时间。RST包是不需要确认的,它会直接关闭连接。针对TCP连接,还有其他一些状态我们没有谈到。表7给出一个完整的状态列表和超时值。
表7 内部状态
这些值不是绝对的,可以随着内核的修订而变化,也可以通过/proc/sys/net/ipv4/netfilter/ip_ct_tcp_*的变量更改。这些默认值都是经过实践检验的。它们的单位是jiffies(百分之一秒),所以3000就代表30s。
注意状态机制在用户空间里的部分不会查看 TCP包的标志位(也就是说 TCP标志对它而言是透明的)。如果我们想让NEW状态的包通过防火墙,就要指定NEW状态,我们理解的NEW状态的意思就是指SYN包,可是iptables又不查看这些标志位。这就是问题所在。有些没有设置SYN或ACK的包,也会被看作NEW状态的。这样的包可能会被冗余防火墙用到,但对只有一个防火墙的网络是很不利的(可能会被攻击)。为了避免这样的包的影响,可以使用未设置SYN的NEW状态包里的命令。还有一个办法,就是安装patch-o-matic里的tcp-window-tracking扩展功能,它可以使防火墙能根据TCP的一些标志位来进行状态跟踪。
4、UDP连接
UDP连接是无状态的,因为它没有任何的连接建立和关闭过程,而且大部分是无序列号的。以某个顺序收到的两个数据包是无法确定它们的发出顺序的。但内核仍然可以对 UDP连接设置状态。我们来看看是如何跟踪UDP连接的,以及conntrack的相关记录。
以用户的角度考虑,UDP连接的建立几乎与TCP的一样。虽然conntrack信息看起来有点儿不同,但本质上是一样的。下面我们先来看看第一个UDP包发出后的conntrack记录。
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秒是短了点儿,但对大部分应用足够了。只要遇到这个连接的包穿过防火墙,超时值就会被重置为默认值,所有的状态都是这样的。
5、ICMP连接
ICMP也是一种无状态协议,它只是用来控制而不是建立连接。ICMP包有很多类型,但只有四种类型有应答包,它们是回显请求和应答(Echo request and reply)、时间戳请求和应答(Timestamp request and reply)、信息请求和应答(Information request and reply),还有地址掩码请求和应答(Address mask request and reply),这些包有两种状态,NEW和 ESTABLISHED。时间戳请求和信息请求已经废除不用了,回显请求还是常用的,比如ping命令就用的到,地址掩码请求不太常用,但是可能有时很有用并且值得使用。如图3所示,就可以大致了解ICMP连接的NEW和ESTABLISHED状态了。
图3 ICMP状态图
如图所示,主机向目标发送一个回显请求,防火墙就认为这个包处于 NEW 状态。目标回应一个回显应答,防火墙就认为包处于 ESTABLISHED 了。当回显请求被发送时,ip_conntrack里就有这样的记录了:
icmp 1 25 src=192.168.1.6 dst=192.168.1.10 type=8 code=0 \
id=33029 [UNREPLIED] src=192.168.1.10 dst=192.168.1.6 \
type=0 code=0 id=33029 use=1
可以看到,ICMP的记录和TCP、UDP的有点区别,协议名称、超时时间和源、目的地址都一样,不同之处在于没有了端口,而新增了三个新的字段:type、code和id。字段type说明ICMP的类型。code说明ICMP的代码,这些代码在附录ICMP类型里有说明。id是ICMP包的ID。每个ICMP包被发送时都被分配一个ID,接收方把同样的ID 分配给应答包,这样发送方能认出是哪个请求的应答。
[UNREPLIED]的含义和前面一样,说明数据的传输只发生在一个方向上,也就是说未收到应答。再往后,是应答包的源、目的地址,还有相应的三个新字段,要注意的是type和code是随着应答包的不同而变化的,id和请求包的一样。
和前面一样,应答包被认为是ESTABLISHED的。然而,在应答包之后,这个ICMP 连接就不再有数据传输了。所以,一旦应答包穿过防火墙,ICMP的连接跟踪记录就被销毁了。
以上各种情况,请求被认为是NEW,应答是ESTABLISHED。换句话说,就是当防火墙看到一个请求包时,就认为连接处于NEW状态,当有应答时,就是ESTABLISHED状态。
ICMP的缺省超时是30秒,可以在/proc/sys/net/ipv4/netfilter/ip_ct_icmp_timeout中修改。这个值是比较合适的,适合于大多数情况。
ICMP的另一个非常重要的作用是,告诉UDP、TCP连接或正在努力建立的连接发生了什么,这时ICMP应答被认为是RELATED的。主机不可达和网络不可达就是这样的例子。当试图连接某台主机不成功时(可能那台主机被关上了),数据包所到达的最后一台路由器就会返回以上的ICMP信息,它们就是RELATED的。
我们发送了一个SYN包到某一地址,防火墙认为它的状态是NEW。但是目标网络有问题不可达,路由器就会返回网络不可达的信息,这是RELATED的。连接跟踪会认出这个错误信息是哪个连接的,连接会中断,同时相应的记录删除会被删除。当UDP连接遇到问题时,同样会有相应的ICMP信息返回,当然它们的状态也是RELATED。
我们发送一个UDP包,当然它是NEW的。但是,目标网络被一些防火墙或路由器所禁止。我们的防火墙就会收到网络被禁止的信息。防火墙知道它是和哪个已打开的UDP连接相关的,并且把这个信息(状态是 RELATED)发给它,同时,把相应的记录删除。客户机收到网络被禁止的信息,连接将被中断。
6、缺省的连接操作
有时conntrack机制并不知道如何处理某个特殊的协议,尤其是在它不了解这个协议或不知道协议如何工作时,比如NETBLT、MUX还有EGP。这种情况下,conntrack使用缺省的操作。这种操作很像对UDP连接的操作,就是第一个包被认作NEW,其后的应答包等等数据都是 ESTABLISHED。
使用缺省操作的包的超时值都是一样的,为600秒,也就是10分钟。当然,这个值可以通过/proc/sys/net/ipv4/netfilter/ip_ct_generic_timeout更改,以便适应通信量,尤其是在耗时较多、流量巨大的情况下,可使用卫星等。
7、复杂协议和连接跟踪
有些协议比其他协议更复杂,这里复杂的意思是指连接跟踪机制很难正确地跟踪它们,比如ICQ、IRC 和FTP,它们都在数据包的数据域里携带某些信息,这些信息用于建立其他的连接。因此,需要一些特殊的 helper来完成工作。
下面以FTP作为例子。FTP协议先建立一个单独的连接——FTP控制会话。通过这个连接发布命令,其他的端口就会打开以便传输和这个命令相关的数据。这些连接的建立方法有两种:主动模式和被动模式。先看主动模式,FTP客户端发送端口和IP地址信息给服务器端,然后,客户端打开这个端口,服务器端从它自己的 20 端口(FTP-Data端口号)建立与这个端口的连接,接着就可以使用这个连接发送数据了。
问题在于防火墙不知道这些额外的连接(相对于控制会话而言),因为这些连接在建立时的磋商信息都在协议数据包的数据域内,而不是在可分析的协议中。因此,防火墙就不知道是不是该放这些从服务器到客户机的连接过关。
解决的办法是为连接跟踪模块增加一个特殊的 helper,以便能检测到那些信息。这样,那些从FTP服务器到客户机的连接就可以被跟踪了,状态是RELATED。被动FTP工作方式下,data连接的建立过程和主动FTP的相反。客户机告诉服务器需要某些数据,服务器就把地址和端口发回给客户机,客户机据此建立连接接收数据。如果FTP服务器在防火墙后面,或对用户限制得比较严格,只允许他们访问HTTP和FTP,而封闭了其他所有端口,为了让在Internet上的客户机能访问到FTP,也需要增加上面提到的helper。Conntrack helper既可以被静态地编译进内核,也可以作为模块,但要用下面的命令装载:
modprobe ip_conntrack_*
注意连接跟踪并不处理 NAT,因此要对连接做 NAT 就需要增加相应的模块。比如,用户想NAT并跟踪FTP连接,除了FTP的相应模块,还要有NAT模块。所有的 NAT helper名字都是以ip_nat_开头的,这是一个命名习惯:FTP NAT helper叫做ip_nat_ftp,IRC的相应模块就是ip_nat_irc。conntrack helper 的命名也遵循一样的习惯:针对IRC的conntrack helper叫ip_conntrack_irc,FTP的叫作ip_conntrack_ftp。
微信公众号:计算机与网络安全
ID:Computer-network