Username: Password:

Iptables 指南 1.1.19(中文版)(四)
来源:Blog.ChinaUnix.net作者:Blog.ChinaUnix.net 发布时间:2008-04-07 05:23:26

很不错的iptables帮助指南,值得学习和收藏

转from http://iptables-tutorial.frozentux.net/cn/iptables-tutorial-cn-1.1.19.html

Chapter 7. 防火墙配置实例 rc.firewall

在本章里,我们将要建立一个防火墙,并且周详地说明了怎样去阅读、理解他。在这个例子中,我们使用的是最基本的配置,对其工作方式和我们在里面做了些什么都有深入的解释。这个例子应该能在某些方面给您提供基本的思路,比如,怎样解决不同的问题(当然是网络方面的),再如,在真正把脚本应用于工作之前应该考虑些什么,等等。对本例中的变量值做些修改就可能在实际的网络中使用,但不建议您这样做,因为您的网络配置和我在例子中使用的情况可能不相同哦。但只要您有了这个基本的防火墙规则集,很可能只需要少量的调整就能够把他用于实际了。

Note

可能有效率更高的方法来建立规则集,但这个脚本就是为易读而写的,所以每个人都能理解他,即使没有多少BASH脚本编程的知识。


7.1. 关于rc.firewall

好,既然您能从头看到这儿,就说明您已做好一切准备来检查这个脚本了。例子rc.firewall.txt(代码在附录示例脚本的代码里)很大,但没有多少注释。我建议您先大致看看他的内容,留个印象,再来仔细地阅读本章(要有耐心哦)。


7.2. rc.firewall详解

7.2.1. 参数配置

本小节要对照着rc.firewall脚本代码来看。

rc.firewall.txt的第一小节是配置选项,包含的都是一些至关重要的信息,他们是随着您的网络的不同而改变的。比如,每个网络的IP地址都不相同,任何要把他放在这儿。$INET_IP的值应该是在Internet上能使用的才能够,假如您有$INET_IP的话。假如没有,您就要看看 rc.DHCP.firewall.txt这种配置方法了,里面有很多有趣的东西。变量 $INET_IFACE应该指向连接Internet的真实设备,比如eth0、eth1、ppp0、tr0等等。

这个脚本里没有包含任何DHCP或PPPoE的选项,所以这两节是空白的。其他空白的部分,也是这样的原因。之所以保留这些空白,是为了更容易区分这些结构相同而内容不同的脚本。假如您需要这些部分,能够从其他脚本拷贝过来,或您自己写了:)

Local Area Network小节包含的是LAN必须的信息,如连接到LAN的网卡的IP、LAN所用的地址段等。

Localhost configuration小节里的信息在99%的情况下都不要改变,因为我们总是使用127.0.0.1作为地址,也总是把接口命名为lo。紧随其后的是IPTables Configuration,里面只有一个变量,即$IPTABLES。他指定的是iptables程式的准确位置,假如是自己编译安装的话,一般都是/usr/local/sbin/iptables。但更多的发行版都把程式放在另外的地方,如 /usr/sbin/iptables,等等。


7.2.2. 外部模块的装载

首先,我们要使用命令/sbin/depmod -a使module dependencies files保持最新,然后,再装载脚本需要的模块。我们应该始终避免装入无需的模块,假如可能,还要尽力避免装入无所事事的模块,除非您确实需要他们。这样做主要是为了安全,因为每增加一个模块都要花费额外的努力以增加新的规则(这样就容易出漏洞哦)。比如,假如您想支持LOG、REJECT和MASQUERADE target,不要把相应的功能静态地编译进内核,我们使用以下模块来完成:

/sbin/insmod ipt_LOG
/sbin/insmod ipt_REJECT
/sbin/insmod ipt_MASQUERADE
    

Caution

注意,本文使用的脚本都是用类似命令装入模块,这可能会引起装载失败(有错误信息显示)。原因是多方面的,但假如较基本的模块也失败的话,那最大的可能是哪个模块或相应的功能已被静态地编译进内核了。进一步的信息能够看看附录常见问题和解答中的模块装载问题

接下来的一行是装载ipt_owner模块,他的作用是“只允许特定的用户创建特定的连接”。在这个例子中,我没有使用到他,但您可能会用到。比如,您可能只允许root建立FTP 和HTTP连接访问redhat.com,而其他用户都不能够。您也能够只允许您自己使用的用户名和root才能访问 Internet,这样别人会很烦的,但您的安全性在某些方面会有所提高哦,比如,把您当作发起攻击的跳板的情况。关于ipt_owner的更多信息,能够看看章节规则是怎样练成的里的Owner match

在这儿我们也能够为状态匹配安装扩展模块。状态匹配和连接跟踪的任何扩展模块的名字都是这样的: ip_conntrack_*和ip_nat_* 。连接跟踪的helper是一些特别的模块,正是他们告诉了内核怎样恰当地跟踪特别的连接。没有这些helper,内核在处理特别连接的时候,就不知道该查看些什么东西。NAT helper就是连接跟踪helper的扩展,他会告诉内核在包里找什么、怎样转换他们,这样连接才能真正工作起来。比如, FTP是个复杂的协议,他利用包的有效数据部分来发送连接信息。假如一台需要被NAT的机子(译者注:也就是说,机子在一个内网里)连接Internet上的FTP服务器,他就会把自己的内网IP地址放在包的数据区内发送出去,以使FTP服务器能连接到那个地址。但私有地址不能在LAN外使用,所以FTP服务器不知道用他做什么,连接就会断掉了。FTP NAT helper能完成这些连接中任何的地址转换工作,因此FTP服务器就知道该往哪儿连了。同样的事情也发生在DCC的文档传输(这里指的是发送)和聊天上,为了建立连接,IP地址和端口都需要利用IRC协议的数据区发送,而且还要做一些转换工作。没有这些helper的话,FTP和IRC只有一部分工作是正常的,但另一部分根本就无法工作。例如,您能够通过DCC接收文档,但就是不能发送。这个问题的原因在于DCC是怎样建立连接的。当DCC想发送文档时,会告诉接收者您要发送文档,并让他知道要连接到什么地方。假如没有helper,这个DCC连接最终会断开,因为接收者收到的是内网的地址。这样,当他按那个地址连接时,其实就连到和他在同一内网的机子了。那为什么能够接收呢?因为发送者给您的是可在 Internet上使用的IP地址(大部分情况下,IRC服务器都有真实的IP地址)。

Note

假如您在通过防火墙使用mIRC DCC时碰到了问题,但和其他IRC客户沟通很正常,看看附录常见问题和解答里的 关于mIRC DCC的问题 吧。

在这个例子中,我们在这儿装载支持FTP和IRC协议的模块。有关连接跟踪和nat的周详信息,请查看附录 常见问题和解答。在patch-o-matic中,更有H.323 conntrack helper等其他象NAT helper的模块。但为了使用他们,您需要使用patch-o-matic提供的补丁,还需要编译内核。周详的操作信息能够查看章节准备阶段

Note

注意,为了能对FTP和IRC协议做网络地址转换,需要装载ip_nat_ftp和ip_nat_irc。在装载NAT模块之前,您还要载入ip_conntrack_ftp和ip_conntrack_irc模块。NAT模块和conntrack模块以相同的方式被使用,但NAT模块使我们能对这两个协议做NAT。


7.2.3. proc的配置

我们能够使用下面的语句打开IP转发功能(IP forwarding):

echo "1" > /proc/sys/net/ipv4/ip_forward

Warning

注意,何时何地打开这个功能才算合适是值得好好考虑的一个问题。在本文所用的脚本中,我都是在创建IP过滤器(在本文里就是指iptables的过滤规则)之前打开他的。这可能引起这样一种情况,就是在一小段时间内(时间的长短随脚本的复杂程度和机子的性能高低而变化,可能只有一毫秒,也可能会长达一分钟),防火墙能够转发任何包(译者注:因为这时防火墙的过滤规则还没有被装入)。这种情况又会导致安全面的问题,不怀好意的人可能会趁此通过防火墙破坏我们的网络。也就是说,我们应该在创建任何防火墙的规则之后再打开IP转发功能,我这样做只是为了保正任何脚本的兼容性。(译者注:我们在实际应用中一定要注意这一点,尽量不要先开IP转发功能)

万一您使用的是SLIP、PPP或DHCP,也就是说您是动态获取IP的,那还要用下面的命令打开ip_dynaddr

echo "1" > /proc/sys/net/ipv4/ip_dynaddr

假如您还要打开其他的proc选项,也是用类似的方法,但有关那些选项的具体介绍以不是本文的内容,您能够看看其他相关的文章。在附录其他资源和链接里就有一些介绍了内核proc系统的短小精干的文章。假如您在本文中很难找到想要的资料,就能够到附录其他资源和链接去看看,您会有所收获的。

Note

在本文所用的脚本中还包含了一个名为Non-Required proc configuration(非必需的proc配置)的小节。当有什么工作不象您所想象的那么正常时,能够来这儿看看,他能提供给您最基本的一些信息,但在您真正弄明白他们的含义之前不要进行改变。


7.2.4. 规则位置的优化

本节简要地描述了针对脚本rc.firewall.txt,我将怎样选择、使用内建的链链和自定义的链。我选择过的一些路径从这个或那个角度看可能是错误的,我会指出这些情况和问题发生在何时何地。这里还对章节 表和链 做了简要的回顾,希望能给您一点儿提醒,以使您能想起在实际应用中包是怎样表和链的。

为了尽可能地少占用CPU,我们已替换了任何不同的自定义链,和此同时,我把主要的精力放在了安全性和易读性上。我不让TCP包去经历ICMP、UDP和TCP规则的洗礼,而是简单地匹配任何的TCP包,然后让他去一个自定义链中旅行。这种方法并不比让他经历任何的规则开销大。下图能够解释在Netfilter中,外来的包是怎样被处理的(相对于章节表和链的深入讨论,这个图像太粗糙了)。我希望通过上面的解释和下面的图像能让大家明白写这个脚本的目的,周详的注释在后面几节。

利用这个图像,我们能够弄清楚脚本的目的。整个脚本基于这样一种假设,我们有一个局域网,一个防火墙及一个Internet连接,且有一个静态IP地址(相对的是动态地址,他们使用的连接是DHCP、PPP、 SLIP,等等),还想把防火墙作为Internet上的一台服务器来运行某些服务。我们完全信任局域网,因此不能阻塞任何从局域网发出的数据传输。更有一个要优先考虑的事,我们只允许那些被明确说明为能够接受的数据通过。为了做到这一点,我们就要把缺省策略设为DROP。这样,那些没有被明确标识为允许进入的数据就都被阻塞了。

在上面的假设里,我们想让局域网能够访问Internet。因为局域网是被完全信任的,所以我们应该允许任何来自局域网的数据通过。但Internet是不被信任的,所以我们想阻塞从Internet向我们的局域网发起的连接。根据上面的任何假设,我们来考虑考虑需要做什么、无需做什么连同我们想做什么。

首先,我们解决的是局域网要能连接到Internet的问题。那我们就要对任何数据包做NAT操作,因为局域网内的机子都没有真实的IP地址。NAT是在PREROUTING链中完成的,这也是脚本最后创建的那个规则所在的链。这意味着我们必须要在FORWARD链中做过滤工作,否则我们就是允许任何外部的机子都能完全访问局域网了。因为我们完全信任局域网,所以允许任何由内向外的数据通过。由于我们假设Internet上的机子都不能够访问局域网内的机子,所以要阻塞任何由外向内的连接,但已建立的或相关的连接除外,因为他们只是用来回应内网对外网的访问,而不是建立对内网的新连接。

由于资金有限,我们的防火墙只提供了有限的几个服务:HTTP FTPSSHIDENTD。因此,我们要在INPUT链里允许这些协议通过,还要在 OUTPUT链里允许返回的数据通过。我们除了完全信任局域网,也信任loopback和他的IP地址,因此我们要有相应的规则来允许任何来自局域网和loopback的数据通过。但是我们不会允许一些特别的包或包头通过,也不会接受Internet上某一段IP的访问。比如,网段 10.0.0.0/8是为局域网而保留的,一般来说,我们不允许来自他们的包进入,因为这样的包90%都是用来进行欺骗的。但是,在实现这条标准之前,还要注意一个问题,就是有一些ISP在他们的网络里使用的恰恰就是这些地址。 在附录常见问题和解答里有这个问题的进一步说明。

因为我们在防火墙上运行FTP服务,而且想让包经历最少的规则,所以要把处理established和related状态的规则放到INPUT链的顶部。基于同样的原因,我们把这些规则分到子链中。这样,包就能够尽量少地穿越规则,从而节省时间,也能够降低网络的冗余。

在这个脚本里,我们依据不同的协议(如TCP UDPICMP)把包分到子链中。用来匹配 TCP包的链叫做tcp_packets,他能够匹配任何我们允许通过的TCP端口和子协议(如FTP、HTTP等)。我们还要建立一个名为allowed的子链,以便在真正接受“那些使用有效端口来访问防火墙的TCP包”之前,对他们进行附加的检查。至于ICMP包,自有称作 icmp_packets的链来处理。在决定怎样建立这个链时,我考虑到假如我们同意接受ICMP包的类型和代码,就没有必要对他们做附加的检查,所以直接接受他们就行了。最后,UDP包由谁处理呢?当然就是 udp_packets了。假如包是那种允许被接收的类型,就直接放行了。

因为我们的网络很小,所以防火墙也要作为工作站来用。这就需要我们要允许一些特别的协议能和他通信,比如speak freelyICQ

现在,我们来考虑考虑OUTPUT链。因为很信任防火墙,所以我们允许几乎任何离开他的包通过,而没有阻塞任何用户和协议。但我们也不想让人利用这台机子进行IP欺骗,因此我们只放行那些从防火墙本身的IP发出的包。为了实现这一点,我们很可能在ACCEPT链中加入这样一条规则:假如包是由防火墙的IP发出的,就放行,否则,他们就会被OUTPUT链的缺省策略DROP掉。


7.2.5. 缺省策略的配置

在开始写其他规则之前,我们先要用下面的语句建立缺省的策略:

iptables [-P ]

每一条链的策略都是用来处理那些在相应的链里没被规则匹配的包。也就是说,假如有一个包没有被规则集中的任何规则匹配,那策略就有用武之地了。

Caution

要谨慎地配置其他表里的链的策略,因为他们不是用来过滤包的,这就可能引起很怪异的行为发生。


7.2.6. 自定义链的配置

现在,您对我们的防火墙应该已有了一个很清楚的印象,心动了吧。心动不如行动,让我们把他变为现实吧。这一节我们就要小心仔细地创建任何自定义链和链内的规则。

如前所述,我们要建立这几条自定义链:icmp_packetstcp_packetsudp_packets allowed,其中allowed链是由tcp_packets链调用的。任何进入$INET_IFACE的ICMP包都会被重定向到icmp_packets链,TCP包是到 tcp_packets链,那UDP包自然就是udp_packets链了,周详的解释都在 INPUT chain里。创建自定义链的命令还记得吗?很简单哦,只要使用选项-N ,再指定链的名字即可(不要忘了,新建的链都是空的),如下:

iptables [-N chain]

在下面的几节里,我们会详尽地介绍上面创建的每一条链,以使您了解他们包含哪些规则、有什么作用。


7.2.6.1. bad_tcp_packets链

这条链包含的规则检查进入包(incoming packet)的包头是否不正常或有没有其他问题,并进行相应地处理。但事实上,我们使用他只是为了过滤掉一些特别的包:没有配置SYN位但又是NEW状态的TCP包,更有那些配置了SYN/ACK但也被认为是NEW状态的TCP包。这条链能够用来检查任何可能的不一致的东西,比如上面的包或XMAS port-scans等。我们还能够为INVALID状态的包增加一条规则的。

假如您想完全了解无SYN位的NEW状态(NEW not SYN),能够去附录常见问题和解答里看看未配置SYN的NEW状态包一节,他介绍了未配置SYN的NEW状态包通过其他规则的情况。在某些情况下能够允许这种包通过,但99%的情况是我们不想让他们通过。因此,我们会先记录这种包,然后再扔掉他们。

我们拒绝SYN/ACK包以NEW状态进入的原因也是很简单的,深入的说明在附录常见问题和解答NEW状态的SYN/ACK包 里。基本上,我们这样做是出于对其他主机的好意,因为我们为他们预防了序列号预测攻击(sequence number prediction)。


7.2.6.2. allowed链

假如包是从$INET_IFACE进入的,而且是TCP包,那他就要经过tcp_packets 链的检验。假如这个连接就是冲着被允许通过的端口来的,我们还要对他进行一些检查,以确定是否真的要接受他。这些“最后的审判”都是在allowed链里进行的。

首先,我们看看这个包是否是SYN包,假如是,他很可能是新连接的第一个包,我们当然接受了。假如不是,那就看看包是否来自某个ESTABLISHEDRELATED状态的连接,是的话,就接受。ESTABLISHED状态的连接是那种在两个方向上都有流量存在的连接。依据状态机制的观点,这个连接一定处于是ESTABLISHED状态的,因为我们现在能看到这个包,说明以前肯定收到了相应的SYN包。最后一条规则将DROP任何其他的包。当包到达最后这条规则,就几乎意味着任何连接都不会有双向的交流,也就是说,我们不会回应 SYN包。当试图用非SYN包开始新的连接时,包也会走到这条规则。不用SYN包建立新连接没有什么实际的用处,当然,端口扫描要排除在外。就我知道的而言,现在没有什么有用的TCP/ IP程式会使用SYN包以外的包来打开一个TCP连接。因此,我们要把这样的包DROP掉,我有99%的把握说他们是端口扫描用的。


7.2.6.3. 处理TCP的链

tcp_packets链指定了哪些端口可从Internet访问。但我们还要对进入的包做更多的检查,因此,每个包都会被发送到上面提到的allowed链。

-A tcp_packets告诉iptables要在哪条链里增加规则,规则被放在指定链的末尾。-p TCP指定要匹配的是TCP包,-s 0/0说明要匹配的源地址是从网络掩码为0.0.0.0的地址0.0.0.0开始的,换句话说,就是任何的地址。这实际上是默认值,我写出来只是尽可能使您更明白。--dport 21指定目的端口,也就是说假如包是发往端口21的,就会被匹配。假如任何的标准都匹配了,包就要被送往allowed链。

TCP的21号端口也是允许访问的,也就是FTP的控制端口,他能够控制FTP连接,前面提到过,我还允许任何RELATED状态的连接通过。这样,我们也就能够使用PASSIVE(主动)和ACTIVE(被动)的连接了,当然,要事先装载ip_conntrack_ftp模块。假如我们不想再提供 FTP服务,就卸载ip_conntrack_ftp模块,并把$IPTABLES -A tcp_packets -p TCP -s 0/0 --dport 21 -j allowed 这一行从文档 rc.firewall.txt里删掉。

22号端口是SSH使用的。假如您允许外网的怎样人都能通过telnet(使用23号端口)访问您的机子,那您还是使用SSH吧,他的安全性要好很多。注意,您操作的是防火墙,把任何访问权分配给除您自己之外的人都不是什么好主意。防火墙总是应该尽量少地暴露自己。

80是HTTP端口,也就是说您在防火墙上运行了网页服务。假如您不提供网页服务,就删掉这条规则吧。

最后我们还提供了IDENTD服务,端口是113。这个服务对某些协议是必须的,如IRC。注意,假如您NAT一些在内网里的主机的话,软件oidentd也值得一用,他会把 IDENTD请求中继给内网里正确的机子。

假如没有匹配上面任何一条规则,包就会被送回tcp_packets链的父链,也就是把他发到 tcp_packets链的那条规则所在的链。假如您想打开更多的端口,只要对tcp_packets链里的任何一行使用“复制、粘贴大法”,再修改一下端口号即可。


7.2.6.4. 处理UDP的链

假如我们在INPUT链中碰到了UDP包,就把他发送到udp_packets链。在那里,我们只处理UDP包,所以要用-p UDP来指定相应的协议。我们接受来自任何地址的包,故有-s 0/0,这其实就是源地址选项的默认值,但为了更明确,我们还是把他写出来了。此外,我们只接受发往特定端口的包,这些端口是我们想对Internet开放的。注意,我们无需依据发送端的源端口来决定是否打开某个端口,这个工作是由状态机制完成的。假如我们想运行某个使用 UDP端口的服务(如DNS),只要开放相应的端口,其他的端口无需打开。那些处于 ESTABLISHED状态、正在进入防火墙的包在到达包含--state ESTABLISHED,RELATED的规则(这是 INPUT链里那些“处理来自Internet的包的规则”中的第一条规则)之后就会被接受了。

我们不接受外来的以53号端口为目的的UDP包,也就是说,我们不想接受外来的DNS查询。其实,规则已写好了,我只是把他给注释掉了。假如您想把防火墙作为一台允许Internet访问的DNS 服务器,那就把注释符号去掉。

就我个人而言,我会打开123号端口,他对应的协议是network time protocol,简称NTP 。我们能够利用这个协议和某台具备精确时间的时间服务器联系,以配置本机的时间。您们中的大部分可能用不到此协议,所以我也把他注释掉了,虽然我已写出了规则。

我打开了2074号端口,他是某些实时的多媒体应用程式使用的。比如speak freely ,您能够用这个程式通过音箱、麦克风或耳麦和其他人进行实时交谈。假如您无需,就把这条规则注释掉吧。

端口4000相应的协议是ICQ协议,由ICQ使用,世界上使用最广泛的聊天程式之一,“地球人都知道”。Linux上至少有2-3种不同的ICQ克隆。我想不必解释为什么要开放这个端口了吧。(译者注:国产的聊天程式,常见的是QQ(端口8000),现在又有了UC(端口3001)等。)

假如您正在经历日志满天飞的苦恼,这里有两个额外的规则能够使用,当然,这要看是因为什么引起的了。我们这里的第一条规则会阻塞目的端口是135到139的广播包。大部分Microsoft使用者会用到NetBIOS SMB,而他们就使用这些广播包。这条规则能够阻塞任何位于外网的那些Microsoft Network产生的广播包,我们的日志也就能够简洁一些了。第二条规则也是解决日志问题,但是问题的产生者变了,这回是外网的DHCP查询。假如您的外网是由非交换的以太网组成的,在那里客户机能够通过DHCP 得到IP地址,也就是说,假如外网里会有很多DHCP查询广播包,那就启用这条规则吧。

Note

注意,我把最后这两条规则也注释掉了,因为有些人可能想看看相关的记录。假如您正经历“合法日志过多”的痛苦,就试试丢弃那些包吧。其实,在INPUT链中,就在这两条有关日志的规则之前,更有更多这种类型的规则。


7.2.6.5. 处理ICMP的链

现在,我们该决定能够接受哪些ICMP类型了。在INPUT链中,假如ICMP包是从eth0 (即本例的Internet接口)进入的,我们就要把他重定向到icmp_packets 链(前面提到过),以检查是否是能够接受的类型。现在,我只接受三种ICMP包:ICMP Echo requestsTTL equals 0 during transitTTL equals 0 during reassembly。默认不接受其他任何ICMP类型的原因是,几乎任何其他类型的ICMP包都是RELATED状态的,也就是说他们都会被处理 RELATED状态的规则放行。

Note

假如一个ICMP包是用来回应“已存在的包或流”的,那他就是和那些流相关的,也就是说,他的状态是RELATED。更多的信息在章节状态机制里。

现在来解释一下我为什么只接受上面提到的三种ICMP包。Echo Request用来请求echo reply,这个操作主要被用来ping其他的机子,以确定那些机子是否可用。假如没有这一条规则,其他机子将不能通过ping来确定我们是否可用。注意,有些人倾向于删掉此规则,只是因为他们不想被Internet看到。删掉这个规则将会使任何来自Internet的、对我们防火墙的ping都无效,因为防火墙对他们完全没有回应。

允许超时(Time Exceeded,如TTL equals 0 during transit传输期间生存时间为0和TTL equals 0 during reassembly在数据报组装期间生存时间为0)信息进入,我们就能够追踪从本地到某台主机的路径,或在包的TTL为0时,我们能得到回应信息。比如,在我们追踪到某台主机的路径时,会以 TTL = 1的包开始。当他得到第一个路由时,TTL减为0,我们也会得到第一个路由返回的超时信息。然后是TTL = 2的包,我们就会得到第二个路由器返回的超时信息。如此,直到得到我们的目的主机返回的信息。这样,我们就能够从路径上的每一台主机得到一个回应,从而我们能够看到路径上的每一台主机,也就能够知道路径是断在哪台机子了。

完整的ICMP类型列表在附录ICMP类型里。关于ICMP类型的更多信息和用法,我建议您看看下面的文章:

  • Ralph Walden的The Internet Control Message Protocol

  • J. Postel的RFC 792 - Internet Control Message Protocol

Note

注意,我阻塞了任何我不想接受的ICMP包,这对您的网络来说可能会有问题,但在我这里,一切工作正常。


7.2.7. INPUT链

我写的INPUT链大部分是使用其他链来完成这个艰难的工作的。这样做,我们就无需从iptables 装载太多的规则(译者注:这是针对装载INPUT链的规则说的,因为这时其他规则已装载好了),而且他在较慢的机子上也能够工作得很好,但另一方面,这样的机子在高负载时还是会丢弃很多包(译者注:机子慢,就是不行)。之所以能做到这一点,是因为对于大量不同的包,我们通过检查特定的细节来确定他们的类别,再把这些包发送到相应的自定义链去处理。这样,我们能够分割规则集使之包含很少的规则,每个包要经历的规则也就少了。从而,在过滤包时,防火墙的开销也就小多了。

首先,我们要检查进入的tcp包的形态是否是不正常的或我们不想要的。这个工作是这样完成的,我们把任何的tcp包送到bad_tcp_packets链,由其中的规则进行检查,具体的描述在小节bad_tcp_packets链里。

然后,我们开始处理被信任的网络的数据传输。这包括任何来自“连接内网的网卡”的流量,任何来自和发往loopback的流量(要注意,和loopback相对应的IP地址包括了任何分配给防火墙的地址,其中也包括连接Internet的地址)。我们把处理LAN的流量的规则放在防火墙的上部,因为我们的局域网产生的流量要远远多于Internet连接。这样,规则会更有效率,防火墙就能以较小的开销去匹配包,从而网络阻塞的可能性也就减小了,而且也便于我们查看经过防火墙的包主要是什么类型。

下面的一些规则会处理来自Internet的信息,在接触这些规则之前,有一个相关的规则,我们可用他来减少一些开销。这是个处理状态的规则,他允许任何处于状态ESTABLISHEDRELATED且发往 Internet接口的包进入。在allowed链中有一个和此类似的规则(译者注:实在是多余,建议大家把他拿掉吧)。顺序上,当然是INPUT链里的规则先处理包了。然而,在allowed链里保留--state ESTABLISHED,RELATED规则还是有一些原因的,比如,方便某些人想剪切此功能,粘贴到其他地方。

INPUT链里,我们会把从$INET_IFACE进入的任何TCP包发往tcp_packets链,类似地,把UDP包发往udp_packets链,把 ICMP包发往icmp_packets链。一般说来,防火墙碰到的最多的包是TCP包,其次是 UDP包,最后是ICMP包。但要注意,这只是一般情况,对您可能不适用。相同的规则因为顺序不同,或说逻辑不同,效率会有很大的差别。假如规则集写得不好,即使只有100条规则,而且有100mbit的网卡,就算是Pentium III的机子也会吃不消的。所以您自己写规则集时一定要注意这一点。

这里有一条被注释掉了规则,万一在我们的防火墙外部有一些Microsoft网络,我们能够启用他来解除日志过多的烦恼。Microsoft的客户机有个坏习惯,就是向地址224.0.0.0/8发送大量的多播包。因此我们要有这条规则来阻塞那些包,以免我们的日志被他们填满。还记得吗?udp_packets链里也有两条类似的规则。忘了的话,就到处理UDP的链看看吧。

在其他的包被INPUT链的策略处理之前,我们会把他们记录下来,以便查找可能的问题或bug:他可能就是我们不想允许他进入的那种包,也可能是对我们做了什么坏事的用户,还可能是防火墙的问题,如我们阻塞了应该被放行的包。我们要了解任何的情况,这样问题才能得以解决。我们每分钟最多记录3个包,因为我们可不想让日志里记载的都是废话。为了容易辨别包的来源,我们还对任何的记录配置了前缀。

任何没被上面的规则处理的包都会被策略DROP掉。策略的配置在本章的小节缺省策略的配置里,距离我们已很远喽。


7.2.8. FORWARD链

在本例中,FORWARD链包含的规则很少。首先,我们会把任何的包发往bad_tcp_packets 链。此链我们前面提到过多次,他能够被多条链调用,其实他也就是为这个目的而设计的。

之后就是FORWARD链的主要规则了。第一个允许任何来自$LAN_IFACE的数据通过,没有任何限制,也就是说,我们的LAN可自由地访问Internet。第二个允许ESTABLISHEDRELATED状态的包能通过防火墙。换句话说,就是任何对我们的内网发出的连接的回应都能够返回局域网。为了使我们的内网能访问Internet,这些规则是必须的,因为我们在前面已把FORWARD链的策略设为DROP了。这样配置规则也是很聪明的,因为他在确保局域网能够访问Internet的同时阻止了Internet对局域网的访问。

最后我们也有一个处理日志的规则,用来记录没被上面任何规则匹配的包。这样的包很可能是形态不正常的或是其他问题,比如可能是黑客攻击。这个规则和INPUT链中的那个类似,只是前缀不同,这里用的是:"IPT FORWARD packet died: "。前缀主要用来分离日志的记录,便于我们查找包的来源和包头的一些信息。


7.2.9. OUTPUT链

除了我几乎没有人把防火墙还当作工作站来使用,但正因为这样,我允许几乎任何从防火墙的IP(包括 LOCALHOST_IP$LAN_IP$STATIC_IP )出发的数据,而阻塞其他情况。因为其他任何情况都可能被人以某种方式欺骗。最后的规则还是用来记录那些要被策略DROP掉的包。这样,我们就能够了解他们,继而能够对产生的问题(可能是具备威胁性的错误,或是用来进行欺骗的包)采取行动。


7.2.10. PREROUTING链

顾名思义,PREROUTING链(nat表的)是在路由之前做网络地址转换工作的。然后,包再经过路由,就会被送到filter表的INPUTFORWARD链。我们在这里讨论这个链的唯一原因是,我们觉得有责任再次指出您不应该在此链中做任何过滤。PREROUTING链只会匹配流的第一个包,也就是说,这个流的任何其他的包都不会被此链检查。事实上,在这个脚本中,我们根本没有用到PREROUTING 链。假如您想对一些包做DNAT操作,例如,您把web server放在了局域网内,这里就是您放置规则的地方。有关PREROUTING链的周详信息在章节表和链中。

Caution

千万注意,PREROUTING链只能做网络地址转换,不能被用来做任何过滤,因为每个流只有第一个包才会经过此链。


7.2.11. POSTROUTING链

我们最后的任务应该是构造网络地址转换,对吧?至少对我来说是的。我们在nat表的 POSTROUTING里只加入了一条规则,他会对任何从Internet接口(对我来说,这是eth0)发出的包进行NAT操作。在任何的例子脚本里,都有一些变量,他们要给以正确的配置。选项-t指定要在那个表里插入规则,这里是nat表。命令-A说明我们要把规则添加到 POSTROUTING链末尾。-o $INET_IFACE指定要匹配任何从接口INET_IFACE出去的包,这里我们使用的是eth0。最后,我们把target配置为SNAT。这样,任何匹配此规则的包都会由SNAT target处理,之后,他们的源地址就是Internet接口的地址了。不要忘了SNAT可是一定要有IP地址的,用--to-source 来配置哦。

在这个脚本中,我们选择SNAT而不用MASQUERADE是有原因的。主要的原因是我们的防火墙有静态IP地址,使用SNAT会更快更有效。更有一个原因是我们要在这个例子中展示他的作用连同怎样使用他。假如您没有静态的IP地址,要想实现SNAT,还是使用MASQUERADE为好,因为他简单易用,而且他能够自动获得IP地址。当然,电脑的消耗会多一点,但假如您使用DHCP,这样做是很值得的。假如您想了解MASQUERADE target的表现,应该看看脚本rc.DHCP.firewall.txt


Chapter 8. 例子简介

本章的目的是对指南提到的每个脚本都给以简单明了的说明,连同提供一个关于这些脚本的框架,描述他们提供的服务。这些脚本不是任何情况都能用的,他们可能并不符合您的意图。也就是说,为了能满足您的需要,还是要取决于您自己。在这方面,下面的内容可能会给您很大的帮助。第一小节介绍了这些脚本的结构,您会发现我们在这些脚本里使用的处理方式还是比较容易的。


8.1. rc.firewall.txt脚本的结构

本指南任何的脚本都是依据一个特定的结构来写的。理由嘛,就是这样能够使他们彼此相似,便于我们查找不同之处。本章将要对这个结构做一个很好的说明,而且还会简单地阐述这些脚本为什么会按照现在这种样子来写,连同我为什么选择一直使用这种结构。

Note

注意,即使我选择了这种结构,您也不一定非要用他,对您来说,他可能并不是最好的。我选择他只是因为他易读,而且能很好地符合我的逻辑。


8.1.1. 脚本结构

这就是本指南任何脚本遵循的脚本结构。假如有不同于此的地方,可能就是我出错了,除非我特意说明为什么要打破这种结构。

  1. Configuration ?? 首先是个配置选项区,里面的变量在脚本中会用到。几乎任何脚本(shell-script)的第一部分都是配置选项区。

    1. Internet ?? 有关Internet连接的配置。假如我们没有任何Internet连接,这一部分就能够跳过去。注意,相比我们列出来的,这一部分可能会包含更多小节,虽然我们这里只有了了几个,但足够应对我们已有的各种Internet连接了。

      1. DHCP ?? 假如脚本用到了DHCP,我们就要在此添加相应的配置。

      2. PPPoE ?? 假如想把脚本用于PPPoE连接,就要在此添加相应的配置。

    2. LAN ?? 假如防火墙后有局域网,就要使用这里的配置了。大部分情况下都会用到这儿,因为局域网几乎总是存在的。

    3. DMZ ?? 对非军事区(DMZ zone)的配置。大部分脚本不会用到这个配置,因为这些脚本针对的主要是一些普通的家庭网络,或小企业的网络。

    4. Localhost ?? 本地(local-host)的有关配置。虽然我把他们写成变量的形式,但一般不会被改变,也不应该有什么理由要改变他们。

    5. iptables ?? 有关iptables的配置。大部分情况下,这里只配置一个变量,用来指向iptables程式的位置。

    6. Other ?? 假如更有什么信息,首先应该把他们放在相应的小节里,实在没有相应的小节,就放这儿吧。

  2. Module loading ?? 脚本应该维护一个模块列表。他分为两部分,第一部分包含必需的模块,同时第二部分要包含不必要的模块的列表。

    Note

    注意,这些模块可能会提高安全性,或为管理者、客户添加某些服务,更有一些模块不是必需的,但他们可能也被加入了列表。但是,在本例中,我已注意了这个问题。

    1. Required modules ?? 这里装载的是必要的模块,他们可能会提高安全性或为管理者、客户增加某些服务。

    2. Non-required modules ?? 这里列出的是不必要的模块,所以他们都被注释掉了。假如您用到了他们提供的功能,就能够启用他们。

  3. proc configuration ?? 这儿关心的是有关proc系统的配置。假如一些选项是必须的,我们就启用他,假如不是,就把他注释掉。大部分有用的proc配置都列在这儿了,但远远不是全部的。

    1. Required proc configuration ?? 包含了使脚本能正常工作的任何必需的proc配置,他也能够包含一些能提高安全性或为管理者、客户增加特定服务的选项。

    2. Non-required proc configuration ?? 这里提到的选项不是必需的,虽然他们可能很有用。因此,我把他们都注释掉了。当然,这里并没有包括任何这样的选项。

  4. rules set up ?? 现在,应该添加规则了。我把任何的规则都明确地分配到了和表、链相应的小节里。任何自定义的规则都写在系统内建的链之前(译者注:当然要写在前面了,因为后面要调用他们哦)。另外,我是按照命令iptables -L输出的顺序来安排此脚本里表和链的出现顺序的(译者注:这样,便于我们查看哦)。

    1. Filter table ?? 首先是filter表,而且我们先要配置策略。

      1. Set policies ?? 为任何系统内建的链配置策略。通常,我会配置 DROP,对于允许使用的服务或流会在后面明确地给以ACCEPT。这样,我们就能够方便地排除任何我们不想让人们使用的端口。

      2. Create user specified chains ?? 在这里创建任何以后会用到的自定义链。假如没有事先建立好,后面是不能使用他们的,所以我们要尽早地建立这些链。

      3. Create content in user specified chains ?? 建立自定义链里使用的规则。其实您也能够在后面的某个地方写这些规则,之所以写在这儿,唯一的原因是这样做规则和链会离得近些,便于我们查看。

      4. INPUT chain ?? 创建INPUT链的规则。

        Note

        从这里开始,我就是遵循iptables -L的输出格式来创建规则的,这样做的唯一原因就是为了便于阅读,避免混淆。

      5. FORWARD chain ?? 为FORWARD链创建规则。

      6. OUTPUT chain ?? 为OUTPUT链创建规则。其实,在这里要建的规则很少。

    2. nat table ?? 在处理完filter表之后,该配置nat表了。我们这样做是有一定原因的。首先,我们不想太早地打开转发机制(译者注:注意,filter表设定的是过滤机制,而不是转发)和NAT功能,因为他们可能导致数据会在错误的时间(也就是这样的时刻:我们打开了NAT,但过滤规则还没有运行)通过防火墙。更有,我把nat表看作是围绕filter表的一个层。也就是说,filter表是核心, nat表是他外部的一个层,mangle表是第二层。从某些观点来看,这可能有点不对,但也八九不离十了。

      1. Set policies ?? 和filter相同,我们先来配置策略。一般说来,缺省的策略,即ACCEPT,就很好。这个表不应该被用来做任何过滤,而且我们也不应该在这儿丢弃任何包,因为对我们假设的网络情况来说,可能会发生一些难以应付的事情。我把策略设为ACCEPT,因为没有什么原因不这样做。

      2. Create user specified chains ?? 在这儿创建nat表会用到的自定义链。一般情况下,我没有任何规则要在这儿建立,但我还是保留了这个小节,以防万一罢了。注意,在被系统内建链调用之前一定要建好相应的自定义链。

      3. Create content in user specified chains ?? 建立自定义链的规则。

      4. PREROUTING chain ?? 要对包做DNAT操作的话,就要用到此链了。大部分脚本不会用到这条链,或是把里面的规则注释掉了,因为我们不想在不了解他的情况下就在防火墙上撕开一个大口子,这会对我们的局域网造成威胁。当然,也有一些脚本默认使用了这条链,因为那些脚本的目的就是提供这样的服务。

      5. POSTROUTING chain ?? 假如使用SNAT操作,就要在此建立规则。您可能有一个或多个局域网需要防火墙的保护,而我就是依据这样的情况来写此脚本的,所以这个脚本中使用的 POSTROUTING链是相当实用的。大部分情况下,我们会使用SNAT target,但有些情况,如PPPoE,我们不得不使用MASQUERADE target。

      6. OUTPUT chain ?? 不管什么脚本都几乎不会用到这个链。迄今为止,我还没有任何好的理由使用他,假如您有什么理由用他了的话,麻烦您把相应的规则也给我一份,我会把他加到本指南里的。

    3. mangle table ?? 最后要做的就是处理mangle表了。通常,我不会使用这个表,因为一般情况下,他不会被任何人要到,除非他们有什么特别的需要,比如为了隐藏一条连接后的多台机子,我们要统一配置TTL或TOS等。在这个脚本里,此表是空白的。但在此指南中还是有个小小的例子说明了mangle表的用处。

      1. Set policies ?? 配置策略。这里的情形和nat表几乎完全相同。这里不应该做过滤,也不应该丢弃任何包。在任何脚本里我都不会把mangle表的策略设为其他的值,也不鼓励您这样做。

      2. Create user specified chains ?? 建立自定义链。我几乎不会用到这个链,所以没有建立任何规则。保留此小节,只是已备后用。

      3. Create content in user specified chains ?? 建立自定义链的规则。

      4. PREROUTING ?? 本指南的任何脚本都未在此链建立规则。

      5. INPUT chain ?? 本指南的任何脚本都未在此链建立规则。

      6. FORWARD chain ?? 本指南的任何脚本都未在此链建立规则。

      7. OUTPUT chain ?? 本指南的任何脚本都未在此链建立规则。

      8. POSTROUTING chain ?? 本指南的任何脚本都未在此链建立规则。

这应该能够较周详地解释每个脚本的结构是怎样的连同他们为什么要使用这个结构了。

Caution

注意,上面的描述其实还是很简单的,应该被看作一个摘要,他简要地解释了脚本为什么要按照这种松散的结构来写。千万注意,我可没有说过这种结构是唯一的、最好的。


8.2. rc.firewall.txt

脚本rc.firewall.txt是核心,第七章防火墙配置实例 rc.firewall对他已做了很周详的解释,其他的脚本都是以他为基础得到的。这个脚本主要是针对具备两个连接的家庭网络而设计的,如一个局域网连接,一个Internet连接。我们假设的情况是您有一个静态IP地址,无需DHCPPPP SLIP或其他什么协议为您动态分配IP。假如您想要的恰恰是使用这些协议的脚本,就到rc.DHCP.firewall.txt看看吧。

脚本rc.firewall.txt要完全发挥作用,系统必需要有下面列出的功能,您能够把他们编译进内核,也能够编译成模块。假如您改变了脚本,就要加入相应的功能模块或把他们编进内核。

  • CONFIG_NETFILTER

  • CONFIG_IP_NF_CONNTRACK

  • CONFIG_IP_NF_IPTABLES

  • CONFIG_IP_NF_MATCH_LIMIT

  • CONFIG_IP_NF_MATCH_STATE

  • CONFIG_IP_NF_FILTER

  • CONFIG_IP_NF_NAT

  • CONFIG_IP_NF_TARGET_LOG


8.3. rc.DMZ.firewall.txt

脚本rc.DMZ.firewall.txt所针对的情况是这样的:有一个可信任的内网,一个DMZ,更有一个Internet连接。这里的DMZ是通过配置一对一的NAT 操作得到的,他需要IP别名(就是在一块网卡上配置多个IP地址)的支持。我们更有其他的方法来实现 DMZ:假如您有一个整个的网段,可划分子网,然后把某个子网分给DMZ,再为防火墙配置相应的内网和外网 IP地址(译者注:第一种方法是针对有多个网段的情况,即内网一个网段,DMZ一个网段,第二种方法是把一个网段划分成几个子网,这样就和第一种情况相同了)。注意,这种方法会多消耗两个IP,一个是网络地址,一个是广播地址(译者注:具体细节请上网搜索子网划分的相关信息,这个指南并不包含此类信息)。以上两种方法用哪一个就要您自己决定了。本指南会给您实现防火墙和NAT的手段或叫做技术,但具体怎样去做,没有完全的说明,因为这已超出本文的范围了。

这个脚本需要以下模块,也可能他们已被编译进内核了。

  • CONFIG_NETFILTER

  • CONFIG_IP_NF_CONNTRACK

  • CONFIG_IP_NF_IPTABLES

  • CONFIG_IP_NF_MATCH_LIMIT

  • CONFIG_IP_NF_MATCH_STATE

  • CONFIG_IP_NF_FILTER

  • CONFIG_IP_NF_NAT

  • CONFIG_IP_NF_TARGET_LOG

从图中能够看出,此脚本假设您有两个内网,一个是可信任的内网,使用地址192.168.0.0/24,另一个是 DMZ(我们正是对他做一对一的NAT),使用地址192.168.1.0/24。假如有人从Internet向我们的DNS_IP发送一个包,我们就要对他使用DNAT,之后,此包的目的地址就指向DMZ 里的DNS服务器了,他也就能够到达真正的DNS服务器。否则,DNS服务器不会看到这个包,也就没有应答之说了。下面是实现上述DNAT功能的语句:

$IPTABLES -t nat -A PREROUTING -p TCP -i $INET_IFACE -d 
$DNS_IP --dport 53 -j DNAT --to-destination $DMZ_DNS_IP
    

我们能够看出,这个规则要放在nat表的PREROUTING链中,包要满足的条件是:使用 TCP协议且使用53号端口,从接口$INET_IFACE进入,而且要以$DNS_IP为目的。被匹配的包要交给DNAT target来处理,他会把包的目的地址改为由--to-destination指定的地址$DMZ_DNS_IP。这就是 DNAT的工作流程。当相应的应答包被发送到防火墙时,会自动地被un-DNAT。

现在,您应该完万能够读懂这个脚本了。假如有什么您不明白的东西在脚本的其他部分没有被用到,那可能就是我的错误了,要告诉我哦。


8.4. rc.DHCP.firewall.txt

脚本rc.DHCP.firewall.txt适用于那些使用DHCPPPPSLIP连接Internet的情况,他和原始的脚本rc.firewall.txt几乎相同,主要的区分在于这里不再使用变量STATIC_IP。原因很简单了,就是他不能和动态的IP一起使用。此脚本相对于原始脚本的改变是很少的,但还是有一些人发信问我做了什么改变。经过大家的考验,这个脚本应该是个很好的解决方案了。

他需要如下功能模块。

  • CONFIG_NETFILTER

  • CONFIG_IP_NF_CONNTRACK

  • CONFIG_IP_NF_IPTABLES

  • CONFIG_IP_NF_MATCH_LIMIT

  • CONFIG_IP_NF_MATCH_STATE

  • CONFIG_IP_NF_FILTER

  • CONFIG_IP_NF_NAT

  • CONFIG_IP_NF_TARGET_MASQUERADE

  • CONFIG_IP_NF_TARGET_LOG

我做的改变主要是删除了变量STATIC_IP连同和他相关的任何东西。以前,主要的过滤工作是基于变量STATIC_IP的,现在是INET_IFACE 了。也就是说,在这个脚本里,我们不再把-d $STATIC_IP作为过滤的条件,而是用 -i $INET_IFACE。这几乎是唯一的改变,也是必需的改变。

可还是有一些问题要考虑。现在,我们不能再在INPUT链依据某些条件,比如--in-interface $LAN_IFACE --dst $INET_IP来进行过滤(译者注:因为这时已无固定的INET_IP)。这强迫我们只能基于Internet接口进行包的过滤,在这种情况下,内网必须访问那个可变的 Internet的IP。这会出现一些问题,有个例子能够说明这一点,就是我们在防火墙上运行HTTP服务。假如我们访问这个网站(其中,主页包含了一个指向HTTP服务器的静态连接,这可能是某个动态的DNS解决方案),问题就暴露了。经过NAT操作的机子会向DNS查询HTTP服务器的IP,然后再试着访问这个IP。万一我们是基于接口和IP做的过滤,这台机子就不能访问到HTTP了,因为INPUT链会 DROP掉这个包(译者注:还是因为Internet接口的IP不固定)。在某种情况下,这也会发生在您有静态IP的时候,但在那种情况下,我们能够增加一条规则,以检查LAN接口的包是否是发往INET_IP的,若是,则ACCEPT

假如您看过以前的内容,得到或写一个能够获取动态IP的脚本可能会是个解决问题的好办法。比如,我们能够写一个脚本,他紧随着Internet连接的启动而运行,而且他能从命令ifconfig的输出中提取IP,再把这个IP赋给某个变量。较好的办法是使用一些程式自带的脚本,如 pppd带的脚本ip-up。也有一些网站,如linuxguruz.org,提供了很多有用的脚本,您能够在附录其他资源和链接找到他的链接。

Note

这个脚本比rc.firewall.txt的安全性要差一点。我明确地建议您尽可能使用后者,因为前者的开放性大了点,所以外部攻击的威胁就大了。

更有一种方法可获得IP,就是在脚本里加上类似这样的语句:

INET_IP=`ifconfig $INET_IFACE | grep inet | cut -d : -f 2 | 
cut -d ’ ’ -f 1`
    

上面这句话的作用是从ifconfig的输出里提取接口$INET_IFACE的IP,再赋给$INET_IP。更好的办法是使用脚本 retreiveip.txt。但要注意,这个方法可能会引起一些不正常的情况,比如使防火墙和内网之间已有的连接停止。下面就说明一下最常见的问题。

  1. 假如这个脚本的代码是在另一个脚本内运行的,而那个脚本又是由PPP daemon启动的,就会因为NEW not SYN rules(具体信息查看未配置SYN的NEW状态包)的原因而挂起所以当前活动的连接。假如您删掉那个规则,可能会没有事,但还是不保险。

  2. 假如您不想改变已有的规则,而又要添加或删除规则,还要不损害已有的规则,这就没法做了。比如,您又想阻塞任何局域网里的机子访问防火墙,又想让他们能控制防火墙上的PPP daemon,假如不删除那个用来阻塞的规则,怎么能完成这样的事?

  3. 事情可能也不必这么复杂,就像上面说的,这会导致一些安全问题。但假如这个脚本能保持简单,维持规则的顺序和发现问题都是很容易的。


8.5. rc.UTIN.firewall.txt

脚本rc.UTIN.firewall.txt适用于这样的情况:我们不信任任何和防火墙连接的网络,包括内网。我们只允许内网使用POP3HTTPFTP。至于从Internet来的连接,权限和其他脚本相同。

此脚本需要以下功能模块。

  • CONFIG_NETFILTER

  • CONFIG_IP_NF_CONNTRACK

  • CONFIG_IP_NF_IPTABLES

  • CONFIG_IP_NF_MATCH_LIMIT

  • CONFIG_IP_NF_MATCH_STATE

  • CONFIG_IP_NF_FILTER

  • CONFIG_IP_NF_NAT

  • CONFIG_IP_NF_TARGET_LOG

这个脚本遵循的原则是不要相信任何人,包括我们自己的员工。这是个令人悲痛的现实,大部分破坏和攻击确实是来自我们内部的。这个脚本只是在加强防火墙方面给了您一个例子。他和 rc.firewall.txt并没有太多的不同,只是少了一些允许通行的规则。


8.6. rc.test-iptables.txt

这个脚本用来测试iptables里任何的链。当然,这要根据您的配置情况做些操作,如打开ip_forwarding或是配置masquerading,等等。只要您的安装了基本的 iptables,就能够使用他。其实这个脚本只使用了LOG,以便能记录任何的ping请求和应答。通过这种方式,我们就能够了解哪些链被穿越了连同被穿越的顺序。使用方法如下,先运行这个脚本,再发布一个ping命令,如:

ping -c 1 host.on.the.internet

    

然后用命令tail -n 0 -f /var/log/messages就可看到用了哪些链连同是什么顺序,除非记录因某些原因被替换了。

Note

此脚本仅仅是为测试而写的。也就是说,不要使用类似这样的规则,他记录某一类包的任何信息,这会很快地占满您的日志分区,而且他会成为一个有效的DoS攻击。他还可能导致在最初的DoS攻击之后,无法记录真正的攻击信息。


8.7. rc.flush-iptables.txt

rc.flush-iptables.txt不应该被称作脚本,他只是重置并清空任何的表、链。他先把filter表的INPUTOUTPUT FORWARD链的策略设为缺省的ACCEPT,然后是nat表的PREROUTING POSTROUTINGOUTPUT链。我们这样做就不必为被关闭的连接和没有通过的包而操心。这个脚本就是为防火墙配置和除错用的,因此我们只关心打开任何的东西并恢复他们的缺省值就行了。

之后,我们清空filter表里任何的链,紧接着是NAT表的。这样,就不会有什么不应该存在的规则了。这个做完后就该删除filter表和NAT表里的自定义链了。这时,脚本的工作就应该完成了。当然,假如您用到了mangle表,能够在这个脚本里添加相应的清空规则。(译者注:其实作者已这样做了)

Note

最后再说明一下,有些人写信建议我把这个脚本放到rc.firewall脚本里面,而且是用Red Hat Linux脚本的语法,这样当rc.firewall启动时,这个脚本也能够启动。但我不会这样做的,因为这是个指南,主要是用来学习iptables的使用方法的,不应该有过多的shell脚本特有的语法。加入shell脚本特有的语法会使阅读的难度大大增加,这就远离了我的初衷。这个指南是按照易读的标准来写的,以后我会继续这样做。


8.8. Limit-match.txt

这个脚本是用来测试limit match的,也会让您明白limit match是怎样工作的。装入这个脚本,再用不同的时间间隔发送ping数据包,能够看出哪个包能够通过,这些包又是以什么频率通过的。您应该能够看出,在limit的burst值再次到达之前,任何的echo replies都会被阻塞。


8.9. Pid-owner.txt

这个脚本说明了怎样使用PID owner match。他其实什么都没做,但您能够运行一下,命令iptables -L -v的输出会说明他确实匹配了些东西。


8.10. Sid-owner.txt

说明SID owner match怎样使用的一个例子。同样,他也是什么都没做,但您能够运行一下,命令iptables -L -v的输出会说明他确实匹配了些东西。


8.11. Ttl-inc.txt

一个小小的例子,说明了怎样隐藏我们的防火墙或路由器,以使跟踪路由程式看不到,这样就能够对可能的攻击者隐藏很多信息。


8.12. Iptables-save ruleset

这只是个输出的例子,他在规则的保存和恢复里被用来说明 iptables-save命令是怎样使用的。所以,他没有任何用处,只是个参考而已。


附录 A. 常用命令详解

A.1. 查看当前规则集的命令

查看当前正在使用的规则集是个十分常用的操作,使用iptables的什么命令还记得吗?我们可是在规则是怎样练成的这一章里介绍过啊,虽然到时说得简单了点。再复习一下吧,命令语法如下:

iptables -L

这个命令会尽可能地以易读的形式显示当前正在使用的规则集。比如,他会尽量用文档/etc/services里相应的名字表示端口号,用相应的DNS记录表示IP地址。但后者可能会导致一些问题,例如,他想尽力把LAN的IP地址(如192.168.1.1)解析成相应的名字。但192.168.0.0/16这个网段是私有的,也就是说,他只能用在局域网里,而不能在Internet里使用,所以他不会被Internet上的DNS服务器解析。因此,当解析这个地址时,命令就似乎停在那儿了。为了避免这种情况的发生,我们就要使用选项:

iptables -L -n

假如您想看看每个策略或每条规则、每条链的简单流量统计,能够在上面的命令后再加一个verbose标志,如下:

iptables -L -n -v

不要忘了,iptables -L命令还能够查看nat表和mangle表的内容哦(更不要忘了,默认的表是filter),只需要使用-t选项,比如我们只想看nat表的规则,就用下面的命令:

iptables -L -t nat

/proc里,可能更有一些文档您会感兴趣。比如,您能够在连接跟踪记录表里看到当前有哪些连接。这个表包含了当前的任何连接,您还能够通过他了解到每个连接处于什么状态。要注意,这个表是不能编辑的,即使能够,也不应该更改他。能够用下面的命令查看这个表:

cat /proc/net/ip_conntrack | less

此命令会显示当前任何被跟踪的连接,但要读懂那些记录可是有些难度哦。


A.2. 修正和清空iptables的命令

即使您把iptables弄的一塌糊涂,我们也有很有效的命令来处理,而不必重新启动电脑。我接到过很多关于这个问题的询问,所以我想最好在这儿回答一下。假如您增加的规则有问题,要想删掉他,只要把命令中的-A改为-D即可。这样,iptables就会找到那个错误的规则并删掉他,但假如在您的规则里有好几条同样的规则,他只能删掉找到的第一条。假如您不想这样的事情发生,那就试试用序号来删除。如,您想删除INPUT链的第10条规则,能够使用 iptables -D INPUT 10

更有一种情况,就是要清空整个链,这就要使用选项-F。比如,我们要清空整个 INPUT链,使用的命令就是iptables -F INPUT。但是要注意,选项-F并不改变链的缺省策略。所以,假如被我们清空的那条INPUT链的策略是DROP,他还是会阻塞任何的包。那怎么才能重置策略呢?还记得策略DROP是怎样配置的吧,还是用那个方法啊。比如,我们把INPUT链的策略改为ACCEPT,就用iptables -P INPUT ACCEPT

我已写了一个用来清空并重置iptables的脚本,叫做rc.flush- iptables.txt(附录里有他的代码),在您写自己的防火墙脚本时,很可能会用到。但假如您在mangle表里乱试乱改而导致问题的话,这个脚本就帮不上忙了。因为在脚本rc.firewall.txt里,我没有用到mangle表,所以在 rc.flush-iptables.txt里也就没有添加相应的恢复功能。


附录 B. 常见问题和解答

B.1. 模块装载问题

装载模块时,您可能会碰到几个问题,比如,有错误提示说明没有您指定名字的那种模块:

insmod: iptable

喜欢本文,那就收藏到:

    Del.icio.us Google书签 Digg Live Bookmark Technorati Furl Yahoo书签 Facebook 百度搜藏 新浪ViVi 365Key网摘 天极网摘 和讯网摘 博拉网 POCO网摘 添加到饭否 QQ书签 Digbuzz我挖网
相关评论  我也要评论
还没有关于此文章的相关评论!
  • 昵称: (为空则显示guest)
  • 评论分数: ★ ★ ★★★ ★★★★ ★★★★★
  • 评论内容:(不能超过250字,需审核后才会公布,请自觉遵守互联网相关政策法规。
  • 导航
    赞助商
    文章类别
    订阅