如何搭建自己的STUN服务器
作者:罗上文,微信:Loken1,公众号:FFmpeg弦外之音
我们前面在使用 libdatachannel 的 client
示例进行 P2P 通信的时候,使用的都是第三方的 STUN 服务器,如下:
./examples/client/client -w 175.178.179.175 -s stun4.l.google.com -t 3478
上面我们使用了 stun4.l.google.com
作为 STUN 服务器。
STUN 服务器的作用是让 内网的机器能获取到自己在公网上对应的 UDP 通道信息,如下:
上图是 Wireshark 抓包的效果图,可以看到,内网机器往 stun4.l.google.com
(142.251.2.127) 发送了一个 STUN Binding 的包,这是通过 UDP 传输的,所以这个请求会在运营商里面打开一个临时的 UDP 通道,如下:
内网机器就是通过这个 临时的 UDP 通道 跟 STUN 服务器通信。所以这个 UDP 通道的信息,STUN 服务器是知道的。因此 STUN 服务器可以把这个 UDP 通道信息 放在 STUN Response 里面返回给 内网的机器。
上图中,我的笔记本在公网中的 UDP 通道信息是 120.231.13.215:8164
。这个 UDP 通道是临时的,可能会被运营商回收。
其他的终端有一定的概率 可以通过 120.231.13.215:8164
这个 UDP 通道跟我的笔记本进行通信。如果能成功通信,就称为 P2P 打洞成功。
由于上面这些 STUN 服务器都是第三方的,使用起来不一定可靠。所以本文就来介绍一下如何搭建自己的 STUN 服务器。
我这里使用的是 STUNTMAN 开源项目的 version1.2.13 版本的源代码。STUN 服务器需要部署在公网上的,请在云服务器上执行下面的操作。
我们需要先安装一下依赖。
sudo apt-get install g++ make libboost-dev libssl-dev libc6-dev
不过这里有一个问题,通常情况,你安装的 openssl
版本是 3.0 的,而 STUNMAN
需要低于 1.1.0 的版本。
这时候我通常是不删除 apt
安装的 openssl 3.0 版本,我让它保留下来,避免影响到其他软件。我会下载一下 openssl 1.0.1s 版本的源代码,然后编译,再把他们安装到 /usr/local/ssl
的目录。
这样就不会影响到原来的 openssl 3.0 版本,我需要用 openssl 1.0.1s 的时候临时设置一下环境变量即可。
这个环境变量的设置也是很有讲究的,我们必须把 /usr/local/ssl
目录设置在最前面,这样 编译器,链接器,加载器 才会优先选择 openssl 1.0.1s 的库
我们先下载一下 openssl 1.0.1s 版本的代码,下载地址如下:
https://github.com/openssl/openssl/releases/tag/OpenSSL_1_0_1s
下载完之后,解压,然后开始编译。命令如下:
cd ~/Documents/openssl-OpenSSL_1_0_1s
./config
make -j4
sud make install
通常安装成功之后,你就能在 /usr/local/ssl/lib
目录看到 openssl 1.0.1s 版本的库了,如下:
由于 STUNTMAN
没有使用 pkgconfig
里面的配置文件,我们需要改他的代码,加上 openssl
的路径,如下:
1,修改 common.inc
#BOOST_INCLUDE := -I/Users/jselbie/boost_1_63_0
#OPENSSL_INCLUDE := -I/Users/jselbie/openssl/include
修改为
BOOST_INCLUDE := -I/usr/include/boost
OPENSSL_INCLUDE := -I/usr/local/ssl/include
2,修改所有的 Makefile
我们要在 LIB_PATH
后面全部加上 -L/usr/local/ssl/lib/
,如下:
STUNTMAN
里面有好几个 Makefile
,一定要全部都加上 ssl
的路径。
现在我们终于可以开始编译 STUNMAN
了,命令如下:
cd ~/Documents/stunserver-version1.2.13
make -j4
编译成功之后就可以看到 stunserver
,stunclient
等可执行文件,如下:
由于 stunserver
是静态链接到 openssl
的,所以我们不需要设置 LD_LIBRARY_PATH
环境变量 也可以正常启动。
export LD_LIBRARY_PATH=/usr/local/ssl/lib/:$LD_LIBRARY_PATH
stunserver
默认是绑定在 3478
端口的,我们可以在局域网用 stunclient
来获取一下自己的 IP 信息。如下:
现在我们就能用自己的 STUN 服务器来进行 P2P 通信了,命令如下:
./examples/client/client -w 175.178.179.175 -s 175.178.179.175 -t 3478
补充:我是在 ubuntu 系统上做的实验,有些读者是在 Debian 系统上做的实验。在 Debian 上编译 openssl
经常会遇到下面这个错误。
undefined reference to `dlopen'
dlopen
是 DL 库的一个函数,DL 的全称是 Dynamically Loaded (DL) Libraries,这是一个系统库来的,通常是 /lib64/ld-linux-x86-64.so.2
每个操作系统基本都有这个库的,找不到是因为 Debian 上的链接工具可能有点不完善。
解决方法就是,你需要修改一下 common.inc
,把 -ldl
加在 -lcrypto
后面就行了,一定要加在后面,不能加在前面,如下:
除了 STUNTMAN,还有另外两个开源项目可以作为 STUN 服务器,如下:
- Violet,libdatachannel 作者 Paul-Louis Ageneau 的另一款经典之作。轻量级的 STUN/TURN 服务器
- coturn,一款重量级的 STUN/TURN 服务器,非常流行。
参考文章: