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

蒋胜凡广博天下客 2019-11-17

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

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

上面是一条普通iptables规则,如果报文匹配前面的条件,就会执行最后的-j DROP,它就是这条规则的动作(target)

普通动作 & 扩展动作

动作又可分为普通target扩展target两类,其中普通动作是指ACCEPT(允许报文通过)、DROP(拒绝报文通过)这类简单明了的行为,而扩展target是指包含了其他操作的动作,比如REJECT动作会产生ICMP差错信息、LOG动作记录日志、SNATDNAT用于进行地址转换。

本文不涉及 How to 配置这些动作的规则,也不涉及这些动作各自的作用是什么,对此有兴趣的读者可以参考链接

表示 target

Netfilter使用xt_standard_target表示一个动作:

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

该结构由两部分组成,其中verdict是动作的编码, 取值有NF_DROPNF_ACCEPTNF_QUEUE等等。对于普通动作来说,有verdict就够了,但对于扩展动作来说,还需要有地方存储额外的信息(eg. 如何进行NAT),这里的target就是存储这些额外信息的地方。与本系列上一篇中说的xt_entry_match一样,xt_entry_target结构同样是一个union。它们的设计思路是一样的:内核代码和iptables用户态代码定义这样一个同样的数据类型,用户态使用的是user部分,设置要使用的扩展动作的name(普通动作的name为""),内核收到该结构后,根据name查询到注册过的动作,将该信息挂到xt_entry_targettarget指针上。而data字段表示的柔性数组区域就是各种扩展模块各显神通的地方了,对NAT来说,这里存储转换后的地址。

注册 target

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

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

除了SNAT, 通过xt_register_target接口,其他各个模块都可以注册自己的动作。根据名字进行区分,所有的target会挂到xf链表上。

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

每个target上有三个函数指针,其中

  • target:这个函数将决定skb的后续处理结果,如果为NULL,那么这条规则的动作就是普通target,处理结果从外面的verdict就可以得出。如果不为NULL,那么就执行这个函数,这个函数返回NF_DROP, NF_ACCEPT, NF_STOLEN这类动作
  • checkentry:这个函数在用户配置规则时被调用,如果返回0,表示配置失败。
  • destroy:这个函数再使用该target的规则被删除时调用。

查找 target

当用户通过iptables下发一条规则时,Netfilter会从xf链表上查找是否已有这样的target
Netfilter 是如何工作的(四):动作(target)

执行 target

当数据包经过HOOK点,如果某条rule的匹配条件与报文一致,就会执行该rule包含的动作。

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

REF

netfilter-hacking-HOWTO

相关推荐