Netfilter-是如何工作的二表table与规则rule

10次阅读

共计 1522 个字符,预计需要花费 4 分钟才能阅读完成。

在 (一) 中说到,报文在内核协议栈中会途经 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. 快速访问到具体的表。

正文完
 0