分类: LINUX
2005-05-23 12:09:40
oan@frozentux.net
Copyright © 2001-2003 by Oskar Andreasson
本文在符合 GNU Free Documentation 许可版本1.1的条件下,可以拷贝、分发、更改,但必须保留绪言和所有的章节,如印刷成书,封面要包括“原著:Oskar Andreasson”,且书背不准有文字。本文附录有 “GNU Free Documentation License”的详细内容。
文中的所有脚本均置于GNU General Public License版本2下,可以自由地分发、更改。
给出这些脚本是希望它们有所作用,但没有任何保证,也没有商业可用性或某些特殊用途的内在保证。参见GNU General Public License
本文附带一份GNU General Public License,在章节“GNU Free Documentation License”中,如没有,请联系the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111- 1307 USA
首先,我要把本文献给我那wonderful的女友Ninel(她给我的帮助远远胜过我给她的):希望我能让你幸福,就象你给我的。( 译者注:我没有想到合适的词能表达作者女友的wonderful,你就自己想去吧。还有,不知他们现在是否结婚了:) )
其次,我要把这篇文章献给所有Linux的开发者和维护者,就是他们完成了令人无法相信的艰难工作,使这么优秀的操作系统成为可能。
译者sllscn是里的“Linux 新鲜社员”,一个Linux爱好者,在实际工作中使用iptables构造防火墙时,发现有关iptables的中文资料太少,故而不得已参考英文版的材料。为了今后参考的方便,也为了广大使用者,不怕自己的英文水平太差,翻着字典翻译了本文。翻译只为了能看懂,达不到“好看”,勿怪!
第一章序言部分除了第三小节介绍的术语要看看,其他都没什么。第二章对想要亲自编译iptables的兄弟们是有些帮助的。第三、第四两章可以使我们理解、掌握iptables工作方式和流程。第五章和第六章是iptables命令使用方法的详细介绍。第七章与第八章是实例讲解,对我们编写自己的规则很有指导意义的,强烈建议你看一看。附录里有一些资源链接是很好的,相信你一定会喜欢。
因为术语的缘故,目录部分有一些未翻译,但正文的内容都翻译了。附录F是本文的更新历史,附录G是GNU Free Documentation License,附录H是GNU General Public License,它们对理解 iptables没有什么作用,故未翻译。
在阅读本文时,你可能会发现有重复的地方,这不是原作者的水平不高,反而恰恰是他为我们考虑的结果。你可以把这篇文章的任何一章抽出来阅读,而不需要反复地参照其他章节。在此,再次向作者表示敬意!
因译者水平有限,对原文的理解不敢保证完全正确,如有意见或建议,可以联系译者slcl@sohu.com
郑重声明:翻译得到了原文作者Oskar Andreasson的许可。对于本文(不是原文),可自由使用、修改、传播、转载,但对以盈利为目的使用,保留所有权利。
< div="" />我的局域网里有很多“年老的”计算机,他们也想连接到Internet上,还要保证安全。做到这一点, iptables是的ipchains的一个很好的升级。使用ipchains你可以通过丢弃所有“目的端口不是特定端口” 的包来建立一个安全的网络。但这将导致一些服务出现问题,比如被动FTP,还有在IRC中流出的DCC。它们在服务器上分配端口,并告知客户端,然后再让客户连接。 但是,iptables的代码中也有一些小毛病,在某些方面我发现这些代码并没有为作为完整的产品发布做好准备,但我仍然建议使用ipchains或更老的 ipfwadm 的人们进行升级,除非他们对正在使用的代码满意,或它们足以满足他们的需要。
< div="" />本文介绍了iptables,以便你可以领会iptables的精彩,文中不包含iptables或Netfilter在安全方面的 bug。如果你发现iptables(或其组成部分)任何bug或特殊的行为,请联系Netfilter mailing lists ,他们会告诉你那是否是bug或如何解决。iptables或Netfilter中几乎没有安全方面的bug,当然偶尔也会出些问题,它们能在中找到。
文中用到的脚本不能解决Netfilter内部的bug,给出它们,只是为了演示如何构造规则,以便我们能解决遇到的数据流管理问题。但本文没有包括象“如何关闭HTTP端口,因为Apache 1.2.12偶尔会被攻击” 这样的问题。本指南会告诉你如何通过iptables关闭HTTP端口,但不是因为Apache偶尔会被攻击。
本文适合于初学者,但也尽可能完善。因为有太多的targets或matches,所以没有完全收录。如果你需要这方面的信息,可以访问。
阅读本文,要具备一些基础知识,如Linux/Unix,shell脚本编写,内核编译,最好还有一些简单的内核知识。
我尝试着尽可能使读者不需要这些知识也能完全弄懂这篇文章,但要理解扩展部分是不行的。所以还是要有点基础的:)
以下的约定会在文中用到:
代码和命令输出使用定宽字体,命令用粗体。
[blueflux@work1 neigh]$ ls default eth0 lo [blueflux@work1 neigh]$
所有的命令和程序名都用粗体。
所有的系统部件,如硬件、内核部件、loopback使用斜体。
计算机文本输出用 这种字体。
文件名和路径名象这样 /usr/local/bin/iptables 。
我发现目前所有的HOWTO都缺乏Linux 2.4.x 内核中的Iptables和Netfilter 函数的信息,于是我试图回答一些问题,比如状态匹配。我会用插图和例子 加以说明,此处的例子可以在你的/etc/rc.d/使用。最初这篇文章是以HOWTO文档的形式书写的,因为许多人只接受HOWTO文档。
还有一个小脚本,我写它只是为使你在配置它的时候能象我一样有成功的感觉。
我请教了Marc Boucher 及netfilter团队的其他核心成员。对他们的工作以及对我在为boingworld.com 书写这个指南时的帮助表示极大的谢意,现在这个指南在我自己的站点frozentux.net上进行维护。这个文档将一步一步教你setup过程,让你对iptables包有更多的了解。这大部分的东西都基于例子rc.firewall 文件,因为我发现这是学习iptables的一个好方法。我决定自顶向下地跟随rc.firewall 文件来学习 iptables。虽然这样会困难一些,但更有逻辑。当你碰到不懂的东西时再来查看这个文件。
文中包含了一些术语,你应该有所了解。这里有一些解释,并说明了本文中如何使用它们。
DNAT - Destination Network Address Translation 目的网络地址转换。 DNAT是一种改变数据包目的 ip地址的技术,经常和SNAT联用,以使多台服务器能共享一个ip地址连入Internet,并且继续服务。通过对同一个ip地址分配不同的端口,来决定数据的流向。
Stream - 流 是指发送和接收的数据包和通信的双方都有关系的一种连接(译者注:本文中,作者把连接看作是单向的,流表示双向的连接)。一般的,这个词用于描述在两个方向上发送两个或三个数据包的连接。对于TCP,流意味着连接,它发送了一个SYN,然后又回复SYN/ACK。但也可能是指这样的连接,发送一个SYN,回复ICMP主机不可达信息。换句话说,我使用这个词很随意。
SNAT - Source Network Address Translation源网络地址转换。这是一种改变数据包源ip地址的技术,经常用来使多台计算机分享一个Internet地址。这只在IPv4中使用,因为IPv4的地址已快用完了,IPv6将解决这个问题。
State - 状态 指明数据包处于什么状态。状态在中定义,或由用户在Netfilter/iptables中自定义。需要注意的是Netfilter设定了一些关于连接和数据包的状态,但没有完全使用使用RFC 793的定义。
User space - 用户空间,指在内核外部或发生在内核外部的任何东西。例如,调用 iptables -h 发生在内核外部,但iptables -A FORWARD -p tcp -j ACCEPT (部分地)发生在内核内部,因为一条新的规则加入了规则集。
Kernel space - 内核空间 ,与用户空间相对,指那些发生在内核内部。
Userland - 参见用户空间
target - 这个词在后文中有大量的应用,它表示对匹配的数据包所做的操作。
这一章是学习iptables的开始,它将帮助你理解Netfilter和iptables在Linux中扮演的角色。它会告诉你如何配置、安装防火墙,你的经验也会随之增长。当然,要想达到你的目标,是要花费时间,还要有毅力。( 译者注:听起来很吓人的:) )
iptables 可以从下载,网站中的FAQs也是很好的教程。iptables 也使用一些内核空间,可以在用make configure配置内核的过程中配置,下面会介绍必要的步骤。
为了运行iptables,需要在内核配置期间,选择以下一些选项,不管你用make config或其他命令。
CONFIG_PACKET - 允许程序直接访问网络设备(译者注:最常用的就是网卡了),象tcpdump 和 snort就要使用这个功能。
严格地说,iptables并不需要CONFIG_PACKET,但是它有很多用处(译者注:其他程序需要),所以就选上了。当然,你不想要,不选就是了。(译者注:建议还是选的为好) |
CONFIG_NETFILTER - 允许计算机作为网关或防火墙。这个是必需的,因为整篇文章都要用到这个功能。我想你也需要这个,谁叫你学iptables呢:)
当然,你要给网络设备安装正确的驱动程序,比如,Ethernet 网卡, PPP 还有 SLIP 。 上面的选项,只是在内核中建立了一个框架, iptables确实已经可以运行,但不能做任何实质性的工作。我们需要更多的选项。以下给出内核2.4.9的选项和简单的说明:
CONFIG_IP_NF_CONNTRACK - 连接跟踪模块,用于 NAT(网络地址转换) 和 Masquerading(ip地址伪装),当然,还有其他应用。如果你想把LAN中的一台机子作为防火墙,这个模块你算选对了。脚本 要想正常工作,就必需有它的存在。
CONFIG_IP_NF_FTP - 这个选项提供针对FTP连接进行连接跟踪的功能。一般情况下,对FTP连接进行连接跟踪是很困难的,要做到这一点,需要一个名为helper的动态链接库。此选项就是用来编译helper的。如果没有这个功能,就无法穿越防火墙或网关使用FTP。
CONFIG_IP_NF_IPTABLES - 有了它,你才能使用过滤、伪装、NAT。它为内核加入了iptables标识框架。没有它,iptables毫无作用。
CONFIG_IP_NF_MATCH_LIMIT - 此模块并不是十分必要,但我在例子中用到了。它提供匹配LIMIT的功能,以便于使用一个适当的规则来控制每分钟要匹配的数据包的数量。比如, -m limit --limit 3/minute 的作用是每分钟最多匹配三个数据包。这个功能也可用来消除某种DoS攻击。
CONFIG_IP_NF_MATCH_MAC - 选择这个模块,可以根据MAC地址匹配数据包。例如,我们想要阻塞使用了某些MAC地址的数据包,或阻塞某些计算机的通信,用这个很容易。因为每个Ethernet网卡都有它自己的MAC地址,且几乎从不会改变。但我在中没有用到这个功能,其他例子也未用到。(译者注:这又一次说明了学习是为将来打基础:) )
CONFIG_IP_NF_MATCH_MARK - 这个选项用来标记数据包。对数据包做 MARK(标记)操作,我们就可以在后面的表中用这个标记来匹配数据包。后文有详细的说明。
CONFIG_IP_NF_MATCH_MULTIPORT - 选择这个模块我们可以使用端口范围来匹配数据包,没有它,是无法做到这一点的。
CONFIG_IP_NF_MATCH_TOS - 使我们可以设置数据包的TOS(Type Of Service 服务类型)。这个工作也可以用命令ip/tc完成,还可在mangle表中用某种规则设定。
CONFIG_IP_NF_MATCH_TCPMSS - 可以基于MSS匹配TCP数据包。
CONFIG_IP_NF_MATCH_STATE - 相比较ipchains 这是最大的更新,有了它,我们可以对数据包做状态匹配。比如,在某个TCP连接的两个方向上已有通信,则这个连接上的数据包就被看作ESTABLISHED(已建立连接)状态。在 里大量使用了此模块的功能。
CONFIG_IP_NF_MATCH_UNCLEAN - 匹配那些不符合类型标准或无效的 P、TCP、UDP、ICMP数据包(译者注:之所以此模块名为UNCLEAN,可以这样理解,凡不是正确模式的包都是脏的。这有些象操作系统内存管理中的“脏页”,那这里就可以称作“脏包”了,自然也就UNCLEAN了)。我们一般丢弃这样的包,但不知这样做是否正确。另外要注意,这种匹配功能还在实验阶段,可能会有些问题。
CONFIG_IP_NF_MATCH_OWNER - 根据套接字的拥有者匹配数据包。比如,我们只允许root访问Internet。在iptables中,这个模块最初只是用一个例子来说明它的功能。同样,这个模块也处于实验阶段,还无法使用。
CONFIG_IP_NF_FILTER - 这个模块为iptables添加基本的过滤表,其中包含INPUT、FORWARD、OUTPUT链。通过过滤表可以做完全的IP过滤。只要想过滤数据包,不管是接收的还是发送的,也不管做何种过滤,都必需此模块。
CONFIG_IP_NF_TARGET_REJECT - 这个操作使我们用ICMP错误信息来回应接收到的数据包,而不是简单地丢弃它。有些情况必须要有回应的,比如,相对于ICMP和UDP来说,要重置或拒绝TCP连接总是需要一个TCP RST包。
CONFIG_IP_NF_TARGET_MIRROR - 这个操作使数据包返回到发送它的计算机。例如,我们在INPUT链里对目的端口为HTTP的包设置了MIRROR操作,当有人访问HTTP时,包就被发送回原计算机,最后,他访问的可能是他自己的主页。(译者注:应该不难理解为什么叫做MIRROR了)
CONFIG_IP_NF_NAT - 顾名思义,本模块提供NAT功能。这个选项使我们有权访问nat表。端口转发和伪装是必需此模块的。当然,如果你的LAN里的所有计算机都有唯一的有效的 IP地址,那在做防火墙或伪装时就无须这个选项了。是需要的:)
CONFIG_IP_NF_TARGET_MASQUERADE - 提供MASQUERADE(伪装)操作。如果我们不知道连接Internet的IP,首选的方法就是使用MASQUERADE,而不是DNAT或SNAT。换句话说,就是如果我们使用PPP或SLIP等连入Internet,由DHCP或其他服务分配IP,使用这个比SNAT好。因为MASQUERADE 不需要预先知道连接Internet的IP,虽然对于计算机来说MASQUERADE要比NAT的负载稍微高一点。
CONFIG_IP_NF_TARGET_REDIRECT - 这个操作和代理程序一起使用是很有用的。它不会让数据包直接通过,而是把包重新映射到本地主机,也就是完成透明代理。
CONFIG_IP_NF_TARGET_LOG - 为iptables增加 LOG(日志)操作。通过它,可以使用系统日志服务记录某些数据包,这样我们就能了解在包上发生了什么。这对于我们做安全审查、调试脚本的帮助是无价的。
CONFIG_IP_NF_TARGET_TCPMSS - 这个选项可以对付一些阻塞ICMP分段信息的ISP(服务提供商)或服务。没有ICMP分段信息,一些网页、大邮件无法通过,虽然小邮件可以,还有,在握手完成之后,ssh可以但scp不能工作。我们可以用TCPMSS解决这个问题,就是使MSS(Maximum Segment Size)被钳制于PMTU(Path Maximum Transmit Unit)。这个方法可以处理被Netfilter开发者们在内核配置帮助中称作“criminally brain-dead ISPs or servers”的问题。
CONFIG_IP_NF_COMPAT_IPCHAINS - ipchains 的,这只是为内核从2.2转换到2.4而使用的,它会在2.6中删除。
CONFIG_IP_NF_COMPAT_IPFWADM - 同上,这只是 ipfwadm的暂时使用的兼容模式。
上面,我简要介绍了很多选项,但这只是内核2.4.9中的。要想看看更多的选项,建议你去Netfilter 看看patch-o-matic。在那里,有其他的一些选项。POM可能会被加到内核里,当然现在还没有。这有很多原因,比如,还不稳定,Linus Torvalds没打算或没坚持要把这些补丁放入主流的内核,因为它们还在实验。
把以下选项编译进内核或编译成模块,才能使用。
CONFIG_PACKET
CONFIG_NETFILTER
CONFIG_IP_NF_CONNTRACK
CONFIG_IP_NF_FTP
CONFIG_IP_NF_IRC
CONFIG_IP_NF_IPTABLES
CONFIG_IP_NF_FILTER
CONFIG_IP_NF_NAT
CONFIG_IP_NF_MATCH_STATE
CONFIG_IP_NF_TARGET_LOG
CONFIG_IP_NF_MATCH_LIMIT
CONFIG_IP_NF_TARGET_MASQUERADE
以上是为保证 正常工作而需要的最少的选项。其他脚本需要的选项,在相应的章节里都有说明。目前,我们只需注意要学习的这个脚本。
下面,我们来看看如何编译iptables。iptables很多组件的配置、编译是与内核的配置、编译相关联的,了解这一点是很重要的。某些Linux产品预装了iptables,比如Red Hat,但是它的缺省设置是不启用iptables的。后文我们会介绍如何启用它,也会介绍一下其他 Linux产品里的iptables情况。
首先要解压iptables包。这里,我用iptables 1.2.6a做例子(译者注:在我翻译时,最新版本已经是 1.2.9,其中又有了不少改进,修补了一些bug,增添了几个match和target。)。命令 bzip2 -cd iptables-1.2.6a.tar.bz2 | tar -xvf -(当然也可以用tar -xjvf iptables-1.2.6a.tar.bz2,但这个命令可能对一些老版的tar不适用 ) 将压缩包解压至目录iptables-1.2.6a,其中的INSTALL文件有很多对编译、运行有用的信息。
这一步,你将配置、安装一些额外的模块,也可以为内核增加一些选项。我们这里只是检查、安装一些未被纳入内核的标准的补丁。当然,更多的在实验阶段的补丁,仅在进行其他某些操作时才会用到。
有一些补丁仅仅处在实验阶段,把它们也安装上不是一个好主意。这一步,你会遇到很多十分有趣的匹配和对数据包的操作,但它们还正在实验。 为了完成这一步,我们要在iptables的目录内用到如下一些命令: |
make pending-patches KERNEL_DIR=/usr/src/linux/
变量KERNEL_DIR指向内核原码的真实路径。一般情况下,都是/usr/src/linux/ ,但也会不一样,这要看你所用的Linux产品了。
总之,只有某些补丁会被询问是否加入内核,而Netfilter的开发者们有大量的补丁或附件想要加入内核,但还要再实验一阵子才能做到。如果你想安装这些东西,就用下面的命令: |
make most-of-pom KERNEL_DIR=/usr/src/linux/
这个命令会安装部分patch-o-matic(netfilter世界对补丁的称呼),忽略掉的是非常极端的那一部分,它们可能会对内核造成严重的破坏。你要知道这个命令的作用,要了解它们对内核原码的影响,好在在你选用之前,会有所提示。下面的命令可以安装所有的patch-o-matic(译者注:一定要小心哦)。
make patch-o-matic KERNEL_DIR=/usr/src/linux/
要仔细的读读每一个补丁的帮助文件,因为有些patch-o-matic会损坏内核,而有些对其他补丁有破坏作用。
你要是不打算用patch-o-matic修补内核,以上的命令都用不着,它们不是必需的。不过,你可以用这些命令来看看有什么有趣的玩意儿,这不会影响任何东西。 |
安装好patch-o-matic,现在应该重新编译内核了,因为其中增加了一些补丁。但别忘了重新配置内核,现有的配置文件里可没有你增加的补丁的信息。当然,你也可以先编译iptables , 再来编译内核。
接下来就该编译iptables了,用下面这个简单的命令:
make KERNEL_DIR=/usr/src/linux/
iptables应该编译好了,如果不行,好好考虑考虑问题在哪儿,要么订阅,那里可能有人能帮助你。
一切顺利的话,我们该安装iptables了,这几乎不会有什么问题的。我们用下面的命令来完成这一步:
make install KERNEL_DIR=/usr/src/linux/
现在大功告成了。如果你在前面没有重新编译、安装内核,现在就要做了,不然,你还是不能使用更新后的iptables。好好看看INSTALL吧,那里面有详细的安装信息。
Red Hat 7.1使用2.4.x的内核,支持Netfilter和iptables。Red Hat包含了所有基本的程序和需要的配置文件,但缺省使用的是B class=COMMAND>ipchains。“iptables为什么不能用”是最常见的问题,下面就让我们就来说说如何关闭ipchains而起用iptables 。
Red Hat 7.1预装的iptables版本有些老了,在使用之前,你可能想装个新的,再自己编译一下内核。 |
我们先要关闭ipchains,并且不想再让它运行起来,做到这一点,要更改目录/etc/rc.d/下的一些文件名。用以下命令完成:
chkconfig --level 0123456 ipchains off
这个命令把所有指向/etc/rc.d/init.d/ipchains的软连接改名为 K92ipchains。以S开头表示,在启动时会由初始化脚本运行此脚本。改为K开头后,就表示终止服务,或以后在启动时不再运行。这样,ipchains以后不会再开机就运行了。
要想终止正在运行的服务,要用service命令。终止ipchains 服务的命令是:
service ipchains stop
现在,我们可以启动iptables服务了。首先,要确定在哪个运行层运行,一般是 2,3和5,这些层有不同的用处:
2. 不带NFS的多用户环境,和层3的区别仅在于不带网络支持。
3. 多用户环境,就是我们一般事用的层。
5. X11,图形界面。
用下面的命令以使iptables能在这些层运行:
chkconfig --level 235 iptables on
你也可以使用这个命令使iptables能在其他层运行。但没这个必要,因为层1是单用户模式,一般用在维修上;层4保留不用;层6用来关闭计算机。
启动iptables用:
service iptables start
在脚本iptables里还没有定义规则。在Red Hat 7.1中添加规则的方法有二:第一个方法是编辑/etc/rc.d/init.d/iptables,要注意在用RPM升级iptables时,已有的规则可能会被删除。另一个方法是先装载规则,然后用命令iptables-save把规则保存到文件中,再由目录rc.d下的脚本(/etc/rc.d/init.d/iptables)自动装载。
我们先来说明如何利用“剪切粘贴大法”设置/etc/rc.d/init.d/iptables。为了能在计算机启动iptables时装载规则,可以把规则放在“start)”节或函数start()中。注意:如果把规则放在“start)”节里,则不要在“start)”节里运行start(),还要编辑“stop)”节,以便在关机时或进入一个不需要iptables的层时,脚本知道如何处理。还应检查“restart”节和“condrestart”节的设置。一定要注意,我们所做的改动在升级iptables时可能会被删除,而不管是通过Red Hat网络自动升级还是用 RPM升级。
下面介绍第二种方法:先写一个规则的脚本,或直接用iptables命令生成规则。规则要适合自己的需要,别忘了实验一下是否有问题,确认正常之后,使用命令iptables-save来保存规则。一般用iptables-save > /etc/sysconfig/iptables生成保存规则的文件 /etc/sysconfig/iptables,也可以用service iptables save,它能把规则自动保存在/etc/sysconfig/iptables中。当计算机启动时,rc.d下的脚本将用命令iptables-restore调用这个文件,从而就自动恢复了规则。
以上两种方法最好不要混用,以免用不同方法定义的规则互相影响,甚至使防火墙的设置无效。
至此,可以删除预装的ipchains和iptables了,这样可以避免新旧版本的iptables之间的冲突。其实,只有当你从原码安装时,才需要这样做。但一般来说,也不会出现互相影响的问题,因为基于rpm的包不使用原码的缺省目录。删除用以下命令:
rpm -e iptables
既然不用ipchains为什么要保留呢?删吧!命令如下:
rpm -e ipchains
历经磨难,胜利终于到来了。你已经能够从源码安装iptables了。那些老版的东西就删掉吧。
这一章我们来讨论数据包是以什么顺序、如何穿越不同的链和表的。稍后,在你自己写规则时,就会知道这个顺序是多么的重要。一些组件是iptables与内核共用的,比如,数据包路由的判断。了解到这一点是很重要的,尤其在你用iptables改变数据包的路由时。这会帮助你弄明白数据包是如何以及为什么被那样路由,一个好的例子是DNAT和SNAT,不要忘了TOS的作用。
当数据包到达防火墙时,如果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链。
在上面的情况里,不要在INPUT链上做过滤。INPUT是专门用来操作那些以我们的机子为目的地址的包的,它们不会被路由到其它地方的。 |
现在,我们来看看在以上三种情况下,用到了哪些不同的链。图示如下:
要弄清楚上面的图,可以这样考虑。在第一个路由判断处,不是发往本地的包,我们会发送它穿过 FORWARD链。若包的目的地是本地监听的IP地址,我们就会发送这个包穿过INPUT链,最后到达本地。
值得注意的是,在做NAT的过程中,发往本机的包的目的地址可能会在PREROUTING链里被改变。这个操作发生在第一次路由之前,所以在地址被改变之后,才能对包进行路由。注意,所有的包都会经过上图中的某一条路径。如果你把一个包DNAT回它原来的网络,这个包会继续走完相应路径上剩下的链,直到它被发送回原来的网络。
想要更多的信息,可以看看,这个脚本包括了一些规则,它们会向你展示包是怎样通过各个表和链的。 |
这个表主要用来mangle包,你可以使用mangle匹配来改变包的TOS等特性。
强烈建议你不要在这个表里做任何过滤,不管是DANT,SNAT或者Masquerade。 |
以下是mangle表中仅有的几种操作:
TOS
TTL
MARK
TOS操作用来设置或改变数据包的服务类型域。这常用来设置网络上的数据包如何被路由等策略。注意这个操作并不完善,有时得不所愿。它在Internet上还不能使用,而且很多路由器不会注意到这个域值。换句话说,不要设置发往Internet的包,除非你打算依靠TOS来路由,比如用iproute2。
TTL操作用来改变数据包的生存时间域,我们可以让所有数据包只有一个特殊的TTL。它的存在有一个很好的理由,那就是我们可以欺骗一些ISP。为什么要欺骗他们呢?因为他们不愿意让我们共享一个连接。那些ISP会查找一台单独的计算机是否使用不同的TTL,并且以此作为判断连接是否被共享的标志。
MARK用来给包设置特殊的标记。iproute2能识别这些标记,并根据不同的标记(或没有标记)决定不同的路由。用这些标记我们可以做带宽限制和基于请求的分类。
此表仅用于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随机分配的。
filter 表用来过滤数据包,我们可以在任何时候匹配包并过滤它们。我们就是在这里根据包的内容对包做DROP或ACCEPT的。当然,我们也可以预先在其他地方做些过滤,但是这个表才是设计用来过滤的。几乎所有的target都可以在这儿使用。大量具体的介绍在后面,现在你只要知道过滤工作主要是在这儿完成的就行了。
本章将详细介绍状态机制。通读本章,你会对状态机制是如何工作的有一个全面的了解。我们用一些例子来进行说明状态机制。实践出真知嘛。
状态机制是iptables中特殊的一部分,其实它不应该叫状态机制,因为它只是一种连接跟踪机制。但是,很多人都认可状态机制这个名字。文中我也或多或或少地用这个名字来表示和连接跟踪相同的意思。这不应该引起什么混乱的。连接跟踪可以让Netfilter知道某个特定连接的状态。运行连接跟踪的防火墙称作带有状态机制的防火墙,以下简称为状态防火墙。状态防火墙比非状态防火墙要安全,因为它允许我们编写更严密的规则。
在iptables里,包是和被跟踪连接的四种不同状态有关的。它们是NEW,ESTABLISHED,RELATED和INVALID。后面我们会深入地讨论每一个状态。使用--state匹配操作,我们能很容易地控制 “谁或什么能发起新的会话”。
所有在内核中由Netfilter的特定框架做的连接跟踪称作conntrack(译者注:就是connection tracking 的首字母缩写)。conntrack可以作为模块安装,也可以作为内核的一部分。大部分情况下,我们想要,也需要更详细的连接跟踪,这是相比于缺省的conntrack而言。也因为此,conntrack中有许多用来处理TCP, UDP或ICMP协议的部件。这些模