Switch-Router

Netfilter是如何工作的(三):规则的匹配(match)

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

每一条iptables配置的rule都包含了匹配条件(match)部分和动作(target)。当报文途径HOOK点时,Netfilter会逐个遍历挂在该钩子点上的表的rule,若报文满足rule的匹配条件,内核就会执行动作(target)。

扩展match的表示

match又可以分为标准match扩展match两部分,其中前者有且只有一个,而后者有零到多个。在Netfilter中,标准match条件用ipt_entry表示(这个在上一篇文章中已经说过了),其中包括源地址和目的地址等基本信息,而扩展matchipt_entry_match表示:

这个结构上面是一个union,下面是一个柔性数组。union的元素有三个,抛开最后一个用于对齐的match_size,前两个元素表示它在用户空间和内核空间的有不同的解释(这个结构在linux内核代码和iptables应用程序代码中定义一样)

什么意思呢? 还是以本文开头的那条rule为例,这条rule使用了tcp扩展模块,匹配条件为--dport 80,所以用户态的iptables程序会这样理解这个结构:

当内核收到这条rule时,会根据名字”tcp”去从Netfilter框架中”搜索”已注册的扩展match,若找到,就设置其match指针.这样,从内核Netfilter的角度来看,扩展匹配条件就变成了这样:

注册扩展 match

我们需要将扩展match预先注册到Netfilter框架中,才能在之后的配置中使用这个匹配条件。就拿本文最初的那条规则来说,需要一个隐含的前提就是tcp这个xt_match事先被注册到Netfilter框架了。这部分工作是在xt_tcpudp.c定义的内核模块中完成的。

除了tcp, 通过xt_register_match接口,其他各个模块都可以注册自己的扩展匹配条件。

每个xt_match有三个函数指针,其中

  • match:这个函数指针会在扩展匹配报文时被调用,用来判断skb是否满足条件,如果满足则返回非0值。
  • checkentry:这个函数在用户配置规则时被调用,如果返回0,表示配置失败。
  • destroy:这个函数再使用该match的规则被删除时调用。

使用扩展match

当数据包真的到达时,Netfilter会调用各个表安装的钩子函数,这些钩子函数用表中的每条rule去尝试匹配数据包

REF

netfilter-hacking-HOWTO