Netfilter-是如何工作的四动作target

38次阅读

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

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

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

普通动作 & 扩展动作

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

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

表示 target

Netfilter使用 xt_standard_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 定义的内核模块中完成:

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

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

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

查找 target

当用户通过 iptables 下发一条规则时,Netfilter会从 xf 链表上查找是否已有这样的target

执行 target

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

REF

netfilter-hacking-HOWTO

正文完
 0