20.13 Linux的防火墙功能: IP Tables
在正常情况下,我们并不建议把Linux(或者UNIX,或者Windows)系统当作防火墙来用,因为功能全面的操作系统一般都不安全。专为路由器和包过滤设计的嵌入式设备(比如Cisco的PIX产品)才是最好的防火墙 。不过,对于一个家用站点,或者没有经费买合适硬件的站点来说,有Linux防火墙比根本没有还是要好,聊胜于无。
如果您正着手用一台Linux机器担当防火墙,请至少要确保它的安全配置和补丁方面已经是最新的。防火墙机器是落实本章所有推荐内容的好地方(从20.12节开始的内容在总体上讨论了包过滤防火墙。如果您不熟悉防火墙的基本概念,最好能在继续阅读下面的内容之前先读一下那一节)。
Linux的2.4版内核引入了一种全新的包过滤引擎,称为Netfilter。控制Netfilter的工具iptables是Linux 2.2版内核中比较老的命令ipchains的兄弟。iptables把有次序的规则“链(chains)”应用到网络包上。链的集合就构成了“表(tables)”,用于处理特殊类型的流量。
例如,默认的iptables表名叫“filter(过滤器)”。这个表里的规则链都用于根据包来过滤网络流量。过滤器表包含3个默认链。内核处理的每个包都要经过3个链中适当的一个。FORWARD链里的规则用于在一个网络接口收到的,而且需要转发到另一个网络接口的所有包。INPUT和OUTPUT链里的规则分别用于目的是本地主机,或者从本地主机发出的流量。这3个标准链通常能够满足两个网络接口之间防火墙的全部需要。如果必要,您还可以定义一个定制的配置,支持更复杂的记账或者路由场合。
除了filter表之外,iptables还包含“nat”和“mangle”表。nat表包含的规则链控制着NAT(Network Address Translation,网络地址转换,这里的“nat”就是iptables表名,“NAT”是一般地址转换机制的叫法)。12.4.6节讨论了NAT,本节给出一个正在起作用的nat表的例子。在本节后面的内容里,我们会使用nat表的PREROUTING链来做反IP欺骗的包过滤。
mangle表包含了链可以修改或者改变在NAT和包过滤之外的网络包的内容。虽然mangle表对于做包的特殊处理很方便,比如重新设定IP包的ttl值,但是在大多数工作环境中一般不会用到它。我们在这一节里只讨论filter和nat表,而把mangle表留给读者自己去探索。
构成一条链的每条规则都有一个“target(目标)”子句,它决定了如何处理匹配包。一旦某个包匹配了一个规则,那么它的结局就确定了,不再用其他规则来检查它。虽然iptables内部定义了许多target,但是还可以指定另一条链作为规则的target。
在filter表中的规则可以使用的target子句有ACCEPT、DROP、REJECT、LOG、MIRROR、QUEUE、REDIRECT、RETURN和ULOG。当一条规则落在了ACCEPT上的时候,匹配这条规则的包就可以继续通过。DROP和REJECT都会把它们的包丢弃。DROP是默默地丢弃,而REJECT会返回一则ICMP错误消息。LOG提供跟踪包匹配规则情况的简单办法,ULOG提供了范围更广的日志记录信息。
REDIRECT把包分流到一个代理,而不是直接让它们通过。您可能会用这个功能来迫使站点上的所有Web流量都通过一个Web高速缓存,比如Squid。RETURN终结用户定义的链,类似于子例程调用中的return语句。MIRROR目标在发送包之前交换IP源和目的地址。最后,QUEUE通过一个内核模块把包交给本地用户程序。
Linux防火墙通常是由rc启动脚本中的一系列iptables命令来实现的。各个iptables命令通常采取下列形式之一:
iptables -F chain-name |
第一种形式(-F)把以前所有的规则都从链中清除掉。第二种形式(-P)给链设置一条默认策略(也就是target)。我们建议您使用DROP作为链默认的目标(target)。第三种形式(-A)把当前的说明追加到链上。除非您用-t参数指定了表(table)名,否则您的命令就会被应用到filter表上。-i参数将规则应用到有名字的接口上,-j则标识出目标(target)。iptables还接受许多别的子句,表20.2给出了其中的一部分。
表20.2 iptables过滤器的命令行标志
|
子 句 |
含义或者可能的取值 |
|
-p proto |
匹配协议:tcp、udp或者icmp |
|
-s source-ip |
匹配主机或者网络源IP地址(CIDR的记法也行) |
|
-d dest-ip |
匹配主机或者网络目的地址 |
|
--sport port# |
匹配源端口(注意要用两个短划线) |
|
--dport port# |
匹配目的端口(注意要用两个短划线) |
|
--icmp-type type |
匹配ICMP类型代码(注意要有两个短划线) |
|
! |
否定一条子句 |
|
-t table |
指定一条命令所应用的表(默认是filter表) |
下面我们剖析一个完整的例子。我们假定接口ppp0通往Internet,接口eth0通往内部网络。ppp0的IP地址是128.138.101.4,eth0的IP地址是10.1.1.1,两个接口的子网掩码都是255.255.255.0。这个例子使用无状态包过滤机制来保护IP地址为10.1.1.2的Web服务器,这是保护Internet服务器的标准方法。在这个例子的后面部分,我们将展示如何使用有状态的过滤机制来保护桌面用户。
在您使用iptables之前,必须启用IP forwarding(IP转发)功能,并且确保内核里已经加载了各个iptables模块。要了解启用IP forwarding功能的更多知识,参见28.4节或者12.11.8节。带有iptables的所有发行版本也都有能够完成启用和加载的启动脚本。
我们的第一组规则是对filter表进行初始化。首先,冲洗掉表中所有的链,然后将INPUT和FORWARD链的默认目标设为DROP。和其他任何网络防火墙一样,最安全的策略就是丢弃您没有明确允许的任何包。
iptables -F |
|
iptables -A INPUT -i eth0 -d 10.1.1.1 -p tcp --dport 22 -j ACCEPT |
|
|
iptables -A INPUT -i ppp0 -j LOG |
iptables -A FORWARD -i eth0 -p ANY -j ACCEPT |
要跟踪复杂的网络会话,比如FTP和IRC,必须加载某些内核模块来启动iptables。如果没有加载这些模块,iptables就会简单地禁止那些连接。虽然有状态包过滤器能够提高站点的安全性,但是它们也增加了网络的复杂性。所以在防火墙上实现它之前,要确信您的确需要有状态功能。
调试iptables规则集最好的办法或许就是用iptables -L -v命令了。这些选项会告诉您链里面的每条规则匹配了多少个包。我们经常在想了解有关匹配包的更多信息时,增加带有LOG目标(target)的临时iptables规则。您可以经常通过使用像tcpdump这样的包探测器解决更棘手的问题。
| 回书目 上一节 下一节 |