数据包流向顺序
我们来讨论数据包是以什么顺序、如何穿越不同的链和表的。稍后,在你自己写规则时,就会知 道这个顺序是多么的重要。一些组件是iptables与内核共用的,比如,数据包路由的判断。了解到这一点是 很重要的,尤其在你用iptables改变数据包的路由时。这会帮助你弄明白数据包是如何以及为什么被那样路 由,一个好的例子是DNAT和SNAT,不要忘了TOS的作用。
以本地为目标的包
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 | 到达本地程序了(比如,服务程序或客户程序) |
以本地为源的包
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) |
被转发的包
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 [-t table] command [match] [target/jump] 1、表名 mangle,nat,filter等 2、命令 -A,-I,-D等 3、匹配 如-p tcp, -m state –state RELATED,ESTABLISHED。 4、target/jump,如-j ACCEPT或-j DROP等。
Tables(表)
选项-t用来指定使用哪个表,它可以是下面介绍的表中的任何一个,默认的是 filter表。
Table | Explanation |
---|---|
nat | nat表的主要用处是网络地址转换,即Network Address Translation,缩写为NAT。做过NAT操作的数据包的地址就被改变了,当然这种改变是根据我们的规则进行 的。属于一个流的包只会经过这个表一次。如果第一个包被允许做NAT或Masqueraded,那么余下的包都会自 动地被做相同的操作。也就是说,余下的包不会再通过这个表,一个一个的被NAT,而是自动地完成。这就 是我们为什么不应该在这个表中做任何过滤的主要原因,对这一点,后面会有更加详细的讨论。PREROUTING 链的作用是在包刚刚到达防火墙时改变它的目的地址,如果需要的话。OUTPUT链改变本地产生的包的目的地 址。POSTROUTING链在包就要离开防火墙之前改变其源地址。 |
mangle | 这个表主要用来mangle数据包。我们可以改变不同的包及包 头的内容,比如 TTL,TOS或MARK。 注意MARK并没有真正地改动数据包,它只是在内核空间为包设了一个标记。防火墙 内的其他的规则或程序(如tc)可以使用这种标记对包进行过滤或高级路由。这个表有五个内建的链:PREROUTING,POSTROUTING, OUTPUT,INPUT和 FORWARD。PREROUTING在包进入防火墙之后、路由判断之前改变 包,POSTROUTING是在所有路由判断之后。OUTPUT在确定包的目的之前更改数据包。INPUT在包被路由到本地 之后,但在用户空间的程序看到它之前改变包。FORWARD在最初的路由判 断之后、最后一次更改包的目的之前mangle包。注意,mangle表不能做任何NAT,它只是改变数据包的 TTL,TOS或MARK,而不是其源目地 址。NAT是在nat表中操作的。 |
filter | filter表是专门过滤包 的,内建三个链,可以毫无问题地对包进行DROP、LOG、ACCEPT和REJECT等操作。FORWARD 链过滤所有不是本地产生的并且目的地不是本地(所谓本地就是防火墙了)的包,而 INPUT恰恰针对那些目的地是本地的包。OUTPUT 是用来过滤所有本地生成的包的。 |
command(命令)
我们将要介绍所有的command以及它们的用途。command指定iptables 对我们提交的规则要做什么样的操作。这些操作可能是在某个表里增加或删除一些东西,或做点儿其他 什么。以下是iptables可用的command(要注意,如不做说明,默认表的是 filter表。):命令表:
Command | -A, –append |
Example | iptables -A INPUT … |
Explanation | 在所选择的链末添加规则。当源地址或目的地址是以名字而 不是ip地址的形式出现时,若这些名字可以被解析为多个地址,则这条规则会和所有可用的地址结合。 |
Command | -D, –delete |
Example | iptables -D INPUT –dport 80 -j DROP或iptables -D INPUT 1 |
Explanation | 从所选链中删除规则。有两种方法指定要删除的规则:一是 把规则完完整整地写出来,再就是指定规则在所选链中的序号(每条链的规则都各自从1被编号)。 |
Command | -R, –replace |
Example | iptables -R INPUT 1 -s 192.168.0.1 -j DROP |
Explanation | 在所选中的链里指定的行上(每条链的规则都各自从1被编 号)替换规则。它主要的用处是试验不同的规则。当源地址或目的地址是以名字而不是ip地址的形式出现 时,若这些名字可以被解析为多个地址,则这条command会失败。 |
Command | -I, –insert |
Example | iptables -I INPUT 1 –dport 80 -j ACCEPT |
Explanation | 根据给出的规则序号向所选链中插入规则。如果序号为1, 规则会被插入链的头部,其实默认序号就是1。 |
Command | -L, –list |
Example | iptables -L INPUT |
Explanation | 显示所选链的所有规则。如果没有指定链,则显示指定表中 的所有链。如果什么都没有指定,就显示默认表所有的链。精确输出受其它参数影响,如-n 和-v等参数,下面会介绍。 |
Command | -F, –flush |
Example | iptables -F INPUT |
Explanation | 清空所选的链。如果没有指定链,则清空指定表中的所有 链。如果什么都没有指定,就清空默认表所有的链。当然,也可以一条一条地删,但用这个command会快些。 |
Command | -Z, –zero |
Example | iptables -Z INPUT |
Explanation | 把指定链(如未指定,则认为是所有链)的所有计数器归 零。 |
Command | -N, –new-chain |
Example | iptables -N allowed |
Explanation | 根据用户指定的名字建立新的链。上面的例子建立了一个名 为allowed的链。注意,所用的名字不能和已有的链、target同名。 |
Command | -X, –delete-chain |
Example | iptables -X allowed |
Explanation | 删除指定的用户自定义链。这个链必须没有被引用,如果被 引用,在删除之前你必须删除或者替换与之有关的规则。如果没有给出参数,这条命令将会删除默认表所有 非内建的链。 |
Command | -P, –policy |
Example | iptables -P INPUT DROP |
Explanation | 为链设置默认的target(可用的是DROP 和ACCEPT,如果还有其它的可用,请告诉我),这个target称作策略。所有不 符合规则的包都被强制使用这个策略。只有内建的链才可以使用规则。但内建的链和用户自定义链都不能被 作为策略使用,也就是说不能象这样使用:iptables -P INPUT allowed(或者是内建的链)。 |
Command | -E, –rename-chain |
Example | iptables -E allowed disallowed |
Explanation | 对自定义的链进行重命名,原来的名字在前,新名字在后。 如上,就是把allowed改为disallowed。这仅仅是改变 链的名字,对整个表的结构、工作没有任何影响。 |
与上面命令配合使用的选项:
Option(选项) | -v, –verbose(详细的) |
可用此选项的命令 | –list, –append, –insert, –delete, –replace |
Explanation(说明) | 这个选项使输出详细化,常与–list 连用。与–list连用时,输出中包括网络接口的地址、规则的选项、TOS掩码、 字节和包计数器,其中计数器是以K、M、G(这里用的是10的幂而不是2的幂哦)为单位的。如果想知道到底 有多少个包、多少字节,还要用到选项-x,下面会介绍。如果-v 和–append、–insert、–delete 或–replace连用,iptables会输出详细的信息告诉你规则是如何被解释的、是 否正确地插入等等。 |
Option | -x, –exact(精确的) |
Commands used with | –list |
Explanation | 使–list输出中的计数器显示准确 的数值,而不用K、M、G等估值。注意此选项只能和–list连用。 |
Option | -n, –numeric(数值) |
Commands used with | –list |
Explanation | 使输出中的IP地址和端口以数值的形式显示,而不是默认的 名字,比如主机名、网络名、程序名等。注意此选项也只能和–list连用。 |
Option | –line-numbers |
Commands used with | –list |
Explanation | 又是一个只能和–list连用的选 项,作用是显示出每条规则在相应链中的序号。这样你可以知道序号了,这对插入新规则很有用哦。 |
Option | -c, –set-counters |
Commands used with | –insert, –append, –replace |
Explanation | 在创建或更改规则时设置计数器,语法如下:–set-counters 20 4000,意思是让内核把包计数器设为20,把字节计数器设为4000。 |
Option | –modprobe |
Commands used with | All |
Explanation | 此选项告诉iptables探测并装载要使用的模块。这是非常有 用的一个选项,万一modprobe命令不在搜索路径中,就要用到了。有了这个选项, 在装载模块时,即使有一个需要用到的模块没装载上,iptables也知道要去搜索。 |
matches(匹配规则)
这一节,我们会详细讨论一些matche,我把它们归为五类。第一类是generic matches(通用的匹配),适用于所有的规则;第二类是TCP matches,顾名思 义,这只能用于TCP包;第三类是UDP matches, 当然它只能用在UDP包上了;第四类是ICMP matches ,针对ICMP包的;第五类比较特殊,针对的是状态(state),所有 者(owner)和访问的频率限制(limit)等,它们已经被分到更多的小类当中,尽管它们并不是完全不同 的。我希望这是一种大家都容易理解的分类。
通用匹配
Match | -p, –protocol |
Example | iptables -A INPUT -p tcp |
Explanation | 匹配指定的协议。指定协议的形式有以下几种: 1、名字,不分大小写,但必须是在/etc/protocols中定 义的。 2、可以使用它们相应的整数值。例如,ICMP的值是1,TCP是6,UDP是17。 3、缺省设置,ALL,相应数值是0,但要注意这只代表匹配TCP、UDP、ICMP,而不是/etc/protocols中定义的所有协议。 4、可以是协议列表,以英文逗号为分隔符,如:udp,tcp 5、可以在协议前加英文的感叹号表示取反,注意有空格,如: –protocol ! tcp 表示非tcp协议,也就是UDP和ICMP。可以看出这个取反的范围只是TCP、UDP和ICMP。 |
Match | -s, –src, –source |
Example | iptables -A INPUT -s 192.168.1.1 |
Explanation | 以IP源地址匹配包。地址的形式如下: 1、单个地址,如192.168.1.1,也可写成 192.168.1.1/255.255.255.255或192.168.1.1/32 2、网络,如192.168.0.0/24,或 192.168.0.0/255.255.255.0 3、在地址前加英文感叹号表示取反,注意空格,如–source ! 192.168.0.0/24 表示除此地址外的所有地址 4、缺省是所有地址 |
Match | -d, –dst, –destination |
Example | iptables -A INPUT -d 192.168.1.1 |
Explanation | 以IP目的地址匹配包。地址的形式和 — source完全一样。 |
Match | -i, –in-interface |
Example | iptables -A INPUT -i eth0 |
Explanation | 以包进入本地所使用的网络接口来匹配包。要注意这个匹配 操作只能用于INPUT,FORWARD和 PREROUTING这三个链,用在其他任何地方都会提示错误信息。指定接口有一下方 法: 1、指定接口名称,如:eth0、ppp0等 2、使用通配符,即英文加号,它代表字符数字串。若直接用一个加号,即iptables -A INPUT -i +表示匹配所有的包,而不考虑使用哪个接口。这也是不指定接口的默认行为。通配符还 可以放在某一类接口的后面,如:eth+表示所有Ethernet接口,也就是说,匹配所有从Ethernet接口进入的 包。 3、在接口前加英文感叹号表示取反,注意空格,如:-i ! eth0意思是匹配来自 除eth0外的所有包。 |
Match | -o, –out-interface |
Example | iptables -A FORWARD -o eth0 |
Explanation | 以包离开本地所使用的网络接口来匹配包。使用的范围和指 定接口的方法与–in-interface完全一样。 |
Match | -f, –fragment |
Example | iptables -A INPUT -f |
Explanation | 用来匹配一个被分片的包的第二片或及以后的部分。因为它 们不包含源或目的地址,或ICMP类型等信息,其他规则无法匹配到它,所以才有这个匹配操作。要注意碎片 ***哦。这个操作也可以加英文感叹号表示取反,但要注意位置,如:! -f 。取反 时,表示只能匹配到没有分片的包或者是被分片的包的第一个碎片,其后的片都不行。现在内核有完善的碎 片重组功能,可以防止碎片***,所以不必使用取反的功能来防止碎片通过。如果你使用连接跟踪,是不会 看到任何碎片的,因为在它们到达任何链之前就被处理过了。 |
隐含匹配
TCP matches
Match | –sport, –source-port |
Example | iptables -A INPUT -p tcp –sport 22 |
Explanation | 基于TCP包的源端口来匹配包,端口的指定形式如下: 1、不指定此项,则暗示所有端口。 2、使用服务名或端口号,但名字必须是在/etc/services 中定义的,因为iptables从这个文件里查找相应的端口号。从这可以看出,使用端口号会使规则装入快一点 儿,当然,可读性就差些了。但是如果你想写一个包含200条或更多规则的规则集,那你还是老老实实地用 端口号吧,时间是主要因素(在一台稍微慢点儿地机子上,这最多会有10秒地不同,但要是1000条、10000 条呢)。 3、可以使用连续的端口,如:–source-port 22:80这表示从22到80的所有端 口,包括22和80。如果两个号的顺序反了也没关系,如:–source-port 80:22这和 –source-port 22:80的效果一样。 4、可以省略第一个号,默认第一个是0,如:–source-port :80表示从0到80的 所有端口。 5、也可以省略第二个号,默认是65535,如:–source-port 22:表示从22到 65535的所有端口 6、在端口号前加英文感叹号表示取反,注意空格,如:–source-port ! 22表 示除22号之外的所有端口;–source-port ! 22:80表示从22到80(包括22和80)之 外的所有端口。注意:这个匹配操作不能识别不连续的端口列表,如:–source-port ! 22, 36, 80 这样的操作是由后面将要介绍的多端口匹配扩展来完成的。 |
Match | –dport, –destination-port |
Example | iptables -A INPUT -p tcp –dport 22 |
Explanation | 基于TCP包的目的端口来匹配包,端口的指定形式和–sport完全一样。 |
Match | –tcp-flags |
Example | |
Explanation | 匹配指定的TCP标记。有两个参数,它们都是列表,列表内 部用英文的逗号作分隔符,这两个列表之间用空格分开。第一个参数指定我们要检查的标记(作用就象掩 码),第二个参数指定“在第一个列表中出现过的且必须被设为1(即状态是打开的)的”标记(第一个列 表中其他的标记必须置0)。也就是说,第一个参数提供检查范围,第二个参数提供被设置的条件(就是哪 些位置1)。这个匹配操作可以识别以下标记:SYN, ACK,FIN,RST ,URG,PSH。另外还有两个词 也可使用,就是ALL和NONE。顾名思义,ALL是指选定所有的标记,NONE是指未选定任何标记。这个匹配也可 在参数前加英文的感叹号表示取反。例如: 1、iptables -p tcp –tcp-flags SYN,FIN,ACK SYN表示匹配那些SYN标记被设 置而FIN和ACK标记没有设置的包,注意各标记之间只有一个逗号而没有空格。 2、–tcp-flags ALL NONE匹配所有标记都未置1的包。 3、iptables -p tcp –tcp-flags ! SYN,FIN,ACK SYN表示匹配那些FIN和ACK标 记被设置而SYN标记没有设置的包,注意和例1比较一下。 |
Match | –syn |
Example | iptables -p tcp –syn |
Explanation | 这个匹配或多或少算是ipchains时代的遗留物,之所以还保 留它,是为了向后兼容,也是为了方便规则在iptables和ipchains间的转换。它匹配那些SYN标记被设置而 ACK和RST标记没有设置的包,这和iptables -p tcp –tcp-flags SYN,RST,ACK SYN 的作用毫无二样。这样的包主要用在TCP连接初始化时发出请求。如果你阻止了这样的包,也就阻止了所有 由外向内的连接企图,这在一定程度上防止了一些***。但外出的连接不受影响,恰恰现在有很多***就利 用这一点。比如有些***黑掉服务器之后安装会一些软件,它们能够利用已存的连接到达你的机子,而不要 再新开一个端口。这个匹配也可用英文感叹号取反,如:! –syn用来匹配那些 RST或ACK被置位的包,换句话说,就是 状态为已建立的连接的包。 |
Match | –tcp-option |
Example | iptables -p tcp –tcp-option 16 |
Explanation | 根据匹配包。TCP选项是TCP头中的特殊部分,有三个不同的 部分。第一个8位组表示选项的类型,第二个8位组表示选项的长度(这个长度是整个选项的长度,但不包含 填充部分所占的字节,而且要注意不是每个TCP选项都有这一部分的),第三部分当然就是选项的内容了。 为了适应标准,我们不必执行所有的选项,但我们可以查看选项的类型,如果不是我们所支持的,那就只是 看看长度然后跳过数据部分。这个操作是根据选项的十进制值来匹配的,它也可以用英文感叹号取反。所有 的选项都可在Internet Engineering Task Force里找到。 |
UDP matches
Match | –sport, –source-port |
Example | iptables -A INPUT -p udp –sport 53 |
Explanation | 基于UDP包的源端口来匹配包,端口的指定形式和TCP matches中的–sport完全一样。 |
Match | –dport, –destination-port |
Example | iptables -A INPUT -p udp –dport 53 |
Explanation | 基于UDP包的目的端口来匹配包,端口的指定形式和TCP matches中的–sport完全一样。 |
ICMP matches ICMP协议也是无连接协议,ICMP包更是短命鬼,比UDP的还短。ICMP协议不是IP协议的下属协议,而是它 的辅助者,其主要作用是报告错误和连接控制。ICMP包的头和IP的很相似,但又有很多不同。这个协议最主 要的特点是它有很多类型,以应对不同的情况。比如,我们想访问一个无法访问的地址,就会收到一个ICMP host unreachable信息,它的意思是主机无法到达。在附录ICMP类型里有完整的ICMP类型列表。虽然有这么多类型,但只有一个 ICMP matche,这就足够对付它们了。这个matche是在指定–protocol ICMP时自动 装入的。注意所有的通用匹配都可以使用,这样我们就可以匹配ICMP包的源、目地址。
Match | –icmp-type |
Example | iptables -A INPUT -p icmp –icmp-type 8 |
Explanation | 根据ICMP类型匹配包,类型的指定可以使用十进制数值或相 应的名字,数值在RFC792中有定义,名字可以用iptables –protocol icmp –help 查看,或者在附录ICMP类型中查找。这个匹配也可用英文感叹号取 反,如:–icmp-type ! 8就表示匹配除类型8之外的所有ICMP包。要注意有些ICMP 类型已经废弃不用了,还有一些可能会对无防护的主机带来“危险”,因为它们可能把包重定向到错误的地 方。 |
显式匹配
显式匹配必须用-m或–match装载,比如要使用状态匹配 就必须使用-m state。有些匹配还需要指定协议,有些就不需要,比如连接状态就 不要。这些状态是NEW(还未建立好的连接的第一个包), ESTABLISHED(已建立的连接,也就是已经在内核里注册过的),RELATED(由 已经存在的、处于已建立状态的连接生成的新连接),等等。有些匹配还处在开发阶段,或者还只是为了说 明iptables的强大能力。这说明不是所有的匹配一开始就是实用的,但以后你可能会用到它。随着iptables 新版本的发布,会有一些新的匹配可用。隐含匹配和显式匹配最大的区别就是一个是跟随协议匹配自动装载 的,一个是显式装载的。 Limit match
Match | –limit |
Example | iptables -A INPUT -m limit –limit 3/hour |
Explanation | 为limit match设置最大平均匹配速 率,也就是单位时间内limit match可以匹配几个包。它的形式是一个数值加一个时 间单位,可以是/second /minute/hour /day 。默认值是每小时3次(用户角度),即3/hour ,也就是每20分钟一次(iptables角度)。 |
Match | –limit-burst |
Example | iptables -A INPUT -m limit –limit-burst 5 |
Explanation | 这里定义的是limit match的峰值, 就是在单位时间(这个时间由上面的–limit指定)内最多可匹配几个包(由此可 见,–limit-burst的值要比–limit的大)。默认值是5。 为了观察它是如何工作的,你可以启动“只有一条规则的脚本”Limit- match.txt,然后用不同的时间间隔、发送不同数量的ping数据包。这样,通过返回的 echo replies就可以看出其工作方式了。 |
MAC match
Match | –mac-source |
Example | iptables -A INPUT -m mac –mac-source 00:00:00:00:00:01 |
Explanation | 基于包的MAC源地址匹配包,地址格式只能是XX:XX:XX:XX:XX:XX,当然它也可以用英文感叹号取反,如–mac- source ! 00:00:00:00:00:01,意思很简单了,就是除此之外的地址都可接受嘛。注意,因为 MAC addresses只用于Ethernet类型的网络,所以这个match只能用于Ethernet接 口。而且,它还只能在PREROUTING,FORWARD 和INPUT链里使用。 |
Mark match
Match | –mark |
Example | iptables -t mangle -A INPUT -m mark –mark 1 |
Explanation | 以包被设置的mark值来匹配包,这个值是是由下面将要介绍 的 MARK target来设置的,它是一个无符号的整数。所有通过 Netfilter的包都会被分配一个相关联的mark field 。但要注意mark值可不是在任何情况下都能使用的,它只能在分配给它值的那台机子里使用,因为 它只是由内核在内存里分配的和包相关的几个字节,并不属于包本身,所以我们不能在本机之外的路由器上 使用。mark的格式是–mark value[/mask],如上面的例子是没有掩码的,带掩码的 例子如–mark 1/1。如果指定了掩码,就先把mark值和掩码取逻辑与,然后再和包 的mark值比较。 |
Multiport match
Match | –source-port |
Example | iptables -A INPUT -p tcp -m multiport –source-port 22,53,80,110 |
Explanation | 源端口多端口匹配,最多可以指定15个端口,以英文逗号分 隔,注意没有空格。使用时必须有-p tcp或-p udp为前提条 件。 |
Match | –destination-port |
Example | iptables -A INPUT -p tcp -m multiport –destination-port 22,53,80,110 |
Explanation | 目的端口多端口匹配,使用方法和源端口多端口匹配一样, 唯一的区别是它匹配的是目的端口。 |
Match | –port |
Example | iptables -A INPUT -p tcp -m multiport –port 22,53,80,110 |
Explanation | 同端口多端口匹配,意思就是它匹配的是那种源端口和目的 端口是同一个端口的包,比如:端口80到端口80的包,110到110的包等。使用方法和源端口多端口匹配一 样。 |
Owner match
Match | –uid-owner |
Example | iptables -A OUTPUT -m owner –uid-owner 500 |
Explanation | 按生成包的用户的ID(UID)来匹配外出的包。使用这个匹 配可以做这样一些事,比如,阻止除root外的用户向防火墙外建立新连接,或阻止除用户http外的任何人使 用HTTP端口发送数据。 |
Match | –gid-owner |
Example | iptables -A OUTPUT -m owner –gid-owner 0 |
Explanation | 按生成包的用户所在组的ID(GID)来匹配外出的包。比 如,我们可以只让属于network组的用户上Internet,而其他用户都不 行;或者只允许http组的成员能从HTTP端口发送数据。 |
Match | –pid-owner |
Example | iptables -A OUTPUT -m owner –pid-owner 78 |
Explanation | 按生成包的进程的ID(GID)来匹配外出的包。比如,我们 可以只允许PID为94的进程(http进程当然不能是多线程的)使用http端口。这个匹配使用起来有一点难 度,因为你要知道进程的ID号。当然,你也可以写一个小小的脚本,先从ps的输出 中得到PID,再添加相应的规则,这儿有个例子Pid-owner.txt。 |
Match | –sid-owner |
Example | iptables -A OUTPUT -m owner –sid-owner 100 |
Explanation | 按生成包的会话的ID(SID)来匹配外出的包。一个进程以 及它的子进程或它的多个线程都有同一个SID。比如,所有的HTTPD进程的SID和它的父进程一样(最初的 HTTPD进程),即使HTTPD是多线程的(现在大部分都是,比如Apache和Roxen)也一样。这里有个脚本Sid-owner.txt可以反映出这一点。 |
State match
Match | –state |
Example | iptables -A INPUT -m state –state RELATED,ESTABLISHED |
Explanation | 指定要匹配包的的状态,当前有4种状态可用:INVALID,ESTABLISHED,NEW和RELATED。 INVALID意味着这个包没有已知的流或连接与之关 联,也可能是它包含的数据或包头有问题。ESTABLISHED意思是包是完全有效的,而 且属于一个已建立的连接,这个连接的两端都已经有数据发送。NEW表示包将要或已 经开始建立一个新的连接,或者是这个包和一个还没有在两端都有数据发送的连接有关。RELATED说明包正在建立一个新的连接,这个连接是和一个已建立的连接相关的。比 如,FTP data transfer,ICMP error 和一个TCP或UDP连接相关。注意NEW状态并不在试图建立新连接的TCP包里寻找SYN标 记,因此它不应该不加修改地用在只有一个防火墙或在不同的防火墙之间没有启用负载平衡的地方。具体如 何使用,你就再看看章节状态机制吧:) |
Targets/Jumps
target/jump决定符合条件的包到何处去,语法是–jump target或-j target。(译者注:本文中,原作者把target细分为两类,即Target和Jump。它们 唯一的区别是jump的目标是一个在同一个表内的链,而target的目标是具体的操作。)我们会先接触到两个 基本的target,就是ACCEPT和DROP。前面提到过用户自定义链要用到-N命令。下面我们在filter表中建一个名为tcp_packets的链: iptables -N tcp_packets 然后再把它作为jump的目标: iptables -A INPUT -p tcp -j tcp_packets 这样我们就会从INPUT链跳入tcp_packets链,开始在tcp_packets中的旅行。如果到达了tcp_packets链的结尾(也 就是未被链中的任何规则匹配),则会退到INPUT链的下一条规则继续它的旅行。如 果在子链中被ACCEPT了,也就相当于在父链中被ACCEPT了,那么它不会再经过父链中的其他规则。但要注意 这个包能被其他表的链匹配,过程可查看章节 表和链。 target指定我们要对包做的操作,比如DROP和ACCEPT,还有很多,我们后面会介绍。不同的target有不 同的结果。一些target会使包停止前景,也就是不再继续比较当前链中的其他规则或父链中的其他规则,最 好的例子就是DROP和ACCEPT。而另外一些target在对包做完操作之后,包还会继续和其他的规则比较,如LOG,ULOG和TOS。它们会对包进行记 录、mangle,然后让包通过,以便匹配这条链中的其他规则。有了这样的target,我们就可以对同一个包既 改变它的TTL又改变它的TOS。有些target必须要有准确的参数(如TOS需要确定的数值),有些就不是必须 的,但如果我们想指定也可以(如日志的前缀,伪装使用的端口,等等)。本节我们会尽可能全面地介绍每 一个target。现在我们就来看看有哪几种target。
ACCEPT target
这个target没有任何选项和参数,使用也很简单,指定-j ACCEPT即可。一旦包 满足了指定的匹配条件,就会被ACCEPT,并且不会再去匹配当前链中的其他规则或同一个表内的其他规则, 但它还要通过其他表中的链,而且在那儿可能会百DROP也说不准哦。
DNAT target
Option | –to-destination |
Example | iptables -t nat -A PREROUTING -p tcp -d 15.45.23.67 –dport 80 -j DNAT –to-destination 192.168.1.1-192.168.1.10 |
Explanation | 指定要写入IP头的地址,这也是包要被转发到的地方。上面 的例子就是把所有发往地址15.45.23.67的包都转发到一段LAN使用的私有地址中,即192.168.1.1到 192.168.1.10。如前所述,在这种情况下,每个流都会被随机分配一个要转发到的地址,但同一个流总是使 用同一个地址。我们也可以只指定一个IP地址作为参数,这样所有的包都被转发到同一台机子。我们还可以 在地址后指定一个或一个范围的端口。比如:–to-destination 192.168.1.1:80或 –to-destination 192.168.1.1:80-100。SNAT的语法和这 个target的一样,只是目的不同罢了。要注意,只有先用–protocol指定了TCP或 UDP协议,才能使用端口。 |
DROP target
顾名思义,如果包符合条件,这个target就会把它丢掉,也就是说包的生命到此结束,不会再向前走一 步,效果就是包被阻塞了。在某些情况下,这个target会引起意外的结果,因为它不会向发送者返回任何信 息,也不会向路由器返回信息,这就可能会使连接的另一方的sockets因苦等回音而亡:) 解决这个问题的较 好的办法是使用REJECT target,(译者注:因为它在丢弃包的同时还会向发送者返 回一个错误信息,这样另一方就能正常结束),尤其是在阻止端口扫描工具获得更多的信息时,可以隐蔽被 过滤掉的端口等等(译者注:因为扫描工具扫描一个端口时,如果没有返回信息,一般会认为端口未打开或 被防火墙等设备过滤掉了)。还要注意如果包在子链中被DROP了,那么它在主链里也不会再继续前进,不管 是在当前的表还是在其他表里。总之,包死翘翘了。
LOG target
这个target是专门用来记录包地有关信息的。这些信息可能是非法的,那就可以用来除错。LOG会返回包 的有关细节,如IP头的大部分和其他有趣的信息。这个功能是通过内核的日志工具完成的,一般是syslogd。返回的信息可用dmesg阅读,或者可以直接查看syslogd的日志文件,也可以用其他的什么程序来看。LOG对调试规则有很大的帮助,你 可以看到包去了哪里、经过了什么规则的处理,什么样的规则处理什么样的包,等等。当你在生产服务器上 调试一个不敢保证100%正常的规则集时,用LOG代替DROP是比较好的(有详细的信息可看,错误就容易定 位、解决了),因为一个小小的语法错误就可能引起严重的连接问题,用户可不喜欢这样哦。如果你想使用 真正地扩展日志地话,可能会对ULOG target有些兴趣,因为它可以把日志直接记录 到MySQL databases或类似的数据库中。
注意,如果在控制台得到的信息不是你想要的,那不是iptables或Netfilter的问题,而是 syslogd 配置文件的事,这个文件一般都是/etc/syslog.conf。有关这个问题的更多信息请查通过man syslog.conf查看。 |
LOG现在有5个选项,你可以用它们指定需要的信息类型或针对不同的信息设定一 些值以便在记录中使用。选项如下:
Table 6-17. LOG target options
Option | –log-level |
Example | iptables -A FORWARD -p tcp -j LOG –log-level debug |
Explanation | 告诉iptables和 syslog使用哪个记录等级。记录等级的详细信息可以查看文件syslog.conf,一般来说有以下几种,它 们的级别依次是:debug,info,notice,warning,warn,err,error,crit,alert, emerg,panic。其中,error和err、warn和warning、panic和emerg分别是同义词,也就是说作用完全 一样的。注意这三种级别是不被赞成使用的,换句话说,就是不要使用它们(因为信息量太大)。信息级别 说明了被记录信息所反映的问题的严重程度。所有信息都是通过内核的功能被记录的,也就是说,先在文件 syslog.conf里设置kern.=info /var/log/iptables,然 后再让所有关于iptables的LOG信息使用级别info,就可以把所有的信息存入文件/var/log/iptables内。注意,其中也可能会有其他的信息,它们是内核中使用info 这个等级的其他部分产生的。有关日志的详细信息,我建议你看看syslog和syslog.conf的帮助,还有HOWTO,等等。 |
Option | –log-prefix |
Example | iptables -A INPUT -p tcp -j LOG –log-prefix “INPUT packets” |
Explanation | 告诉iptables在记录的信息之前加 上指定的前缀。这样和grep或其他工具一起使用时就容易追踪特定的问题,而且也 方便从不同的规则输出。前缀最多能有29个英文字符,这已经是包括空白字符和其他特殊符号的总长度了。 |
Option | –log-tcp-sequence |
Example | iptables -A INPUT -p tcp -j LOG –log-tcp-sequence |
Explanation | 把包的TCP序列号和其他日志信息一起记录下来。TCP序列号 可以唯一标识一个包,在重组时也是用它来确定每个分组在包里的位置。注意,这个选项可能会带来危险, 因为这些记录被未授权的用户看到的话,可能会使他们更容易地破坏系统。其实,任何iptables的输出信息 都增加了这种危险。(译者注:现在,我深刻理解了什么是“言多必失”,什么是“沉默是金”) |
Option | –log-tcp-options |
Example | iptables -A FORWARD -p tcp -j LOG –log-tcp-options |
Explanation | 记录TCP包头中的字段大小不变的选项。这对一些除错是很 有价值的,通过它提供的信息,可以知道哪里可能出错,或者哪里已经出了错。 |
Option | –log-ip-options |
Example | iptables -A FORWARD -p tcp -j LOG –log-ip-options |
Explanation | 记录IP包头中的字段大小不变的选项。这对一些除错是很有 价值的,还可以用来跟踪特定地址的包。 |
MASQUERADE target
这个target和SNAT target的作用是一样的,区别就是它不需要指定–to-source 。MASQUERADE是被专门设计用于那些动态获取IP地址的连接的,比如,拨号上网、DHCP连接等。如果你 有固定的IP地址,还是用SNAT target吧。伪装一个连接意味着,我们自动获取网络接口的IP地址,而不使用–to-source 。当接口停用时,MASQUERADE不会记住任何连接,这在我们kill掉接口时是有 很大好处的。如果我们使用SNAT target,连接跟踪的数据是被保留下来的,而且时 间要好几天哦,这可是要占用很多连接跟踪的内存的。一般情况下,这种处理方式对于拨号上网来说是较好 的(这有利于已有那连接继续使用)。如果我们被分配给了一个不同于前一次的IP,不管怎样已有的连接都 要丢失,但或多或少地还是有一些连接记录被保留了(真是白痴,是吧)。即使你有静态的IP,也可以使用MASQUERADE,而不用SNAT 。不过,这不是被赞成的,因为它会带来额外的开销,而且以后还可能引起矛盾,比如它也许会影响你 的脚本,使它们不能用。注意,MASQUERADE和SNAT一样,只能用于nat表的 POSTROUTING链,而且它只有一个选项(不是必需的):
Table 6-19. MASQUERADE target
Option | –to-ports |
Example | iptables -t nat -A POSTROUTING -p TCP -j MASQUERADE –to-ports 1024-31000 |
Explanation | 在指定TCP或UDP的前提下,设置外出包能使用的端口,方式 是单个端口,如–to-ports 1025,或者是端口范围,如–to- ports 1024-3000。注意,在指定范围时要使用连字号。这改变了SNAT中缺省的端口选择,详情请查看 SNAT target。 |
REDIRECT target
在防火墙所在的机子内部转发包或流到另一个端口。比如,我们可以把所有去往端口HTTP的包REDIRECT到HTTP proxy(例如squid),当然这都发生在我们自己的主机内部。本地生成的包都会被映射到127.0.0.1。换句 话说,这个target把要转发的包的目的地址改写为我们自己机子的IP。我们在做透明代理(LAN内的机子根 本不需要知道代理的存在就可以正常上网)时,这个target可是起了很大作用的。注意,它只能用在nat表的PREROUTING、OUTPUT链和被它们调用的自定义链里。 REDIRECT只有一个选项:
Table 6-20. REDIRECT target
Option | –to-ports |
Example | iptables -t nat -A PREROUTING -p tcp –dport 80 -j REDIRECT –to-ports 8080 |
Explanation | 在指定TCP或UDP协议的前提下,定义目的端口,方式如下: 1、不使用这个选项,目的端口不会被改变。 2、指定一个端口,如–to-ports 8080 3、指定端口范围,如–to-ports 8080-8090 |
REJECT target
REJECT和DROP基本一样,区别在于它除了阻塞包之外, 还向发送者返回错误信息。现在,此target还只能用在INPUT、FORWARD、OUTPUT和它们的子链里,而且包含 REJECT的链也只能被它们调用,否则不能发挥作用。它只有一个选项,是用来控制 返回的错误信息的种类的。虽然有很多种类,但如果你有TCP/IP方面的基础知识,就很容易理解它们。
Table 6-21. REJECT target
Option | –reject-with |
Example | iptables -A FORWARD -p TCP –dport 22 -j REJECT –reject-with tcp-reset |
Explanation | 告诉REJECT target应向发送者返回 什么样的信息。一旦包满足了设定的条件,就要发送相应的信息,然后再象DROP一 样无情地抛弃那些包。可用的信息类型有:1、icmp-net-unreachable 2、icmp-host-unreachable 3、 icmp-port-unreachable 4、icmp-proto-unreachable 5、icmp-net-prohibited 6、icmp-host-prohibited 。其中缺省的是port-unreachable。你可以在附录ICMP类 型中看到更多的信息。还有一个类型——echo-reply,它只能和匹配 ICMP ping包的规则联用。最后一个类型是tcp-reset,(显然,只能用于TCP协议) 它的作用是告诉REJECT返回一个TCP RST包(这个包以文雅的方式关闭TCP连接,有关它的详细信息在RFC 793 – Transmission Control Protocol里)给发送者。正如iptables的 man page中说的,tcp-reset主要用来阻塞身份识别探针(即113/tcp,当向被破坏的邮件主机发送邮件时, 探针常被用到,否则它不会接受你的信)。 |
SNAT target
这个target是用来做源网络地址转换的,就是重写包的源IP地址。当我们有几个机子共享一个Internet 连接时,就能用到它了。先在内核里打开ip转发功能,然后再写一个SNAT规则,就 可以把所有从本地网络出去的包的源地址改为Internet连接的地址了。如果我们不这样做而是直接转发本地 网的包的话,Internet上的机子就不知道往哪儿发送应答了,因为在本地网里我们一般使用的是IANA组织专 门指定的一段地址,它们是不能在Internet上使用的。SNAT target的作用就是让所 有从本地网出发的包看起来都是从一台机子发出的,这台机子一般就是防火墙。 SNAT只能用在nat表的POSTROUTING链里。只要连接的第一个符合条件的包被SNAT了,那么这个连接的其他所有的包都会自动地被SNAT,而且这个规则还会应用于这 个连接所在流的所有数据包。
Option | –to-source |
Example | iptables -t nat -A POSTROUTING -p tcp -o eth0 -j SNAT –to-source 194.236.50.155-194.236.50.160:1024-32000 |
Explanation | 指定源地址和端口,有以下几种方式: 1、单独的地址。 2、一段连续的地址,用连字符分隔,如194.236.50.155-194.236.50.160,这样可以实现负载平衡。每 个流会被随机分配一个IP,但对于同一个流使用的是同一个IP。 3、在指定-p tcp 或 -p udp的前提下,可以指定源端口的范围,如194.236.50.155:1024-32000,这样 包的源端口就被限制在1024-32000了。注意,如果可能,iptables总是想避免任何的端口变更,换句话说,它总是尽力使用建立连接时所用的 端口。但是如果两台机子使用相同的源端口,iptables 将会把他们的其中之一映射到另外的一个端口。如 果没有指定端口范围, 所有的在512以内的源端口会被映射到512以内的另一个端口,512和1023之间的将会 被映射到 1024内,其他的将会被映射到大于或对于1024的端口,也就是说是同范围映射。还要注意,这种 映射和目的端口无关。因此,如果客户想和防火墙外的HTTP服务器联系,它是不会被映射到FTP control所用的端口的。 |
参考:http://www.frozentux.net/iptables-tutorial/cn/iptables-tutorial-cn-1.1.19.html
本文出自 Linux运维日志,转载时请注明出处及相应链接。
本文永久链接: https://www.centos.bz/2012/07/iptables-notes/