在 NAT 的网络环境下要进行 P2P 通信的前提是进行 NAT 打洞 (NAT hole-punching),我们可以借助实现了 STUN 协议的 STUN 服务器来获取双方的地址来帮助做到打洞。但如果双方的 NAT 类型无法进行打洞(详情见我的这篇文章:P2P 的 NAT),就需要借助实现了 TURN 协议的 TURN 服务器来进行双方数据的交换。

ICE 协议同时使用了 STUN 协议和 TURN 协议。

我们可以使用 coturn 来方便搭建一个 ICE 服务器。

coturn

地址:https://github.com/coturn/coturn

你可以在 Linux 上直接使用包管理安装,或者使用 Docker 部署,但是在我使用 Docker 部署的时候总是失败,同时占满了我服务器的内存和 CPU 和网络,没搞懂是什么原因。所以这里我直接用 apt-get 安装。

$ sudo apt-get update
$ sudo apt-get install coturn

然后可以直接启动

$ sudo coturn

启动后它会告诉你有一些东西没有配置,比如证书等,所有的配置都默认在这个路径下:/etc/turnserver.conf

证书

首先我们配置证书。

使用 openssl 生成证书和密钥:

$ openssl req -x509 -newkey rsa:2048 -keyout /usr/local/etc/turn_server_pkey.pem -out /usr/local/etc/turn_server_cert.pem -days 99999 -nodes

证书和密钥你可以放在任何你想要的路径。然后在 /etc/turnserver.conf 中配置证书和密钥的路径:

cert=/usr/local/etc/turn_server_cert.pem
pkey=/usr/local/etc/turn_server_pkey.pem

监听端口

然后配置各种端口,也是在 /etc/turnserver.conf 中配置。

# 监听端口,0.0.0.0 即可
listening-ip=0.0.0.0 
# 公网 ip
external-ip=<你的公网IP>

有些文章(CSDN)会教你配置 relay-ip=<公网IP>,但其实你并不需要配置,或者配置为 0.0.0.0 即可,(参考:Cannot Assign Requested Address - running through all the ports)。

用户名密码 realm

使用 TURN 协议需要用户名和密码,所以要配置一个。至于 realm,就是一个域名啦,指定一个域名可以让你使用域名而不知 IP 的方式来使用 ICE 服务。要注意让你的域名正确解析到你的服务器地址。

比如在这里我配置的 realm 是 turn.rustsoft.cn

在配置 /etc/turnserver.conf 中配置你的用户名和密码和 realm

user=<你的用户名>:<密码>
realm=<你的域名>

配置好了后重启一下 coturn,然在 这里 测试你的 ICE 服务器。

测试

file

如果只想测试 STUN 的话可以在 STUN or TURN URI 的输入框输入 stun:<你的 stun 服务器地址>,点击 Add Server,然后在下方点击 Gather candidates 测试,在显示的列表中的 Type Foundation 列中有 srflx 的话就表明 STUN 服务器正常。

如果测试 TURN 的话可以在 STUN or TURN URI 的输入框输入 turn:<你的 stun 服务器地址>,然后在 TURN usernameTURN password 输入框中分别输入你在先前配置的用户名和密码,点击 Add Server,然后在下方点击 Gather candidates 测试,在显示的列表中的 Type Foundation 列中有 relay 的话就表明 STUN 服务器正常。

后台自启动

可以使用以下命令让你的 coturn 在后台运行和开机自启:

systemctl restart coturn
systemctl enable coturn

完事儿