STUN协议定义:http://www.ietf.org/rfc/rfc3489.txt
STUN协议的实现项目: http://sourceforge.net/projects/stun/ and http://developer.berlios.de/projects/mystun/
下面描述在debian(sarge)下安装stun server的过程:
1:做stun server的机器需要双网卡,我的测试机器的/etc/network/interfaces文件内容如附录1.
2:下载stund的程序源代码并编译
wget http://aleron.dl.sourceforge.net/sourceforge/stun/stund_0.94_Oct29.tgz
tar xzvf stund_0.94_Oct29.tgz
cd stund
make ## 编译生成程序 server
mkdir -p /root/bin
cp server /root/bin ##根据自己的需要放置到相应的目录
3: 制作辅助脚本文件 start_stund_server.sh(参见附录2)和stop_stund_server.sh(参见附录3)
chmod +x start_stund_server.sh
chmod +x stop_stund_server.sh
4: 修改start_stund_server.sh 文件中的ip地址为实际使用的地址
5:为了使系统启动时自动加载,创建文件 /etc/init.d/stund (参见附录4)
chmod +x /etc/init.d/stund
使用rcconf命令,在其中选择stund来激活启动是自动加载.当然,你也可以使用别的工具,
比如 sysvconf等。
6:不希望reboot机器,现在先手工启动stund、
/etc/init.d/stund start
7: 检查一下看看是否正常:
# ps aux | grep /root/bin/server
root 950 0.0 0.0 2436 888 ? S 03:45 0:00 /root/bin/server -h 210.202.244.132 -a 210.202.244.133 -b
看起来没什么问题。
当然可以进一步检查,看看端口是否正常:
# netstat -na | grep 347
udp 0 0 210.202.244.133:3478 0.0.0.0:*
udp 0 0 210.202.244.132:3478 0.0.0.0:*
udp 0 0 210.202.244.133:3479 0.0.0.0:*
udp 0 0 210.202.244.132:3479 0.0.0.0:*
看起来没什么问题。
8: 好了,可以下载一个客户端来测试一下了,http://sourceforge.net/projects/stun/提供一个windows的客户段
用起来不错的。你可以比较一下自己的server和公网上的server测试结果是否一样来判定自己的server是否工作
正常。
公网上stun server有:
current iTalk stun-server at: 216.16.193.43
WinStun default server: larry.gloo.net
vovida.org active stun-server : 128.107.250.38 128.107.250.39
9:希望一切顺利。
附录1: # cat /etc/network/interfaces
auto lo
iface lo inet loopback
auto eth0
iface eth0 inet static
address 210.202.244.132
netmask 255.255.255.192
network 210.202.244.128
broadcast 210.202.244.191
gateway 210.202.244.190
auto eth1
iface eth1 inet static
address 210.202.244.133
netmask 255.255.255.192
network 210.202.244.128
broadcast 210.202.244.191
附录2: # cat /root/bin/start_stund_server.sh
/root/bin/server -h 210.202.244.132 -a 210.202.244.133 -b > /dev/null 2>&1
附录3: # cat /root/bin/stop_stund_server.sh
killall /root/bin/server
附录4: # cat /etc/init.d/stund
#! /bin/sh
#
# /etc/init.d/stund: start and stop the STUND daemon
#
DAEMON_START="/root/bin/start_stund_server.sh"
DAEMON_STOP="/root/bin/stop_stund_server.sh"
test -x $DAEMON_START || exit 0
test -x $DAEMON_STOP || exit 0
case "$1" in
start)
echo -n "Starting STUND server: stund"
$DAEMON_START
echo "ok."
;;
stop)
echo -n "Stopping STUND server: stund"
$DAEMON_STOP
echo "ok."
;;
reload|force-reload)
echo -n "Restarting STUND server: stund"
$DAEMON_STOP
$DAEMON_START
echo "ok."
;;
restart)
echo -n "Restarting STUND server: stund"
$DAEMON_STOP
$DAEMON_START
echo "ok."
;;
*)
echo "Usage: /etc/init.d/stund {start|stop|reload|force-reload|restart}"
exit 1
esac
exit 0
stun_nat_traversal
简单来说,STUN解决的过程如下:
1、 将STUN Client放在NAT后的终端中。
2、 该终端在发送OLC之前调用STUN Client,去连接位于公网的任一台STUN Server.
3、 STUN Server与STUN Client进行STUN Messgae交互(STUN Server将对应的RTP/RTCP经NAT转换后的地址 告之STUN Client)。
4、 该终端在打开本地逻辑通道时,使用STUN Client已经发送过的地址作为RTP/RTCP地址。 并且在填写OLC时将STUN Client得到的NAT转换后的地址填写到OLC报文中。 比如:STUN Client使用192.168.1.4:40000与192.168.1.4:40001 与STUN Server通讯; 得到的经NAT转换后的地址为:221.12.27.14:2000与221.12.27.14:2039; 那么终端在打开本地的RTP/RTCP就指定为40000与40001, 同时OLC中地址替换为221.12.27.14:2000与221.12.27.14:2039。
5、 这样公网的终端将会把数据发到221.12.27.14:2000与221.12.27.14:2039上, NAT会送到192.168.1.4:40000与192.168.1.4:40001上。
在《这篇文档》中,提及了4种NAT类型,上面使用STUN的结果会有不同:
● 如果STUN Server和被叫不是同一主机,那么只有Full Cone类型的NAT才能成功。
● 如果STUN Server和被叫是同一主机(也就是被叫终端安装STUN Server),但STUN Server使用的端口与本地OLC 的端口不同,那么Restricted Cone NAT类型的也能成功。
● 如果STUN Server和被叫是同一主机,而且STUN Server使用的端口与本地OLC的端口相同,那么都能成功。
OpenH323 在其class H323EndPoint/class H323_RTP_UDP/class RTP_UDP中已经加入了STUN Client支持, 你只需要调用H323EndPoint ::SetSTUNServer(…),就可以完成Client的功能。 其STUN Client的代码在PWLIB中: http://cvs.sourceforge.net/viewcvs.py/openh323/pwlib/src/ptclib/pstun.cxx
虽然OpenH323没有提供STUN Server的支持,但是找到一个成熟的STUN Server/Client并添加到 OpenH323中并不是一件难事:http://sourceforge.net/projects/stun/ 是不错的选择。
将http://sourceforge.net/projects/stun/的代码放入PWLIB中编译,并相应的修改OpenH323,以支持STUN Server。
前一段在研究SIP,这里涉及到NAT穿越的问题。NAT有4种,其中symmetric NAT是无法穿越的。
为了检查电脑连接网络所用的NAT类型,有一个STUN协议(RFC3489),而按照STUN协议实现的一个工具软件是WinSTUN,这是一个开源软件,在Windows上运行就可以通过STUN协议与STUN服务器交换信息从而获知本机上网的NAT类型。
我在电脑上安装了WinSTUN,分别设置了两个STUN server,居然返回了2个不同的结果:
stun.iptel.org----
NAT Mapping is not endpoint independent - VOIP will NOT work
Does not preserve port number
Does not supports hairpin of media
stun.ekiga.net----
Nat with Independend Mapping and Port Dependent Filter - VoIP will work with STUN
Does not preserve port number
Does not supports hairpin of media
这当然是不合理的。在google上搜了一下,发现也有人碰到了同样的问题,不过没有解决或解释。
没办法,只有靠自己了,好在STUN协议还比较简单。于是用wireshark做了一下跟踪,跟踪过程简单记录如下:
1. stun.iptel.org
- sport:26884 --> 75:3478 Return 16.203:58135 with change address 93:3479
- sport:26885 --> 75:3478 no return
- sport:26884 --> 93:3478 return 16.203:58153
Result: different NAT port for different destine address, it is symmetric NAT.
2. stun.ekiga.net
- sport:17902 --> 138.128:3478 return 16.203:56118 but change address and source address exchanged in the package.
- sport:17903 --> 138.128:3479 no return
从跟踪过程可以看出,我这个NAT确实是symmetric NAT,stun.iptel.org返回的结果是对的,而stun.ekiga.net返回的包有问题导致WinSTUN没有完成STUN测试从而出来错误的结果。另外,还有别的STUN服务器也返回与ekiga相同的结果,后来发现其实stun.xten.com、stun.counterpath.com、stun.ekiga.net这几个都是相同的IP,是同一台服务器。
至此,这个问题就很清楚了,以后用STUN测试NAT类型,就别用ekiga的STUN服务器了。
http://hi.baidu.com/yeqing0218/blog/item/31572708fcc09f20e82488e6.html