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

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

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

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


默认情况下,在一条数据流被linux成功转发时,struct sk_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规则的执行次数记录来确定了。



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值