当数据包首次进入防火墙时,它会经过硬件处理,然后被传递给内核中适当的设备驱动程序。然后,数据包会在内核中经历一系列步骤,要么被发送给正确的应用程序(本地),要么被发送给另一个主机,或者发生其他情况。
iptables的重要两个概念是Table和Chain:
- Table:表示用来做什么类型的判断。例如,规则是处理NAT的,就放到nat表;规则是过滤数据包的,就放到filter表。
- Chain:在表的内部,规则进一步被分类为不同的链,表示规则在数据包的哪个阶段被触发。即何时被匹配。
目标是本机
首先,让我们看一下目标是自己本地主机的数据包,在被发送给接收它的应用程序之前,它将会经过以下步骤:
步骤 | Table | Chain | 描述 |
---|---|---|---|
1 | 被外部接收(例如以太网) | ||
2 | 被接口接收(例如eth0) | ||
3 | raw | PREROUTING | 这个链用于在连接追踪之前处理数据包 例如:可以使用它来设定不追踪特定连接 |
4 | 连接追踪(conntrack)处理 | ||
5 | mangle | PREROUTING | 在路由之前修改数据包 例如改变TOS等 |
6 | nat | PREROUTING | 这个链主要用于对入站数据包进行DNAT 请避免在这个链中进行过滤,因为在某些情况下它会被绕过 |
7 | 路由决策,即数据包应该发送到本地主机还是其他地方 | ||
8 | mangle | INPUT | 在路由之后,被发送到实际进程之前修改数据包 |
9 | filter | INPUT | 这是我们为所有发送到本机的入流量进行过滤的地方 注意,无论数据包来自于哪个接口或方向,所有发送给 该主机的数据包都会通过这个链 |
10 | 数据包传递给本地应用程序处理 |
发送给本地的数据包(由路由决定)只会经过INPUT链而不会经过FORWARD链。
源是本机
现在我们来看一下从我们自己的本地主机发送的出站数据包以及它们经历的步骤:
步骤 | Table | Chain | 描述 |
---|---|---|---|
1 | 本地应用程序(例如服务器或客户端) | ||
2 | 路由决策。确定使用哪个源地址,使用哪个出站接口 以及需要收集的其他必要信息 |
||
3 | raw | OUTPUT | 这个链用于在连接追踪之前处理数据包 例如:可以使用它来设定不追踪特定连接 |
4 | 连接追踪(conntrack)处理 | ||
5 | mangle | OUTPUT | 这是我们修改数据包的地方,建议不要在这个链中进行过滤 因为它可能会产生副作用 |
6 | nat | OUTPUT | 这个链可以用来对出站数据包进行NAT |
7 | 路由决策,之前的mangle和NAT更改可能已经改变了 数据包的路由方式 |
||
8 | filter | OUTPUT | 这是我们过滤从本地主机发出的数据包的地方 |
9 | mangle | POSTROUTING | 在路由决策之后,离开主机之前对数据包进行修改 经过防火墙以及防火墙本身发出的数据包都会经过这个链 |
10 | nat | POSTROUTING | 这个链用来对出站数据包进行SNAT 请避免在这个链中进行过滤,因为在某些情况下它会被绕过 |
11 | 被发送给接口(例如eth0) | ||
12 | 被发送给外部(例如以太网) |
转发数据包
步骤 | Table | Chain | 描述 |
---|---|---|---|
1 | 被外部接收(例如以太网) | ||
2 | 被接口接收(例如eth0) | ||
3 | raw | PREROUTING | 这个链用于在连接追踪之前处理数据包 例如:可以使用它来设定不追踪特定连接 |
4 | 连接追踪(conntrack)处理 | ||
5 | mangle | PREROUTING | 在路由之前修改数据包 例如改变TOS等 |
6 | nat | PREROUTING | 这个链主要用于对入站数据包进行DNAT 请避免在这个链中进行过滤,因为在某些情况下它会被绕过 |
7 | 路由决策,即数据包应该发送到本地主机还是其他地方 | ||
8 | mangle | FORWARD | 数据包被发送到mangle表的FORWARD链 这可以在初始路由决策之后,在最后路由决策之前 修改数据包 |
9 | filter | FORWARD | 数据包被发送到filter表的FORWARD链。 只有转发的数据包会经过这里,我们在这里进行所有的过滤 请注意,所有转发的流量都会经过这里(不仅仅是单向) 在编写规则集时需要考虑到这一点。 |
10 | mangle | POSTROUTING | 在完成各种路由之后,修改数据包 |
11 | nat | POSTROUTING | 这个链用来对出站数据包进行SNAT 请避免在这个链中进行过滤,因为在某些情况下它会被绕过 |
12 | 进入出站接口(例如eth1) | ||
13 | 再次进入外部(例如以太网) |
Mangle table
一般用来修改数据包,具体来说一般用来修改IP头。一般用来修改:
- TOS:可以设置数据包在网络上如何被路由等方面的策略。
- TTL:修改数据包的存活时间。
- MARK:给数据包设置特殊的标记值。这些标记可以被iproute2识别。我们可以基础这些标记进行带宽限制和基于类别的排队。
- SECMARK:进行安全上下文标记,提供被SELinux这样的安全系统使用。
- CONNSECMARK:将安全上下文从数据包复制到整个连接。
Nat table
用来进行NAT的表:
- DNAT:修改数据包的目的地址。一般用于将数据包重定向到其他主机。
- SNAT:修改数据包的源地址。一个典型例子是,在只有一个出口IP的情况下,防火墙对发往互联网的数据包进行SNAT和反SNAT,以实现局域网访问外网。
- MASQUERADE:跟SNAT一样,但是会自动检查要替换的IP地址,而不是像SNAT那样使用单个配置的IP地址。
Raw table
这个表只做一件事情,在数据包上打一个标记,表示它们不应该被conntrack跟踪处理。这是通过在数据包上面使用NOTRACK目标来实现的。
该表只有PREROUTING和OUTPUT链。其他链不是必需的,因为这两个链是在数据包提供给conntrack处理前的唯二位置。
Filter table
过滤表主要用于过滤数据包,我们可以根据需要匹配和过滤数据包。我们可以查看数据包的内容并更具需要进行ACCEPT或DROP。
几乎所有的targets在这个表中都可以使用。
用户自定义链
当一个数据包命中某个规则时,我们可以指定它跳转到同一表中的不同链。新链必须是用户指定的,不能是内置链,比如INPUT或FORWARD链。
用户自定义链只能从内置链跳转到它,不能被自动触发。
用户自定义链在结束的时候,可以返回内置链,也可以继续跳转到其他自定义链。