iptables--规则

1.基本语法

基本语法如下:

iptables [-t table ] command [match] [target/jump]

对于这个句法没什么可说的,但注意 target 指令必须在最后。为了易读,我们一般用这种语法。总之,你将见到的大部分规则都是按这种语法写的。在[table]处指定表名。一般情况下没有必要指定使用的表,因为 iptables 默认使用 filter 表来执行所有的命令。command告诉程序该做什么,比如:插入一个规则,还是在链的末尾增加一个规则,还是删除一个规则。match 细致地描述了包的某个特点,以使这个包区别于其它所有的包。在这里,我们可以指定包的来源 IP 地址,网络接口,端口,协议类型,或者其他什么。最后是数据包的目标所在。若数据包符合所有的 match,内核就用 target 来处理它,或者说把包发往 target。比如,我们可以让内核把包发送到当前表中的其他链(可能是我们自己建立的),或者只是丢弃这个包而没有什么处理,或者向发送者返回某个特殊的应答。

2.表

选项-t 用来指定使用哪个表,它可以是下面介绍的表中的任何一个,默认的是
filter 表。

Table (表名) Explanation (注释)
nat 主要用处是网络地址转换,即 Network AddressTranslation,缩写为 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 专门过滤包的,内建三个链,可以毫无问题地对包进行 DROP、LOG、ACCEPT 和 REJECT 等操作。 FORWARD 链过滤所有不是本地产生的并且目的地不是本地(所谓本地就是防火墙了)的包,而 INPUT 恰恰针对那些目的地是本地的包。 OUTPUT 是用来过滤所有本地生成的包的。

3.命令

command 指定iptables 对我们提交的规则要做什么样的操作。这些操作可能是在某个表里增加或删除一些东西,或做点儿其他什么。

命令 -A, --append
举例 iptables -A INPUT …
说明 在所选择的链末添加规则。当源地址或目的地址是以名字而不是ip 地址的形式出现时,若这些名字可以被解析为多个地址,则这条规则会和所有可用的地址结合。
命令 -C, --check
举例 iptables -C INPUT --dport 80 -j DROP
说明 检查所选链中的规则是否存在
命令 -D, --delete
举例 iptables -D INPUT --dport 80 -j DROP 或 iptables -D INPUT 1
说明 从所选链中删除规则。有两种方法指定要删除的规则:一是把规则完完整整地写出来,再就是指定规则在所选链中的序号(每条链的规则都各自从 1 被编号)。
命令 -R, --replace
举例 iptables -R INPUT 1 -s 192.168.0.1 -j DROP
说明 在所选中的链里指定的行上(每条链的规则都各自从 1 被编号)替换规则。它主要的用处是试验不同的规则。当源地址或目的地址是以名字而不是 ip 地址的形式出现时,若这些名字可以被解析为多个地址,则这条 command 会失败。
命令 -I, --insert
举例 iptables -I INPUT 1 --dport 80 -j ACCEPT
说明 根据给出的规则序号向所选链中插入规则。如果序号为 1,规则会被插入链的头部,其实默认序号就是 1。
命令 -L, --list
举例 iptables -L INPUT
说明 列出所选链的所有规则。如果没有指定链,则显示指定表中的所有链。如果什么都没有指定,就显示默认表所有的链。精确输出受其它参数影响,如-n 和-v 等参数,下面会介绍。
命令 -S, --list-rules
举例 iptables -S INPUT
说明 打印所选链的所有规则。如果没有指定链,则显示指定表中的所有链。如果什么都没有指定,就显示默认表所有的链。
命令 -F, --flush
举例 iptables -F INPUT
说明 清空所选的链。如果没有指定链,则清空指定表中的所有链。如果什么都没有指定,就清空默认表所有的链。当然,也可以一条一条地删,但用这个 command 会快些。
命令 -Z, --zero
举例 iptables -Z INPUT
说明 把指定链(如未指定,则认为是所有链)的所有计数器归零。
命令 -N, --new-chain
举例 iptables -N allowed
说明 根据用户指定的名字建立新的链。上面的例子建立了一个名为allowed 的链。注意,所用的名字不能和已有的链、target 同名。
命令 -X, --delete-chain
举例 iptables -X allowed
说明 删除指定的用户自定义链。这个链必须没有被引用,如果被引用,在删除之前你必须删除或者替换与之有关的规则。如果没有给出参数,这条命令将会删除默认表所有非内建的链。
命令 -P, --policy
举例 iptables -P INPUT DROP
说明 为链设置默认的 target(可用的是 DROP 和 ACCEPT,如果还有其它的可用,请告诉我),这个 target 称作策略。所有不符合规则的包都被强制使用这个策略。只有内建的链才可以使用规则。但内建的链和用户自定义链都不能被作为策略使用,也就是说不能像这样使用:iptables -P INPUT allowed(或者是内建的链)。
命令 -E, --rename-chain
举例 iptables -E allowed disallowed
说明 对自定义的链进行重命名,原来的名字在前,新名字在后。如上,就是把 allowed 改为 disallowed。这仅仅是改变链的名字,对整个表的结构、工作没有任何影响。

4.选项

选项 -t, --table
可用此选项的命令 all
说明 表操作,默认为filter
选项 -v, --verbose
可用此选项的命令 -L,-A,-I,-D,-R
说明 这个选项使输出详细化,常与-L连用。与-L连用时,输(说明)出中包括网络接口的地址、规则的选项、TOS 掩码、字节和包计数器,其中计数器是以 K、M、G(这里用的是 10 的幂而不是 2 的幂哦)为单位的。如果想知道到底有多少个包、多少字节,还要用到选项-x,下面会介绍。如果-v 和-A,-I,-D 或-R 连用,iptables 会输出详细的信息告诉你规则是如何被解释的、是否正确地插入等等。
选项 -x, --exact
可用此选项的命令 -L
说明 使-L输出中的计数器显示准确的数值,而不用 K、M、G 等估值。
选项 -n, --numeric
可用此选项的命令 -L
说明 使输出中的 IP 地址和端口以数值的形式显示,而不是默认的名字,比如主机名、网络名、程序名等。
选项 –line-numbers
可用此选项的命令 -L
说明 显示出每条规则在相应链中的序号。
选项 -c, --set-counters
可用此选项的命令 -A,-I,-R
说明 在创建或更改规则时设置计数器,语法如下:–set-counters 20 4000,意思是让内核把包计数器设为 20,把字节计数器设为 4000。

5.匹配

归为五类。第一类是 generic matches(通用的匹配) ,适用于所有的规则;第二类是 TCP matches ,顾名思义,这只能用于 TCP 包;第三类是 UDP matches ,当然它只能用在 UDP 包上了;第四类是 ICMP matches ,针对 ICMP 包的;第五类比较特殊,针对的是状态(state),所有者(owner)和访问的频率限制(limit)等。

5.1 通用匹配

无论我们使用的是何种协议,也不管我们又装入了匹配的何种扩展,通用匹配都使可用的。也就是说,它们可以直接使用,而不需要什么前提条件,在后面你会看到,有很多匹配操作是需要其他的匹配作为前提的。

匹配 -p, --protocol
举例 iptables -A INPUT -p tcp
说明 匹配指定的协议。指定协议的形式有以下几种:1、名字,不分大小写,但必须是在 /etc/protocols 中定义的。2、可以使用它们相应的整数值。例如,ICMP 的值是 1,TCP 是 6,UDP 是 17。3、缺省设置,ALL,相应数值是 0,但要注意这只代表匹配 TCP、UDP、ICMP,而不是 /etc/protocols 中定义的所有协议。4、可以是协议列表,以英文逗号为分隔符,如:udp,tcp5、可以在协议前加英文的感叹号表示取反,注意有空格,如:-p ! tcp 表示非 tcp 协议,也就是 UDP 和 ICMP。可以看出这个取反的范围只是 TCP、UDP 和 ICMP。
匹配 -s, --src, --source
举例 iptables -A INPUT -s 192.168.1.1
说明 以 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、缺省是所有地址
匹配 -d, --dst, --destination
举例 iptables -A INPUT -d 192.168.1.1
说明 以 IP 目的地址匹配包。地址的形式和 – source 完全一样。
匹配 -i, --in-interface
举例 iptables -A INPUT -i eth0
说明 以包进入本地所使用的网络接口来匹配包。要注意这个匹配操作只能用于 INPUT , FORWARD 和 PREROUTING 这三个链,用在其他任何地方都会提示错误信息。指定接口有一下方法:1、指定接口名称,如:eth0、ppp0 等。2、使用通配符,即英文加号,它代表字符数字串。若直接用一个加号,即 iptables -A INPUT -i +表示匹配所有的包,而不考虑使用哪个接口。这也是不指定接口的默认行为。通配符还可以放在某一类接口的后面,如:eth+表示所有 Ethernet 接口,也就是说,匹配所有从 Ethernet 接口进入的包。3、在接口前加英文感叹号表示取反,注意空格,如:-i ! eth0意思是匹配来自除 eth0 外的所有包。
匹配 -o, --out-interface
举例 iptables -A FORWARD -o eth0
说明 以包离开本地所使用的网络接口来匹配包。使用的范围和指定接口的方法与–in-interface 完全一样。
匹配 -f, --fragment
举例 iptables -A INPUT -f
说明 用来匹配一个被分片的包的第二片或及以后的部分。因为它们不包含源或目的地址,或 ICMP 类型等信息,其他规则无法匹配到它,所以才有这个匹配操作。要注意碎片攻击哦。这个操作也可以加英文感叹号表示取反,但要注意位置,如:! -f 。取反时,表示只能匹配到没有分片的包或者是被分片的包的第一个碎片,其后的片都不行。现在内核有完善的碎片重组功能,可以防止碎片攻击,所以不必使用取反的功能来防止碎片通过。如果你使用连接跟踪,是不会看到任何碎片的,因为在它们到达任何链之前就被处理过了。

5.2 隐含匹配

这种匹配操作是自动地或隐含地装载入内核的。例如我们使用–protocol tcp时,不需再装入任何东西就可以匹配只有 IP 包才有的一些特点。现在有三种隐含的匹配针对三种不同的协议,即 TCP matches , UDP matches 和 ICMP matches 。它们分别包括一套只适用于相应协议的判别标准。

5.2.1 TCP匹配

TCP matches 只能匹配 TCP 包或流的细节,它们必须有–protocol tcp 作为前提条件。

匹配 –sport, --source-port
举例 iptables -A INPUT -p tcp --sport 22
说明 基于 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 这样的操作是由后面将要介绍的多端口匹配扩展来完成的。
匹配 –dport, --destination-port
举例 iptables -A INPUT -p tcp --dport 22
说明 基于 TCP 包的目的端口来匹配包,端口的指定形式和–sport 完全一样。
匹配 –tcp-flags
举例 iptables -p tcp --tcp-flags SYN ACK
说明 匹配指定的 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比较一下。
匹配 –tcp-option
举例 iptables -p tcp --tcp-option 16
说明 根据匹配包。TCP 选项是 TCP 头中的特殊部分,有三个不同的部分。第一个 8 位组表示选项的类型,第二个 8 位组表示选项的长度(这个长度是整个选项的长度,但不包含填充部分所占的字节,而且要注意不是每个 TCP 选项都有这一部分的),第三部分当然就是选项的内容了。为了适应标准,我们不必执行所有的选项,但我们可以查看选项的类型,如果不是我们所支持的,那就只是看看长度然后跳过数据部分。这个操作是根据选项的十进制值来匹配的,它也可以用英文感叹号取反。

5.2.2 UDP匹配

UDP matches 是在指定–protocol UDP 时自动装入的。UDP 是一种无连接协议,
所以在它打开、关闭连接以及在发送数据时没有多少标记要设置,它也不需要任
何类型的确认。数据丢失了,就丢失了(不会发送 ICMP 错误信息的)。这就说
明 UDP matches 要比 TCP matches 少多了。

匹配 –sport, --source-port
举例 iptables -A INPUT -p udp --sport 53
说明 基于 UDP 包的源端口来匹配包,端口的指定形式和 TCP matches 中的–sport 完全一样。
匹配 –dport, --destination-port
举例 iptables -A INPUT -p udp --dport 53
说明 基于 UDP 包的目的端口来匹配包,端口的指定形式和 TCP matches中的–sport 完全一样。

5.2.3 ICMP匹配

ICMP 协议也是无连接协议。ICMP 协议不是IP 协议的下属协议,而是它的辅助者,其主要作用是报告错误和连接控制。

匹配 –icmp-type
举例 iptables -A INPUT -p icmp --icmp-type 8
说明 根据 ICMP 类型匹配包,类型的指定可以使用十进制数值或相应的名字,数值在 RFC792 中有定义,名字可以用 iptables --protocol icmp --help 查看,或者在附录 ICMP 类型 中查找。这个匹配也可用英文感叹号取反,如:–icmp-type ! 8 就表示匹配除类型 8 之外的所有 ICMP 包。要注意有些 ICMP 类型已经废弃不用了,还有一些可能会对无防护的主机带来“危险”,因为它们可能把包重定向到错误的地方。

5.3 显式匹配

显式匹配必须用-m 或–match 装载,比如要使用状态匹配就必须使用-m state。
有些匹配还需要指定协议,有些就不需要,比如连接状态就不要。隐含匹配和显式匹配最大的区别就是一个是跟随协议匹配自动装载的,一个是显式装载的。

5.3.1 Limit匹配

这个匹配操作必须由-m limit 明确指定才能使用。有了它的帮助,就可以对指定的规则的日志数量加以限制,以免你被信息的洪流淹没哦。比如,你可以事先设定一个限定值,当符合条件的包的数量不超过它时,就记录;超过了,就不记录了。我们可以控制某条规则在一段时间内的匹配次数(也就是可以匹配的包的数量),这样就能够减少 DoS syn flood 攻击的影响。这是它的主要作用,当然,还有很多其他作用(译者注:比如,对于某些不常用的服务可以限制连接数量,以免影响其他服务)。limit match 也可以用英文感叹号取反,如:-m limit ! --limit 5/s 表示在数量超过限定值后,所有的包都会被匹配。比如,你指定了–limit 3/minute --limit-burst 5 ,意思是开始时有 5 个,用完之后每 20 秒增加一个(这就是从 iptables 的角度看的,要是以用户的角度看,说法就是每一分钟增加三个或者每分钟只能过三个)。你要是想每 20 分钟过一个,只能写成–limit 3/hour --limit-burst 5,也就是说你要把时间单位凑成整的。

匹配 –limit
举例 iptables -A INPUT -m limit --limit 3/hour
说明 设置最大平均匹配速率,也就是单位时间内 limit match 可以匹配几个包。它的形式是一个数值加一个时间单位,可以是/second /minute /hour /day 。默认值是每小时 3 次(用户角度),即 3/hour ,也就是每 20 分钟一次(iptables 角度)。
匹配 –limit-burst
举例 iptables -A INPUT -m limit --limit-burst 5
说明 这里定义的是 limit match 的峰值,就是在单位时间(这个时间由上面的–limit 指定)内最多可匹配几个包(由此可见,–limit-burst 的值要比–limit 的大)。默认值是 5。

5.3.2 MAC匹配

基于包的 MAC 源地址匹配包。

匹配 –mac-source
举例 iptables -A INPUT -m mac --mac-source 00:00:00:00:00:01
说明 基于包的 MAC 源地址匹配包,地址格式只能是 XX:XX:XX:XX:XX:XX ,当然它也可以用英文感叹号取反,如–mac- source !00:00:00:00:00:01,意思很简单了,就是除此之外的地址都可接受嘛。注意,因为 MAC addresses 只用于 Ethernet 类型的网络,所以这个 match 只能用于 Ethernet 接口。而且,它还只能在PREROUTING , FORWARD 和 INPUT 链里使用。

5.3.3 Mark匹配

以包被设置的 mark 来匹配包,这个值只能由内核更改。前面曾经提到过,mark
比较特殊,它不是包本身的一部分,而是在包穿越计算机的过程中由内核分配的
和它相关联的一个字段。它可能被用来改变包的传输路径或过滤。时至今日,在
linux 里只有一种方法能设置 mark,即 iptables 的 MARK target。mark 字段的值是一个无符号的整数,在 32 位系统上最大可以是 4294967296(就是 2 的 32 次方)。

匹配 –mark
举例 iptables -t mangle -A INPUT -m mark --mark 1
说明 以包被设置的 mark 值来匹配包,这个值是是由下面将要介绍的MARK target 来设置的,它是一个无符号的整数。所有通过Netfilter 的包都会被分配一个相关联的 mark field 。但要注意mark 值可不是在任何情况下都能使用的,它只能在分配给它值的那台机子里使用,因为它只是由内核在内存里分配的和包相关的几个字节,并不属于包本身,所以我们不能在本机之外的路由器上使用。mark 的格式是–mark value[/mask],如上面的例子是没有掩码的,带掩码的例子如–mark 1/1。如果指定了掩码,就先把 mark值和掩码取逻辑与,然后再和包的 mark 值比较。

5.3.4 Multiport匹配

多端口匹配扩展使我们能够在一条规则里指定不连续的多个端口,如果没有这个
扩展,我们只能按端口来写规则了。

匹配 –source-port
举例 iptables -A INPUT -p tcp -m multiport --source-port 22,53,80,110
说明 源端口多端口匹配,最多可以指定 15 个端口,以英文逗号分隔,注意没有空格。使用时必须有-p tcp 或-p udp 为前提条件。
匹配 –destination-port
举例 iptables -A INPUT -p tcp -m multiport --destination-port 22,53,80,110
说明 目的端口多端口匹配,使用方法和源端口多端口匹配一样,唯一的区别是它匹配的是目的端口。
匹配 –port
举例 iptables -A INPUT -p tcp -m multiport --port 22,53,80,110
说明 同端口多端口匹配,意思就是它匹配的是那种源端口和目的端口是同一个端口的包,比如:端口 80 到端口 80 的包,110 到 110 的包等。使用方法和源端口多端口匹配一样。

5.3.5 State匹配

匹配 –state
举例 iptables -A INPUT -m state --state RELATED,ESTABLISHED
说明 指定要匹配包的的状态,当前有 4 种状态可用:INVALID,ESTABLISHED,NEW 和 RELATED。 INVALID 意味着这个包没有已知的流或连接与之关联,也可能是它包含的数据或包头有问题。ESTABLISHED 意思是包是完全有效的,而且属于一个已建立的连接,这个连接的两端都已经有数据发送。NEW 表示包将要或已经开始建立一个新的连接,或者是这个包和一个还没有在两端都有数据发送的连接有关。RELATED 说明包正在建立一个新的连接,这个连接是和一个已建立的连接相关的。比如, FTP data transfer , ICMP error和一个 TCP 或 UDP 连接相关。注意 NEW 状态并不在试图建立新连接的 TCP 包里寻找 SYN 标记,因此它不应该不加修改地用在只有一个防火墙或在不同的防火墙之间没有启用负载平衡的地方。

5.3.6 TOS匹配

TOS 是 IP 头的一部分,其含义是 Type Of Service ,由 8 个二进制位组成,包括一个 3 bit 的优先权子字段(现在已被忽略),4 bit 的 TOS 子字段和 1 bit 未用位(必须置 0)。它一般用来把当前流的优先权和需要的服务(比如,最小延时、最大吞吐量等)通知路由器。但路由器和管理员对这个值的处理相差很大,有的根本就不理会,而有的就会尽量满足要求。

匹配 –state
举例 iptables -A INPUT -p tcp -m tos --tos 0x16
说明 根据 TOS 字段匹配包。这个 match 常被用来 mark 包,以便后用,除此之外,它还常和 iproute2 或高级路由功能一起使用。它的参数可以是 16 进制数,也可以是十进制数,还可以是相应的名字(用iptables -m tos -h 能查到)。到写这篇文章时,有以下参数可用:Minimize-Delay 16 (0x10),要求找一条路径使延时最小,一些标准服务如 telnet、SSH、FTP-control 就需要这个选项。Maximize-Throughput 8 (0x08),要求找一条路径能使吞吐量最大,标准服务 FTP-data 能用到这个。Maximize-Reliability 4 (0x04),要求找一条路径能使可靠性最高,使用它的有 BOOTP 和 TFTP。Minimize-Cost 2 (0x02),要求找一条路径能使费用最低,一般情况下使用这个选项的是一些视频音频流协议,如 RTSP(Real TimeStream Control Protocol)。Normal-Service 0 (0x00),一般服务,没有什么特殊要求。

5.3.7 TTL匹配

根据 IP 头里的 TTL (Time To Live,即生存期)字段来匹配包一旦经过一个处理它的路由器,它的值就减去 1 它的值。当该字段的值减为 0 时,报文就被认为是不可转发的,数据报就被丢弃,并发送 ICMP 报文通知源主机,不可转发的报文被丢弃。

匹配 –ttl
举例 iptables -A OUTPUT -m ttl --ttl 60
说明 根据 TTL 的值来匹配包,参数的形式只有一种,就是十进制数值。它可以被用来调试你的局域网,比如解决 LAN 内的主机到 Internet上的主机的连接问题,或找出 Trojan(Trojan)可能的入口。这个 match 的用处相对有限,但它其实是很有用的,这就看你的想象力如何了。比如可以用它来发现那些 TTL 具有错误缺省值的机子(这可能是实现 TCP/IP 栈功能的那个程序本身的错误,或者是配置有问题)。

6.目标/跳跃

target/jump 决定符合条件的包到何处去,语法是–jump target 或-j target。它们唯
一的区别是 jump 的目标是一个在同一个表内的链,而 target 的目标是具体的操
作。用户自定义链要用到-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。

6.1 ACCEPT target

这个 target 没有任何选项和参数,使用也很简单,指定-j ACCEPT 即可。一旦包满足了指定的匹配条件,就会被 ACCEPT,并且不会再去匹配当前链中的其他规则或同一个表内的其他规则,但它还要通过其他表中的链,而且在那儿可能会被DROP 也说不准哦。

6.2 DNAT target

这个 target 是用来做目的网络地址转换的,就是重写包的目的 IP 地址。如果一
个包被匹配了,那么和它属于同一个流的所有的包都会被自动转换,然后就可以
被路由到正确的主机或网络。DNAT target 是非常有用的。比如,你的 Web 服务
器在 LAN 内部,而且没有可在 Internet 上使用的真实 IP 地址,那就可以使用这个 target 让防火墙把所有到它自己 HTTP 端口的包转发给 LAN 内部真正的 Web
服务器。目的地址也可以是一个范围,这样的话,DNAT 会为每一个流随机分配
一个地址。因此,我们可以用这个 target 做某种类型地负载平衡。
注意,DANT target 只能用在 nat 表的 PREROUTING 和 OUTPUT 链中,或者是被这两条链调用的链里。但还要注意的是,包含 DANT target 的链不能被除此之外的其他链调用,如 POSTROUTING。

选项 –to-destination
举例 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
说明 指定要写入 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 协议,才能使用端口。

6.3 DROP target

如果包符合条件,这个 target 就会把它丢掉,也就是说包的生命到此结束,不会再向前走一步,效果就是包被阻塞了。在某些情况下,这个 target会引起意外的结果,因为它不会向发送者返回任何信息,也不会向路由器返回信息,这就可能会使连接的另一方的 sockets 因苦等回音而亡。解决这个问题的较好的办法是使用 REJECT target,(译者注:因为它在丢弃包的同时还会向发送者返回一个错误信息,这样另一方就能正常结束),尤其是在阻止端口扫描工具获得更多的信息时,可以隐蔽被过滤掉的端口等等(译者注:因为扫描工具扫描一个端口时,如果没有返回信息,一般会认为端口未打开或被防火墙等设备过滤掉了)。还要注意如果包在子链中被 DROP 了,那么它在主链里也不会再继续前进,不管是在当前的表还是在其他表里。

6.4 LOG target

这个 target 是专门用来记录包地有关信息的。这些信息可能是非法的,那就可以用来除错。LOG 会返回包的有关细节,如 IP 头的大部分和其他有趣的信息。这个功能是通过内核的日志工具完成的,一般是 syslogd。返回的信息可用 dmesg阅读,或者可以直接查看 syslogd 的日志文件,也可以用其他的什么程序来看。LOG 对调试规则有很大的帮助,你可以看到包去了哪里、经过了什么规则的处理,什么样的规则处理什么样的包,等等。当你在生产服务器上调试一个不敢保证100%正常的规则集时,用 LOG 代替 DROP 是比较好的(有详细的信息可看,错误就容易定位、解决了)。

6.5 MARK target

用来设置 mark 值,这个值只能在本地的 mangle 表里使用,不能用在其他任何地方,就更不用说路由器或另一台机子了。因为 mark 比较特殊,它不是包本身的一部分,而是在包穿越计算机的过程中由内核分配的和它相关联的一个字段。它可以和本地的高级路由功能联用,以使不同的包能使用不同的队列要求,等等。如果你想在传输过程中也有这种功能,还是用 TOS target 吧。

选项 –set-mark
举例 iptables -t mangle -A PREROUTING -p tcp --dport 22 -j MARK --set-mark 2
说明 设置 mark 值,这个值是一个无符号的整数。比如,我们对一个流或从某台机子发出的所有的包设置了 mark 值,就可以利用高级路由功能来对它们进行流量控制等操作了。

6.6 MASQUERADE target

这个 target 和 SNAT target 的作用是一样的,区别就是它不需要指定–to-source 。MASQUERADE 是被专门设计用于那些动态获取 IP 地址的连接的,比如,拨号上网、DHCP 连接等。如果你有固定的 IP 地址,还是用 SNAT target吧。
伪装一个连接意味着,我们自动获取网络接口的 IP 地址,而不使用–to-source 。当接口停用时,MASQUERADE 不会记住任何连接,这在我们 kill掉接口时是有很大好处的。如果我们使用 SNAT target,连接跟踪的数据是被保留下来的,而且时间要好几天哦,这可是要占用很多连接跟踪的内存的。一般情况下,这种处理方式对于拨号上网来说是较好的(这有利于已有那连接继续使用)。如果我们被分配给了一个不同于前一次的 IP,不管怎样已有的连接都要丢失,但或多或少地还是有一些连接记录被保留了(真是白痴,是吧)。
即使你有静态的 IP,也可以使用 MASQUERADE,而不用 SNAT 。不过,这不是被赞成的,因为它会带来额外的开销,而且以后还可能引起矛盾,比如它也许会影响你的脚本,使它们不能用。

选项 –to-ports
举例 iptables -t nat -A POSTROUTING -p TCP -j MASQUERADE --to-ports 1024-31000
说明 在指定 TCP 或 UDP 的前提下,设置外出包能使用的端口,方式是单个端口,如–to-ports 1025,或者是端口范围,如–to- ports1024-3000。注意,在指定范围时要使用连字号。

6.7 REDIRECT target

在防火墙所在的机子内部转发包或流到另一个端口。比如,我们可以把所有去往
端口 HTTP 的包 REDIRECT 到 HTTP proxy(例如 squid),当然这都发生在我们自
己的主机内部。本地生成的包都会被映射到 127.0.0.1。换句话说,这个 target把要转发的包的目的地址改写为我们自己机子的 IP。我们在做透明代理(LAN内的机子根本不需要知道代理的存在就可以正常上网)时,这个 target 可是起了很大作用的。
注意,它只能用在 nat 表的 PREROUTING、OUTPUT 链和被它们调用的自定义链里。

选项 –to-ports
举例 iptables -t nat -A PREROUTING -p tcp --dport 80 -j REDIRECT --to-ports 8080
说明 在指定 TCP 或 UDP 协议的前提下,定义目的端口,方式如下:1、不使用这个选项,目的端口不会被改变。2、指定一个端口,如–to-ports 8080。3、指定端口范围,如–to-ports 8080-8090

6.8 REJECT target

REJECT 和 DROP 基本一样,区别在于它除了阻塞包之外,还向发送者返回错误信
息。现在,此 target 还只能用在 INPUT、FORWARD、OUTPUT 和它们的子链里,而且包含 REJECT 的链也只能被它们调用,否则不能发挥作用。它只有一个选项,是用来控制返回的错误信息的种类的。

选项 –reject-with
举例 iptables -A FORWARD -p TCP --dport 22 -j REJECT --reject-with tcp-reset
说明 告诉 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。

6.9 RETURN target

使包返回上一层,顺序是:子链——>父链——>缺省的策略。具体地说,就是若包在子链中遇到了 RETURN,则返回父链的下一条规则继续进行条件的比较,若是在父链(或称主链,比如 INPUT)中遇到了 RETURN,就要被缺省的策略(一般是ACCEPT 或 DROP)操作了。

6.10 SNAT target

这个 target 是用来做源网络地址转换的,就是重写包的源 IP 地址。当我们有几
个机子共享一个 Internet 连接时,就能用到它了。先在内核里打开 ip 转发功能,然后再写一个 SNAT 规则,就可以把所有从本地网络出去的包的源地址改为Internet 连接的地址了。SNAT target 的作用就是让所有从本地网出发的包看起来都是从一台机子发出的,这台机子一般就是防火墙。
SNAT 只能用在 nat 表的 POSTROUTING 链里。只要连接的第一个符合条件的包被SNAT 了,那么这个连接的其他所有的包都会自动地被 SNAT,而且这个规则还会应用于这个连接所在流的所有数据包。

选项 –to-source
举例 iptables -t nat -A POSTROUTING -p tcp -o eth0 -j SNAT --to-source 194.236.50.155-194.236.50.160:1024-32000
说明 指定源地址和端口,有以下几种方式: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 所用的端口的。

6.11 TOS target

TOS 是用来设置 IP 头中的 Type of Service 字段的。这个字段长一个字节,可以控制包的路由情况。它也是 iproute2 及其子系统可以直接使用的字段之一。值得注意的是,如果你有几个独立的防火墙和路由器,而且还想在他们之间利用包的头部来传递路由信息,TOS 是唯一的办法。前面说过,MARK 是不能用来传递这种信息的。如果你需要为某个包或流传递路由信息,就要使用 TOS 字段,它也
正是为这个而被开发的。

选项 –set-tos
举例 iptables -t mangle -A PREROUTING -p TCP --dport 22 -j TOS --set-tos 0x10
说明 设置 TOS 的值,值的形式可以是名字或者使相应的数值(十进制或16 进制的)。一般情况下,建议你使用名字而不使用数值形式,因为以后这些数值可能会有所改变,而名字一般是固定的。TOS 字段有 8 个二进制位,所以可能的值是 0-255(十进制)或 0x00-0xFF(16 进制)。1、Minimize-Delay 16 (0x10),要求找一条路径使延时最小,一些标准服务如 telnet、SSH、FTP- control 就需要这个选项。2、Maximize-Throughput 8 (0x08),要求找一条路径能使吞吐量

最大,标准服务 FTP-data 能用到这个。3、Maximize-Reliability 4 (0x04),要求找一条路径能使可靠性最高,使用它的有 BOOTP 和 TFTP。4、Minimize-Cost 2 (0x02),要求找一条路径能使费用最低,一般情况下使用这个选项的是一些视频音频流协议,如 RTSP(Real Time Stream Control Protocol)。5、Normal-Service 0 (0x00),一般服务,没有什么特殊要求。这个值也是大部分包的缺省值。

6.12 TTL target

TTL 可以修改 IP 头中 Time To Live 字段的值。它有很大的作用,我们可以把所
有外出包的 Time To Live 值都改为一样的,比如 64,这是 Linux 的默认值。有
些 ISP 不允许我们共享连接(他们可以通过 TTL 的值来区分是不是有多个机子使
用同一个连接),如果我们把 TTL 都改为一样的值,他们就不能再根据 TTL 来判
断了。

选项 –ttl-set
举例 iptables -t mangle -A PREROUTING -i eth0 -j TTL --ttl-set 64
说明 设置 TTL 的值。这个值不要太大,也不要太小,大约 64 就很好。值太大会影响网络,而且有点不道德,为什么这样说呢?如果有些路由器的配置不太正确,包的 TTL 又非常大,那它们就会在这些路由器之间往返很多次,值越大,占用的带宽越多。这个 target 就可以被用来限制包能走多远,一个比较恰当的距离是刚好能到达DNS 服务器。
选项 –ttl-dec
举例 iptables -t mangle -A PREROUTING -i eth0 -j TTL --ttl-dec 1
说明 设定 TTL 要被减掉的值,比如–ttl-dec 3。假设一个进来的包的TTL 是 53,那么当它离开我们这台机子时,TTL 就变为 49 了。为什么不是 50 呢?因为经过我们这台机子,TTL 本身就要减 1,还要被 TTL target 再减 3,当然总共就是减去 4 了。使用这个 target可以限制“使用我们的服务的用户”离我们有多远。比如,用户总是使用比较近的 DNS,那我们就可以对我们的 DNS 服务器发出的包进行几个–ttl-dec。(译者注:意思是,我们只想让距离 DNS 服务器近一些的用户访问我们的服务)当然,用–set-ttl 控制更方便些。
选项 –ttl-inc
举例 iptables -t mangle -A PREROUTING -i eth0 -j TTL --ttl-inc 1
说明 设定 TTL 要被增加的值,比如–ttl-inc 4。假设一个进来的包的TTL 是 53,那么当它离开我们这台机子时,TTL 应是多少呢?答案是 56,原因同–ttl-dec。使用这个选项可以使我们的防火墙更加隐蔽,而不被 trace-routes 发现,方法就是设置–ttl-inc 1。原因应该很简单了,包每经过一个设备,TTL 就要自动减 1,但在我们的防火墙里这个 1 又被补上了,也就是说,TTL 的值没变,那么trace-routes 就会认为我们的防火墙是不存在的。Trace-routes让人又爱又恨,爱它是因为在连接出问题时,它可以给我们提供极有用的信息,告诉我们哪里有毛病;恨它是由于它也可以被黑客或骇客用来收集目标机器的资料。

温馨提示:
以上文章描述如有不清晰之处,欢迎在评论区评论,如有时间,会第一时间回复,谢谢!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章