Chinaunix

标题: netfilter修改http报文后抓包正常,浏览器无法显示 [打印本页]

作者: 泽畔无材    时间: 2014-05-05 10:53
标题: netfilter修改http报文后抓包正常,浏览器无法显示
本帖最后由 泽畔无材 于 2014-05-06 09:13 编辑

rt, 在网关处加载一个内核模块,利用netfilter在网页中加一小段代码。
参考了网上很多朋友的资料,昨天曾经几乎做出来了,后来不知道改了哪里,结果就出现了标题说的问题。。
主要处理方式就是:
if (ct && __nf_nat_mangle_tcp_packet(skb, ct, ctinfo,
         iph->ihl*4 , (int)(head - payload), 0,
        _ins, LEN_INS, true )) {
                skb->local_df = 1;        //强制分片
                skb_shinfo(skb)->gso_size = 0;        //hack:防止warning。。
}
貌似__nf_nat_mangle_tcp_packet里都处理好了一切,另外还用了ct->status的高几位标示连接状态,方便插入。
在PC端的wireshark里的抓包结果是:

可见整个http通信过程非常顺利啊。。
然而chrome浏览器显示无法显示此网页,错误代码:ERR_INVALID_CHUNKED_ENCODING
chrome端的处理过程是:

也就是说接收完头部之后,处理body时出现了错误。。但是查看body部分报文也是非常正常的。。
后来用较早前备份的成功的代码测试也是相同的错误,很诡异。。

求问大婶们,可能是什么地方出了问题呢?我可能调太久调头晕了。。

PS:对于有些网页,比如2345网址导航, 不管其长度是否要分片,上述模块可以正确添加一小段代码,比如<!-- test -->, 但是对于多数网页来说,都是返回ERR_INVALID_CHUNKED_ENCODING。。
PPS:刚发现是网页内容被截断了,但content-length已经被我改过了的啊,见下面截图,不清楚为什么实际上还是按原始长度解析:


更新:已查明是Transfer-Encoding: chunked 搞的鬼,这都是http部分的事情了,害我在底层找半天。。
更新:修正 上面这个属性后,初步搞定了~


                       
作者: lonelyair    时间: 2014-05-05 11:12
content-length是不是正确的?
作者: 泽畔无材    时间: 2014-05-05 11:19
回复 2# lonelyair
content length 也改过了的,有些动态生成的网页是没有content length的,经过测试,即使不改centent length, chrome也可以显示整个网页。
另外,诡异的是,对于有些网页,不管其长度是否要分片,上述模块可以正确添加一小段代码,比如<!-- test -->, 但是对于多数网页来说,都是返回ERR_INVALID_CHUNKED_ENCODING。。


   
作者: lonelyair    时间: 2014-05-05 11:27
那这个是本身chrome有几率出现这个错误,还是你修改导致的?
另外content cache与encode怎么设置的?不知道有没有影响


另,修改BODY部分也没成功过,还请赐教
作者: 泽畔无材    时间: 2014-05-05 11:36
回复 4# lonelyair
移除模块后不会出现这个错误。
content cache没有设置,不过每次测试前都清除浏览器缓存数据,并且将请求改为不允许gzip压缩编码等
应该只要找出目前这个问题所在,就差不多能完成http的报文修改了(虽然昨天已经实现过了的啊,后来不知道改了哪里就成这样了。。)


   
作者: lonelyair    时间: 2014-05-05 17:34
回复 1# 泽畔无材


    恭喜恭喜啊,能不能把过程详细些,chunk会导致content-length的长度?对于HTTP处理不太理解
作者: 我不重要    时间: 2014-05-05 18:56
楼主,你好,请问你能不能把你写的代码给我一份吗,我现在特别想学netfiter,可是没有例子,想借你的程序看看,demo也行,谢谢
作者: 瀚海书香    时间: 2014-05-05 19:37
回复 7# 我不重要
楼主,你好,请问你能不能把你写的代码给我一份吗,我现在特别想学netfiter,可是没有例子,想借你的程序看看,demo也行,谢谢

直接看net/netfilter的源码不就行了

   
作者: mnipxh    时间: 2014-05-05 21:01
恭喜lz找出问题。chunk以\r\n'0'\r\n\r\n作为结束标志,
作者: 我不重要    时间: 2014-05-06 09:16
回复 8# 瀚海书香
不好意思啊,因为我对netfilter不是很熟,我刚才看了一下,不知道如何入手,我觉得应该先netfilter的接口先入手吧,以后弄熟了在去看他的源代码比较好,不知道我说的对不对,谢谢大神


   
作者: 泽畔无材    时间: 2014-05-06 09:18
回复 6# lonelyair

Transfer-Encoding是chunk的话,即分块策略传输,每段开始有一个十六进制数字表示该段的长度。
我是参考http://www.cnblogs.com/jcli/archive/2012/10/19/2730440.html的内容的。
   
作者: Godbach    时间: 2014-05-06 09:25
回复 1# 泽畔无材

校验和都处理正确了吗

   
作者: lonelyair    时间: 2014-05-06 09:40
回复 11# 泽畔无材


    谢谢,去看看
作者: 瀚海书香    时间: 2014-05-06 09:52
回复 10# 我不重要
看看这个http://bbs.chinaunix.net/forum.php?mod=viewthread&tid=3565585

   
作者: 泽畔无材    时间: 2014-05-06 10:34
回复 13# Godbach
我直接调用__nf_nat_mangle_tcp_packet,它会帮忙全部处理了的。后来发现不是底层的问题,是http层的问题,见主贴底部的更新。。


   
作者: 我不重要    时间: 2014-05-06 11:30
回复 15# 瀚海书香


    谢谢
作者: Godbach    时间: 2014-05-06 12:48
回复 16# 泽畔无材

赞一个。

   
作者: lonelyair    时间: 2014-05-06 16:24
回复 16# 泽畔无材


    有意思,这样netfilter hook在那里?
__nf_nat_mangle_tcp_packet有没有影响,还有HTTP请求与响应都要修改啊,处理会不会复杂些,一直是想处理响应部分了,能不能说明下?
作者: 泽畔无材    时间: 2014-05-06 20:58
回复 19# lonelyair

hook在NF_INET_POST_ROUTING,
我仔细看了下__nf_nat_mangle_tcp_packet,好像只处理了当前包的seq修正,可能接下来的包有系统自带的hook根据status的那个标志位自动处理seq修正了?反正抓包结果表明序列号都是对的。。
HTTP请求只是改了下禁止gzip,和响应的改法差不多。
   
作者: 泽畔无材    时间: 2014-05-08 15:48
回复 18# Godbach

现在发现个小问题,我的hook点在NF_INET_POST_ROUTING,而dnat在NF_IP_PRE_ROUTING就处理了,在我的hook里检查,发现dst ip的确已经被改正了,但是mac仍然是网关的mac,想问下数据包的mac是何时被改正为内网机子的mac呢?在这个hook里能否获取到目标的mac?
   
作者: Godbach    时间: 2014-08-14 15:24
回复 21# 泽畔无材
各层 header 是在各层处理的 ,MAC 要到二层的处理函数中设置


   
作者: lyyxh2004    时间: 2014-08-21 21:54
楼主  请问一下如果http返回的数据包刚好达到了MTU的最大值,还能插入数据吗?
作者: 泽畔无材    时间: 2014-08-22 11:48
回复 23# lyyxh2004

可以的,ip层自动分片
   
作者: Godbach    时间: 2014-10-10 09:52
回复 21# 泽畔无材

找到 mac_header 不就找到二层头部了吗
   
作者: 木鱼长老    时间: 2014-12-24 22:24
大牛,最近也在想实现这个功能,但是一直毫无头绪,能否分享一些资料,源码或者是设计思想,非常感谢!!!邮箱:candxiao@126.com
作者: songboyu331234    时间: 2016-08-30 02:12
最后Transfer-Encoding: chunked是怎么修正的呀,我也遇到一样的问题了,还有你用的内核是3.1x吧?发现3.2x里__nf_nat_mangle_tcp_packet不会设置ct->status里
作者: songboyu331234    时间: 2016-08-30 03:03
呀,刚刚找到解决方法啦,我是在请求的时候把HTTP/1.1换成了HTTP/1.0,这样就不会返回chunked的数据啦




欢迎光临 Chinaunix (http://bbs.chinaunix.net/) Powered by Discuz! X3.2