作者:
dagger
無崖閣
xyg.ods.org
版本:
1.02003-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
http://sourceforge.net/projects/upnp
linuxigd-0.92.tgz
http://sourceforge.net/projects/linux-igd
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 ([email protected])
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=http://192.168.0.1:52869/gatedesc.xml
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",
http://www.microsoft.com/windowsxp/pro/techinfo/deployment/natfw/default.asp
"UPnP NAT Traversal FAQ",http://www.microsoft.com/windowsxp/pro/techinfo/planning/networking/natfaq.asp