每一条iptables
配置的rule
都包含了匹配条件(match
)部分和目标(target
)。当报文途径HOOK
点时,Netfilter
会逐个遍历挂在该钩子点上的表的rule
,若报文满足rule
的匹配条件,内核就会执行目标(target
)。
扩展匹配条件的表示
而匹配条件又可以分为标准匹配
和扩展匹配
两部分,其中前者有且只有一个,而后者有零到多个。在Netfilter
中,标准匹配条件用ipt_entry
表示(这个在上一篇文章中已经说过了),其中包括源地址和目的地址等基本信息,而扩展匹配条件用ipt_entry_match
表示:
这个结构上面是一个union
,下面是一个柔性数组。union
的元素有三个,抛开最后一个用于对齐的match_size
,前两个元素表示它在用户空间和内核空间的有不同的解释(这个结构在linux
内核代码和iptables
应用程序代码中定义一样)
什么意思呢? 还是以本文开头的那条rule
为例,这条rule
使用了tcp
扩展模块,匹配条件为--dport 80
,所以用户态的iptables
程序会这样理解这个结构:
当内核收到这条rule
时,会根据名字"tcp"去从Netfilter
框架中"搜索"已注册的扩展匹配条件,若找到,就设置其match
指针.这样,从内核Netfilter
的角度来看,扩展匹配条件就变成了这样:
扩展匹配条件的注册
上面的过程之所以能搜索到扩展匹配条件,有一个隐含的前提就是"tcp"这个xt_match
事先被注册到Netfilter
框架了。这部分工作是在xt_tcpudp.c
定义的内核模块中完成的。
通过xt_register_match
接口,各个内核模块可以完成扩展匹配条件的注册。
扩展匹配条件的匹配时机
当数据包真的到达时,Netfilter
会调用各个表安装的钩子函数,这些钩子函数用表中的每条rule
去尝试匹配数据包