RFC文档链接

摘要

NAT会话穿越应用程序 (STUN) 是一种协议,在处理网络地址转换(Network Address Translator, NAT)穿越时充当其他协议的工具。终端可以使用它来确定NAT分配给它的IP地址和端口。它还可以用来检查两端之间的连通性,并作为keep-alive协议来维护NAT的绑定。STUN与许多现有的NAT网络一起工作,不需要它们的任何特殊处理。

STUN本身并不是一个NAT穿越解决方案。相反,它是一个用于NAT穿越解决方案中的工具。与该规范的前一个版本(RFC3489)相比,这是一个重要的变化,RFC3489将STUN作为一个完整的解决方案提供。

1、简介

在这个规范中定义的协议,STUN(Session Traversal Utilities for NAT),提供了一个解决NAT网络间的工具。它为终端提供了一种方法来确定NAT分配的IP地址和端口,该IP地址和端口对应于其私有IP地址和端口。它还为双方提供了一种保持NAT保活的方法。通过一些扩展,该协议可用于在双方之间进行连接性检查[MMUSIC-ICE],或者在双方之间中继数据包[BEHAVE-TURN]。

为了作为工具的性质,该规范定义了一种可扩展的数据包格式,定义多个传输协议上的操作,同时又提供两种形式的身份验证。

STUN用于一个或多个NAT穿越解决方案的上下文中。这些解决方案以STUN用法而被人熟知。每种用法都描述了如何利用STUN实现NAT穿越解决方案。通常的用法是何时发送包含一些可选属性、用什么样的服务器以及用什么身份验证机制的STUN消息。交互式连接建立(ICE) [music -ICE]就是STUN的一种用法。SIP[SIP- Outbound]是STUN的另一种用法。在某些情况下,需要对STUN进行扩展。STUN扩展可以采用新方法、属性或错误响应代码的形式。有关STUN用法的更多资料,请参阅第14节。

2、从RFC3489的演变

STUN最初在RFC3489中定义[RFC3489]。该规范有时被称为“经典STUN”,它将自己描述为NAT穿越问题的完整解决方案。在此解决方案中,客户端会发现它是否在NAT网络后,确定其NAT类型,并能在最外层NAT侧发现它的公网IP地址和端口,然后利用协议体中的IP地址和端口,例如SIP(Session Initiation Protocol)协议[RFC3261]。然而,从RFC3489发布以来的经验来看,经典STUN并不能很好地作为一个可部署的解决方案。通过经典STUN学到的地址和端口有时可用来与对等体通信,有时不可用。经典STUN没有提供任何方法是不管它是否有效,也不提供任何补救措施。此外,经典STUN对于NAT类型分类的算法是问题的,因为许多NAT并没有完全符合他们定义的类型。

经典STUN也有安全漏洞 —— 攻击者可以在某些拓扑和约束下为客户端提供不正确的映射地址,这是根本无法通过任何加密手段解决的。尽管这个问题仍然存在于该规范中,不过现在通过使用更完整的解决方案(使用STUN),这些攻击已经得到了缓解。

由于这些原因,该规范淘汰了RFC3489,取而代之的是将STUN描述为一个工具,它被用作完整NAT穿越解决方案的一部分。ICE [music -ICE]是一个基于offer/answer [RFC3264]方法的完整的NAT穿越解决方案,又比如SIP。SIP Outbound [SIP- Outbound]是SIP信令穿越的完整解决方案,它以一种非常不同的方式使用STUN。尽管协议本身可以使用STUN(经典STUN)作为穿越解决方案,但这里不介绍这种用法,而且由于上述原因,强烈建议不要使用这种用法。

本书所描述的协议仅与经典STUN略有不同。除了UDP协议,该协议现在还在TCP上运行。可扩展性以更结构化的方式添加到协议中。通过从RFC3489中定义的128位事务ID中拿出32位,添加了一种魔术字(magic cookie)机制,用于与应用协议解复用,使得这些变化可以向后兼容。映射地址使用一种新的异或格式编码。还有其他更小的变化。参见第19节获得更完整的清单。

由于范围的变化,STUN也被从Simple Traversal of UDP through NAT更名为Session Traversal Utilities for NAT。这个缩写仍然是STUN,就像所有人熟知的那样。

3、操作概述

本节仅作描述。

图1显示了一种可能的STUN组网配置。在此组网中,有两个实体(称为STUN代理)实现了STUN协议。图中最底层连接私网1的客户端。这个网络通过NAT1连接到私网2,。私网2通过NAT2连接到公网。途中最上面的代理是服务器,直接部署在公网上。

STUN是一个客户端-服务器协议。它支持两种类型的事务。一个是客户机向服务器发送的请求/响应(request/response)事务,服务器返回一个响应。第二种是指示(indication)事务,其中任何代理(客户端或者服务器)都可以发送一个不需要响应的指示消息。这两种类型的事务都包括一个随机生成的96位(12字节)的事务ID(transaction ID)。对于请求/响应事务来说,这个事务ID(transaction ID)使得客户端可以将返回的响应与本端发出的请求进行关联起来。对于指示,事务ID(transaction ID)可作为调试辅助手段。

所有STUN消息都以固定包头开始的,这个固定包头包含一个方法(method),一个类型(class),一个事务ID(transaction ID)。方法(method)指出这是各种请求或指示中的哪一个。这个规范只定义了一个方法:Binding,但是其他方法有可能在其他文档中定义。类型(class)指示这是请求、成功响应、错误响应或是指示。固定包头之后是0个或多个属性,它们是类型-长度-值(Type-Length-Value:TLV)扩展,用于传递特定消息的附加信息。

该文档定义了一个名为Binding的方法。Binding方法既可以用于请求/响应事务,也可以用于指示事务。当在请求/响应事务中使用时,Binding方法可以用来确定NAT分配给STUN客户端的特定“绑定”。当在请求/响应或指示事务中使用时,Binding方法还可以用来保持这些“绑定”保活状态。

在Binding请求/响应事务中,Binding请求从STUN客户端发送到STUN服务器。当Binding请求到达STUN服务器时,它可能已经在STUN客户端和STUN服务器之间经过了一个或多个NAT网络(图1中就有2个这样的NAT网络)。当Binding请求消息经过NAT时,NAT将修改包的源传输地址(即源IP地址和源端口)。因此,服务器接收到的请求的源传输地址将是NAT修改后的最接近服务器的公网IP地址和端口。这被称为反射传输地址。STUN服务器将这个地址复制到STUN Binding响应中的XOR-MAPPED-ADDRESS属性中,并将Binding响应发送回STUN客户端。当这个数据包通过NAT返回时,NAT将修改IP报头中的目的传输地址,但是STUN响应体中XOR-MAPPED-ADDRESS属性中的传输地址将保持不变。通过这种方式,客户端可以了解自己在最外层NAT网络的反射传输地址。

某些用法中,STUN必须与其他协议复用(比如[MMUSIC-ICE], [SIP-OUTBOUND])。在这些用法中,必须有一种方法来检查数据包并确定它是否是STUN数据包。STUN在STUN头中提供了三个字段,这些字段具有可用于此目的的固定值。如果这还不够,那么STUN报文还可以包含一个FINGERPRINT值,该值可以进一步用于区分是否是STUN报文。

STUN定义了一组可选流程,用户可以决定使用这些流程,称为机制。这些机制包括DNS发现,到备用服务器的重定向技术,用于多路复用的指纹属性,以及两次身份验证和消息完整性交换。身份验证机制以用户名、密码和消息完整性值的使用为中心。两种认证机制是在本规范中有定义的长期认证机制和短期认证机制。每次使用都指定了允许使用的机制。

在长期凭据机制中,客户端和服务器共享预先提供(但在细节上有所不同)的用户名和密码,并根据为HTTP[RFC2617]定义的用户名和密码执行摘要质询/响应(challenge/ response)交换。在短期凭证机制中,在进行STUN交换之前,客户端和服务器通过某种带外方法交换用户名和密码。例如,在ICE[MMUSIC-ICE]使用中,双发使用带外信令交换用户名和密码。这些被用来对请求和响应进行完整保护和身份验证。这不是什么挑战,而且已经在用了。

4、术语

略。

5、定义

STUN代理:STUN代理是实现STUN协议的实体。该实体可以是STUN客户端,也可以是STUN服务器。

STUN客户端:STUN客户端是发送STUN请求和接收STUN响应的实体。STUN客户端也可以发送指示。在本规范中,术语STUN客户端和客户端是同义词。

STUN服务器:STUN服务器是接收STUN请求和发送STUN响应的实体。STUN服务器也可以发送指示。在本规范中,术语STUN服务器和服务器是同义词。

传输地址:IP地址和端口号的组合(例如UDP或TCP端口号)。

反射传输地址:客户机学到的一种传输地址,它将该客户机标识为IP网络中的另一台主机(通常是STUN服务器)所看到的客户机。当客户端和另一台主机之间有一个中间NAT时,反射传输地址表示在NAT的公网端分配给客户端的映射地址。 反射传输地址是从STUN响应(MAPPED-ADDRESS or XOR- MAPPED-ADDRESS)中的映射地址属性学习的。

映射地址:与反射地址意思相同。仅由于历史原因以及MAPPED-ADDRESS和XOR-MAPPED-ADDRESS属性的命名,才保留了这个术语。

长期凭据:表示客户端和服务器之间共享秘密的用户名和关联密码。长期凭据通常在订阅者注册服务并持续到订阅者离开服务或显式更改凭据时授予客户端。

长期密码:来自长期凭据的密码。

短期凭据:代表客户端和服务器之间共享秘密的临时用户名和关联密码。在STUN交换之前,客户端和服务器之间通过某种协议机制获得短期凭证。 短期凭证具有明确的时间有效期,它可能基于特定的时间长短(比如5分钟)或者在一个事件 (例如终止SIP对话)。短期凭据的具体范围是由应用程序使用情况定义的。

短期密码:短期凭证的密码。

STUN指示:一个不需要接收响应的STUN消息包。

属性:STUN术语,指可以添加到STUN消息中的Type-Length-Value(TLV)对象。属性分为两种类型:包含必须和包含可选。STUN代理可以安全地忽略它们无法解析的已知属性,但是,如果消息包含无法解析的已知属性时,则无法成功处理消息。

重传超时(RTO):重传超时,它定义了从请求的传输到该请求的第一次重传之间的初始时间段。

6、STUN消息结构

STUN消息使用面向网络的格式以二进制编码(最重要的字节或八位字节在前,通常也称为大端字节序)。传输顺序在rfc791的附录B中有详细描述。除非特别说明,数字常量都是十进制的。

所有STUN消息必须以一个20字节的头开始,后面跟着0个或多个属性。STUN头包含STUN消息类型,消息长度,魔术字(magic cookie)和事务ID。

每个STUN消息的最开始的2位必须为零。当STUN在同一端口上与其他协议复用时,可以通过此功能将STUN报文与其他协议区分开来。

消息类型定义消息种类(请求,成功响应,失败响应,或指示)和STUN消息的消息方法(主要功能)。尽管有四个消息种类,但STUN中只有两种事务类型:请求/响应事务(由请求消息和响应消息组成)和指示事务(由单个指示消息组成)。响应种类被分为错误响应和成功响应,以帮助快速处理STUN消息。

消息类型字段被进一步分解成如下结构:

在这里,消息类型字段中的有效位是从最高有效位(M11)到最低有效位(M0)。M11到M0表示一种12位编码的方法。C1和C0表示种类的2位编码。C1C0:00:请求,01:指示,10:成功响应,11:错误响应。本文规范定义了一个方法叫:Binding。方法和类是可以取交集的,因此对于每个方法,都有可能有请求、成功响应、错误响应和指示。定义新方法的扩展必须指明该方法允许使用哪些种类。

例如:Binding请求种类是00(请求)(注:对应C1和C0都是0)方法是000000000001(Binding方法),前16位进行16进制编码就是0x0001。Binding响应种类是10(成功响应)方法是000000000001,前16位进行16进制编码就是0x0101.

注意:这种不幸的编码是[RFC3489]赋予的,当时没有考虑用位编码“指示”、“成功”和“错误”类型,一句话:历史原因。

消息长度必须包含消息的大小,以字节为单位,不包括20字节的STUN头。由于所有STUN属性是字节对齐的:被填充为4个字节的倍数,因此长度字段的最后2位始终为零。这提供了另一种方法来区分STUN数据包与其他协议的数据包。

魔术字字段必须以网络字节顺序包含固定值0x2112A442。在RFC3489中,该字段是事务ID的一部分。将魔术字放置在这个位置允许服务器检测客户端是否理解在修改后的规范中添加的某些属性。此外,当STUN在同一端口上与其他协议复用时,它有助于将STUN包与其他协议包区分开来。

事务ID(transaction ID)是一个96位的标识,用于标识唯一的STUN事务。对于请求/响应事务,事务ID由STUN客户端在发送请求消息时填充,并由服务器直接填入在响应消息中(对于指示,它是由发送指示的代理端选择)。它主要用于将请求与响应消息关联起来,尽管它在帮助防止某些类型的攻击方面也起着很小的作用。服务器还使用事务ID作为键,在所有客户端中惟一地标识每个事务。因此,事务ID必须统一且随机地从0-2^96-1中选择,并且应该是密码随机的。重发相同请求需要重用相同的事务ID:客户端必须为新事务选择一个新事务ID。除非新请求与前一个请求在所有位上相同,并且从相同源传输地址发送到相同的目的IP地址(注:就是要么重发(按文中意思是每一位都与前一个包相同)的时候使用原事务ID,其他时候都随机生成一个96位的密码随机事务ID)。成功和错误响应必须携带与相应请求相同的事务ID。当代理作既作为STUN服务器又作为STUN客户端在使用同一端口时,作为客户端时发送的请求中的事务ID与作为服务器时接收的请求中的事务ID没有关系(双工方向的事务ID没有任何关系)。

在STUN固定头部后面跟着是零或多个属性。每个属性都用TLV (Type-Length-Value)编码。编码和属性本身的细节在第15节中给出。

7、基础协议过程

本节介绍STUN协议的基本过程。它描述了信息是如何形成的,如何发送的,和当被接收时如何处理的。还定义了Binding方法的详细处理。本文档的其他部分描述了一种用法在某些情况下可能选择使用的可选过程。其他文档可能定义STUN的其他扩展,通过添加新方法,新属性或者新的错误响应码。

7.1、构造请求或指示

当构造请求或指示消息时,当创建报头时,代理必须遵循第6节中的规则。此外,消息种类必须是“Request”或“Indication”(适当的),方法必须是Binding或在另一个文档中定义的某个方法。

然后,代理添加特定方法或用法所指定的任何属性。例如,一些用法可能指定代理使用身份验证方法(章节10)或FINGERPRINT属性(章节8)。

如果代理正在发送请求,它应该向请求添加一个SOFTWARE属性。根据方法的不同,代理可以在指示中包括软件属性。STUN的扩展应该讨论SOFTWARE在新的指示中是否有用。对于不需要身份验证的Binding方法,除非用法另有规定,否则不需要任何属性。

如果已知,所有通过UDP发送的STUN消息应该小于路径MTU。如果路径MTU未知,则IPv4报文[RFC1122]的第一跳MTU为576字节,IPv6报文[RFC2460]的第一跳MTU为1280字节。该值对应IP报文的总体大小。因此,对于IPV4,实际的STUN消息需要小于548字(576减去20位的IP头,减去8位的UDP头,假设没有使用IP选项)。STUN不提供处理请求在MTU下但响应将大于MTU的情况的能力。这是想象不到的,这一限制将成为STUN的一个问题。MTU限制是SHOULD,而不是MUST,以解释STUN本身用于探测MTU特性的情况([BEHAVE-NAT])。在此或类似的应用程序之外,必须遵循MTU约束。

7.2、发送请求或指示

代理发送请求或指示。本文档指定了如何通过UDP、TCP或TLS-over-TCP发送STUN消息;将来可能会添加其他传输协议。STUN使用必须指定使用哪种传输协议,以及代理如何确定接收方的IP地址和端口。第9节描述了一种基于DNS的方法,用于确定用户可能选择使用的服务器的IP地址和端口。STUN可以用于任播地址,但仅用于UDP和不使用身份验证的用法。

在任何时候,客户端都可能与同一个服务器有多个未完成的STUN请求(也就是说,使用不同事务id的多个事务正在进行中)。对新事务的发起速率没有其他限制(例如ICE为连接性检查或在TCP上运行STUN时),客户端应该通过RTO机制将新的事务分给服务器,并且应该将自己在同一个服务器上的未完成事务限制到十个。

7.2.1、使用UDP发送

当STUN运行在UDP上时,STUN消息可能会被网络丢弃。STUN请求/响应事务的可靠性是通过客户机应用程序本身重新传输请求消息来实现的。STUN指示消息是不会重传的;因此,UDP上的指示事务是不可靠的。

客户端应该以RTO(超时重传:Retransmission TimeOut)为间隔重新发送STUN请求消息,每次重传后RTO需加倍,RTO是往返时间(RTT)的估计,其计算方法如RFC2988 [RFC2988]所述,但有两个例外。首先,RTO的初始值应该是可配置的(而不是RFC 2988中推荐的3s)并且应该大于500ms。这个“应该”的例外情况是使用其他机制来获得拥塞阈值(例如ICE中为固定码率流定义的那些),或者当STUN在具有已知网络容量的非internet环境中使用时。在固定线路接入链路中,建议设置为500ms。其次,RTO的值不应该四舍五入到最接近的秒。相反,应该保持1毫秒的精度。推荐与TCP一样使用Karn[KARN87]算法。当应用于STUN时,这意味着不应该从导致请求重传的STUN事务中计算RTT估计值。

RTO的值应该在事务完成后由客户端缓存,并且用来作为相同服务器(IP地址相同)下的下次事务的RTO的起始值。该值在10分钟后将被视为过时并丢弃(注:RTO有效期建议设置为10分钟)。

连续重传消息直到收到响应,或者直到Rc请求(Rc requests??)全部发送完毕。Rc应该是可配置的,默认值应该是7。如果,在最后一个请求之后,持续Rm*RTO时间内没有响应的(提供充足的时间来获得响应,如果最后的请求实际上成功)。客户端应该认为事务已经失败。Rm应该是可配置的,默认值应该是16。如果出现硬ICMP错误[RFC1122],则UDP上的STUN事务也被认为是失败的。例如,假设RTO为500 ms,请求的发送时间为0 ms、500 ms、1500 ms、3500 ms、7500 ms、15500 ms和31500 ms。如果客户端在39500毫秒后没有收到响应,客户端将认为事务超时。

7.2.2、使用TCP或TLS-over-TCP发送

对于TCP和TLS-over-TCP,客户端创建到服务器的TCP连接。

在STUN的某些用法中,STUN作为TCP连接上的唯一协议发送。在这种情况下,它可以在没有任何额外的帧或解复用的帮助下发送。在其他用法或其他扩展中,它可能通过TCP连接与其他数据复用。在这种情况下,STUN必须在某种由用法或扩展的帧协议之上运行,该协议允许代理提取完整的STUN消息和完整的应用层消息。第9节说明,在DNS发现的众所周知端口和端口列表上运行的STUN服务是STUN独占端口,而不是用于STUN与其他数据复用。因此,在与这些服务器的连接中不使用帧协议。当使用额外的帧时,该用法将指定客户端知道使用并且要连接到哪个端口。例如,在ICE连接性检查的情况下,这些内容是通过客户机和服务器之间的带外协商获得的。

当STUN通过TLS-over-TCP运行时,必须至少实现TLS_RSA_WITH_AES_128_CBC_SHA加密套件。也可以支持任何其他加密套件。当接收到TLS证书消息时,客户应核实证书,并检查证书所标识的场景。如果证书无效或被吊销,或者它没有确定合适的一方,客户端是绝对不能发送STUN消息或继续进行STUN事务。客户端必须验证服务器的身份。为此,它遵循RFC 2818第3.1节中定义的识别过程。这些过程假定客户端正在解除对URI的引用。出于使用本规范的目的,客户端将(第8.1节中描述的)域名或IP地址作为已经被引用的URI主机部分对待。或者,客户端可以配置一组受信任的域或IP地址。如果收到标识这些域或IP地址之一的证书,客户端要验证服务器身份与证书的一致性。

当STUN运行时,通过TLS-over-TCP连接与其他协议复用,强制加密套件和TLS处理过程按照这些协议的定义进行操作。

STUN对TCP和TLS-over-TCP的可靠性由TCP自己处理,因为在STUN协议上没有重传机制进行保证的。但是,对于请求/响应事务,如果客户端在发送SYN建立连接后Ti秒(Ti seconds)内没有收到的响应,它就会认为之前的事务已经超时。Ti应该是可配置的,默认值应该是39.5s。选择这个值是为了使初始默认RTO值和的TCP和UDP的超时相等。另外,如果客户端无法建立TCP连接,TCP连接在收到响应之前被重置或失败,任何正在进行的请求/响应事务都被视为失败。客户端可以通过一个TCP(或者TLS:TLS- over-TCP)连接发送多个事务,它可能会在收到对前一个请求的响应之前发送另一个请求。客户端应该保持连接打开,直到:

  • 没有其他的STUN请求消息或者指示消息通过这个连接发送时
  • 没有计划使用通过该连接发送的STUN请求学到的任何资源(比如映射地址(MAPPED-ADDRESS或者XOR-MAPPED-ADDRESS)或转发地址[BEHAVE-TURN])
  • 如果在该端口上多路复用其他应用程序协议,则表示已完成使用该其他应用程序
  • 如果使用反射的端口与远端,并且已经建立了与该远端的通信,这是某些TCP NAT穿越技术所需要的

在服务器端,服务器应该保持连接打开,并让客户端关闭它,除非服务器已确定连接已超时(例如,由于客户端断开网络连接)。只有当连接保持打开时,客户端学到的绑定当连接保持打开时才会在NAT网络中持续有效。只有客户端知道需要绑定多长时间。服务器不应该关闭一个可以接收到请求但是还没发送响应的连接。服务器绝不能仅仅为了发送响应而打开指向客户端的连接。服务器在过载情况下应该遵循关于连接管理的最佳实践。

7.3、接收STUN消息

本节指出了对STUN消息的处理。这里指定的处理是针对本规范中定义的STUN消息;向后兼容的附加规则定义在第12节。这些附加的处理过程是可选的,可以选择性地使用它们。首先,应用一组独立于种类的处理操作。接下来是特定于种类的处理,将在下面的小节中进行描述。

当STUN代理收到一条STUN消息时,它首先检查该消息是否遵守第6节的规则。检查它的前两位是否为0,魔术字(magic cookie)字段是否有正确的值,消息长度是否合理,方法值是否支持。它检查特定方法是否是允许的消息种类。如果消息类是“成功响应(Success Response)”或“错误响应(Error Response)”,代理将检查事务ID是否与仍在进行中的事务ID匹配。如果正在使用FINGERPRINT扩展,代理检查FINGERPRINT属性是否存在并包含正确的值。如果检测到任何错误,消息将被无声地丢弃。在STUN与其他协议复用的情况下,错误可能表明这不是真正的STUN消息。在这种情况下,代理应该尝试将消息解析为不同的协议。

然后STUN代理执行使用所指定的身份验证机制所要求的任何检查(参见第10节)。

一旦身份验证检查完成,STUN代理检查消息中的未知属性、已知但意想不到的属性。未知的可选属性必须被代理忽略。已知但意想不到的属性应该被代理忽略。未知的必须要明确的属性将依赖于消息种类的处理,如下所述。

此时,进一步的处理取决于请求的消息种类。

7.3.1、处理请求

如果请求包含一个或多个未知的必要的属性,服务器响应一个错误响应,错误代码为420(未知属性:Unknown Attribute),并且要在返回的响应中包含一个UNKNOWN-ATTRIBUTE属性,该属性列出遇到的未知理解所需的属性。
然后,服务器执行方法或特定用法所需的任何额外检查。如果所有检查都成功,服务器将生成如下所述的成功响应。

当运行UDP上时,服务器接收到的请求应该是事务的第一个请求,或者是重传。服务器必须对重新传输作出响应,以保留以下属性:如果客户端接收到对重传输的响应,而不是发送到原始请求的响应,客户机和服务器上的总体状态与只接收原始重传的响应的情况相同,或者接收到两个响应的地方(在这种情况下,客户端将使用第一个)。满足此需求的最简单方法是让服务器记住通过UDP接收的所有的事务ID以及它们在过去40秒内的相应响应。然而,这需要服务器保持状态,并且对未经过身份验证的所有客户端的任何请求都是不合适的。另一种方法是重新处理请求并重新计算响应。后一种技术必须仅应用于幂等(当同一个请求可以安全地重复而不影响系统的整体状态时,该请求被认为是幂等的)的请求,并导致相同请求的相同成功响应。Binding方法被认为是幂等的。请注意,某些罕见的网络事件可能会导致反射传输地址值发生变化,导致在不同的成功响应中有不同的映射地址。STUN扩展必须讨论在不存储事务状态的服务器上重新传输请求的含义。

7.3.1.1、构建成功或错误响应

构建响应(成功或失败)时,服务器遵循第6节的规则。响应的方法与请求的方法相同,消息类是“Success Response”或“Error Response”。
对于错误响应,服务器必须添加一个ERROR-CODE属性,该属性包含在上述处理中指定的错误代码。原因内容短语不是固定的,但应该对应错误代码。对于某些错误,会向消息添加额外的属性。这些属性在错误代码指定的描述中详细说明。例如,对于错误代码420(未知属性:Unknown Attribute),服务器必须包含一个UNKNOWN-ATTRIBUTES属性。某些身份验证错误也会导致添加属性(见第10节)。扩展可以定义其他错误、附加属性添加到错误实例中。
如果服务器使用身份验证机制对请求进行身份验证,则服务器应该向响应添加适当的身份验证属性(见第10节)。
服务器还添加特定方法或使用所需的任何属性。此外,服务器应该向消息添加一个SOFTWARE属性。
对于Binding方法,除非用法另有规定,否则不需要额外的检查。当构建成功响应时,服务器将XOR-MAPPED-ADDRESS属性添加到响应中,其中属性的内容是请求消息的源传输地址。对于UDP,这是请求消息的源IP地址和源UDP端口。对于TCP和TLS-over-TCP,这是服务器所看到的TCP连接的源IP地址和源TCP端口。

7.3.1.2、发送成功或错误响应

响应(成功或错误)通过与接收请求相同的传输路径来发送。如果请求是通过UDP接收的,响应的目的IP地址和端口是收到请求消息的源IP地址和端口,响应的源IP地址和端口等于接收请求消息的目的IP地址和端口。如果请求是通过TCP或TLS-over-TCP接收的,响应在接收请求的同一TCP连接上发送回去。

7.3.2、处理指示

如果指示消息中包含未知的需要理解的属性,指示消息会被丢弃,处理停止。

然后,代理执行方法或特定用法所需的任何附加检查。如果所有检查都成功,则代理将处理当前这个指示。不用对指示产生响应。

对于Binding方法,不需要额外的检查或处理,除非用法另有规定。仅仅是接收到代理的消息就会刷新在NAT网络中的“绑定”。

因为指示不会在UDP上重新传输(不像请求)。不需要在发送代理处处理指示的重新传输。

7.3.3、处理成功响应

如果成功响应包含未知的需要理解的属性,那么该响应被丢弃,事务被认为已经失败。然后,客户端执行方法或特定用法所需的任何附加检查。如果所有检查都成功,那么客户端将处理成功响应。

对于Binding方法,客户端检查响应中是否存在XOR-MAPPED-ADDRESS属性。客户端检查指定的地址族。如果它是一个不支持的地址族,该属性应该被忽略。如果它是一个意外但支持的地址族(比如:绑定事务通过IPv4发送,但是指定的地址族是IPv6的),然后客户端可以接受并使用该值。

7.3.4、处理错误响应

如果错误响应包含未知的需要理解的属性,又或者错误响应不包含ERROR-CODE属性,然后简单地认为事务已经失败。

然后,客户机执行身份验证机制指定的任何处理(见第10节)。这可能导致新的事务尝试。
此时的处理取决于错误码,方法和使用方式;
默认的处理规则如下:

  • 如果错误代码是300到399,除非使用了ALTERNATE-SERVER扩展,否则客户端应该将事务视为失败。见第11节
  • 如果错误代码是400到499,客户端声明事务失败;在420(未知属性)的情况下,响应应该包含一个UNKNOWN-ATTRIBUTES属性,该属性提供额外的信息。

如果错误码是500到599,客户端可以重新发送请求;客户端必须限制重发次数。任何其他错误代码都会导致客户端认为事务失败。

8、FINGERPRINT机制

本节介绍一种可选的STUN机制,当STUN消息和其他协议的包在同一传输地址上复用时,该机制有助于区分它们。这个机制是可选的,但是STUN的必须对它进行描述以及何时使用。FINGERPRINT机制不兼容RFC3489版本,并且不能在需要这种兼容性的环境中使用。在某些情况下,STUN消息在与其他协议相同的传输地址上被多路复用,例如实时传输协议(RTP)。以便应用第7节所述的处理,首先必须将STUN消息与应用程序包区分开。

第6节描述了STUN头文件中可用于此目的的三个固定字段。然而,在某些情况下,这三个固定字段可能不够。当使用FINGERPRINT扩展时,一个代理在发送给另一个代理的消息中包含FINGERPRINT属性。第15.5节描述了这个属性的位置和值。当代理收到它认为是一个STUN消息时,然后,除了其他基本检查,代理还检查消息是否包含FINGERPRINT属性以及该属性是否包含正确的值。7.3节描述了在STUN消息执行FINGERPRINT检查的整个处理过程。这个额外的检查帮助代理检测是否是其他协议的消息,否则这些消息可能看起来是STUN消息。

9、服务器的DNS探索

本节介绍STUN的可选操作步骤,允许客户端通过DNS来确定服务器的IP地址和端口。一个STUN用法必须描述如果和何时使用这个扩展。要使用这个过程,客户端必须知道服务器的域名和服务名称。该用法还必须描述客户端如何获得这些信息。不建议将服务器域名硬编码到软件中,以防域名丢失或因法律或其他原因需要修改。

当客户端希望在公网中找到接受Binding请求/响应事务的STUN服务器时,SRV服务名称为“stun”。当它希望定位通过TLS会话去找到接受Binding请求/响应事务的STUN服务器时,SRV服务名称为“stuns”。STUN用法可以定义额外的DNS SRV服务名称。

使用[RFC2782]中指定的SRV过程将域名解析为传输地址。DNS SRV服务名称是提供给此过程的输入的服务名称。SRV查找中的协议是客户端将运行STUN的传输协议:“udp”用于udp,“tcp”用于tcp。注意,此时只有“tcp”被定义为“stuns”。

按照RFC2782的程序确定要联系的服务器。RFC2782详细说明了如何对一组SRV记录进行排序,然后进行尝试。然而,RFC2782只声明客户端应该“尝试连接到(协议、地址、服务)”,而没有提供任何关于失败时发生的细节。当遵循这些过程时,如果STUN事务超时而没有收到响应,客户端应该按照RFC2782定义的顺序将请求重试到下一个服务器。这种重试只可能用于请求/响应传输,因为指示事务不会生成响应或超时。

STUN请求的默认端口对于TCP或UDP都是3478。STUN服务器的管理员应该在UDP和TCP的SRV记录中使用这个端口。在所有情况下,DNS中的端口必须反映服务器正在侦听的端口。STUN over TLS默认端口为5349。如果服务器软件支持判断初始消息是TLS还是STUN消息。服务器是可以与TCP一样,在相同的端口TLS协议上运行STUN。

如果没有找到SRV记录,客户端对域名执行A或AAAA记录查找。结果将是一个IP地址列表,可以使用UDP或TCP在默认端口联系它们,与STUN的使用无关。对于需要TLS的使用,客户端使用默认的TLS之上的端口连接到其中一个IP地址。

10、身份验证和消息完整性机制

本节定义了STUN的两种机制,客户机和服务器可以使用它们来提供身份验证和消息完整性。这两种机制被称为短期证书机制和长期证书机制。这两种机制是可选的,而且每次使用都必须指定是否以及何时使用这些机制。因此,客户端和服务器都将根据应用的情况知道要遵循哪种机制(如果有的话)。例如,公网上支持ICE的STUN服务器应该不需要身份验证,而支持连接性检查的代理中的STUN服务器功能将利用短期证书。这两种机制的概述已经在第3节中给出。

每种机制都指定使用该机制所需的附加处理,扩展的处理在第7节已经指明了。额外的处理发生在三个不同的地方:构建消息时,在执行基本检查后立即接收消息时,在进行错误响应的详细处理时。

10.1、短期证书机制

短期凭据机制假设,在STUN事务之前,客户机和服务器使用了一些其他协议以用户名和密码的形式交换凭据。此证书有时间限制。时间限制由用法来定义。

例如,在ICE使用[MMUSIC-ICE]中,两个端点使用带外信令来商定一个用户名和密码,该用户名和密码适用于整个媒体会话期间。

此凭据用于在每个请求和许多响应中进行消息完整性检查。没有像长期机制那样的挑战和应对;因此,由于凭据的时间限制性质,可以防止重播。

10.1.1、构建请求或指示

对于请求或指示消息,代理必须在消息中包含USERNAME和MESSAGE-INTEGRITY属性。MESSAGE-INTEGRITY属性的HMA计算方法见章节15.4。请注意,密码从未包含在请求或指示中。

10.1.2、接收请求或指示

在代理完成消息的基本处理之后,代理按照指定的顺序执行下面列出的检查:

  • 如果消息不同时包含MESSAGE-INTEGRITY和USERNAME属性时:

    *:如果消息是请求,服务器必须拒绝请求并给出错误响应。此响应必须使用错误码400 (错误请求:Bad Request)。

    *:如果消息是指示,则代理必须以静默方式放弃该指示。

  • 如果USERNAME不包含在服务器中当前有效的USERNAME值时:

    *:如果消息是请求,服务器必须拒绝请求并给出错误响应。此响应必须使用401(未授权)的错误代码。

    *:如果消息是指示,则代理必须以静默方式放弃该指示。

  • 使用与用户名关联的密码,计算消息完整性的值,请参见第15.4节。如果结果值与MESSAGE-INTEGRITY属性的内容不匹配:

    *:如果消息是请求,服务器必须拒绝请求并给出错误响应。此响应必须使用401(未授权)的错误代码。

    *:如果消息是指示,则代理必须以静默方式放弃该指示。

如果这些检查通过,代理将继续处理请求或指示。服务器生成的任何响应都必须包含MESSAGE-INTEGRITY属性,使用用于验证请求的密码计算。响应必须不包含USERNAME属性。

如果任何检查失败,服务器一定不能在错误响应中包含MESSAGE-INTEGRITY或USERNAME属性。这是因为,在这些故障情况下,服务器无法确定计算MESSAGE-INTEGRITY所需的共享秘密。

10.1.3、接收响应

客户端在响应中查找MESSAGE-INTEGRITY属性。如果存在,客户端使用与请求相同的密码计算响应上的消息完整性,如章节15.4中定义的那样。如果结果值与MESSAGE-INTEGRITY属性的内容匹配,则认为响应已经过身份验证。如果值不匹配,或者如果MESSAGE-INTEGRITY不存在,则必须丢弃响应,就像从未收到过响应一样。这意味着重新传输,如果适用,那么一切继续。

10.2、长期证书机制

长期证书机制依赖于长期证书,其形式为客户端和服务器之间共享的用户名和密码。证书被认为是长期的,因为它是假设它是为用户准备的,并且持续有效直到用户不再是系统的订阅者为止。这基本上是给用户的一个传统的“登录”用的用户名和密码。

由于这些用户名和密码在较长时间内都是有效的,因此以摘要挑战的形式提供了重播预防。在此机制中,客户端最初发送请求,而不提供任何凭据或任何完整性检查。服务器拒绝此请求,为用户提供一个范围(用于指导代理选择用户名和密码)和一个随机数。随机数提供重放保护。它是服务器选择的一个cookie,并以表明其有效的有效期或客户端身份的方式进行编码。客户端重新尝试请求,这次包括它的用户名和领域,并返回服务器提供的NONCE。客户端还包括消息完整性,它为整个请求(包括NONCE)提供HMAC。服务器验证NONCE并检查消息的完整性。如果匹配,则对请求进行身份验证。如果NONCE不再有效,则认为它“过时”,服务器拒绝请求,提供一个新的NONCE。

在向同一服务器的后续请求中,客户机将重用以前使用的NONCE、用户名、领域和密码。这样,在NONCE失效之前,后续的请求不会被服务器拒绝,在这种情况下,拒绝为客户端提供了一个新的NONCE。
请注意,长期凭据机制不能用于保护指示消息,因为指示消息不能受到质疑。使用指示的用法必须使用短期凭据或省略其身份验证和消息完整性。由于长期凭据机制容易受到脱机字典攻击,部署应该使用难以猜测的密码。如果用户没有输入凭据,而是在设备配置期间放置在客户机设备上,那么密码应该至少具有128位的随机性。在用户输入凭据的情况下,他们应该遵循关于密码结构的最佳当前实践。(本小节未校准)

10.2.1、构建请求

这里有构建请求的两种情况。在第一种情况下,这是从客户机到服务器的第一个请求(由其IP地址和端口标识)。在第二种情况下,一旦前一个请求/响应事务成功完成,客户端就会提交一个后续请求。由于401或438错误响应而形成请求将在第10.2.3节中讨论,它不被认为是“后续请求”,因此不利用第10.2.1.2节中描述的规则。

10.2.1.1、第一个请求

如果客户端还没有成功地完成与服务器之间的请求/响应事务(如果使用了第9节的DNS程序,则使用IP地址),它应该忽略USERNAME、MESSAGE-INTEGRITY、REALM和NONCE属性。换句话说,发送第一个请求时,就好像没有应用身份验证或消息完整性一样。

10.2.1.2、随后的请求

一旦请求/响应事务成功完成,客户端就会被服务器呈现一个域,并选择一个用户名和密码进行身份验证。客户机应该缓存用户名、密码、领域和NONCE,以便与服务器进行后续通信。当客户端发送一个后续请求时,它应该包含USERNAME、REALM和NONCE属性以及这些缓存的值。它应该包括一个MESSAGE-INTEGRITY属性,该属性在第15.4节中使用缓存的密码进行计算。

10.2.2、接收请求

在服务器完成请求的基本处理之后,它按照指定的顺序执行下面列出的检查:

  • 如果消息不包含MESSAGE-INTEGRITY属性,服务器必须生成一个错误响应,错误代码为401(未经授权)。此响应必须包含REALM值。建议“REALM”的值为STUN服务器提供商的域名。响应必须包含由服务器选择的NONCE。响应不应该包含USERNAME或MESSAGE-INTEGRITY属性。
  • 如果消息包含MESSAGE-INTEGRITY属性,但是缺少USERNAME、REALM或NONCE属性,服务器必须生成一个错误响应,错误代码为400(错误请求)。此响应不应包含USERNAME、NONCE、REALM或MESSAGE-INTEGRITY属性。
  • 如果NONCE不再有效,服务器必须生成一个错误响应,错误代码为438(过期NONCE)。此响应必须包括NONCE和REALM属性,而不应包括USERNAME或MESSAGE-INTEGRITY属性。服务器可以使NONCE失效,以提供额外的安全性。参考[RFC2617]第4.3节的指导方针。
  • 如果USERNAME属性中的用户名无效,服务器必须生成一个错误响应,错误代码为401(未经授权)。此响应必须包含REALM值。建议“REALM”的值为STUN服务器提供商的域名。响应必须包含由服务器选择的NONCE。响应不应该包含USERNAME或MESSAGE-INTEGRITY属性。
  • 使用USERNAME属性中与用户名关联的密码,计算消息完整性的值,如第15.4节所述。如果结果值与MESSAGE-INTEGRITY属性的内容不匹配,服务器必须使用错误响应拒绝请求。此响应必须使用401的错误代码(未经授权)。它必须包括REALM和NONCE属性,而不应该包括USERNAME或MESSAGE- INTEGRITY属性。
  • 如果这些检查通过,服务器将继续处理请求。服务器生成的任何响应(上面描述的情况除外)都必须包含MESSAGE-INTEGRITY属性,该属性使用用于验证请求的用户名和密码计算。REALM、NONCE和USERNAME属性不应该包含在内。

10.2.3、接收响应

如果响应是一个错误响应,错误代码为401(未授权),客户端应该用一个新的事务重试请求。此请求必须包含一个用户名,由客户端从错误响应中确定作为REALM的适当用户名。请求必须包含从错误响应中复制的REALM。请求必须包含从错误响应中复制的NONCE。请求必须包含MESSAGE-INTEGRITY属性,该属性使用USERNAME属性中与用户名关联的密码计算得到。如果客户端没有更改上一次尝试的USERNAME或REALM或其关联密码,则绝不能执行此重试。

如果响应是一个错误响应,错误代码为438(过期的NONCE),客户端必须使用438 (Stale NONCE)响应中提供的新NONCE重试请求。此重试必须还包括USERNAME、REALM和MESSAGE-INTEGRITY。

客户机在响应中查找MESSAGE-INTEGRITY属性(要么成功,要么失败)。如果存在,客户端使用与请求相同的密码计算响应上的消息完整性,如章节15.4中定义的那样。如果结果值与MESSAGE-INTEGRITY属性的内容匹配,则认为响应已经过身份验证。如果值不匹配,或者如果MESSAGE-INTEGRITY不存在,则必须丢弃响应,就像从未收到过响应一样。这意味着重新传输,如果适用,将继续。

11、备用服务器(ALTERNATE-SERVER)机制

本节描述STUN中的一种机制,该机制允许服务器将客户端重定向到另一个服务器。这个扩展是可选的,一个用法必须定义是否以及何时使用这个扩展。使用此扩展的服务器通过回复带有错误码300(尝试替换)的请求消息将客户端重定向到另一个服务器。服务器必须在错误响应中包含一个ALTERNATE-SERVER属性。错误响应消息可以被验证;然而,在某些情况下,响应的身份验证是不可能或不实际的。

使用此扩展的客户端按如下方式处理300(尝试替换)错误代码。客户机在错误响应中查找ALTERNATE-SERVER属性。如果找到一个,则客户端认为当前事务失败,并使用属性中指定的服务器重新尝试请求,使用与前一个请求使用的相同的传输协议。如果经过身份验证,该请求必须使用客户机在向执行重定向的服务器请求中使用的相同凭据。如果客户端被重定向到服务器,并且在过去五分钟内它已经尝试过这个请求,那么它必须忽略重定向并认为事务已经失败。在重定向循环的情况下,这可以防止服务器之间无限的ping-pong。(到此未校准)

12、向后兼容RFC3489

本节定义了允许与RFC3489 [RFC3489]中定义的原始协议在一定程度上向后兼容的过程。这种机制是可选的,只在新客户机可以连接到旧服务器的情况下使用,反之亦然。用法必须定义是否以及何时使用此过程。

第19节列出了本规范和RFC3489之间的所有更改。然而,并非所有这些差异都是重要的,因为“经典STUN”仅用于少数特定的方式。对于这个扩展的目的,重要的更改如下。RFC3489中:

  • UDP是唯一支持的传输协议。
  • 现在是魔术字(magic cookie)字段的字段是事务ID字段的一部分,事务ID长度为128位。
  • XOR-MAPPED-ADDRESS属性不存在,Binding方法使用MAPPED-ADDRESS属性。
  • 有三个需要理解的属性,RESPONSE-ADDRESS、CHANGE-REQUEST和CHANGED-ADDRESS,已经从这个规范中删除了。
  • CHANGE-REQUEST和CHANGED-ADDRESS现在是NAT行为发现用法[Behavior -NAT]的一部分,另一个用法已弃用。

12.1、作为客户端处理

想要与RFC3489服务器互操作的客户端应该发送一个请求消息,该消息使用Binding方法,不包含任何属性,并使用UDP作为服务器的传输协议。如果成功,从服务器接收到的成功响应将包含一个MAPPED-ADDRESS属性,而不是一个XOR-MAPPED-ADDRESS属性。寻求与旧服务器互操作的客户端必须准备接收其中任何一个。而且,客户端必须忽略响应中可能出现的任何保留理解所需的属性。第18.2节中的Reserved属性:0x0002, 0x0004, 0x0005, 和0x000B可能出现在与RFC 3489兼容的服务器的Binding响应中。除了这个变更之外,响应的处理与上面描述的过程相同。

12.2、作为服务端处理

当一个给定的绑定请求消息从RFC3489 [RFC3489]客户端发送时,STUN服务器可以检测魔术字(magic cookie)字段中没有正确的值。当服务器检测到RFC3489客户端时,它应该将Binding请求中魔术字(magic cookie)字段中的值复制到Binding响应消息中的魔术字(magic cookie)字段中,并插入一个MAPPED-ADDRESS属性而不是XOR- MAPPED-ADDRESS属性。

在极少数情况下,客户端可能包括RESPONSE-ADDRESS或CHANGE-REQUEST属性。在这些情况下,服务器将这些视为未知的必须属性,并使用错误响应进行回复。由于不再支持使用这些属性的机制,这种行为是可以接受的。

STUN的RFC3489版本缺乏魔术字(magic cookie)和FINGERPRINT属性,这使得在与其他协议复用时正确识别STUN消息的概率非常高。因此,在STUN将与另一个协议复用的情况下,不应该使用向后兼容RFC3489的STUN实现。然而,这应该不是一个问题,因为在RFC3489中没有这种多路复用。

13、基本的服务器行为

本节定义基本的、独立的STUN服务器的行为。基本的STUN服务器通过接收和响应STUN绑定请求为客户端提供服务器反射传输地址。

STUN服务器必须支持Binding方法。不应利用短期或长期的凭证机制。这是因为对请求进行身份验证所涉及的工作比简单地处理它要多。出于同样的原因,它不应该利用ALTERNATE-SERVER机制。必须支持UDP和TCP。它可能支持通过TCP/TLS的STUN;然而,在这种基本操作模式下,TLS提供的安全性好处微乎其微。它可能使用指纹机制,但绝不能强制要求。由于独立服务器只运行STUN,因此FINGERPRINT无法提供任何好处。如果强制要求将破坏与RFC3489的兼容性,而这种兼容性在独立服务器中是理想的。独立的STUN服务器应该支持向后兼容[RFC3489]客户端,如第12节所述。

建议STUN服务器的管理员按照第9节的描述为这些服务器提供DNS条目。

一个基本的STUN服务器本身并不是NAT穿越的解决方案。然而,它可以通过STUN用法作为解决方案的一部分来使用。这将在第14节进一步讨论。

14、STUN使用方式

STUN本身并不能解决NAT穿越问题。相反,STUN定义了一个可以在更大的解决方案中使用的工具。术语“STUN用法”用于任何使用STUN作为组件的解决方案。

在撰写本文时,STUN的三种用法被定义为:交互连接建立(ICE) [music -ICE]、客户端发起的SIP连接[SIP- outbound]、NAT行为发现[Behavior -NAT]。其他STUN用法可能在将来定义。

STUN用法定义了如何实际使用STUN——何时发送请求、如何处理响应,以及使用这里定义的(或在STUN的扩展中)哪些可选过程。用法也可能定义如下:

  • 使用哪些STUN方法。
  • 使用什么身份验证和消息完整性机制。
  • 关于完整性机制的手动和自动键派生的考虑,如[RFC4107]中所讨论的。
  • 使用什么机制来区分STUN消息与其他消息。当STUN在TCP上运行时,可能需要一种帧机制。
  • STUN客户端如何确定STUN服务器的IP地址和端口。
  • 是否需要向后兼容RFC3489。
  • 什么样的可选属性(如FINGERPRINT和ALTERNATE-SERVER)或者其他扩展被定义为必需的。

此外,任何STUN使用都必须考虑在该使用中使用STUN的安全影响。许多针对STUN的攻击是已知的(请参阅本文档的安全注意事项一节),任何使用都必须考虑如何打败或减轻这些攻击。

最后,使用时必须考虑STUN的使用是否是NAT穿越的单边自地址修复方法的一个例子,如果是,解决RFC3424 [RFC3424]中提出的问题。

15、STUN属性

在STUN头之后是零或多个属性。每个属性必须经过TLV编码,16位类型、16位长度和值。每个STUN属性必须以32位边界结束。如上所述,属性中的所有字段都先传输最高位。

长度字段中的值必须包含属性的值部分在填充之前的长度,以字节为单位。由于STUN在32位边界上对齐属性,因此内容不是4字节倍数的属性将用1、2或3个字节的填充,以便其值包含4字节的倍数。填充位被忽略,可以是任何值。

任何属性类型都可以在STUN消息中出现不止一次。除非另有说明,出现顺序是重要的:只有第一个事件需要由接收方处理,任何重复的事件都可能被接收方忽略。

为了允许将来修改该规范时添加新的属性,属性空间被划分为两个范围。值介于0x0000和0x7FFF之间的属性是必须的属性,这意味着STUN代理无法成功处理消息,除非它理解属性。值在0x8000和0xFFFF之间的属性是可选属性,这意味着如果STUN代理不理解这些属性,可以忽略它们。

STUN属性类型集由IANA维护。本规范定义的初始集合见第18.2节。

本节的其余部分描述了本规范中定义的各种属性的格式。

15.1、MAPPED-ADDRESS

MAPPED-ADDRESS属性表示客户端的反射传输地址。它由一个8位地址簇和一个16位端口组成,然后是一个固定长度的值代表IP地址。地址簇为IPv4时,地址必须为32位。如果地址簇为IPv6,则地址必须为128位。所有字段必须按网络字节顺序排列。

MAPPED-ADDRESS属性的格式为:

地址族(Family)可以采用以下值:

    0x01:IPv4
    0x02:IPv6

MAPPED-ADDRESS的前8位必须设置为0,并且必须被接收方忽略。这些位用于在自然的32位边界上对齐参数。

此属性仅用于服务器实现与RFC3489 [RFC3489]客户端的向后兼容。

15.2、XOR-MAPPED-ADDRESS

XOR-MAPPED-ADDRESS属性与MAPPED-ADDRESS属性相同,除了反射传输地址是通过XOR函数混淆的。XOR-MAPPED-ADDRESS的格式为:

Family表示IP地址簇(Family),与MAPPED-ADDRESS中的Family编码相同。

X-Port的计算方法是按照主机字节顺序取映射端口,将它与魔术字(magic cookie)的最重要的16位进行异或运算,然后将结果转换为网络字节顺序。如果IP地址族是IPv4, X-Address的计算方法是按照主机字节顺序取映射的IP地址,与魔术字(magic cookie)进行异或,并将结果转换为网络字节顺序。如果IP地址族是IPv6, X-Address的计算方法是按照主机字节顺序取映射的IP地址,将其与魔术字(magic cookie)和96位事务ID的连接异或,并将结果转换为网络字节顺序。

编码和处理属性值的前8位的规则、处理属性多次出现的规则以及处理地址族的规则与MAPPED-ADDRESS相同。

  注意:XOR-MAPPED-ADDRESS和MAPPED-ADDRESS仅在传输地址的编码上有所不同。前者通过对传输地址和魔术字(magic cookie)进行异或得到的。后者直接用二进制编码。RFC 3489最初只指定了映射地址。然而,根据部署经验,一些NAT重写了包含NAT公共IP地址的32位二进制有效负载,例如STUN的MAPPED-ADDRESS属性,它试图提供一个通用的ALG函数,这是善意的,但却是错误的尝试。这种行为会干扰STUN的操作,也会导致STUN的消息完整性检查失败。

15.3、USERNAME

USERNAME属性用于消息完整性。它识别在消息完整性检查中使用的用户名和密码组合。USERNAME的值是一个变长值。必须包含一个小于513字节的UTF-8 [RFC3629]编码序列,并且必须已经使用SASLprep [RFC4013]处理过。

15.4、MESSAGE-INTEGRITY

MESSAGE-INTEGRITY属性包含STUN消息的HMAC-SHA1 [RFC2104]。MESSAGE-INTEGRITY属性可以出现在任何STUN消息类型中。因为它使用的是SHA1哈希,所以HMAC将是20个字节。作为HMAC输入的文本是STUN消息,包括头部,直到并包括MESSAGE-INTEGRITY属性之前的属性。除了出现在MESSAGE-INTEGRITY之后的FINGERPRINT属性外,代理必须忽略MESSAGE-INTEGRITY之后的所有其他属性。

HMAC的关键在于使用的是长期证书还是短期证书。对于长期凭证,密钥是16字节:

    值= MD5(username ":" realm ":" SASLprep(password))

也就是说,16字节的密钥是通过连接以下5个字段的结果的MD5哈希值形成的:(1)用户名,去掉任何引号和尾随空,取自USERNAME属性(在这种情况下,SASLprep已经应用);(2)单个冒号;(3)删除任何引号和末尾空值的REALM;(4)单个冒号;(5)使用SASLprep处理删除任何尾随空字符的密码(password)。例如,如果username是'user', realm是'realm',password是'pass',那么16字节的HMAC密钥将是对字符串'user:realm:pass'执行MD5哈希的结果,结果哈希为0x8493fbc53ba582fb4c044c456bdc40eb。

对于短期的凭证:

    值= SASLprep(password)

其中MD5定义在RFC1321 [RFC1321]中,SASLprep()定义在RFC4013 [RFC4013]中。

与长期凭据一起使用时,密钥的结构有助于在同样使用SIP的系统中进行部署。通常,使用SIP摘要身份验证机制的SIP系统并不实际将密码存储在数据库中。相反,它们存储一个名为H(A1)的值,该值等于上面定义的键。

基于上述规则,用于构造MESSAGE- INTEGRITY的散列包括来自STUN消息头的长度字段。在执行散列之前,必须将MESSAGE-INTEGRITY属性插入消息中(用假数据:(with dummy content?))。然后,必须将长度设置为指向消息的长度,包括MESSAGE-INTEGRITY属性本身,但不包括它之后的任何属性。一旦执行了计算,就可以填充MESSAGE-INTEGRITY属性的值,并且可以将STUN头中的长度值设置为其正确的值——整个消息的长度。类似地,在验证MESSAGE-INTEGRITY时,在计算HMAC之前,长度字段应调整为指向MESSAGE-INTEGRITY属性的末尾。当属性(如FINGERPRINT)出现在消息完整性之后时,这种调整是必要的。

15.5、FINGERPRINT

FINGERPRINT属性可能会出现在所有的STUN消息中。属性的值作为STUN消息的CRC-32计算,直到(但不包括)FINGERPRINT属性本身,与32位值0x5354554e的异或(XOR在应用程序包中也使用CRC-32的情况下有帮助)。32位CRC是在ITU V.42 [ITU. v42 .2002]中定义的。它的生成器多项式是x32+x26+x23+x22+x16+x12+x11+x10+x8+x7+x5+x4+x2+x+1。当出现时,FINGERPRINT属性必须是消息中的最后一个属性,因此将出现在MESSAGE-INTEGRITY之后。

FINGERPRINT属性可以帮助区分STUN报文和其他协议的报文。见第8节

与MESSAGE-INTEGRITY一样,FINGERPRINT属性中使用的CRC覆盖来自STUN消息头的长度字段。因此,该值必须是正确的,并且在计算CRC之前,将CRC属性作为消息长度的一部分。当在消息中使用FINGERPRINT属性时,首先将该属性放入带有虚拟值的消息中,然后计算CRC,然后更新该属性的值。如果还提供了MESSAGE-INTEGRITY属性,那么在计算CRC之前,它必须提供正确的MESSAGE-INTEGRITY值,因为CRC也是对MESSAGE-INTEGRITY属性的值进行的。

15.6、ERROR-CODE

ERROR-CODE属性用于错误响应消息。它包含一个300 ~ 699的数字错误码值加上一个以UTF-8 [RFC3629]编码的文本原因短语,在代码分配和语义上与SIP [RFC3261]和HTTP [RFC2616]一致。原因短语是为用户使用的,可以是任何适合错误代码的内容。IANA错误码注册表中包含定义错误码的推荐原因短语。reason phrase必须是UTF-8 [RFC3629]编码序列,长度小于128个字符(哪个可以长达763字节)。

为了便于处理,错误代码(百位数)的类与其余代码分开编码,如图7所示。

保留位应该是0,用于在32位边界上对齐。接收者必须忽略这些比特。类表示错误代码的百位数。取值范围为3 ~ 6。Number表示以100为模的错误码,其值必须在0到99之间。

定义了以下错误代码及其建议的原因短语:

300:尝试替换:客户端应该联系该请求的备用服务器。这个错误说明请求未包含USERNAME属性或有效的MESSAGE-INTEGRITY属性。否则,必须不发送,建议发送错误码为400(错误请求)。此错误响应必须使用MESSAGE-INTEGRITY属性进行保护,并且接收者在将自己重定向到备用服务器之前必须验证此响应的MESSAGE-INTEGRITY。

注意:未能为300响应生成和验证消息完整性,将允许路径上的攻击者伪造300响应,从而导致随后的STUN消息被发送给受害者。

400:错误请求:这个请求不正确。客户端不应该在没有修改前一次尝试的情况下重试请求。服务器可能无法为此错误生成有效的MESSAGE-INTEGRITY,因此客户端一定不能期望此响应具有有效的MESSAGE-INTEGRITY属性。

401:未授权:请求不包含继续的正确凭据。客户端应该用正确的凭据重试请求。

402:未知属性:服务器收到一个STUN包,其中包含它不理解的理解所需的属性。服务器必须将这个未知属性放在错误响应的UNKNOWN-ATTRIBUTE属性中。

438:旧的Nonce:客户端使用的NONCE失效。客户端应该重试,使用响应中提供的NONCE。

500:服务器错误:服务器出现临时错误。客户端应该再试一次。

15.7、REALM

REALM属性可能出现在请求和响应中。它包含符合RFC3261 [RFC3261]中描述的“realm-value”语法的文本,但没有双引号及其周围的空格。也就是说,它是一个未引用的领域值(因此,它是qdtext或引号对的序列)。必须是UTF-8 [RFC3629]编码序列,长度小于128个字符(没有可以长达763字节的),并且必须使用SASLprepSASLprep处理过的。

请求中REALM属性的存在表明长期凭据正在用于身份验证。在某些错误响应中出现表明服务器希望客户机使用长期凭据进行身份验证。 

15.8、NONCE

NONCE属性可能出现在请求和响应中。它包含一个qdtext或引号对序列,在RFC3261 [RFC3261]中定义。注意,这意味着NONCE属性将不包含实际的引号字符。参见RFC2617 [RFC2617],章节4.3,在服务器中选择NONCE值的指导。

它必须小于128个字符(可以长到763个字节)。

15.9、UNKNOWN-ATTRIBUTES

只有当ERROR-CODE属性的响应码为420时,UNKNOWN-ATTRIBUTES属性才会出现在错误响应中。

该属性包含一个16位值的列表,每个值代表服务器无法理解的属性类型。

注意:在[RFC3489]中,该字段通过复制最后一个属性被填充为32。在该规范的这个版本中,使用了属性的普通填充规则。

15.10、SOFTWARE

SOFTWARE属性包含发送消息的代理所使用的软件的文本描述。它被客户端和服务器使用。它的值应该包括制造商和版本号。该属性对协议的操作没有影响,只是作为诊断和调试的工具。“SOFTWARE”的值为可变长度。必须是UTF-8 [RFC3629]编码序列,长度小于128个字符。

15:11、ALTERNATE-SERVER

备用服务器表示备用传输地址,标识STUN客户端应该尝试的另一个STUN服务器。

它的编码方式与MAPPED-ADDRESS相同,因此通过IP地址指代单个服务器。IP地址族必须与请求的源IP地址族相同。

16、安全注意事项

16.1、对协议的攻击

16.1.1、外部攻击

攻击者可以尝试修改传输中的STUN消息,以导致STUN操作失败。通过消息完整性机制(使用短期或长期凭据)对请求和响应检测这些攻击。当然,一旦检测到,被操纵的数据包将被丢弃,从而导致STUN事务实际上失败。只有路径上的攻击者才可能进行这种攻击。

可以观察但不能修改传输中的STUN消息的攻击者(例如,存在于共享访问介质(如Wi-Fi)上的攻击者),可以看到一个STUN请求,然后立即发送一个STUN响应,通常是一个错误响应,以便中断STUN处理。对于利用MESSAGE-INTEGRITY的消息,还可以防止这种攻击。但是,一些错误响应,特别是与身份验证相关的响应,不能被MESSAGE-INTEGRITY保护。当STUN本身通过安全传输协议(例如TLS)运行时,这些攻击将完全减轻。

根据STUN的使用情况,这些攻击的后果可能很小,因此不需要消息完整性来减轻。例如,当将STUN用于基本STUN服务器以发现用于ICE的服务器反射候选时,不需要身份验证和消息完整性,因为这些攻击是在连接性检查阶段检测到的。然而,连通性检查本身需要保护ICE的正常运行。如第14节所述,STUN用法描述了需要身份验证和消息完整性的情况。

由于STUN使用共享秘密的HMAC来进行身份验证和完整性保护,因此它容易受到脱机字典攻击。当使用身份验证时,应该使用强密码,这样不会轻易受到脱机字典攻击。使用TLS保护信道本身,可以减少这些攻击。然而,STUN通常会超过UDP,在这种情况下,强密码是防止这些攻击的唯一方法。

16.1.2、内部攻击

非法客户端可能通过向服务器发送大量的STUN请求,试图对服务器发起DoS攻击。幸运的是,STUN请求可以由服务器无状态地处理,这使得此类攻击很难启动。非法客户端可能使用STUN服务器作为反射器,使用伪造的源IP地址和端口向STUN服务器发送请求。在这种情况下,响应将被传递到源IP和端口。这种攻击不会增加报文的数量(客户端每发送一个报文,STUN服务器就发送一个报文),尽管数据量略有增加,因为STUN响应通常比请求大。通过入源地址过滤,可以有效缓解这种攻击。

通过SOFTWARE属性揭示代理的特定软件版本可能会使它们更容易受到已知含有安全漏洞的软件的攻击。实现者应该使用SOFTWARE属性作为可配置选项。

16.2、影响使用的攻击

本节列出可能针对使用STUN发起的攻击。每次使用STUN都必须考虑这些攻击是否适用于它,如果适用,讨论应对措施。本节中的大多数攻击都围绕着攻击者修改STUN客户端通过绑定请求/响应事务学到的自反地址。由于反射地址的使用方式是函数,因此这些攻击的适用性和补救是特定于使用的。通常情况下,路径上的攻击者很容易修改自反地址。例如,考虑STUN直接通过UDP运行的常见情况。在这种情况下,路径上的攻击者可以在Binding请求到达STUN服务器之前修改源IP地址。STUN服务器然后将XOR-MAPPED-ADDRESS属性中的这个IP地址返回给客户端,并将响应发送回该(伪造的)IP地址和端口。如果攻击者也可以拦截此响应,则可以将其引导回客户机。使用消息完整性检查来防止这种攻击是不可能的,因为消息完整性值不能覆盖源IP地址,因为插入的NAT必须能够修改这个值。相反,防止下面列出的攻击的一个解决方案是让客户端验证学到的自反地址,就像在ICE [music -ICE]中所做的那样。其他用法可以使用其他方法来防止这些攻击。

16.2.1、方式1:针对目标的分布式DoS (DDoS)攻击

在这种攻击中,攻击者向一个或多个客户机提供指向预期目标的相同虚假自反地址。这将欺骗STUN客户端,使其认为自己的反射地址与目标地址相同。如果客户端为了接收其上的流量而发出该自反地址(例如,SIP消息中),流量将被发送到目标。这种攻击可以提供巨大的放大效果,特别是当与使用STUN启用多媒体应用程序的客户端一起使用时。然而,它只能针对从STUN服务器到目标的数据包通过攻击者的目标发射,限制了它可能的情况。

16.2.2、方式2:静默一个客户端

在这种攻击中,攻击者向STUN客户端提供一个伪造的反射地址。它提供的自反地址是一个不路由到任何地方的传输地址。因此,当客户端发出反射地址时,它将不会收到任何它期望收到的包。这种利用对攻击者来说不是很有趣。它影响单个客户端,而这通常不是期望的目标。此外,任何能够发起攻击的攻击者也可以通过其他方式拒绝对客户端服务,例如阻止客户端收到来自STUN服务器的响应,甚至是DHCP服务器的响应。与16.2.1节中的攻击一样,只有当攻击者处于从STUN服务器发送到这个未使用IP地址的报文的路径上时,才可能发生这种攻击。

16.2.3、方式3:假冒客户的身份

这个类似于方式2,然而,虚假的反射地址指向攻击者本身。这使得攻击者可以接收目标为客户端的流量。

16.2.4、方式4:窃听

在这种攻击中,攻击者强制客户端使用路由到自身的反射地址。然后它将接收到的任何数据包转发给客户端。这种攻击将允许攻击者观察发送到客户端的所有数据包。然而,为了发动攻击,攻击者必须已经能够观察从客户端到STUN服务器的数据包。大多数情(例如,当攻击从接入网发起时),这意味着攻击者可能已经观察到了发送给客户端的数据包。因此,这种攻击只能用于观察攻击者从客户端到STUN服务器的路径上的流量,但是通常不在路由到客户端的包的路径上。

16.3、哈希敏捷计划

该规范使用HMAC-SHA-1进行消息完整性的计算。如果以后发现HMAC-SHA-1存在漏洞,则将采用以下补救措施。

我们将定义一个STUN扩展,引入一个新的MESSAGE-INTEGRITY属性,该属性使用新的散列计算。客户端需要在他们的请求或指示中同时包含新的和旧的消息完整性属性。新服务器将利用新的消息完整性属性,而旧服务器将利用旧的消息完整性属性。在部署混合实现的过渡阶段之后,旧的消息完整性属性将被另一个规范弃用,客户端将停止在请求中包含它。

还需要注意的是,HMAC是使用密钥完成的,密钥本身是使用用户密码的MD5计算的。之所以选择MD5散列,是因为存在以这种形式存储密码的遗留数据库。如果未来的工作发现MD5输入的HMAC不安全,需要不同的哈希值,也可以使用这个计划更改它。但是,这需要管理员重新填充数据库。

17、IAB注意事项

IAB研究了单边自地址固定问题(UNSAF),这是一个通用的过程,客户端通过协作协议反射机制(RFC3424 [RFC3424])试图确定它在NAT另一端的另一个域中的地址。如果一个代理在NAT后面,而另一个在NAT的公共端,则可以使用STUN通过绑定请求/响应事务来执行此功能。

IAB要求为此目的制定的协议必须包含一组特定的考虑因素。因为一些STUN用法提供UNSAF功能(如ICE [music -ICE]),而其他不提供(如SIP Outbound [SIP- Outbound]),这些考虑的答案需要由用法本身来解决。

18、IANA注意事项

IANA创建了三个新的注册表:“STUN方法注册表”、“STUN属性注册表”和“STUN错误码注册表”。IANA还将指定的用于STUN的IANA端口的名称从“nat- stunt -port”改为“STUN”。

18.1、STUN方法注册

STUN方法是一个十六进制数,范围是0x000 - 0xFFF。将STUN方法编码为STUN消息,请参见第6节。

最初的STUN方法是:

  0x000:(保留) 0x001:Binding 0x002:(保留;SharedSecret)。

范围为0x000 - 0x7FF的STUN方法由IETF Review [RFC5226]分配。范围为0x800 - 0xFFF的STUN方法由Designated Expert分配[RFC5226]。专家的职责是验证所选的代码点没有被使用,并且请求不是针对异常数量的代码点。延长期限本身的技术审查不属于指定专家的责任范围。

18.2、STUN属性注册

STUN属性类型是十六进制数字,范围是0x0000 - 0xFFFF。范围为0x0000 - 0x7FFF的STUN属性类型被认为是需要理解的;0x8000 - 0xFFFF范围内的STUN属性类型被认为是可理解的。STUN代理以不同的方式处理未知的理解要求和理解可选属性。

最初的STUN属性如下:

需要理解的范围(0x0000-0x7FFF):0x0000: (保留);0x0001: MAPPED-ADDRESS;0x0002: (保留; 作为RESPONSE-ADDRESS);0x0003: (保留; 作为CHANGE-ADDRESS);0x0004: (保留; 作为SOURCE-ADDRESS);0x0005: (保留; 作为CHANGED-ADDRESS);0x0006: USERNAME;0x0007: (保留; 作为PASSWORD);0x0008: MESSAGE-INTEGRITY;0x0009: ERROR-CODE;0x000A: UNKNOWN-ATTRIBUTES;0x000B: (保留; 作为 REFLECTED-FROM);0x0014: REALM;0x0015: NONCE;0x0020: XOR-MAPPED-ADDRESS

可选理解的范围(0x8000-0xFFFF):0x8022: SOFTWARE;0x8023: ALTERNATE-SERVER;0x8028: FINGERPRINT

STUN属性类型在理解要求范围的前半部分(0x0000 - 0x3FFF)和理解可选范围的前半部分(0x8000 - 0xBFFF)由IETF Review [RFC5226]分配。。STUN属性类型在推导要求范围的后半部分(0x4000 - 0x7FFF)和推导可选范围的后半部分(0xC000 - 0xFFFF)由Designated Expert分配[RFC5226]。专家的职责是验证所选的代码点没有被使用,并且请求不是针对异常数量的代码点。延长期限本身的技术审查不属于指定专家的责任范围。

18.3、错误码注册

STUN错误码是一个范围为0 - 699的数字。STUN错误代码伴随着一个UTF-8 [RFC3629]格式的文本原因短语,仅供人类使用,可以是任何合适的内容;本文档仅提出建议值。

STUN错误码在码点分配和语义上与SIP [RFC3261]和HTTP [RFC2616]一致。

注册的初始值在第15.6节中给出。

基于IETF Review分配新的STUN错误码[RFC5226]。规范必须仔细考虑不理解此错误代码的客户在批准请求之前如何处理它。参见第7.3.4节中的规则。

18.4、STUN TCP/UDP端口

IANA之前已经为STUN分配了3478端口。该端口在IANA注册表中以“nat- stunt -port”的名称出现。为了使DNS SRV过程与已注册的协议服务对齐,请求IANA将分配给3478端口的协议名称从“nat- stuns -port”更改为“stun”,文本名称从"Simple Traversal of UDP Through NAT (STUN)"到"Session Traversal Utilities for NAT",这样IANA端口注册表就会读取。

此外,IANA还为“stuns”服务分配了端口号5349,该服务通过TCP和UDP定义。UDP端口目前没有定义;但是,它是保留给将来使用的。

19、自RFC 3489以来的更改

本规范废止了RFC3489 [RFC3489]。该规范与RFC 3489的不同之处在于:

  • 删除了STUN是一个完整的NAT穿越解决方案的概念。STUN现在是一个可以用来生成NAT穿越解决方案的工具。因此,将协议的名称改为会话遍历实用程序的NAT。
  • 介绍了STUN用法的概念,并描述了STUN用法必须记录的内容。
  • 取消了STUN用于NAT类型检测和绑定生命周期发现的使用。这些技术已经被证明过于脆弱,因为NAT设备的类型比本文描述的更广泛的变化。删除了RESPONSE-ADDRESS、CHANGED-ADDRESS、CHANGE-REQUEST、SOURCE-ADDRESS和REFLECTED-FROM等属性。
  • 增加了一个固定的32位魔术cookie,并减少了32位事务ID的长度。魔术字(magic cookie)以与原始事务ID相同的偏移量开始。
  • 添加了XOR-MAPPED-ADDRESS属性,如果请求中出现魔术字(magic cookie),则在Binding响应中包含该属性。否则,RFC 3489行为将被保留(也就是说,绑定响应包含MAPPED-ADDRESS)。请参阅XOR-MAPPED- ADDRESS中有关此更改的讨论。
  • 在消息类型报头字段中引入了正式的结构,使用显式的一对位来表示请求、响应、错误响应或指示。因此,消息类型字段被分割为类(前四个字段之一)和方法。
  • 明确指出STUN最重要的2位是0b00,当与ICE一起使用时,允许与RTP包轻松区分。
  • 增加了FINGERPRINT属性,提供了一种方法,可以明确检测STUN和另一个协议在一起复用时的差异。
  • 增加IPv6支持。说明IPv4客户端可以获得IPv6映射地址,反之亦然。
  • 添加基于长期资格身份验证。
  • 添加了SOFTWARE、REALM、NONCE和ALTERNATE-SERVER属性。
  • 删除了SharedSecret方法和PASSWORD属性。这个方法几乎从未实现过,并且在当前的使用中也不需要。
  • 移除继续监听眩晕反应10秒以识别攻击的建议。
  • 更改事务计时器,使之更加TCP友好。
  • 删除了围绕控制平面和媒体平面分离的STUN示例。相反,本文提供了更多关于使用STUN与协议的信息。
  • 定义了一种通用填充机制,用于更改长度属性的解释。理论上,这将破坏向后兼容性。然而,RFC 3489中的机制从未对少数在32位边界上没有自然对齐的属性起作用。
  • REALM, SERVER, 原因短语和NONCE限制在127个字符。用户名到513字节。
  • 修改了TCP和TLS的DNS SRV过程。UDP保持不变。

20、贡献者

略。

21、鸣谢

略。

22、参考文献

22.1、规范性参考

[ITU.V42.2002]    International Telecommunications Union, "Error-correcting Procedures for DCEs Using Asynchronous-to-Synchronous Conversion", ITU-T Recommendation V.42, March 2002.

[RFC0791]    Postel, J., "Internet Protocol", STD 5, RFC 791, September 1981.

[RFC1122]    Braden, R., "Requirements for Internet Hosts - Communication Layers", STD 3, RFC 1122, October 1989.

[RFC1321]    Rivest, R., "The MD5 Message-Digest Algorithm", RFC 1321, April 1992.

[RFC2104]    Krawczyk, H., Bellare, M., and R. Canetti, "HMAC: Keyed-Hashing for Message Authentication", RFC 2104, February 1997.

[RFC2119]    Bradner, S., "Key words for use in RFCs to Indicate Requirement Levels", BCP 14, RFC 2119, March 1997.

[RFC2460]    Deering, S. and R. Hinden, "Internet Protocol, Version 6 (IPv6) Specification", RFC 2460, December 1998.

[RFC2617]    Franks, J., Hallam-Baker, P., Hostetler, J., Lawrence, S., Leach, P., Luotonen, A., and L.Stewart, "HTTP Authentication: Basic and Digest Access Authentication", RFC 2617, June 1999.

[RFC2782]    Gulbrandsen, A., Vixie, P., and L. Esibov, "A DNS RR for specifying the location of services (DNS SRV)", RFC 2782, February 2000.

[RFC2818]    Rescorla, E., "HTTP Over TLS", RFC 2818, May 2000.

[RFC2988]    Paxson, V. and M. Allman, "Computing TCP’s Retransmission Timer", RFC 2988, November 2000.

[RFC3629]    Yergeau, F., "UTF-8, a transformation format of ISO 10646", STD 63, RFC 3629, November 2003.

[RFC4013]    Zeilenga, K., "SASLprep: Stringprep Profile for User Names and Passwords", RFC 4013, February 2005.

22.2、参考资料

[BEHAVE-NAT]    MacDonald, D. and B. Lowekamp, "NAT Behavior Discovery Using STUN", Work in Progress, July 2008.

[BEHAVE-TURN]    Rosenberg, J., Mahy, R., and P. Matthews, "Traversal Using Relays around NAT (TURN): Relay Extensions to Session Traversal Utilities for NAT (STUN)", Work in Progress, July 2008.

[KARN87]    Karn, P. and C. Partridge, "Improving Round-Trip Time Estimates in Reliable Transport Protocols", SIGCOMM 1987, August 1987.

[MMUSIC-ICE]    Rosenberg, J., "Interactive Connectivity Establishment (ICE): A Protocol for Network Address Translator (NAT) Traversal for Offer/Answer Protocols", Work in Progress, October 2007.

[MMUSIC-ICE-TCP]    Rosenberg, J., "TCP Candidates with Interactive Connectivity Establishment (ICE)", Work in Progress, July 2008.

[RFC2616]    Fielding, R., Gettys, J., Mogul, J., Frystyk, H., Masinter, L., Leach, P., and T. Berners-Lee, "Hypertext Transfer Protocol -- HTTP/1.1", RFC 2616, June 1999.

[RFC3261]    Rosenberg, J., Schulzrinne, H., Camarillo, G., Johnston, A., Peterson, J., Sparks, R., Handley, M., and E. Schooler, "SIP: Session Initiation Protocol", RFC 3261, June 2002.

[RFC3264]    Rosenberg, J. and H. Schulzrinne, "An Offer/Answer Model with Session Description Protocol (SDP)", RFC 3264, June 2002.

[RFC3424]    Daigle, L. and IAB, "IAB Considerations for UNilateral Self-Address Fixing (UNSAF) Across Network Address Translation", RFC 3424, November 2002.

[RFC3489]    Rosenberg, J., Weinberger, J., Huitema, C., and R. Mahy, "STUN - Simple Traversal of User Datagram Protocol (UDP) Through Network Address Translators (NATs)", RFC 3489, March 2003.

[RFC4107]    Bellovin, S. and R. Housley, "Guidelines for Cryptographic Key Management", BCP 107, RFC 4107, June 2005.

[RFC5226]    Narten, T. and H. Alvestrand, "Guidelines for Writing an IANA Considerations Section in RFCs", BCP 26, RFC 5226, May 2008.

[SIP-OUTBOUND]    Jennings, C. and R. Mahy, "Managing Client Initiated Connections in the Session Initiation Protocol (SIP)", Work in Progress, June 2008.

附录 A. C 片段以确定 STUN 消息类型

给定 msg_type 参数中主机字节顺序的 16 位 STUN 消息类型值,以下是用于确定 STUN 消息类型的 C 宏:

#define IS_REQUEST(msg_type)                             (((msg_type) & 0x0110) == 0x0000)
#define IS_INDICATION(msg_type)                          (((msg_type) & 0x0110) == 0x0010)
#define IS_SUCCESS_RESP(msg_type)                 (((msg_type) & 0x0110) == 0x0100)
#define IS_ERR_RESP(msg_type)                           (((msg_type) & 0x0110) == 0x0110)

NAT会话穿越应用程序(STUN)(RFC-5389)相关推荐

  1. P2P通信中的NAT/FW穿越

    摘要:P2P(Peer-to-Peer)通信的发展极其迅速,形成了很大的影响.和传统通信一样,P2P通信同样受到NAT/FW穿越问题的制约,因此解决好其相关的NAT/FW穿越问题非常重要.和传统通信相 ...

  2. SIP穿越NAT SIP穿越防火墙

    FireWall&NAT 其实光口板本质就相当于NAT设备.达到NAT穿透,光口板对SIP处理也就无问题. FireWall是一种被动网络安全防卫技术,位于网络的边界,在两个网络之间执行访问控 ...

  3. 转-SIP穿越NAT SIP穿越防火墙

    FireWall&NAT  FireWall是一种被动网络安全防卫技术,位于网络的边界.在两个网络之间运行訪问控制策略.防止外部网络对内部信息资源的非法訪问,也能够阻止特定信息从内部网络被非法 ...

  4. php在线备忘录,一个会话备忘录小程序的实现方法

    前面我们分享过很多微信小程序的文章,包括微信小程序仿知乎,今天我们继续和大家分享一个有取得小程序:一个会话备忘录的小程序的实现,希望大家喜欢. 说明: 数据在本地缓存中操作,纯前端无后台,不用担心信息 ...

  5. 阿呆穿越当程序员之设计模式系列-总纲

    叮~~~,阿呆被一阵闹钟吵醒.头疼剧烈的阿呆脑子里涌入了两个人的记忆,自己所在身体叫阿呆,在一个平行世界是将近百万的应届毕业生中的一员,大学学的是计算机专业,还有一个思想也是阿呆是某大厂的资深程序员. ...

  6. NAT ALG和STUN技术

    目录 NAT ALG 应用层网关讲解 Client1使用FTP主动模式建立FTP Client1使用FTP被动模式建立FTP STUN讲解 NAT ALG 应用层网关讲解 ALG主要用来替换应用层信息 ...

  7. 新型DDoS来袭 | 基于STUN协议的DDoS反射攻击分析

    简介: 作为新型反射类型,目前仍存绕过防御可能性. 阿里云安全近期发现利用STUN(Session Traversal Utilities for NAT,NAT会话穿越应用程序)服务发起的DDoS反 ...

  8. Webrtc中stun和turn的理解

    对于stun和turn的理解 在介绍turn和stun之前我们先来了解几个概念 会话描述协议 SDP(Session Description Protocol ) 网络地址转换 NAT (Networ ...

  9. webrtc下的媒体网络连接STUN、TURN、UDP、TCP

    一.理想的网络 媒体流创建流程: 1. PeerA.PeerB分别把自己的IP地址(包含端口号)和媒体能力(本地能支持的音视频编解码类型)告诉信令服务器. 2. 信令服务器对媒体能力进行协商,找到一组 ...

最新文章

  1. mysql数据库导出最大值_4.6 MySQL数据库导入与导出攻略
  2. 深入理解分布式技术 - ServiceMesh 服务网格
  3. json数组显示格式
  4. 计算机2级access,计算机二级-Access-窗体的设计视图
  5. 分布式事务,EventBus 解决方案:CAP【中文文档】
  6. React前端格式化时间
  7. 关于一类docker容器闪退问题定位
  8. 双系统 android 华硕,华硕发布Duet TD300,首款真正Windows+安卓双系统笔记本
  9. Feature pyramid networks for object detection
  10. 列表理解与lambda +过滤器
  11. HFSS之天线设计实例
  12. 「超级右键」Mac上最强的右键菜单工具,让你效率飞起!
  13. 神华集团世界500强酷站欣赏
  14. 沈阳农业大学计算机专业排名,沈阳农业大学王牌专业排名
  15. docker运行jenkins挂掉_使用Jenkins在Kubernetes上设置CI/CD管道
  16. npm安装依赖包报ERR问题汇总及处理
  17. 商业分析师应如何构建一个商业故事
  18. 华硕ddns注册ip地址不正确_华硕路由器 ddns注册成功,但是连接不上,怎么修改成别的ddns...
  19. ContextCaptureMaster/Smart3D 集群处理详解
  20. ANSYS CMD

热门文章

  1. 多测师肖sir_高级金牌讲师__python之常见if语句
  2. 二维小波变换_小波变换完美通俗讲解系列之 (一)
  3. def read()
  4. Python数据爬取之中国人口数据【附整理好的分省数据下载链接】
  5. 2021物理化学实验4:液体饱和蒸气压的测定
  6. 保研之旅5:上海科技大学信息学院夏令营
  7. 面试中,五大经典“送命题”该如何正确回答?
  8. 人工神经网络分析方法,人工神经网络算法步骤
  9. Python基于OpenCV的交通路口红绿灯控制系统设计
  10. Qt 添加 QtNetwork 库文件(包括vs中和qt中)