linux之iptables - piaoling - JavaEye技术网站

来源:百度文库 编辑:神马文学网 时间:2024/04/24 01:48:02

关键字: iptables命令帮助

书写规则的语法格式是:
iptables [-t table] command [match] [target/jump]
主要有三表五链(filter,mangle,nat),五链(PREROUTING,FORWARD,INPUT,OUTPUT,POSROUTING)
表:
选项-t用来指定使用哪个表,它可以是下面介绍的表中的任何一个,默认的是 filter表

Table (表名) Explanation (注释) nat nat表的主要用处是网络地址转换,即Network Address Translation,缩写为NAT。做过NAT操作的数据包的地址就被改变了,当然这种改变是根据我们的规则进行的。属于一个流的包只会经过这个表一次。如果第一个包被允许做NAT或Masqueraded,那么余下的包都会自动地被做相同的操作。也就是说,余下的包不会再通过这个表,一个一个的被NAT,而是自动地完成。这就是我们为什么不应该在这个表中做任何过滤的主要原因,对这一点,后面会有更加详细的讨论。PREROUTING 链的作用是在包刚刚到达防火墙时改变它的目的地址,如果需要的话。OUTPUT链改变本地产生的包的目的地址。POSTROUTING链在包就要离开防火墙之前改变其源地址。 mangle 这个表主要用来mangle数据包。我们可以改变不同的包及包头的内容,比如 TTLTOSMARK。注意MARK并没有真正地改动数据包,它只是在内核空间为包设了一个标记。防火墙内的其他的规则或程序(如tc)可以使用这种标记对包进行过滤或高级路由。这个表有五个内建的链: PREROUTINGPOSTROUTING OUTPUTINPUT FORWARDPREROUTING在包进入防火墙之后、路由判断之前改变包,POSTROUTING是在所有路由判断之后。 OUTPUT在确定包的目的之前更改数据包。INPUT在包被路由到本地之后,但在用户空间的程序看到它之前改变包。FORWARD在最初的路由判断之后、最后一次更改包的目的之前mangle包。注意,mangle表不能做任何NAT,它只是改变数据包的 TTLTOSMARK,而不是其源目地址。NAT是在nat表中操作的。 filter filter表是专门过滤包的,内建三个链,可以毫无问题地对包进行DROPLOGACCEPTREJECT等操作。FORWARD 链过滤所有不是本地产生的并且目的地不是本地(所谓本地就是防火墙了)的包,而 INPUT恰恰针对那些目的地是本地的包。OUTPUT 是用来过滤所有本地生成的包的。

iptables命令:
Command -A, --append Example iptables -A INPUT ... Explanation 在所选择的链末添加规则。当源地址或目的地址是以名字而不是ip地址的形式出现时,若这些名字可以被解析为多个地址,则这条规则会和所有可用的地址结合。 Command -D, --delete Example iptables -D INPUT --dport 80 -j DROPiptables -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)
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.255192.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 以包进入本地所使用的网络接口来匹配包。要注意这个匹配操作只能用于INPUTFORWARD 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 。取反时,表示只能匹配到没有分片的包或者是被分片的包的第一个碎片,其后的片都不行。现在内核有完善的碎片重组功能,可以防止碎片攻击,所以不必使用取反的功能来防止碎片通过。如果你使用连接跟踪,是不会看到任何碎片的,因为在它们到达任何链之前就被处理过了。 隐含的匹配规则
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 ACKFINRST URGPSH。另外还有两个词也可使用,就是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用来匹配那些 RSTACK被置位的包,换句话说,就是状态为已建立的连接的包。 Match --tcp-option Example iptables -p tcp --tcp-option 16 Explanation 根据匹配包。TCP选项是TCP头中的特殊部分,有三个不同的部分。第一个8位组表示选项的类型,第二个8位组表示选项的长度(这个长度是整个选项的长度,但不包含填充部分所占的字节,而且要注意不是每个TCP选项都有这一部分的),第三部分当然就是选项的内容了。为了适应标准,我们不必执行所有的选项,但我们可以查看选项的类型,如果不是我们所支持的,那就只是看看长度然后跳过数据部分。这个操作是根据选项的十进制值来匹配的,它也可以用英文感叹号取反。所有的选项都可在Internet Engineering Task Force里找到。
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 类型已经废弃不用了,还有一些可能会对无防护的主机带来“危险”,因为它们可能把包重定向到错误的地方。
MAC地址匹配
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接口。而且,它还只能在PREROUTINGFORWARD INPUT链里使用。
多端口匹配(Multiport match options)
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的包等。使用方法和源端口多端口匹配一样。


状态匹配(State matches)

Match --state Example iptables -A INPUT -m state --state RELATED,ESTABLISHED Explanation 指定要匹配包的的状态,当前有4种状态可用:INVALIDESTABLISHEDNEWRELATEDINVALID意味着这个包没有已知的流或连接与之关联,也可能是它包含的数据或包头有问题。ESTABLISHED意思是包是完全有效的,而且属于一个已建立的连接,这个连接的两端都已经有数据发送。NEW表示包将要或已经开始建立一个新的连接,或者是这个包和一个还没有在两端都有数据发送的连接有关。RELATED说明包正在建立一个新的连接,这个连接是和一个已建立的连接相关的。比如,FTP data transferICMP error 和一个TCP或UDP连接相关。注意NEW状态并不在试图建立新连接的TCP包里寻找SYN标记,因此它不应该不加修改地用在只有一个防火墙或在不同的防火墙之间没有启用负载平衡的地方。具体如何使用,你就再看看章节状态机制吧:)
匹配结果处理(Targets/Jumps)
target/jump决定符合条件的包到何处去,语法是--jump target-j target。(译者注:本文中,原作者把target细分为两类,即Target和Jump。它们唯一的区别是jump的目标是一个在同一个表内的链,而target的目标是具体的操作。)我们会先接触到两个基本的target,就是ACCEPT和DROP
ACCEPT target

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

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

注意,DANT target只能用在nat表的PREROUTING和OUTPUT链中,或者是被这两条链调用的链里。但还要注意的是,包含DANT target的链不能被除此之外的其他链调用,如POSTROUTING。

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-100SNAT的语法和这个target的一样,只是目的不同罢了。要注意,只有先用--protocol指定了TCP或 UDP协议,才能使用端口

因为DNAT要做很多工作,所以我要再罗嗦一点。我们通过一个例子来大致理解一下它是如何工作的。比如,我想通过Internet连接发布我们的网站,但是HTTP server在我们的内网里,而且我们对外只有一个合法的IP,就是防火墙那个对外的IP——$INET_IP。防火墙还有一个内网的IP——$LAN_IP,HTTP server的IP是$HTTP_IP (这当然是内网的了)。为了完成我们的设想,要做的第一件事就是把下面的这个简单的规则加入到nat表的PREROUTING链中:

iptables -t nat -A PREROUTING --dst $INET_IP -p tcp --dport 80 -j DNAT \ --to-destination $HTTP_IP

现在,所有从Internet来的、到防火墙的80端口去的包都会被转发(或称做被DNAT )到在内网的HTTP服务器上。如果你在Internet上试验一下,一切正常吧。再从内网里试验一下,完全不能用吧。这其实是路由的问题。下面我们来好好分析这个问题。为了容易阅读,我们把在外网上访问我们服务器的那台机子的IP地址记为$EXT_BOX

 

  1. 包从地址为$EXT_BOX的机子出发,去往地址为$INET_IP 的机子。

  2. 包到达防火墙。

  3. 防火墙DNAT(也就是转发)这个包,而且包会经过很多其他的链检验及处理。

  4. 包离开防火墙向$HTTP_IP前进。

  5. 包到达HTTP服务器,服务器就会通过防火墙给以回应,当然,这要求把防火墙作为HTTP到达$EXT_BOX的网关。一般情况下,防火墙就是HTTP服务器的缺省网关。

  6. 防火墙再对返回包做Un-DNAT(就是照着DNAT的步骤反过来做一遍),这样就好像是防火墙自己回复了那个来自外网的请求包。

  7. 返回包好象没经过这么复杂的处理、没事一样回到$EXT_BOX

现在,我们来考虑和HTTP服务器在同一个内网(这里是指所有机子不需要经过路由器而可以直接互相访问的网络,不不是那种把服务器和客户机又分在不同子网的情况)的客户访问它时会发生什么。我们假设客户机的IP为$LAN_BOX,其他设置同上。

 

  1. 包离开$LAN_BOX,去往$INET_IP

  2. 包到达防火墙。

  3. 包被DNAT,而且还会经过其他的处理。但是包没有经过SNAT 的处理,所以包还是使用它自己的源地址,就是$LAN_BOX(译者注:这就是IP 传输包的特点,只根据目的地的不同改变目的地址,但不因传输过程中要经过很多路由器而随着路由器改变其源地址,除非你单独进行源地址的改变。其实这一步的处理和对外来包的处理是一样的,只不过内网包的问题就在于此,所以这里交待一下原因)。

  4. 包离开防火墙,到达HTTP服务器。

  5. HTTP服务器试图回复这个包。它在路由数据库中看到包是来自同一个网络的一台机子,因此它会把回复包直接发送到请求包的源地址(现在是回复包的目的地址),也就是$LAN_BOX

  6. 回复包到达客户机,但它会很困惑,因为这个包不是来自它访问的那台机子。这样,它就会把这个包扔掉而去等待“真正”的回复包。

针对这个问题有个简单的解决办法,因为这些包都要进入防火墙,而且它们都去往需要做DNAT才能到达的那个地址,所以我们只要对这些包做SNAT操作即可。比如,我们来考虑上面的例子,如果对那些进入防火墙而且是去往地址为$HTTP_IP、端口为80的包做SNAT操作,那么这些包就好象是从$LAN_IP来的了,也就是说,这些包的源地址被改为$LAN_IP了。这样,HTTP服务器就会把回复包发给防火墙,而防火墙会再对包做 Un-DNAT操作,并把包发送到客户机。解决问题的规则如下:

iptables -t nat -A POSTROUTING -p tcp --dst $HTTP_IP --dport 80 -j SNAT \ --to-source $LAN_IP

要记住,按运行的顺序POSTROUTING链是所有链中最后一个,因此包到达这条链时,已经被做过DNAT操作了,所以我们在规则里要基于内网的地址$HTTP_IP(包的目的地)来匹配包。

DROP target

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

LOG target

这个target是专门用来记录包地有关信息的。这些信息可能是非法的,那就可以用来除错。LOG会返回包的有关细节,如IP头的大部分和其他有趣的信息。这个功能是通过内核的日志工具完成的,一般是syslogd。返回的信息可用dmesg阅读,或者可以直接查看syslogd的日志文件,也可以用其他的什么程序来看。LOG对调试规则有很大的帮助,你可以看到包去了哪里、经过了什么规则的处理,什么样的规则处理什么样的包,等等。当你在生产服务器上调试一个不敢保证100%正常的规则集时,用LOG代替DROP是比较好的(有详细的信息可看,错误就容易定位、解决了),因为一个小小的语法错误就可能引起严重的连接问题,用户可不喜欢这样哦。如果你想使用真正地扩展日志地话,可能会对ULOG target有些兴趣,因为它可以把日志直接记录到MySQL databases或类似的数据库中。

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 这个等级的其他部分产生的。有关日志的详细信息,我建议你看看syslogsyslog.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 。不过,这不是被赞成的,因为它会带来额外的开销,而且以后还可能引起矛盾,比如它也许会影响你的脚本,使它们不能用。

注意,MASQUERADESNAT一样,只能用于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
REJECT target

REJECTDROP基本一样,区别在于它除了阻塞包之外,还向发送者返回错误信息。现在,此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,而且这个规则还会应用于这个连接所在流的所有数据包。

Table 6-22. SNAT target

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所用的端口的。