免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 2147 | 回复: 3

[网络子系统] 如何能更高效的通过hook修改源地址? [复制链接]

论坛徽章:
0
发表于 2015-09-01 10:35 |显示全部楼层
A机器是转发服务器,B机器是流媒体服务器,A和B在不同的机房,都只有公网地址,系统都是ubuntu server 14.04,iptables的默认策略都是accept,客户端的请求包和服务器的响应包都是udp包
为了隐藏和保护B机器的真实ip地址,计划做如下配置:
1. 让客户端向A机器请求服务,A机器上做DNAT,把请求包转发到真实的服务器B
2. 在B上做SNAT,修改响应包的源地址为A的ip地址。

A机器上DNAT到B很正常,但B机器上无法通过SNAT来修改源ip,命令如下:
iptables -t nat -A POSTROUTING  -s B-ip -p udp --sport B-port -j SNAT --to-sourece A-ip
用过端口匹配,ESTABLISHED匹配,源地址匹配都无法实现修改源ip,就好像SNAT没有效果,但用conntrack -L -p udp可以看到有conntrack到连接
最后,只能写hook来修改源地址,参考了这个帖子:netfilter修改IP以后一直发不出包,只是修改tcp协议为udp协议
make后加载模块,可以修改源ip了,但要命的是B机器的流量较大,高峰时超过1Gbps,此时cpu使用率超过90%,在top中查看,sys的cpu使用率也超过30%,B机器上基本是原始ubuntu server系统,只升级后就部署了服务程序和上述的内核模块

请问如何能高效实现修改源ip?
我能想到的:
1. 设置为硬件校验和skb->ip_summed = CHECKSUM_PARTIAL;让这部分计算由网卡完成,已经通过ethtool -k eth0检查,确认网卡支持发送包硬件校验和;
2. 在模块中加入conntrack,实现快速匹配,只匹配连接的头包,此连接后面的包都直接修改。
当然,如果在B机器上能直接使用SNAT是应该比较高效,但一直没能实现。

请教各位大神,上述的提高效率的方法是否可行,有其他的方法能以较小的成本实现修改源ip的需求吗?

论坛徽章:
0
发表于 2015-09-02 17:43 |显示全部楼层
直接用netfilter 修改源地址的性能的性能不会这么差, 大致看了下那个代码,  里面有线性处理,   if ( skb_linearize(skb) != 0 )  这个直接修改包头的话就不用进行线性化.  直接这样修改就行了 inet_proto_csum_replace4(&udph->check, skb, oldip, newip, true);

论坛徽章:
0
发表于 2015-09-02 22:03 |显示全部楼层
非常感谢!我马上修改编译测试一下。

论坛徽章:
0
发表于 2015-10-09 21:39 |显示全部楼层
snat只有在连接状态为new时才会去设置nat信息。在你描述的场景中(假设客户端为C)B首先收到C->B的数据,这是conntrack状态为NEW,当B->C时在LOCALOUT处状态变为established,在postrouting时就不会去执行nat信息的设置,所以添加规则不能修改IP地址。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP