深入理解 netfilter 和 iptables!( 四 )


enum nf_ip_hook_priorities { NF_IP_PRI_RAW = -300, NF_IP_PRI_MANGLE = -150, NF_IP_PRI_NAT_DST = -100, NF_IP_PRI_FILTER = 0, NF_IP_PRI_SECURITY = 50, NF_IP_PRI_NAT_SRC = https://www.wendabaike.com/wiki/100, };
当数据包到达某一 hook 触发点时,会依次执行不同 table 在该 hook 上注册的所有回调函数,这些回调函数总是根据上文的 priority 值以固定的相对顺序执行:

深入理解 netfilter 和 iptables!

文章插图
tables-priority ipt_do_table
filter 注册的 hook 回调函数 iptable_filter_hook[3] 将对 xt_table 结构执行公共的规则检查函数 ipt_do_table[4]。ipt_do_table 接收 skb 、 hook 和 xt_table 作为参数,对 skb 执行后两个参数所确定的规则集,返回 netfilter 向量作为回调函数的返回值 。
在深入规则执行过程前,需要先了解规则集如何在内存中表示 。每一条规则由 3 部分组成:
一个 ipt_entry 结构体 。通过 .next_offset 指向下一个 ipt_entry 的内存偏移地址 。
0 个或多个 ipt_entry_match 结构体,每个结构体可以动态的添加额外数据 。
1 个 ipt_entry_target 结构体,结构体可以动态的添加额外数据 。
ipt_entry 结构体定义如下:
struct ipt_entry { struct ipt_ip ip; unsigned int nfcache; /* ipt_entry + matches 在内存中的大小*/ u_int16_t target_offset; /* ipt_entry + matches + target 在内存中的大小 */ u_int16_t next_offset; /* 跳转后指向前一规则 */ unsigned int comefrom; /* 数据包计数器 */ struct xt_counters counters; /* 长度为0数组的特殊用法,作为 match 的内存地址 */ unsigned char elems[0]; };
ipt_do_table 首先根据 hook 类型以及 xt_table.private.entries 属性跳转到对应的规则集内存区域,执行如下过程:
深入理解 netfilter 和 iptables!

文章插图
ipt_do_table
首先检查数据包的 IP 首部与第一条规则 ipt_entry 的 .ipt_ip 属性是否一致,如不匹配根据 next_offset 属性跳转到下一条规则 。
若 IP 首部匹配 ,则开始依次检查该规则所定义的所有 ipt_entry_match 对象,与对象关联的匹配函数将被调用,根据调用返回值有返回到回调函数(以及是否丢弃数据包)、跳转到下一规则或继续检查等结果 。
所有检查通过后读取 ipt_entry_target ,根据其属性返回 netfilter 向量到回调函数、继续下一规则或跳转到指定内存地址的其他规则,非标准 ipt_entry_target 还会调用被绑定的函数,但只能返回向量值不能跳转其他规则 。
灵活性和更新时延
以上数据结构与执行方式为 iptables 提供了强大的扩展能力,我们可以灵活地自定义每条规则的匹配条件并根据结果执行不同行为,甚至还能在额外的规则集之间栈式跳转 。
由于每条规则长度不等、内部结构复杂,且同一规则集位于连续的内存空间,iptables 使用全量替换的方式来更新规则,这使得我们能够从用户空间以原子操作来添加/删除规则,但非增量式的规则更新会在规则数量级较大时带来严重的性能问题:假如在一个大规模 Kubernetes 集群中使用 iptables 方式实现 Service,当 service 数量较多时,哪怕更新一个 service 也会整体修改 iptables 规则表 。全量提交的过程会 kernel lock 进行保护,因此会有很大的更新时延 。
用户空间的 tables、chains 和 rules
用户空间的 iptables 命令行可以读取指定表的数据并渲染到终端,添加新的规则(实际上是替换整个 table 的规则表)等 。
iptables 主要操作以下几种对象:
table:对应内核空间的 xt_table 结构,iptable 的所有操作都对指定的 table 执行,默认为 filter 。
chain:对应指定 table 通过特定 netfilter hook 调用的规则集,此外还可以自定义规则集,然后从 hook 规则集中跳转过去 。


以上关于本文的内容,仅作参考!温馨提示:如遇专业性较强的问题(如:疾病、健康、理财等),还请咨询专业人士给予相关指导!

「辽宁龙网」www.liaoninglong.com小编还为您精选了以下内容,希望对您有所帮助: