Switch-Router

Netfilter是如何工作的(二):表(table)与规则(rule)

Published at 2019-06-12 | Last Update 2019-06-12

在(一)中说到,报文在内核协议栈中会途经5HOOK点,在每个HOOK点上会依次执行链表上的钩子函数,那么这些钩子函数是如何与用户使用iptables下发的各个rule联系起来的呢?这些rule又是如何存储的呢? 本文详细描述这个问题。

table

内核使用struct xt_table这个结构来表示一个表(table)。结构中记录了这个表在哪些HOOK点有效,它的private指针保存了这个表包含的所有规则。

每个新的net namespace创建时,Netfitler会创建所有属于当前net namespace的表,并将其记录到自己的net namespace中。

从图中可以看出,创建一个包含默认ruletable分两步

  1. 根据已有的模板,生成默认rule
  2. 注册tableNetfilter框架中

生成默认rule

如果你使用过iptables,可能会知道每张table的每条chain都有一个默认POLICY,它表示chain中的所有的rule都不匹配,则执行默认的行为。这个默认行为可以通过iptables配置,在系统启动时默认行为都被设置为NF_ACCEPT.而这里的默认rule就是这个意思,Netfilter会为每个chain创建一条默认的rule,并将它们加入到table

ipt_replace

上图创建默认rule的时候使用了一个struct ipt_replace的结构,这个结构的来历和iptables的配置方法是紧密相连的:iptables采用的是读-修改-写的方式进行配置的!

举个例子,当你使用iptablesNetfilterfilter表添加一条新的rule时,iptables会将filter整个表读取到用户空间,在用户空间修改完成后,再将其重新设置到Netfilter。所以,这是一个替换(Replace)的过程。

因此,ipt_replace一般就是指用户使用iptables下发的表。典型的结构如下:

hook_entryunderflow分别表示各个HOOK上的第一条rule和最后一条rule的偏移(具体的规则在最后一个ipt_entry的柔性数组里!)

但在这里,由于还处于初始化阶段,所以这里的repl是内核自己由packet_filter模板生成的,它会为filter所在的LOCAL_INFORWARDLOCAL_OUT这几个HOOK点各创建一条默认rule.

ipt_entry

内核使用struct ipt_entry表示一条用户使用iptables配置的rule. 这个结构后面会紧跟若干个ipt_entry_match结构和1ipt_standard_target结构。它与一条用户配置的iptables的关系如下:

其中

  • ipt_entry:表示标准匹配结构。包括报文的源IP、目的IP、入接口、出接口等条件
  • ipt_entry_match:表示扩展匹配。一条完整的rule包含零个到多个该结构
  • ipt_standard_target:表示匹配后的动作

如果对iptables的匹配规则不太熟悉,建议点此扩展匹配了解一下

注册 table 到 Netfilter 框架

在完成了默认规则的创建之后(保存在ipt_replace),接下来就是应该注册新的表了。

xt_table中保存规则的private指针类型是struct xt_table_info,因此这里第一部就是把repl转换为newinfo。接下来就是调用xt_register_table创建新的表并注册到框架了

注册完成之后,Netfilter可以通过net->xt.tables[af]链表遍历到所有注册的表,也可以通过net->ipv4.快速访问到具体的表。