STUN Server — 是Session Traversal Utilities for NAT (STUN)协议的服务器,允许客户端确定其外部IP地址和端口,以及其所处的Network Address Translation (NAT)类型。据IETF RFC 5389, 2008,STUN是WebRTC基础设施的必要组件,确保NAT后的客户端之间建立直接的对等网络(P2P)连接。
核心要点
STUN Server (Session Traversal Utilities for NAT) — 是一种网络服务,按照RFC 5389中定义并在RFC 8489中更新的协议工作。STUN服务器的主要任务是向客户端提供关于其自身从外部网络可见的公共IP地址和端口的信息,以及确定客户端和互联网之间的NAT设备类型。
STUN架构包括两个组件:嵌入应用程序的STUN客户端(例如浏览器或原生WebRTC应用程序)和部署在公共网络中的STUN服务器。客户端向服务器发送STUN Binding Request,服务器在响应中指明请求来源的IP地址和端口——即服务器看到的客户端公共地址。通过将这些数据与本地地址进行比较,客户端可以确定其网络中使用的NAT类型。
STUN通过UDP(默认端口3478)或TCP(端口3478或为TLS用5349)工作。STUN消息由20字节的头部和可变数量的属性组成。头部包含消息类型(Binding Request、Binding Response、Binding Error Response)、长度和唯一的交易标识符(96比特),用于匹配请求和响应。每个Binding Response包含XOR-MAPPED-ADDRESS属性——客户端的外部地址,通过进行掩码处理以保护其不受基于截获STUN流量的攻击。
STUN服务器按照简单的请求-响应协议工作。位于NAT后的客户端构建Binding Request并发送给STUN服务器。服务器接收数据包,从UDP头部提取源IP地址和发送方端口,然后将该地址封装到XOR-MAPPED-ADDRESS属性中构建Binding Response。响应被发回给请求的源地址。
客户端接收响应并提取XOR-MAPPED-ADDRESS,其中包含NAT设备分配的外部IP地址和端口。然后客户端将该地址与其本地(RFC 1919——私有)地址进行比较。如果地址一致——客户端不在NAT后。如果不同——客户端在NAT后,外部地址作为ICE(Interactive Connectivity Establishment)的候选人用于WebRTC。
STUN服务器通过一系列测试请求确定NAT类型。客户端发送带有不同标志(CHANGE-REQUEST)的请求并分析响应。完整的检测循环包括向STUN服务器的不同IP地址和端口发送请求。如果服务器响应带有修改端口的请求——则NAT为Restricted Cone类型。如果不响应带有修改端口和IP的请求——则NAT为Symmetric类型。这一信息对于在WebRTC中选择ICE策略至关重要。
STUN服务器能够确定四种主要的NAT类型,每种类型对建立P2P连接的可能性有不同的影响。NAT类型决定STUN是否能够提供两个客户端之间的直接连接。使用哪个ICE候选人——host、server reflexive或relay——取决于NAT类型。
| NAT类型 | 行为 | STUN工作 | ICE Fallback |
|---|---|---|---|
| Full Cone | 任何外部主机都可以向客户端发送数据包 | 是 | Server Reflexive |
| Restricted Cone | 仅客户端发送过数据包的主机 | 是 | Server Reflexive |
| Port Restricted | 与Restricted类似,但还按源端口进行过滤 | 是 | Server Reflexive |
| Symmetric NAT | 外部地址对每个主机:端口对是唯一的 | 否 | Relay (TURN) |
Symmetric NAT — STUN无法处理的唯一类型。在Symmetric NAT中,每个向新目标主机发送的新请求都会获得不同的外部地址(IP和/或端口)。由于STUN服务器报告的地址是用于与STUN服务器本身连接的,该地址无法用于与另一个客户端的连接。在这种情况下,WebRTC中使用TURN服务器转发流量。据研究(Ford等,RFC 3489, 2003),互联网上约8–10%的NAT设备是对称的。
STUN服务器通过RTCPeerConnection配置集成到WebRTC中。浏览器或原生应用程序使用STUN收集ICE候选人,然后通过信令服务器(Signaling Server)交换。在WebRTC配置中,STUN服务器在iceServers数组中以stun:前缀(用于UDP)或stuns:前缀(用于TLS连接)指定。
让我们看一个在JavaScript中为WebRTC应用程序创建RTCPeerConnection时配置STUN服务器的示例。
const config = {
iceServers: [
{
urls: "stun:stun.l.google.com:19302"
},
{
urls: "stun:stun1.l.google.com:19302"
}
]
};
const pc = new RTCPeerConnection(config);
pc.onicecandidate = (event) => {
if (event.candidate) {
console.log("ICE候选:", event.candidate.candidate);
}
};
const offer = await pc.createOffer();
await pc.setLocalDescription(offer);
在这个示例中,使用了Google的公共STUN服务器(stun.l.google.com:19302)。创建offer或answer时,浏览器自动向指定的服务器发送STUN Binding Request,接收外部地址(服务器反射候选人)并将其添加到ICE候选人列表中。收集所有候选人后,它们通过信令服务器发送给远程对方,以尝试建立直接的P2P连接。
在ICE过程中有三种类型的候选人:host(本地地址)、srflx(服务器反射——从STUN获取)和relay(通过TURN转发)。STUN服务器确保了srflx候选人的出现,这些候选人比relay具有更高的优先级,因为通过STUN的连接是直接的,不需要转发。ICE过程检查双方所有候选人的组合(本地的和从STUN获取的),从最高优先级开始。
STUN服务器具有与协议架构相关的根本性局限。主要局限是无法与Symmetric NAT工作,每个向外部主机发送的新请求都会获得唯一的外部端口。在这种情况下,从STUN服务器获取的地址不能用于与另一个对方连接,因为NAT仅为与STUN服务器本身的通信创建了绑定。
第二个局限在于STUN不提供数据转发。如果直接P2P连接不可能(双方都在Symmetric NAT后),STUN不提供替代的数据传输路径。在这种情况下需要TURN服务器,它作为参与方之间媒体流量的转发器,从一个参与者接收数据并通过其公共IP地址发送给另一个。
尽管有这些局限,STUN服务器仍然是WebRTC基础设施的关键组件。在多数情况下(80–90%),可以通过STUN建立直接的P2P连接,这可以避免TURN转发的成本并减少媒体数据传输的延迟。对于公共WebRTC应用程序,建议使用STUN和TURN服务器的组合,并配备自动写回机制,以保证在所有网络条件下的连接。
常见问题
STUN服务器 — 是互联网上的一面镜子,告诉客户端其外部IP地址。当计算机位于路由器(NAT)后时,它不知道自己的公共地址。STUN服务器帮助它了解这一点,以便其他计算机可以直接连接。
在WebRTC中,STUN服务器在RTCPeerConnection配置中指定。浏览器发送STUN请求以获取候选人的外部地址(srflx)。该候选人通过信令服务器传递给远程对方,ICE尝试在他们之间建立直接连接。
STUN帮助查找直接P2P连接的外部地址。TURN在P2P不可能时通过其自己的服务器转发流量。STUN是镜子,TURN是中介。TURN会给服务器带来负荷并增加延迟,因此STUN更受推荐。
Google提供免费的STUN服务器:stun.l.google.com:19302,stun1.l.google.com:19302。Twilio也通过Network Traversal Service提供STUN + TURN基础设施。对于生产应用程序,更好的做法是使用自己的或商业的STUN/TURN服务器,以保证可用性。
Symmetric NAT为每个本地地址:外部目标地址对创建唯一的外部端口映射。客户端从STUN服务器获取的地址绑定到与该STUN服务器的连接。当另一个对方尝图使用该地址时,Symmetric NAT会拦截数据包,因为新目标地址的端口映射不同。
总结
我们将开发一款交钥匙移动应用程序
IT Sectr自2017年以来为初创企业和企业打造iOS和Android应用程序。我们将为您提供咨询并提出最佳解决方案。