浅析“TCP Proxy”设计
作者 appleleaf | 2010-03-13 20:03 | 类型 行业动感 | 14条用户评论 »
|
在入行网络安全领域之前,笔者并不知道这个东东的存在。对于主机软件研发人员和以及传统的路由交换研发人员,TCP Proxy这个模块并不存在。但是对于网络安全设备厂商而言,该模块至为重要。笔者所在的公司也有自己研发的TCP Proxy模块,但是本人从未阅读过模块的代码和设计(不读的原因是没有那个闲工夫)。本文是根据笔者对于上层安全应用特点以及TCP协议栈的经验总结的一些个人对于这个模块的设计看法,未必完全正确。 1.应用需求
上图是本人早年绘制的,是笔者对于TCP Proxy需求的理解。 九阴神功第一层For IDS:这个时候TCP Proxy需要尽力而为重组流量,但因为有些IDS工作在sniffer模式,而非inline,因此CPU处理速度可能无法match traffic的速度,遗漏一些报文,无法收齐报文是正常的。例如TCP Proxy可能会看到Ack来了,却没有收到对应的数据信息,这是正常的,表示遗漏了报文。 九阴神功第二层For IPS:同IDS不同,IPS必然是inline部署,此时肯定是可以收全报文的,否则则表示设备的网络部署有问题,因此TCP Proxy的实现可以相对严格。 九阴神功第三层For ALG:因为ALG需要根据NAT信息修改报文内容,因此对于ALG来说,TCP Proxy是Writable。而不像前两者那样是只读的,这就要求Proxy要handle序号更改、报文生成之类的东东。 九阴神功第四层For Host:不用多说了,一个full TCP协议栈(注意:这里仅仅用于对比,而不是一个TCP Proxy了)。与前述的东东相比,主机TCP协议最显著的特性就是要支持TCP之中的几个Timer,而且作为Internet的参与者,各种拥塞控制的义务是一定要尽到的,否则Internet很容易塞车。 九阴神功第五层For AV(UTM):这个层面的TCP Proxy原则上有义务实现Full TCP协议栈,至少几个timer是要实现的,可能杂七杂八的选项无法支持全。其相比四层神功的特点是需要协调两端的TCP连接。例如:TCP一段是GE上来的,另一端从WAN出去。此时如果不协调流控,则从GE上来的流量会噎死中间设备。这个增加了系统实现的复杂度。 2.效率考量 看过Socket实现的读者会知道,在协议内容传递到应用的时候,零散的Segment会被拷贝到一个平面缓冲区以供应用读取。对于技术偏着狂来说,这简直就是一种侮辱。因此,笔者考虑,应该可以直接利用原始Segment直接组装成Buffer Chain进行上交,如此可以满足研发人员的0拷贝的快感。 这样提高效率的代价是,应用层要意识到segment的存在,要enhance一些API。例如以往针对平面缓冲区的memcpy等标准库函数要增强其chain的实现。要想做模式匹配也要顾及到这种二维的情况。 3.自适应的设计 实现了上述的所有功能,是否很酷呢,非也:-) 对于使用类Socket的实现异或Buffer Chain的实现,设计上并非是非此即彼。笔者认为可以采用自适应的方式。对于大部分不需要特殊处理的流量采用buffer chain方式,如果需要组起来方便,可以动态提升对应的proxy session的能力。这个想法不知道是否正确,没有细想。 4.TCP Proxy模块的Driver
具我分析,TCP Proxy有上述的驱动源。 1.XXBuf:适配不同的Pkt结构,这样实现可以应用于不同的系统。 2.XXTimer,适配不同的Timer机制,提供基准时钟,用于驱动TCP协议内的不同定时器。 3.Session,适配不同的Session,如有下层提供session,这里可以用作宿主,保存一些东东。 必不得已而去,于斯三者何先?叶子曰:去Timer,对于ALG、IPS等应用,不需要提供tmer。必不得已而去,于斯二者何先?叶子曰:去Session,大不了大爷我自己组织TCP层的流量表。自古皆有死,TCP Proxy无Pkt不立:-) 5.开源软件的尴尬 目前还没有开源的TCP Proxy实现,一则难度大,二则门外的开发爱好者不了解需求。但是可以负责任的说,哪位大侠有余力搞一个高水平的TCP Proxy开源项目,必然成名立万。当然,一些工程师会为此丢了职位:-)。不过,此模块没有一年半载也搞不出来。当今社会晓畅兵机者多,刚明苦毅者少,至少笔者是没有这个额外精力了。 | ||
雁过留声
“浅析“TCP Proxy”设计”有14个回复
发表评论



这个以前也做过, 最大的难点其实是在转发层面的code上. 当然有C code的接口实现就相对容易些. 但转发平面也会更复杂一些.
难点有很多
1.如何高效实现
2.如何适应各种上层应用需求
等等。
兄台说的TCP Proxy不只与我的定义的是否相同。
grinder就是一个Man-in-Middle的TCP Proxy
http://grinder.sourceforge.net/
gradetwo,我看了一下是java项目就没有再看,如果java实现tcp proxy,则必然是基于两边建立两个socket的形式,没有什么太大的用途。
appleleaf说的可是tcp splicing技术?这个lvs项目中有个补丁,也被haproxy所使用了,不过他不支持option。
基于socket的tcp proxy,用户空间的倒是很多,不过能实现高效确实不容易,为了减少系统调用的开销,lvs的一个tcp proxy子项目将转发放到了内核空间,不过帮助应该不大就是了。Linux提供的操纵内核缓冲区的API splice,在特定的网卡下(支持TSO,并且驱动receive部分是用page map DMA),是可以实现ZERO copy的。目前还不知道哪个项目是用这个的。
实际上基于socket也没什么不好,能避免很多重复劳动,少走很多弯路,并且在需要转换TCP特性的场合,如TCP WAN acceleration方面还是非常有用的。
不知道haproxy 算不算呢?
多谢楼上两位的回复,我回来研究一下看看。
另外est的blog的图片很好玩,视角独特,呵呵。
“对于技术偏着狂来说,这简直就是一种侮辱。”呵呵,形容的非常生动。
目前国内有一家fw公司也自己实现了tcpprxy,非常的强大。当然,我相信你们的智商能猜出来是谁的。
TCP proxy的难点在于支持chained application, 传统的socket接口,只能有一个process/thread监听,而不能多个application监听,也就是说,tcp context没办法在多个application之间共享。如果只有一个application,tcp stack的socket interface改一改就可以了(参考以前的khttp,一个in-kernel的web server),如果是chained app,相互之间如何协调就是个问题。如果能够定义一套标准api(基于bsd socket),相信会有很大的价值。
那家公司,笔者冒充毕业生混进去看看。
to droplet,不算难,就是一个生产者,多个监听者的模型。
估计是hillstone…
“目前国内有一家fw公司也自己实现了tcpprxy,非常的强大。当然,我相信你们的智商能猜出来是谁的”
是不是每一个做fw的公司都会有自己实现的tcpproxy? 说“非常强大”,仁者见仁智者见智,很难说谁好谁不好吧?