- 代码和命令输出使用定宽字体,命令用粗体。 [blueflux@work1 neigh]$ lsdefault eth0 lo[blueflux@work1 neigh]$ 所有的命令和程序名都用粗体。 所有的系统部件,如硬件、内核部件、loopback使用斜体。 计算机文本输出用 这种字体。
- 文件名和路径名象这样 /usr/local/bin/iptables 。
![]() | 严格地说,iptables并不需要CONFIG_PACKET,但是它有很多用处(译者注:其他程序需要),所以就选上了。当然,你不想要,不选就是了。(译者注:建议还是选的为好) |
- 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的目录内用到如下一些命令: |
![]() | 总之,只有某些补丁会被询问是否加入内核,而Netfilter的开发者们有大量的补丁或附件想要加入内核,但还要再实验一阵子才能做到。如果你想安装这些东西,就用下面的命令: |
![]() | 你要是不打算用patch-o-matic修补内核,以上的命令都用不着,它们不是必需的。不过,你可以用这些命令来看看有什么有趣的玩意儿,这不会影响任何东西。 |
![]() | Red Hat 7.1预装的iptables版本有些老了,在使用之前,你可能想装个新的,再自己编译一下内核。 |
- 2. 不带NFS的多用户环境,和层3的区别仅在于不带网络支持。
- 3. 多用户环境,就是我们一般事用的层。
- 5. X11,图形界面。
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) |
![]() | 在上面的情况里,不要在INPUT链上做过滤。INPUT是专门用来操作那些以我们的机子为目的地址的包的,它们不会被路由到其它地方的。 |

![]() | 想要更多的信息,可以看看rc.test-iptables.txt ,这个脚本包括了一些规则,它们会向你展示包是怎样通过各个表和链的。 |
![]() | 强烈建议你不要在这个表里做任何过滤,不管是DANT,SNAT或者Masquerade。 |
- TOS
- TTL
- MARK
- DNAT
- SNAT
- MASQUERADE
![]() | 最近patch-o-matic里有一个新的补丁,可以把上面提到的超时时间也作为系统变量,这样我们就能够在系统空闲时改变它们的值。以后,我们就不必为了改变这些值而重编译内核了。 这些可通过/proc/sys/net/ipv4/netfilter下的一些特殊的系统调用来改变。仔细看看/proc/sys/net/ipv4/netfilter/ip_ct_*里的变量吧。 |
State(状态) | Explanation(注释) |
NEW | NEW说明这个包是我们看到的第一个包。意思就是,这是conntrack模块看到的某个连接第一个包,它即将被匹配了。比如,我们看到一个SYN 包,是我们所留意的连接的第一个包,就要匹配它。第一个包也可能不是SYN包,但它仍会被认为是NEW状态。这样做有时会导致一些问题,但对某些情况是有非常大的帮助的。例如,在我们想恢复某条从其他的防火墙丢失的连接时,或者某个连接已经超时,但实际上并未关闭时。 |
ESTABLISHED | ESTABLISHED已经注意到两个方向上的数据传输,而且会继续匹配这个连接的包。处于ESTABLISHED状态的连接是非常容易理解的。只要发送并接到应答,连接就是ESTABLISHED的了。一个连接要从NEW变为ESTABLISHED,只需要接到应答包即可,不管这个包是发往防火墙的,还是要由防火墙转发的。ICMP的错误和重定向等信息包也被看作是ESTABLISHED,只要它们是我们所发出的信息的应答。 |
RELATED | RELATED是个比较麻烦的状态。当一个连接和某个已处于ESTABLISHED状态的连接有关系时,就被认为是RELATED的了。换句话说,一个连接要想是RELATED的,首先要有一个ESTABLISHED的连接。这个ESTABLISHED连接再产生一个主连接之外的连接,这个新的连接就是RELATED的了,当然前提是conntrack模块要能理解RELATED。ftp是个很好的例子,FTP-data 连接就是和FTP-control有RELATED的。还有其他的例子,比如,通过IRC的DCC连接。有了这个状态,ICMP应答、FTP传输、DCC等才能穿过防火墙正常工作。注意,大部分还有一些UDP协议都依赖这个机制。这些协议是很复杂的,它们把连接信息放在数据包里,并且要求这些信息能被正确理解。 |
INVALID | INVALID说明数据包不能被识别属于哪个连接或没有任何状态。有几个原因可以产生这种情况,比如,内存溢出,收到不知属于哪个连接的ICMP 错误信息。一般地,我们DROP这个状态的任何东西。 |


State | Timeout value |
NONE | 30 minutes |
ESTABLISHED | 5 days |
SYN_SENT | 2 minutes |
SYN_RECV | 60 seconds |
FIN_WAIT | 2 minutes |
TIME_WAIT | 2 minutes |
CLOSE | 10 seconds |
CLOSE_WAIT | 12 hours |
LAST_ACK | 30 seconds |
LISTEN> | 2 minutes |
![]() | 注意状态机制在用户空间里的部分不会查看TCP包的标志位(也就是说TCP标志对它而言是透明的)。如果我们想让NEW状态的包通过防火墙,就要指定NEW状态,我们理解的NEW状态的意思就是指SYN包,可是iptables又不查看这些标志位。这就是问题所在。有些没有设置SYN或ACK的包,也会被看作NEW状态的。这样的包可能会被冗余防火墙用到,但对只有一个防火墙的网络是很不利的(可能会被攻击哦)。那我们怎样才能不受这样的包的影响呢?你可以使用未设置SYN的NEW状态包 里的命令。还有一个办法,就是安装patch-o-matic里的tcp-window-tracking扩展功能,它可以使防火墙能根据TCP的一些标志位来进行状态跟踪。 |


![]() | 注意,应答包必须符合一定的标准,连接才能被认作established的,每个传输类型都是这样。 |



