STUNTMAN 开源STUN服务器完全指南:从部署到测试
一、项目概述
STUNTMAN 是一款由 John Selbie 开发的高性能开源 STUN 服务器实现,严格遵循 RFC 5389、5769 和 5780 标准,同时向后兼容 RFC 3489。该项目采用 C++ 编写,支持 Linux、macOS、BSD、Solaris 等主流 UNIX 系操作系统,并可通过 Cygwin 在 Windows 环境下运行。作为一款 Apache 2.0 许可的开源软件,STUNTMAN 不仅提供了高性能的服务端程序,还包含了功能完整的客户端工具和可嵌入应用程序的代码库,是 WebRTC 应用开发和 NAT 环境诊断的重要工具。
STUN(Session Traversal Utilities for NAT)协议的核心价值在于帮助位于内网(NAT 后方)的设备发现自身在公网上的映射地址(IP 和端口),这是建立 P2P 直连通信的关键第一步。无论是音视频通话、在线游戏还是文件共享,STUN 都为后续的 ICE 协商奠定了基础。
二、安装与编译
2.1 获取源码
访问 STUNTMAN 官方网站(https://www.stunprotocol.org)下载最新稳定版本。以版本 1.2.16 为例,Linux/macOS 用户应获取 stunserver-1.2.16.tgz 源码包,Windows 用户可根据系统位数选择对应的 Cygwin 二进制压缩包。
下载完成后,通过以下命令解压源码包:
tar -xzf stunserver-1.2.16.tgz
cd stunserver-1.2.16
2.2 安装依赖库
STUNTMAN 的编译依赖于 Boost 库。在不同操作系统上安装 Boost 的方式有所差异:
Ubuntu/Debian 系发行版:
sudo apt update
sudo apt install libboost-all-dev build-essential
macOS(需先安装 Homebrew):
brew install boost
CentOS/RHEL 系发行版:
sudo yum install boost-devel gcc-c++ make
注意:直接使用
sudo apt install boost会失败,因为不存在名为boost的软件包。正确的包名是libboost-all-dev。
2.3 编译源码
在源码根目录下执行 make 命令即可开始编译。Makefile 会依次进入 common、stuncore、networkutils、testcode、client、server 六个子目录进行编译,最终生成三个关键的可执行文件:
- stunserver:STUN 服务端程序,部署在公网服务器上运行
- stunclient:STUN 客户端工具,用于发起查询和诊断
- stuntestcode:单元测试程序,用于验证编译结果是否正确
make # 编译所有组件(debug模式,默认)
make debug # 明确指定debug模式
make profile # 编译profile优化版本
编译完成后,copybin 目标会自动将三个可执行文件复制到根目录。
注意:该项目不支持单独编译
stunserver或stunclient,执行make时必须完整编译所有组件。
编译完成后,建议运行单元测试以验证编译结果:
./stuntestcode
如果所有测试项均显示 PASS,说明编译成功,环境配置正确。
2.4 关于 make install
STUNTMAN 的 Makefile 没有提供 make install 功能。编译完成后,可执行文件位于当前目录,可以通过以下方式使用:
- 直接在当前目录运行:
./stunserver或./stunclient - 手动复制到系统路径:
sudo cp stunserver stunclient /usr/local/bin/
2.5 清理编译文件
make clean # 清理所有子目录中的目标文件,并删除根目录下的三个可执行文件
三、服务端部署(stunserver)
3.1 运行模式
STUNTMAN 服务器支持两种运行模式,通过 --mode 参数指定:
| 模式 | 所需IP | 功能 | 适用场景 |
|---|---|---|---|
basic(默认) | 1个公网IP | 响应基础的STUN绑定请求,返回客户端的公网地址和端口 | 最常见的部署方式,满足WebRTC等绝大部分应用的地址查询需求 |
full | 必须拥有2个不同的公网IP | 除了基础请求,还能响应客户端的 CHANGE-REQUEST,用于NAT行为(Behavior)和过滤(Filtering)的深度检测 | 用于网络环境诊断和NAT类型研究 |
重要:
full模式要求服务器拥有两个不同的公网IP地址,并且需要明确指定--primaryinterface和--altinterface。
3.2 服务端参数详解
| 参数 | 说明 | 默认值 |
|---|---|---|
--mode MODE | 运行模式,可选 basic 或 full | basic |
--primaryinterface INTERFACE | 主监听IP地址或网卡名(如 eth0) | basic模式下监听所有网卡 |
--altinterface INTERFACE | 备监听IP地址或网卡名(仅 full 模式) | 无 |
--primaryport PORTNUM | 主监听端口 | 3478 |
--altport PORTNUM | 备监听端口(仅 full 模式) | 3479 |
--family IPVERSION | IP协议版本,4 或 6 | 4 |
--protocol PROTO | 传输协议,udp 或 tcp | udp |
--maxconn MAXCONN | TCP模式下的最大并发连接数(1-100000) | 1000 |
--verbosity LOGLEVEL | 日志详细程度(0-3) | 0 |
--ddp | 启用DDoS防护 | 默认关闭 |
--primaryadvertised IP | 向客户端通告的主公网IP(云环境专用) | 无 |
--altadvertised IP | 向客户端通告的备公网IP(云环境专用) | 无 |
--configfile FILENAME | 使用JSON配置文件启动 | 无 |
--reuseaddr | 允许端口复用 | 默认关闭 |
--help | 显示帮助信息 | – |
3.3 服务端部署示例
基础模式(最常用):
# 使用默认配置启动
./stunserver
# 指定IP并提高日志级别
./stunserver --primaryinterface 192.168.1.100 --verbosity 1
Full模式(用于NAT检测):
./stunserver --mode full --primaryinterface 128.34.56.78 --altinterface 128.34.56.79
启动后,服务会监听以下四个地址:
128.34.56.78:3478128.34.56.78:3479128.34.56.79:3478128.34.56.79:3479
TCP模式:
./stunserver --protocol tcp
3.4 云环境(AWS EC2)特殊配置
在AWS EC2、阿里云等云主机上部署时,服务器通常只有一个内网IP,公网IP由云平台通过NAT映射。此时需要使用 --primaryadvertised 和 --altadvertised 参数手动指定公网IP:
./stunserver --mode full \
--primaryinterface 10.0.0.5 \
--altinterface 10.0.0.6 \
--primaryadvertised 54.123.45.67 \
--altadvertised 54.123.45.68
如果不设置这两个参数,服务器返回的 OTHER-ADDRESS 和 CHANGED-ADDRESS 属性会是内网IP,导致客户端无法完成正确的NAT检测。
3.5 防火墙配置
部署服务端时,必须在服务器的防火墙以及云服务商的安全组中放行相应端口。默认情况下需要开放 UDP 3478 端口。若需要支持TCP模式,则还需开放 TCP 3478 端口。Full模式下还需要放行 3479 端口。
四、客户端测试(stunclient)
4.1 测试模式
stunclient 支持三种测试模式,通过 --mode 参数指定:
| 模式 | 功能 | 适用场景 |
|---|---|---|
basic(默认) | 执行一次简单的STUN绑定请求,获取公网IP和端口 | 最常见的需求,验证服务可用性 |
behavior | 诊断NAT的“映射行为”,检测端口分配是否独立于目标地址 | 分析NAT是“锥形”还是“对称型”,预测P2P打洞成功率 |
filtering | 诊断NAT的“过滤行为”,检测外部主机在什么条件下能向你发送数据 | 分析NAT的防火墙规则严格程度(仅支持UDP) |
注意:
full模式已被标记为“弃用”,官方建议将behavior和filtering分开测试。
4.2 客户端参数详解
| 参数 | 说明 | 默认值 |
|---|---|---|
server | 必需参数。STUN服务器的IP地址或域名 | – |
port | 服务器端口 | 3478 |
--mode MODE | 测试模式,可选 basic、behavior、filtering | basic |
--localaddr INTERFACE | 指定本地网卡或IP地址用于通信 | 系统自动选择 |
--localport PORTNUM | 指定本地端口(1-65535) | 系统随机分配 |
--family IPVERSION | IP协议版本,4 或 6 | 4 |
--protocol PROTO | 传输协议,udp 或 tcp | udp |
--verbosity LOGLEVEL | 日志详细程度(0-3) | 0 |
--help | 显示帮助信息 | – |
4.3 客户端测试示例
基础绑定测试:
./stunclient stunserver2025.stunprotocol.org 3478
返回示例:
Binding test: success
Local address: 192.168.0.173:58063
Mapped address: 14.155.76.36:62405
NAT行为测试(映射规则):
./stunclient --mode behavior stunserver2025.stunprotocol.org
返回示例:
Behavior test: success
Nat behavior: Endpoint Independent Mapping
NAT过滤测试(入站规则):
./stunclient --mode filtering --localport 9999 stunserver2025.stunprotocol.org
返回示例:
Filtering test: success
Nat filtering: Address and Port Dependent Filtering
TCP协议测试:
./stunclient --protocol tcp stunserver2025.stunprotocol.org
五、测试结果解读
5.1 基础模式结果
成功的绑定请求会返回以下信息:
- Local address:客户端在内网中的实际IP和端口
- Mapped address:NAT设备映射后的公网IP和端口,这是STUN查询的核心结果
如果看到 Binding test: failed 或请求超时,可能的原因包括:
- 服务器未正确启动或防火墙未放行端口
- 客户端网络环境存在出站UDP限制
- 域名解析失败
5.2 NAT行为测试结果
| 结果类型 | 含义 | P2P友好度 |
|---|---|---|
| Endpoint Independent Mapping | 从同一内网地址端口发往任何目标,NAT都分配同一个公网端口。最宽松的锥形NAT。 | ⭐⭐⭐ 最佳 |
| Address Dependent Mapping | 从同一内网地址端口发往不同目标IP时,NAT会分配不同的公网端口。 | ⭐⭐ 中等 |
| Address and Port Dependent Mapping | 从同一内网地址端口发往不同目标IP或端口时,NAT都会分配不同的公网端口。最严格的对称型NAT。 | ⭐ 最差,需TURN保底 |
5.3 NAT过滤测试结果
| 结果类型 | 含义 | 安全级别 |
|---|---|---|
| Endpoint Independent Filtering | 任何外部主机都能向已映射的公网地址发送数据,只要之前有通信。 | 低(最开放) |
| Address Dependent Filtering | 外部主机必须满足IP匹配条件(之前通信过的IP)。 | 中 |
| Address and Port Dependent Filtering | 外部主机必须同时满足IP和端口匹配条件。最严格的过滤策略。 | 高(最严格) |
5.4 综合判断示例
在一次实际测试中,得到以下结果:
Nat behavior: Endpoint Independent Mapping
Nat filtering: Address and Port Dependent Filtering
这意味着该网络具有 “容易出得去,但不容易进得来” 的特点:
- 映射行为:优秀(端点独立),P2P打洞成功率高
- 过滤行为:严格(地址和端口依赖),入站连接受限
对于WebRTC等P2P应用:
- 连接大概率能建立:得益于“端点独立映射”,打洞成功的机会很大
- 可能需要TURN保底:在最坏情况下(双方都是严格过滤),依然需要TURN服务器转发数据
六、总结
STUNTMAN 作为一款成熟稳定的开源STUN服务器实现,具有以下特点:
| 维度 | 说明 |
|---|---|
| 部署 | 编译过程清晰,依赖简单(仅需Boost库),无 make install 步骤,手动复制即可使用 |
| 服务端 | 支持 basic 和 full 两种模式,单IP即可满足基础需求,双IP可实现完整NAT检测 |
| 客户端 | 支持 basic、behavior、filtering 三种测试模式,覆盖从地址查询到深度诊断的全部场景 |
| 云环境 | 通过 --primaryadvertised 等参数完美支持AWS EC2等云主机部署 |
| 协议支持 | 同时支持UDP和TCP,IPv4和IPv6 |
无论是自建WebRTC基础设施,还是深入研究NAT穿透技术,STUNTMAN 都是一个值得信赖的技术组件。通过服务端与客户端的配合使用,你可以全面了解自己的网络环境,并据此做出合理的架构决策。
附图 P2P连接成功率
