Chinaunix首页 | 论坛 | 博客
  • 博客访问: 6929372
  • 博文数量: 637
  • 博客积分: 10265
  • 博客等级: 上将
  • 技术积分: 6165
  • 用 户 组: 普通用户
  • 注册时间: 2004-12-12 22:00
文章分类

全部博文(637)

文章存档

2011年(1)

2010年(1)

2009年(3)

2008年(12)

2007年(44)

2006年(156)

2005年(419)

2004年(1)

分类: LINUX

2005-07-23 07:06:21

作者:
dagger
无崖阁
xyg.ods.org

版本:
1.0 2003-06-22
初始版本

一、引言
目前Linux的NAT和firewall只支持MSN Messenger的文字聊天,
本文介绍了如何让Linux的NAT和firewall支持MSN Messenger的语音聊天、文件传送等其它功能的方法。

二、几个基本概念
1、Linux NAT
Network Address Translation (NAT)是IETF的一个标准,用来使在私有网络中的PC和设备共享一个公开的可路由的IPv4地址。
使用NAT的一个主要原因是缓解目前IPv4地址资源的不足。通常NAT被用在网关设备中,位于私有网络和公共Internet之间。
当IP包要通过网关时,NAT就会把私有IP地址、端口和公开的IP地址、端口作转换。
Linux 2.4内核中NAT分为两种,Source NAT (SNAT)和Destination NAT (DNAT)。Source NAT就是转换IP包头的源地址,
SNAT总是在POSTROUTING中处理,即包被发送出去之前。Masquerading(IP伪装)是SNAT的一种特殊形式。
Destination NAT就是转换IP包头的目的地址,DNAT总是在PREROUTING中处理,即在收到包后在路由处理之前。
Port forwarding、load sharing、和transparent proxying都是属于DNAT。
Linux 2.4内核的NAT流程图:
_____ _____
/ /
PREROUTING -->[Routing ]----------------->POSTROUTING----->
D-NAT/ [Decision] S-NAT/
| ^
| |
| |
| |
| |
| |
| |
--------> Local Process ------

2、Linux Packet Filter
在Linux中使用包过滤(Packet Filter)来实现防火墙(firewall)的功能。Linux在内核中检查通过的包头,
决定所有包的命运,可能是丢弃(DROP)这个包,或允许(ACCEPT)包通过,或其它更复杂的动作。使用包过滤主要可以实现控制、
安全和警戒的功能。Linux 2.4内核中有三个过滤规则表,它们是INPUT、FORWARD和OUTPUT。对于数据包,如果是发给本机的,
则交INPUT处理;如果是发给其它PC或设备的,则交FORWARD处理;如果是由本机发送的,则交OUTPUT处理。
Linux 2.4内核的Packet Filter流程图:
_____
Incoming / Outgoing
-->[Routing ]--->|FORWARD|------->
[Decision] \_____/ ^
| |
v ____
___ /
/ |OUTPUT|
|INPUT| \____/
\___/ ^
| |
----> Local Process ----


3、UPnP
Universal Plug and Play (UPnP)是一种架构,用来实现目前流行的PC、智能设备或装置(特别是家庭中的)的端到端的网络连接。
UPnP基于Internet标准和技术,如TCP/IP、HTTP和XML,支持“零配置”网络和自动发现,一个设备可以动态地加入一个网络,
获得一个IP地址,声明自己的名字,向其它设备回应自己的能力,并学习到网络中其它设备的存在和能力。进一步,
一个设备可以平滑地并自动地离开这个网络,不会留下任何不期望保存的状态。UPnP会集了多个厂商的合作,以建立标准的
Device Control Protocols (DCPs),使用XML来表达,通过HTTP来通信,并提出了Internet Gateway Device (IGD)规格。

4、MSN Messenger使用的端口
微软的MSN Messenger软件是流行的即时通行软件,包含很多功能,根据微软的资料这个软件需要使用很多端口。
文字聊天:TCP 1863或80
音频和视频聊天:UDP 5004-65535 动态分配
应用共享和白板:TCP 1503
文件传输:TCP 6891-6900 允许一次传10个文件
远程助手:TCP 3389

三、遇到的问题
目前我这里的环境是在网关的计算机上装了Redhat Linux 8.0,配置了Masquerading可以让内部网络中的计算机共享上网;
配置了firewall限制外部计算机对网关的部分端口的访问。内部网络中的计算机除了MSN Messenger的文字聊天可以正常与外界通信外,
其它如音频聊天、文件传输等功能都无法实现。
NAT的问题:
* 在NAT后面的计算机使用私有IP地址,MSN Messenger会把这个私有IP地址的数据传送给对端,而NAT只能转换IP包头的内容,
无法转换IP包数据中包含的私有地址。
* NAT需要Port forwarding (端口映射)来使外部IP地址和端口与内部计算机IP地址与端口对应。MSN Messenger动态使用端口,
需要NAT能动态端口映射。
* 对于使用静态端口的情况,在NAT后面只能有一台计算机使用此功能。
firewall的问题:
* 对应MSN Messenger的TCP和UDP端口不能禁止,需要都开放。

四、解决方法
1、方案
MSN Messenger使用了UPnP,我们只要在Linux网关中支持UPnP,就能让MSN Messenger实现自动获得相应的NAT或firewall信息,
从而可以使用正确的IP地址和端口来通信。
目前已经有Linux下的UPnP开发包(libupnp)和支持Internet Gateway Device规格的应用软件(linux-igd)。

2、获得软件包
libupnp-1.2.1.tar.gz

linuxigd-0.92.tgz


3、编译安装
由于linuxigd-0.92原来是基于1.0.4版的UPnP开发包开发的,所以需要适当改动以支持最新的1.2.1版UPnP开发包。
(1) 编译安装libupnp
tar xzvf libupnp-1.2.1.tar.gz
cd libupnp-1.2.1/upnp/
make DEBUG=1 WEB=0
make install
安装后UPnP开发包的头文件就安装在/usr/include/upnp目录下,库文件就安装在/usr/lib目录下。

(2) 编译安装linuxigd
tar xzvf linuxigd-0.92.tgz
cd linux-igd/
cp ../libupnp-1.2.1/upnp/sample/common/sample_util.c sample_util.cpp
cp ../libupnp-1.2.1/upnp/sample/common/sample_util.h sample_util.h
并修改sample_utils.cpp文件:
把第661行的
*controlURL =
替换为
*controlURL = (char *)
把第671行的
*eventURL =
替换为
*eventURL = (char *)

修改gateway.h文件:
把第29行的
#define INIT_PORT 2869
替换为
#define INIT_PORT 52869

修改gate.cpp文件:
在第34行插入3行
#define UpnpDocument_free ixmlDocument_free
#define UpnpParse_Buffer ixmlParseBuffer
typedef IXML_Document *Upnp_Document;

链接头文件目录:
ln -s ../libupnp-1.2.1/upnp/inc upnp
并修改gate.h文件:
把第27行的
#include
替换为
#include "upnp/upnp.h"

修改gateway.cpp文件:
把第36行的
#include
替换为
#include "upnp/upnp.h"

修改sample_util.h文件:
把第43行的
#include "upnptools.h"
替换为
#include "upnp/upnptools.h"

再修改Makefile文件:
把第3行的
LIBS= -lpthread /usr/lib/libupnp.so
替换为
LIBS= -lpthread -lupnp

以上都修改完后,执行make,make install
安装后执行文件在/usr/bin目录下,配置文件在/etc/linuxigd目录下。

4、配置运行
添加一条路由:
route add -net 239.0.0.0 netmask 255.0.0.0 eth1
这里eth1是连接内部网络的网卡。
在/usr/sbin目录下添加iptables的符号连接:
ln -s /sbin/iptables /usr/sbin/iptables
因为linux-igd使用/usr/sbin/iptables,而Redhat Linux 8.0的iptables在/sbin目录下。
启动linux-igd:
upnpd eth0 eth1
这里eth0是连接Internet的网卡。
upnpd的debug信息输出在/var/log/debug文件中,如果你的系统上没有这个文件,可以编辑/etc/syslog.conf文件,加入:
*.debug /var/log/debug
并重新启动syslogd就可以了。

5、功能测试
upnpd程序正常启动后,我们可以在/var/log/debug文件中看到如下信息:
Jun 15 17:49:43 svr upnpd: The Linux UPnP Internet Gateway Device Ver 0.92 by Dime (dime@gulfsales.com)
Jun 15 17:49:43 svr upnpd: Special Thanks for Intel's Open Source SDK and original author Genmei Mori's work.
Jun 15 17:49:43 svr upnpd: Intializing UPnP with desc_doc_url=
Jun 15 17:49:43 svr upnpd: ipaddress=192.168.0.1 port=52869
Jun 15 17:49:43 svr upnpd: conf_dir_path=/etc/linuxigd/
Jun 15 17:49:43 svr upnpd: UPnP Initialization Completed
Jun 15 17:49:43 svr upnpd: Setting webserver root directory -- /etc/linuxigd/
Jun 15 17:49:43 svr upnpd: Registering the root device
Jun 15 17:49:43 svr upnpd: RootDevice Registered
Jun 15 17:49:43 svr upnpd: Initializing State Table
Jun 15 17:49:43 svr upnpd: State Table Initialized
Jun 15 17:49:45 svr upnpd: Advertisements Sent

上面的192.168.0.1是网关计算机的eth1的IP地址。
在内部网络中的计算机上启动MSN Messenger,与Internet上的其他Messenger用户测试语音聊天、文件传输都可以正常使用了。
在/var/log/debug文件中看到如下信息:
Jun 15 17:53:47 svr upnpd: AddPortMap: RemoteHost: (null) Prot: 17 ExtPort: 2032 Int: 192.168.0.19.12216
Jun 15 17:53:47 svr upnpd: AddPortMap: RemoteHost: (null) Prot: 6 ExtPort: 31989 Int: 192.168.0.19.13767

还可以使用iptables -t nat -L命令查看NAT配置情况,upnpd可以在PREROUTING中动态添加和删除表项。
注意:firewall还需要根据上面MSN Messenger的端口要求进行配置,在INPUT中开放相应的端口,并且FORWARD也需要ACCEPT。

五、参考资料
"NAT HOWTO",http://www.netfilter.org/documentation/
"Packet Filtering HOWTO",http://www.netfilter.org/documentation/
"Windows Messenger in Windows XP: Working with Firewalls and Network Address Translation Devices",

"UPnP NAT Traversal FAQ",
阅读(1457) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~