使用iptables CONNMARK target和conntrack 模块记录数据流的转发

1、每个数据流在linux 内核中由一个structsk_buff结构来表示,这个sk_buff结构有一个32位无符号整型的mark成员,用来保存该skb的mark标记值,在netfilter框架中可以动态修改该mark值。

2、每条在linux内核中成功转发的数据流都会在netfilter中的conntrack模块中保存一条状态跟踪连接记录,这是个struct nf_conn结构,该结构中有一个32位无符号整型的mark成员,用来保存该记录的标记值。

注:未被成功转发的数据流(如被防火墙拦截了),不会在系统中记录其conntrack信息。

默认情况下,在一条数据流被linux成功转发时,structsk_buff中的mark值不会保存到struct nf_conn结构中的mark成员中,struct nf_conn结构中的mark值始终为0。

使用iptables …-j CONNMARK –bit-save-mark –nfmask 0xffff0000 –ctmask 0xffffffff 可以将当前匹配的数据流skb的mark值保存在conntrack的mark值中。

使用iptables …-j CONNMARK –restore-mark –nfmask 0xffffffff –ctmask 0xffff 可以对当前匹配的数据流进行mark值的恢复操作,将该数据流在conntrack模块中对应的记录struct nf_conn中的mark值提取出来保存在当前数据流sk_buff的mark值中。

注:支持mark值的位存储和恢复。

应用:

1、在系统中存在大量的iptables/ebtables规则时,一条数据流被转发需要消耗大量的CPU时间,会严重影响设备的throughput。

方案:使用CONNMARK 的save-mark/retore-mark机制可以用来保存skb的最终状态,使得netfilter可以提前预判该数据包的最终状态(ACCEPT/DROP和其MARK值),实现对该数据流快速转发,且最终状态完成符合整个netfilter框架的完整处理结果。

详细设计:

a.在Mangle 的PREROUTING最开始,对特定的数据流进行匹配执行CONNMARK –restore-mark的操作,然后根据其skb的mark值中的特定Bit来判断其状态是被ACCEPT还是DROP,如果是ACCEPT则提供ACCEPT该skb,然后在每个tables的主chain中执行判断是否提前ACCEPT的操作。

b.在Mangle的POSTROUTING中,对满足条件的数据流打上ACCEPTed的标记(skb->mark),然后执行CONNMARK save-mark的操作将skb的mark值保存到conntrack对应的记录中。

c. 当netfilter的规则发生任何变化时,需要调用conntrack -U -m 0 shell命令,将当前conntrack模块中的所有状态跟踪记录的mark值设置为0。保证所有数据包的状态不受旧的规则的影响,在新的netfilter规则框架下,,conntrack记录中的每个数据流都能够得到正确的逻辑处理和状态结果。

注意:使用该方案后,系统中转发的数据流的计数就不能通过netfilter规则的执行次数记录来确定了。

细数门前落叶,倾听窗外雨声,

使用iptables CONNMARK target和conntrack 模块记录数据流的转发

相关文章:

你感兴趣的文章:

标签云: