对于Internet上的系统,不管是什么情况,首先我们要明确一点:网络是不安全的。因此,虽然创建一个防火墙并不能保证系统100%安全,但却是绝对必要的。和社会上其它任何事物一样,Internet经常会受到一些无聊的或者别有用心的人的干扰,防火墙的目的就是将这类人挡在你的网络之外,同时使你仍然可以完成自己的工作。
那么构筑怎样的Linux防火墙系统才算是足够安全呢?这是一个很难回答的问题,因为不同的应用环境对安全的要求不一样。用一句比较恰当而且简单的话来回答这个问题:用户了解自己的Linux系统和设置,并且可以很好地保护好自己的数据和机密文件的安全,这对于该计算机用户来说就可以称之为他的计算机有足够的安全性。
那么到底什么是防火墙呢?防火墙是一个或一组系统,它在网络之间执行访问控制策略。实现防火墙的实际方式各不相同,但是在原则上,防火墙可以被认为是这样一对机制:一种机制是拦阻传输流通行,另一种机制是允许传输流通过。
一些防火墙偏重拦阻传输流的通行,而另一些防火墙则偏重允许传输流通过。了解有关防火墙的最重要的概念可能就是它实现了一种访问控制策略。
一般来说,防火墙在配置上是防止来自“外部”世界未经授权的交互式登录的。这大大有助于防止破坏者登录到你网络中的计算机上。一些设计更为精巧的防火墙可以防止来自外部的传输流进入内部,但又允许内部的用户可以自由地与外部通信。如果你切断防火墙的话,它可以保护你免受网络上任何类型的攻击。
防火墙的另一个非常重要的特性是可以提供一个单独的“拦阻点”,在“拦阻点”上设置安全和审计检查。与计算机系统正受到某些人利用调制解调器拨入攻击的情况不同,防火墙可以发挥一种有效的“电话监听”和跟踪工具的作用。防火墙提供了一种重要的记录和审计功能;它们经常可以向管理员提供一些情况概要,提供有关通过防火墙的传输流的类型和数量,以及有多少次试图闯入防火墙的企图等信息。
两种类型防火墙的平衡
在概念上,有两种类型的防火墙:网络级防火墙和应用级防火墙。这两种类型防火墙的差异并不如想像中那样大,最新的技术模糊了两者之间的区别,使哪个“更好”或“更坏”不再那么明显。
网络级防火墙一般根据源、目的地址做出决策,输入单个的IP包。一台简单的路由器是“传统的”网络级防火墙,因为它不能做出复杂的决策,不能判断出一个包的实际含意或包的实际出处。现代网络级防火墙已变得越来越复杂,可以保持流经它的接入状态、一些数据流的内容等有关信息。
许多网络级防火墙之间的一个重要差别是防火墙可以使传输流直接通过,因此要使用这样的防火墙通常需要分配有效的IP地址块。网络级防火墙一般速度都很快,对用户很透明。
应用级防火墙一般是运行代理服务器的主机,它不允许传输流在网络之间直接传输,并对通过它的传输流进行记录和审计。由于代理应用程序是运行在防火墙上的软件部件,因此它处于实施记录和访问控制的理想位置。
应用级防火墙可以被用作网络地址翻译器,因为传输流通过有效地屏蔽掉起始接入原址的应用程序后,从一面进来,从另一面出去。
在某些情况下,设置了应用级防火墙后,可能会对性能造成影响,会使防火墙不太透明。早期的应用级防火墙,对于最终用户不很透明,并需要对用户进行培训。应用级防火墙一般会提供更详尽的审计报告,比网络级防火墙实施更保守的安全模型。
防火墙未来的位置应当处于网络级防火墙与应用级防火墙之间的某一位置。网络级防火墙可能对流经它们的信息越来越“了解”,而应用级防火墙可能将变得更加“低级”和透明。最终的结果将是能够对通过的数据流记录和审计的快速包屏蔽系统。
Linux为我们提供了一个非常优秀的防火墙工具,它就是netfilter/iptables(http: //www.netfilter.org/)。它完全是免费的,并且可以在一台低配置的老机器上很好地运行。netfilter/iptables功能强大,使用灵活,并且可以对流入和流出的信息进行细化的控制。
事实上,每一个主要的Linux版本中都有不同的防火墙软件套件。Iptabels(netfilter)应用程序被认为是Linux中实现包过虑功能的第四代应用程序。第一代是Linux 内核1.1版本所使用的Alan Cox从BSD Unix中移植过来的ipfw。
在2.0版的内核中,Jos Vos和其它一些程序员对ipfw进行了扩展,并且添加了ipfwadm用户工具。在2.2版内核中, Russell和Michael Neuling做了一些非常重要的改进,也就是在该内核中,Russell添加了帮助用户控制过虑规则的ipchains工具。后来,Russell又完成了其名为netfilter(http://www.netfilter.org)的内核框架。这些防火墙软件套件一般都比其前任有所改进,表现越来越出众。
netfilter/iptables已经包含在了2.4以后的内核当中,它可以实现防火墙、NAT(网络地址翻译)和数据包的分割等功能。 netfilter工作在内核内部,而iptables则是让用户定义规则集的表结构。netfilter/iptables是从ipchains和 ipwadfm(IP防火墙管理)演化而来的,为了简单起见,下文中,我就将其统一称为iptables。
iptables的其它一些好的用法是为Unix、Linux和BSD个人工作站创建一个防火墙,当然也可以为一个子网创建防火墙以保护其它的系统平台。 iptables只读取数据包的头,所以不会给信息流增加负担,此外它也无需进行验证。如果要想获得更好的安全性,可以将其和一个代理服务器(比如 squid)相结合。
iptable的概念和用法
防火墙典型的设置是有两个网卡,一个流入,一个流出。iptables读取流入和流出的数据包的报头,然后将它们与规划集(ruleset)相比较,然后将可接受的数据包从一个网卡转发至另外一个网卡。对于被拒绝的数据包,可以被丢弃或者按照你所定义的方式来处理。
通过向防火墙提供有关对来自某个源、到某个目的地或具有特定协议类型的信息包要做些什么的指令的规则,控制信息包的过滤。通过使用iptables系统提供的特殊命令 iptables,建立这些规则,并将其添加到内核空间的特定信息包过滤表内的链中。关于添加、除去、编辑规则的命令的一般语法如下:
iptables [-t table] command [match] [target]
现实中,为了易读,我们一般都用这种语法。大部分规则都是按这种语法写的,因此,如果看到别人写的规则,你很可能会发现用的也是这种语法。
如果不想用标准的表,就要在[table]处指定表名。一般情况下没有必要指定使用的表,因为iptables 默认使用filter表来执行所有的命令。也没有必要非得在这里指定表名,实际上几乎可在规则的任何地方指定表名。当然,把表名放在开始处已经是约定俗成的标准。尽管命令总是放在开头,或者是直接放在表名后面,我们也要考虑到底放在哪儿易读。
“command”告诉程序该做什么,比如:插入一个规则,还是在链的末尾增加一个规则,还是删除一个规则。下面会仔细地介绍。
“match”细致地描述了包的某个特点,以使这个包区别于其它所有的包。在这里,我们可以指定包的来源IP 地址、网络接口、端口、协议类型,或者其他什么。下面我们将会看到许多不同的match。
最后是数据包的目标所在“target”。若数据包符合所有的match,内核就用target来处理它,或者说把包发往target。比如,我们可以让内核把包发送到当前表中的其他链(可能是我们自己建立的),或者只是丢弃这个包而不做任何处理,或者向发送者返回某个特殊的应答。下面我们来逐个讨论这些选项:
[-t table]选项允许使用标准表之外的任何表。表是包含仅处理特定类型信息包的规则和链的信息包过滤表。有三种可用的表选项:filter、nat 和 mangle。该选项不是必需的,如果未指定,则filter用作缺省表。下面介绍各表实现的功能。
filter
filter 表用来过滤数据包,我们可以在任何时候匹配包并过滤它们。我们就是在这里根据包的内容对包做DROP或ACCEPT的。当然,我们也可以预先在其他地方做些过滤,但是这个表才是设计用来过滤的。几乎所有的target都可以在这儿使用。
nat
nat表的主要用处是网络地址转换,即Network Address Translation,缩写为NAT。做过NAT操作的数据包的地址就被改变了,当然这种改变是根据我们的规则进行的。属于一个流的包只会经过这个表一次。
如果第一个包被允许做NAT或Masqueraded,那么余下的包都会自动地被做相同的操作。也就是说,余下的包不会再通过这个表,一个一个的被 NAT,而是自动地完成。这就是我们为什么不应该在这个表中做任何过滤的主要原因。PREROUTING 链的作用是在包刚刚到达防火墙时改变它的目的地址,如果需要的话。OUTPUT链改变本地产生的包的目的地址。
POSTROUTING链在包就要离开防火墙之前改变其源地址此表仅用于NAT,也就是转换包的源或目标地址。注意,只有流的第一个包会被这个链匹配,其后的包会自动被做相同的处理。实际的操作分为以下几类:
◆ DNAT
◆ SNAT
◆ MASQUERADE
DNAT操作主要用在这样一种情况,你有一个合法的IP地址,要把对防火墙的访问 重定向到其他的机子上(比如DMZ)。也就是说,我们改变的是目的地址,以使包能重路由到某台主机。
SNAT改变包的源地址,这在极大程度上可以隐藏你的本地网络或者DMZ等。一个很好的例子是我们知道防火墙的外部地址,但必须用这个地址替换本地网络地址。有了这个操作,防火墙就 能自动地对包做SNAT和De-SNAT(就是反向的SNAT),以使LAN能连接到Internet。
如果使用类似 192.168.0.0/24这样的地址,是不会从Internet得到任何回应的。因为IANA定义这些网络(还有其他的)为私有的,只能用于LAN内部。
MASQUERADE的作用和MASQUERADE完全一样,只是计算机的负荷稍微多一点。因为对每个匹配的包,MASQUERADE都要查找可用的IP地址,而不象SNAT用的IP地址是配置好的。当然,这也有好处,就是我们可以使用通过PPP、 PPPOE、SLIP等拨号得到的地址,这些地址可是由ISP的DHCP随机分配的。
Mangle
这个表主要用来mangle数据包。我们可以改变不同的包及包头的内容,比如 TTL,TOS或MARK。注意MARK并没有真正地改动数据包,它只是在内核空间为包设了一个标记。防火墙内的其他的规则或程序(如tc)可以使用这种标记对包进行过滤或高级路由。这个表有五个内建的链: PREROUTING,POSTROUTING, OUTPUT,INPUT和 FORWARD。
PREROUTING在包进入防火墙之后、路由判断之前改变包,POSTROUTING是在所有路由判断之后。 OUTPUT在确定包的目的之前更改数据包。INPUT在包被路由到本地之后,但在用户空间的程序看到它之前改变包。注意,mangle表不能做任何 NAT,它只是改变数据包的TTL,TOS或MARK,而不是其源目的地址。NAT是在nat表中操作的,以下是mangle表中仅有的几种操作:
◆ TOS
◆ TTL
◆ MARK
TOS操作用来设置或改变数据包的服务类型域。这常用来设置网络上的数据包如何被路由等策略。注意这个操作并不完善,有时得不所愿。它在Internet上还不能使用,而且很多路由器不会注意到这个域值。换句话说,不要设置发往Internet的包,除非你打算依靠TOS来路由,比如用iproute2。
TTL操作用来改变数据包的生存时间域,我们可以让所有数据包只有一个特殊的TTL。它的存在有一个很好的理由,那就是我们可以欺骗一些ISP。为什么要欺骗他们呢?因为他们不愿意让我们共享 一个连接。
那些ISP会查找一台单独的计算机是否使用不同的TTL,并且以此作为判断连接是否被共享的标志。
MARK用来给包设置特殊的标记。iproute2能识别这些标记,并根据不同的标记(或没有标记) 决定不同的路由。用这些标记我们可以做带宽限制和基于请求的分类。
命令(command)
命令中必要的组成部分command是iptables命令的最重要部分。它告诉 iptables 命令要做什么,例如,插入规则、将规则添加到链的末尾或删除规则。
在使用iptables时,如果必须的参数没有输入就按了回车,那么它就会给出一些提示信息,告诉你需要哪些参数等。iptables的选项-v用来显示iptables的版本,-h给出语法的简短说明。
匹配(match)
iptables命令的可选match部分指定信息包与规则匹配所应具有的特征(如源和目的地地址、协议等)。可把它们归为五类:第一类是generic matches(通用的匹配),适用于所有的规则;第二类是TCP matches,顾名思义,这只能用于TCP包;第三类是UDP matches,当然它只能用在UDP包上了;第四类是ICMP matches ,针对ICMP包的;第五类比较特殊,针对的是状态,指所有者和访问的频率限制等。在此,只介绍通用匹配,熟悉了通用匹配,其它的几种也就比较容易理解了。
目标(target)
我们已经知道,目标是由规则指定的操作,那些与规则匹配的信息包执行这些操作。除了允许用户定义的目标之外,还有许多可用的目标选项。用于建立高级规则的目标,如LOG、REDIRECT、MARK、MIRROR 和MASQUERADE等。
状态机制
状态机制是iptables中特殊的一部分,其实它不应该叫状态机制,因为它只是一种连接跟踪机制。但是,很多人都认可状态机制这个名字。连接跟踪可以让 netfilter知道某个特定连接的状态。运行连接跟踪的防火墙称作带有状态机制的防火墙,以下简称为状态防火墙。状态防火墙比非状态防火墙要安全,因为它允许我们编写更严密的规则。
在iptables里,包是和被跟踪连接的四种不同状态有关的。它们是NEW、ESTABLISHED、RELATED和INVALID。使用--state匹配操作,我们能很容易地控制“谁或什么能发起新的会话”。
所有在内核中由netfilter的特定框架做的连接跟踪称作conntrack(就是connection tracking的首字母缩写)。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种状态:NEW、ESTABLISHED、RELATED和INVALID。它们主要是和状态匹配一起使用。
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的。
INVALID
INVALID说明数据包不能被识别属于哪个连接或没有任何状态。有几个原因可以产生这种情况,比如,内存溢出,收到不知属于哪个连接的ICMP错误信息。一般地,我们DROP这个状态的任何东西。
这些状态可以一起使用,以便匹配数据包。这可以使我们的防火墙非常强壮和有效。以前,我们经常打开1024以上的所有端口来放行应答的数据。现在,有了状态机制,就不需再这样了。因为我们可以只开放那些有应答数据的端口,其他的都可以关闭。这样就安全多了。
用iptables搭建防火墙规则
前面介绍了iptables的基本概念和用法,下面我们就开始正式使用iptables来创建我们的防火墙。启动和停止iptables的方法取决于所使用的Linux发行版,你可以查看所使用Linux版本的文档。在Red Hat中,启动iptables用:
#service iptables start
一般情况下,iptables已经包含在了Linux发行版中,可以运行iptables --version来查看系统是否安装了iptables。在我使用的Fedora Core 1中,安装的版本是iptables v1.2.8。如果你的系统确实没有安装iptables,那么可以从以下地址下载:
http://www.netfilter.org/
查看规则集
虽然上文对iptables的用法作一个简单介绍,但现实中我们可能需要知道更完整的信息,这时我们可以运行man iptables来查看所有命令和选项的完整介绍,也可以运行iptables help来查看一个快速帮助。要查看系统中现有的iptables规划集,可以运行以下命令:
iptables list
下面是没有定义规划时iptables的样子:
Chain INPUT (policy ACCEPT)
target prot opt source destination
Chain FORWARD (policy ACCEPT)
target prot opt source destination
Chain OUTPUT (policy ACCEPT)
target prot opt source destination
如上面的例子所示,每一个数据包都要通过三个内建的链(INPUT、OUTPUT和FORWARD)中的一个。 filter是最常用的表,上文所示设置所有的表规则的基本语法:iptables [-t table] command [match] [target]。
现实中,不一定要用到这里所列出的所有选项,也不一定是以这个顺序。当然,这是一种惯例,因为规则一般都比较长,为了清晰起见,最好能够按照这个顺序。
在没有指定规则表的情况下,缺省时使用的filter表。在filter表中最常用的三个目标是ACCEPT、DROP和REJECT。DROP会丢弃数据包,不再对其进行任何处理。REJECT会把出错信息传送至发送数据包的主机。虽然有时会有一些预想不到的影响,但在很多时候它还是非常有用。
增加规则
本例中的规则将会阻止来自某一特定IP范围内的数据包,因为该IP地址范围被管理员怀疑有大量恶意的攻击者在活动:
# iptables -t filter -A INPUT -s 123.456.789.0/24 -j DROP
要了解有关iptables详细的参数和命令格式,请使用man iptables查看。可以说,现在我们对于网络上的恶意攻击者已经深恶痛绝,但不管怎么说,我们也不能因为憎恨它们就以同样的方法对其实行简单的报复,至少这种事情不能在你的网络里发生。因此,我们也可以很轻易地阻止所有流向攻击者IP地址的数据包,该命令也只是稍有不同:
# iptables -t filter -A OUTPUT -d 123.456.789.0/24 -j DROP
注意这里的A选项,如前所述,使用它说明是给现有的链添加规则。
删除规则
网络上的恶意攻击者总是在变化着的,因此我们也要不断改变IP。假设我们了解的一个网上攻击者转移到了新的IP地址,而其老的IP地址被分配给了一些清白的用户,那么这时这些用户的数据包就无法通过你的网络了。这种情况下,我们可以使用带-D选项的命令来删除现有的规则:
# iptables -t filter -D OUTPUT -d 123.456.789.0/24 -j DROP
缺省的策略
创建一个具有很好灵活性,可以抵御各种意外事件的规则需要花大量的时间。对于那些不想这样做的人,最基本的原则就是“先拒绝所有的数据包,然后再允许需要的”。下面我们来为每一个链设置缺省的规则:
# iptables -P INPUT DROP
# iptables -P FORWARD DROP
# iptables -P OUTPUT ACCEPT
这里选项-P用于设置链的策略,只有三个内建的链才有策略。这些策略可以让信息毫无限制地流出,但不允许信息流入。但很多时候,我们还是需要接收外部信息的。这时可使用以下命令:
# iptables -t filter -A INPUT -s 123.456.789.0/24 -j ACCEPT
SYN的使用
我们不能关闭所有的端口,那将会把我们自己完全“与世隔绝”。我们也不能只指定某些端口处于打开状态,因为我们无法预见哪一个端口将会被使用。事实上,只简单地允许目的地为某一特定端口的数据流通过将对阻止恶意的攻击毫无意义。那么我们怎样才能设置一个有效的规则,即可以允许普通用户正常通过,又可以阻止恶意攻击者访问我们的网络呢?
对于刚开始使用iptables的人,我们可以充分利用syn标识来阻止那些未经授权的访问。因为iptables只检测数据包的报头,所以不会增加有效负荷。事实上,除iptables以外,很多其它有用的数据包分析都是基于报头的。
比如,在进行Web冲浪时,一个请求从你的PC发送至其它某一个地方的Web服务器之上,接着该服务器就会响应请求并且向你发回一个数据包,并且得到你的系统上的一个临时端口。与响应请求不同的是,服务器并不关心你所传送的内容。这们可以利用这种特点,来设置一个规则,让它阻止所有没有经过你的系统授权的TCP连接:
# iptables -t filter -A INPUT -i eth0 -p tcp --syn -j DROP
这里的-i指的是网卡,-p则是指协议,--syn则表示带有syn标识设置的TCP数据包。从中我们可以看出,对TCP/IP的了解将非常有利于维护网络安全。SYN用于初始化一个TCP连接,如果你在自己的机器上没有运行任何服务器,别人自然也就不会向你发送SYN数据包了。
就这点而言,有人会说:何必如此麻烦?的确,我们有更简单的创建防火墙的方法,也有很多不错的软件也可以帮助我们来构建自己的规则集,但是我们应该清楚,最简单的办法,往往不是最好的方法。既然我们有更好的方法,为什么不使用呢?
共享一个Internet连接
网络地址翻译和IP伪装都可以实现多台主机共享一个Internet连接,而这个局域网可以是Linux和Windows系统组成的多系统局域网。假设现在我们有一台机器有两个网卡,其中eth0为“公共”网卡,eth1为“私有”网卡。
换句话说,eth0被分配了一个静态的,可路由的IP地址,而eth1则被分配给了一个私有的、不能路由的IP,也就是说该IP是属于该局域网子网的。要实现上述功能,我们需要向nat和filter表中添加一些链:
# iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
# iptables -t filter -A FORWARD -i eth0 -o eth1 -m state --state
RELATED,ESTABLISHED -j ACCEPT
# iptables -t filter -A FORWARD -i eth1 -o eth0 -j ACCEPT
这显示了有状态的数据包检测的价值。请注意,我们这里是如何实现流入数据包只有在属于一个已经存在的连接时才被允许的,而所有来自局域网内流向外的数据包则都允许通过 (注意:这里的filter是缺省的表,但它并不是必须的)。第一条规则让所有流出的信息看起来都是来自防火墙机器的,而并不会显示出防火墙后面还有一个局域网。
下面的例子是为FORWARD和POSTROUTING链设置了缺省的策略,在使用伪装时,有一个缺省的POSTROUTING DROP策略是非常重要的,否则,就有可能有心怀恶意的用户突破网关后伪装它自己的身份。
# iptables -t filter -P FORWARD DROP
# iptables -t nat -P POSTROUTING DROP
下面的例子是为了拨号连接设置的,它可以动态地分配IP地址:
# iptables -t nat -A POSTROUTING -o ppp0 -j MASQUERADE
规则的保存
使用脚本更改规则的问题是:改动每个规则都要调用命令iptables,而每一次调用iptables,它首先要把netfilter内核空间中的整个规则集都提取出来,然后再插入或附加,或做其他的改动,最后,再把新的规则集从它的内存空间插入到内核空间中,这显然会花费很多时间。
为了解决这个问题,可以使用命令iptables-save和restore 。iptables-save用来把规则集保存到一个特殊格式的文本文件里,而iptables-restore则用来把这个文件重新装入到内核空间中。
这两个命令最好的地方在于一次调用就可以装载和保存规则集,而不像脚本中每个规则都要调用一次iptables。
iptables-save运行一次就可以把整个规则集从内核里提取出来,并保存到文件里,而iptables-restore每次装入一个规则表。换句话说,对于一个很大的规则集,如果用脚本来设置,那这些规则就会反复地被卸载、安装很多次,而我们现在可以把整个规则集一次就保存下来,安装时则是一次一个表,这可是节省了大量的时间。所以,一旦测试结果令你满意,你就可以将它们保存为脚本:
# iptables-save > iptables-script
现在,信息包过滤表中的所有规则都被保存在文件iptables-script中。无论何时再次引导系统,都可以使用 iptables-restore 命令将规则集从该脚本文件恢复到信息包过滤表,恢复指令如下所示:
# iptables-restore iptables-script
如果您愿意在每次引导系统时自动恢复该规则集,则可以将上面指定的这条命令放到任何一个初始化shell脚本中。
事实上,大部分发行版都为用户提供了一个可以自动加载的文件,让用户在其中编辑规则集,并且大部分发行版都会有一个已经预先配置好的防火墙。不同的发行版的配置文件位置不尽相同,我们可以使用命令locate iptables来找到配置文件。对于Red Hat或者 Fedora Core而言,这个配置文件位于/etc/sysconfig/iptables。该文件初始的内容如下:
1 # Firewall configuration
2 *filter
3 :INPUT
4 :FORWARD
5 :OUTPUT
6
7 # your rules here
8
9 COMMIT
建议将其基本框架改成以下内容:
1 *filter
2 :INPUT DROP [0:0]
3 :FORWARD DROP [0:0]
4 :OUTPUT ACCEPT [0:0]
5
6 # allow local loopback connections
7 -A INPUT -i lo -j ACCEPT
8
9 # drop INVALID connections
10 -A INPUT -m state --state INVALID -j DROP
11 -A OUTPUT -m state --state INVALID -j DROP
12 -A FORWARD -m state --state INVALID -j DROP
13
14 # allow all established and related
15 -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
16
17 # add anymore rules here
18
19 COMMIT
具体例子:
作为例子,我们来为一个普通家庭用户创建一个防火墙。假设该家庭用户一般将自己的计算机用于Internet浏览、电子邮件等。我们所要做的就是允许所有必须的连接通过,而禁止所有不相关的连接。以下是防火墙配置文件的内容:
1 *filter
2 :INPUT DROP [0:0]
3 :FORWARD DROP [0:0]
4 :OUTPUT DROP [0:0]
5
6 # 允许本地loopback连接
7 -A INPUT -i lo -j ACCEPT
8
9 # drop非法连接
10 -A INPUT -m state --state INVALID -j DROP
11 -A OUTPUT -m state --state INVALID -j DROP
12 -A FORWARD -m state --state INVALID -j DROP
13
14 # 允许所有已经建立的和相关的连接
15 -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
16 -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
17
18 # 允许连接的ISP的DNS服务器
19 -A OUTPUT -d 2.3.4.10 -m state --state NEW -p udp --dport 53 -o eth0 -j ACCEPT
20 -A OUTPUT -d 2.3.4.11 -m state --state NEW -p udp --dport 53 -o eth0 -j ACCEPT
21
22 # 允许向外连接到Web服务器
23 -A OUTPUT -d 0/0 -m state --state NEW -p tcp --dport http -o eth0 -j ACCEPT
24 -A OUTPUT -m state --state NEW -p tcp --dport https -o eth0 -j ACCEPT
25
26 # 允许向外连接到ISP的SMTP和POP3服务器
27 -A OUTPUT -d 2.3.4.5 -m state --state NEW -p tcp --dport smtp -o eth0 -j ACCEPT
28 -A OUTPUT -d 2.3.4.5 -m state --state NEW -p tcp --dport pop3 -o eth0 -j ACCEPT
29
30 # 记录其它试图向外进行的连接
31 -A OUTPUT -o eth0 -j LOG
32 # 缺省情况下是DROP向外的连接
33
34 COMMIT
有关具体命令行的意义参照上文很容易就可以理解,这里就不在赘述。事实上,只要熟悉了某一特定环境下防火墙的设置,我们就可以比较容易地为其它的应用环境创建相应的防火墙。