免费注册 查看新帖 |

Chinaunix

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

[网络管理] iptables conntrack module for qq (oicq) 有了吗? [复制链接]

论坛徽章:
0
发表于 2003-02-09 13:08 |显示全部楼层
在网易看到相关的介绍

http://uh1.gz.163.com/cgi/readelite?i=462547

主题:iptables和qq
发信人: shixudong(5270)
整理人: qiaoqian(2002-05-13 06:53:32), 站内信件  
一、提出问题
在用iptables作nat时,qq间通信经常需要通过服务器中转,而且有些时候发送速度很慢。具体表现为以下几种情形:
1、隐身用户或在线用户发送信息给nat后面的隐身用户、离线用户时,总需要经过服务器中转,但此时发送速度并不慢。
2、隐身用户发送信息给nat后面的在线用户时,不管这个隐身用户是不是也在nat后面,总需要经过服务器中转,而且此时发送速度很慢。
3、在线用户a发送信息给nat后面的在线用户b时,又分三种情况:
(1)、在线用户a不在nat后面,当a向b发送信息时,只要b不回答a,那么a发给b的信息总需要经过服务器中转,而且此时发送速度很慢;一旦b答复了a(由于a不在nat后面,所以b答复a很正常),那么此后a发给b的信息将恢复正常(即不需要中转,发送速度也很快)。
(2)、在线用户a也在nat后面,那么不论是a向b发送信息,还是b回答a的信息,有时候经过服务器中转,此时发送速度很慢;有时候又不必中转,此时发送速度很快。
(3)、是(2)的一个特例,在线用户a和在线用户b在同一个nat后面,他们之间互发信息,总是需要经过服务器中转,而且发送速度很慢。
二、分析问题
解铃还需系铃人,既然是在用iptables作nat时出现的问题,那我们还是通过分析iptables的工作原理来分析qq的问题。netfilter/iptables是基于linux2.4内核的具有状态检测功能的新一代包过滤防火墙,它的状态检测功能是通过连接跟踪模块实现的。iptables的连接跟踪模块不仅可以跟踪tcp,还可以跟踪无连接的udp。udp跟踪的实现原理如下:
当一个"初始"udp包从内网到达nat时,iptables会在/proc/net/ip_conntrack文件里记录该udp"连接"的一些信息:源地址/端口、目标地址/端口、期待的应答包的源地址/端口(对应于发送包的目标地址/端口)、期待的应答包的目标地址/端口(对应于发送包的masqed后的源地址/端口,即nat的外部地址/端口)。当该udp的应答包从外网到达nat时,在目标地址/端口符合的前提下,iptables还将用应答包的源地址/端口去匹配先前iptables保存的期待的应答包的源地址/端口。如果源地址/端口匹配,则iptables对其demasq并转交给nat后面的原始发送者;如果源地址/端口不匹配,则由于应答包的目标地址/端口是nat本身,iptables将该包放入INPUT链。一般情况下,INPUT链的默认策略为ACCEPT,则该udp应答包将被转交给nat的本地进程处理,但事实上由于不存在这样的本地进程,结果是nat向产生udp应答包的机器发回一个icmp-port-unreachable包(注意,这个包是linux系统产生的,不是iptables的REJECT目标产生的)。如果INPUT链的策略为DROP,则该udp应答包被DROP。
qq的即时通讯使用了udp,当nat后面的qq用户在登陆注册时,它必须向qq服务器的8000(udp)端口发送登陆请求,这是iptables看到的该udp的初始包,所以iptables记下了它的相关信息,当qq服务器的udp应答包到达nat时,能够匹配源地址/端口,所以iptables将其转交给nat后面的原qq用户。当该qq用户在qq服务器上登陆的同时,也注册了它的地址(发送包的masqed后的源地址/端口,即nat的外部地址/端口)。
如果用户a向nat后面的用户b发送信息,分两种情况:
1、b隐身,则a向qq服务器发送信息,然后再由b登陆时对应的qq服务器中转,由于这个中转包总是能够匹配源地址/端口,于是iptables将其转交给nat后面的b,所以此时虽然需要中转,但发送速度并不慢。
2、b在线,则a向b发送信息,实际上就是向b注册的地址发送udp包。然而,iptables在处理这个从外网来的udp包时,由于无法匹配该包的源地址/端口。如前所述,一般情况下,nat会向a发回一个icmp-port-unreachable包(用户a如果使用sniffer,应该能够捕获到这个icmp包)。然后,a会重复这个过程若干次,都无法发送成功。最后只能通过服务器中转,所以发送速度很慢。其实在这种情况下,还可细分:
(1)、a在线且不在nat后面,则只要b答复a,由于这个答复包在iptables看来是一个udp初始包,所以,iptables记下它的相关信息。当以后a再向b发送信息时,就能够匹配源地址/端口,从而a与b之间的通信不必再由服务器中转。
(2)、a在线但也在nat后面,当a第一次向b发送信息时,在a的nat处的iptables也会记录该udp包(aàb)的相关信息,但如前所述,这个包无法直接发送到b,必须经由服务器中转。当b答复a时,可分为两种情况:
如果b一收到a发来的信息(由服务器中转),就立即答复a。由于这个答复包在iptables看来是一个udp初始包,所以,iptables记下它的相关信息。当这个答复包到达a处的nat时,由于a处nat的iptables先前记下的相关信息尚未超时,能够匹配源地址/端口,所以该答复包(bàa)能够直接发送到a,此后a到b也能直接发送信息。
如果b收到a发来的信息(由服务器中转)后,过了一段时间才答复a。由于这个答复包在iptables看来是一个udp初始包,所以,iptables记下它的相关信息。当这个答复包到达a处的nat时,由于a处nat的iptables先前记下的相关信息已因超时而删除,因而无法匹配源地址/端口,所以该答复包(bàa)也只能够经由服务器中转发送到a。
作为(2)的一个特例,当a与b在同一个nat后面,无论如何,总是需要经过服务器中转,而且发送速度很慢。
在(1)和(2)两种情况下,即使a和b之间已经能够直接互发信息,但如果a与b之间长时间不联络,则由于udp"连接"的超时,iptables会删除超时的相关信息。从而a与b之间的通信将重复上述过程,所以会出现有时需要中转、有时不必中转的现象。
(3)、a隐身,则b答复a总是通过服务器中转,当以后a再向b发送信息时,仍然无法匹配源地址/端口,所以a与b之间的通信始终只能通过服务器中转 。虽然双方都需要中转,但是a向b发送消息很慢,而b向a发送消息很快。
由上面的分析可知,qq间通信经常需要通过服务器中转,"罪魁祸首"不是nat,而是iptables的连接跟踪。在iptables中,连接跟踪已经作为一个单独的模块被实现,对于nat来说,该模块自动且必须被启用,而在用iptables实现包过滤时,也可以使用连接跟踪功能。换句话说,不仅是nat,即使是包过滤(即和internet直接相连),只要使用了连接跟踪模块,同样无法避免qq间通信时产生服务器中转的现象。
如果使用ipchains取代iptables,尽管它没有连接跟踪功能,但在用ipchains作nat时,ipchains会记录一个masq表,该表的功能有些类似于iptables的连接状态表。所以,用ipchains作nat,一般情况下,qq间通信也会出现通过服务器中转的现象。但由于ipchains是基于linux2.2内核,而从linux2.2.3内核开始,另有一个参数专门用于控制udp,即/proc/sys/net/ipv4/ip_masq_udp_dloose。如果ip_masq_udp_dloose为0,则ipchains处理从外网到来的udp时,必须去匹配源地址/端口。如果ip_masq_udp_dloose为1,则ipchains处理从外网到来的udp时,不去匹配源地址/端口,任何目标地址/端口符合的udp包,都将被ipchains转交给nat后面的原qq用户,从而也就不会出现qq间通信通过服务器中转的现象。从linux2.2.16内核开始,ip_masq_udp_dloose默认为0,而在此之前,ip_masq_udp_dloose默认为1。也就是说,如果使用linux2.2.3内核以后、linux2.2.16内核以前的ipchains,默认情况下,qq间通信是不会出现通过服务器中转现象的。
三、解决问题
前文提到,qq间通信经常需要通过服务器中转,是由iptables的连接跟踪功能造成的。事实上,不仅是qq,只要是基于udp的即时通讯软件,在使用iptables的连接跟踪功能时都有这个问题;还有我们常用的tftp客户端,由于tftp服务端返回的udp包使用的源端口不同于客户端发出的udp包的目标端口,所以也无法和iptables的连接跟踪功能一道使用。  
为了使这些软件能和iptables的连接跟踪功能协同工作,需要加载附加的连接跟踪模块,如ip_conntrack_qq.o、ip_conntrack_tftp.o。此外,为了使这些软件在nat后面也能正常工作,考虑到nat总是和iptables的连接跟踪捆绑在一起,所以,在nat环境下,不仅需要加载这些软件的连接跟踪模块,还需要加载它们的nat模块,如ip_nat_qq.o、ip_nat_tftp.o。然而,到目前为止,netfilter/iptables的标准发布只提供ftp和irc的相关模块。至于其他软件的相关模块,则需要自行编写。有关编写这些连接跟踪和nat相关模块的资料可以参见如下网址:http://www.gnumonks.org/ftp/pub/doc/conntrack+nat.html。下面这个网址列出了一些常用软件(如tftp客户端)的已经可用的连接跟踪和nat相关模块的一些资料:http://netfilter.samba.org/documentation/HOWTO//netfilter-extensions-HOWTO-5.html,具体的模块则可以通过google搜索得到。
对于qq软件,编写这个模块的大致思路如下,在qq用户登陆注册时,它必须向qq服务器的8000(udp)端口发送登陆请求,所以这个模块只要监控向外的8000(udp)端口的初始连接,一旦发现这个初始连接,该模块就可记住初始udp包对应的masqed后的源地址/端口,即nat的外部地址/端口。以后,当有其他qq用户向这个nat后面的qq用户发送信息时,实际上就是向该模块记住的nat的外部地址/端口发送udp包,只要这些udp包的目标地址/端口符合该模块记住的nat的外部地址/端口,该模块就不去匹配源地址/端口,直接将这些udp包转交给nat后面的原qq用户,从而也就不会出现qq间通信通过服务器中转的现象。这就是ip_conntrack_qq/ip_nat_qq模块的简单实现,至于复杂的实现,还可以让不同nat后面的qq用户进行文件传输。
事实上,qq的连接跟踪和nat相关模块的编写者,最理想的莫过于腾讯公司了。希望老马能看到这篇文章,并希望老马在看到这篇文章后,不是从经济利益出发,而是本着GNU的精神,为广大linux/iptables后面的qq迷们带来福音。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP