当前位置: 首页 > Linux

Netfilter是如何工作的(四):动作(target)

时间:2023-04-06 21:00:52 Linux

每个iptables配置规则(rule)都包含匹配条件(match)部分和动作(target)。当消息经过HOOK点时,Netfilter会逐一遍历挂在hook点上的表的规则。如果消息满足规则的匹配条件,内核将执行动作(目标)。以上是一个普通的iptables规则。如果数据包符合前面的条件,将执行最后的SNAT,这就是这条规则的动作(目标)。普通动作&扩展动作动作分为普通目标和扩展目标。其中,普通动作是指ACCEPT(允许数据包通过)、DROP(拒绝数据包通过)等简单明了的动作,而扩展目标是指包含其他操作的动作,如产生ICMP错误的REJECT动作消息和日志操作日志、SNAT和DNAT用于地址转换。本文不涉及如何配置这些动作的规则,也不涉及这些动作的作用是什么。对此感兴趣的读者可以参考链接。targetNetfilter使用xt_standard_target来表示一个action:该结构由两部分组成,其中verdict是action的编码,取值有NF_DROP、NF_ACCEPT、NF_QUEUE等。对于普通的动作,verdict就够了,但是对于扩展的动作,需要有一个地方来存放额外的信息(比如如何进行NAT),这里的target就是存放这些额外信息的地方。xt_entry_target结构和本系列上一篇文章中提到的xt_entry_match一样,也是一个union。他们的设计思路是一样的:内核代码和iptables用户态代码定义相同的数据类型,用户态使用user部分,设置要使用的扩展动作的名字(普通动作的名字是“”),内核收到该结构体后,根据名称查询注册的动作,并将信息挂在xt_entry_target的目标指针上。数据字段所代表的灵活数组区是各种扩展模块大显身手的地方。对于NAT,转换后的地址存储在这里。注册目标我们需要将目标预先注册到Netfilter框架中,以便在后续配置中使用该目标。以本文的原始规则为例,一个隐含的前提是SNAT的xt_target已经提前注册到Netfilter框架中。这部分工作是在xt_nat.c定义的内核模块中完成的:除了SNAT,其他模块可以通过xt_register_target接口注册自己的动作。根据名字区分,所有的target都会挂到xf链表上。每个target上有3个函数指针,其中target:这个函数会决定skb后续的处理结果,如果为NULL,那么这个rule的动作就是一个普通的target,处理结果可以从外部获取判决。如果不为NULL,则执行该函数,该函数返回NF_DROP、NF_ACCEPT、NF_STOLENactioncheckentry:该函数在用户配置规则时调用,如果返回0,则表示配置失败。destroy:删除使用此目标的规则时调用此函数。查找目标当用户通过iptables发送一条规则时,Netfilter会从xf链表中检查是否有这样的目标来执行该目标。当数据包经过HOOK点时,如果某个规则的匹配条件与数据包一致,就会执行目标规则中包含的动作。REFnetfilter-hacking-HOWTO