TR-069_Amendment-4:附录G.穿越NAT网关的连接请求方式

Posted sybblogs

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了TR-069_Amendment-4:附录G.穿越NAT网关的连接请求方式相关的知识,希望对你有一定的参考价值。

 

注意:这种机制只适用于RFC 3489[21]中定义的经典STUNRFC 5389引入后,这个机制已经过时。这个机制不是设计用于RFC 5389中定义的STUNIPv6部署要么不使用NAT,要么以不同的方式使用它。

G.1介绍

CWMP可以用来对通过网关连接的局域网下的CPE设备进行远程管理。当设备部在NAT网关之后,并被分配了私网IP后,CWMP依然可以对其进行管理,但有了限制,通过Connection Request触发CWMP会话的机制不可用。

本附录定义了一种方式,允许ACS初始化位于NAT网关后的设备的CWMP会话,它提供了与Connection Request相同的功能,但使用的是不同的机制,以适应这个场景。

此机制不要求网关支持CWMP协议,仅需要ACSCPE做出支持。

G.2过程

为满足此特性,CPEACS需要满足如下要求:

CPE必须能够发现它到ACS的连接是穿过了一个NAT网关,并且这个NAT网关为CPE分配了一个私IP地址

CPE必须能够维护一个NAT绑定通道ACS通过它可以随时向CPE发送数据包,而不是仅在收到CPE的请求后,以响应此请求的方式发送数据包。

CPE必须能够确定与NAT绑定通道相关联的公IP地址和端口,并将此信息发送ACS

为适应上述各项功能,本附录定义了一些STUN协议的特别用法,即基于UDPConnection Request机制,做为基于TCPConnection Request的补充。

借助于STUN发送UDP Connection RequestCPE过程总结如下

ACS开启CPESTUN功能(如果出厂默认配置下尚未启用的话),并告知CPE相应的STUN Server地址

CPE通过STUN确定CPE是否位于NAT网关后面并且被分配了私网地址。

如果CPE位于NAT网关后面并且被分配了私网地址,则CPE使用STUN中定义的过程探测绑定通道的超时时间

CPE一定的频率周期性发送的STUN绑定请求,以维持NAT绑定通道的畅通,侦听UDP连接请求

CPE探测穿越NAT后的公网IP和端口,及其变化,将这些信息发送给ACS

ACS有两种方式获取这些信息,一是通过STUN绑定请求消息本身;二是通过TR069中的UDPConnectionRequestAddress参数

ACS建立CPE的连接时,向CPE发送UDP Connection Request。为了适应最广泛的NAT网关,它将从与STUN服务器相同的源地址和端口发送否则无法穿越“对称型NAT网关”

G.2.1CPE的要求

CPETR069参数,根据设备情况,要符合TR098TR181参数模型。

如果TR069STUNEnable参数的值为trueCPE必须判断与STUN Server之间是否发生了ip/port转换,如果发生了转换,CPE必须:

判断穿过NAT后的公网IP和端口。

探知NAT绑定通道的超时时间,并以保持绑定通道所需的速率,周期性发送绑定请求。

通过STUN可选属性,指出CPE正在监听哪个绑定通道上的UDP Connection Request,以及绑定通道是否发生了更改。另外,更新TR069中的UDPConnectionRequestAddress参数,以指出与绑定通道关联的公共IP地址和端口。

侦听UDP Connection Request消息,并在这些消息到达时,根据其做出响应。

如上各条目的细节,会在下面的章节中详述。

G.2.1.1 探知绑定通道

当通过TR069ManagementServer对象的STUNEnable参数启用STUN后,CPE必须向指定的STUN服务器(TR069STUNServerAddressSTUNServerPort参数中指定的)发送绑定请求消息,如[21]中定义的那样。如果TR069STUNServerAddress参数没有值,则必须使用ACS URLhost部分作为STUN服务器地址。

如果发生了IP/PORT转换,则为了探知绑定通道,发送绑定请求的IP/PORT必须是监听UDP ConnectionRequestIP/PORT(探知绑定通道的超时时间时,将从不同的端口发送)。

CPE通过基本绑定请求消息,探知CPESTUN服务器之间,是否发生了地址和端口转换。方法是:比较请求发送的源IP/PORTSTUN服务器返回的MAPPED-ADDRESS属性,如果IPPORT不同,则说明发生了转换。

如果探知到发生了IP/PORT转换,则CPE必须记录最新收到的MAPPED-ADDRESS属性的值(一对IP/PORT),UDP ConnectionRequest将发送至其表示的IP/PORT

后续,为了维持绑定通道畅通,CPE定期发送绑定请求,此时CPE必须再次确定是否发生IP/PORT转换,如果发生了转换,CPE必须记录成功响应的MAPPED-ADDRESS属性值。

如果CPE被预分配了STUNUsername/STUNPasswordTR069参数),并且CPE收到了Bainding Error Response,错误码为401(未授权),那么CPE必须重新发送Binding Request,并且携带USERNAMEMESSAGE-INTEGRITY属性。

当发送携带MESSAGEINTEGRITY属性的绑定请求时,如果绑定响应中的MESSAGE-INTEGRITY属性无效或不存在,CPE必须丢弃相应的绑定响应。

如果CPE的本地IP变更,CPE必须重新探测绑定通道,这种情况下,TR069STUNMinimumKeepAlivePeriod参数定义的绑定请求周期的最小限制不适用。

除了STUN服务器响应中明确的使用了401(未授权)错误码,CPE不能在任何Binding Request中包含MESSAGE-INTEGRITY属性。

CPE中的STUN客户端,不需要支持STUN绑定请求的CHANGE-REQUEST属性,也不需要识别绑定响应中出现的属性的CHANGED-ADDRESSSOURCE-ADDRESSREFLECTED-FROM属性。

CPE中的STUN客户端,不需要支持交互共享秘钥的消息,本附录定义的过程中,没有使用这些消息。

G.2.1.2 维持绑定通道

为了维持绑定通道,CPE必须周期性的发送Binding Request消息,发送消息时,使用监听UDP ConnectionRequest消息的IP/PORT作为源IP/PORT

CPE发送这些绑定请求的频率不能超过TR069ManagementServer对象的STUNMinimumKeepAlivePeriod参数所指定的频率。

CPE必须至少以TR069STUNMaximumKeepAlivePeriod参数指定的频率,发送这些绑定请求(如果这个参数有值的话)。

如果TR069STUNMinimumKeepAlivePeriodSTUNMaximumKeepAlivePeriod参数的值不相等,那么CPE必须主动发现NAT绑定通道所能维持的最长时间。为此,CPE必须使用在[21]中描述的过程来探知绑定通道的超时时间。具体地说,CPE必须能够通过辅助源端口(与主源端口不同)发送绑定请求,来测试绑定是否超时,并使用绑定请求中的RESPONSEADDRESS属性,指示将STUN绑定响应发送到主源端口(CPE侦听UDP Connection Request消息的端口)。

CPE使用辅助源端口发出的绑定请求,来确定绑定超时的具体过程,由CPE厂商自行决定。 一般由两个阶段组成:一个是发现阶段,一个是监控阶段。在发现阶段,CPE试图探知绑定超时的时间,并将测试不同的超时时间值,来确定实际的超时值(例如,使用二进制搜索)。在监控阶段,CPE将在刷新绑定通道之前,定期测试绑定通道,以确定绑定通道是否仍然存在。如果绑定通道不存在了,那么CPE可以返回到发现阶段,以探知新的绑定通道。

TR069STUNMinimumKeepAlivePeriod参数定义的绑定请求周期,不适用于从辅助源端口发送的绑定请求。

G.2.1.3 将绑定通道的信息发送给ACS

有两种方法可以将绑定通道信息告知ACS。这两种方法,CPE都必须支持。第一种方法,发送Binding Request时,通过STUN的可选属性告知ACS。第二个方法是,CPE在绑定信息更改时,更新TR069UDPConnectionRequestAddress参数的值。

Table 103列出了一组STUN属性。它们使用大于0x7FFF的属性类型值,STUN规范将其定义为可选的。不识别可选属性的STUN服务器需要忽略它们。

Table 103 用于Binding Request消息中的STUN可选属性。

Attribute Type

Name

Description

0xC001

CONNECTION-REQUEST-BINDING

指出CPE监听UDP Connection Request的绑定通道信息。

Value元素必须是如下内容:

0x64 0x73 0x6C 0x66

0x6F 0x72 0x75 0x6D

0x2E 0x6F 0x72 0x67

0x2F 0x54 0x52 0x2D

0x31 0x31 0x31 0x20

这相当于字符串:“dslforum.org/TR-111

最后一个字符是空格,目的是使长度为4个字符的整数倍。

它的Length元素必须是0x0014,也就是十进制的20

0xC002

BINDING-CHANGE

表示绑定信息已经变化了。

这个属性不包含值,它的Length元素必须是0

这个属性只能在包含CONNECTION-REQUEST-BINDING的情况下使用。

CPE使用监听UDP Connection RequestIP/PORT(即主源IP/PORT)发送的Binding Request,必须包含CONNECTION-REQUEST-BINDING属性。其他的所有Binding Request消息,必须不包含这个属性。

如果TR069中的STUNUsername参数不为空,包含CONNECTION-REQUEST-BINDING属性的Binding Request消息必须包含USERNAME属性,且值为TR069 STUNUsername参数的值,如果有必要,需要在后面补充空格,以保证长度为4字节的整数倍(STUN协议规定)。

每当CPE探测到NAT绑定通道变更(也包含第一次探测到绑定通道),必须立即发送一个Binding Request消息,从主源端口,也就是监听UDP Connection Request消息的端口,并且包含BINDING-CHANGE属性。这次Binding Request必须不包含RESPONSE-ADDRESS或者CHANGE-REQUEST属性。在其他Binding Request消息中,CPE必须不包含BINDING-CHANGE属性。TR069STUNMinimumKeepAlivePeriod定义的Binding Request的最小周期限制,对于包含BINDING-CHANGE属性的Binding Request消息不适用。

对于包含BINDING-CHANGE属性的Binding Request消息,CPE必须遵从[21]定义的重传过程,以确保此消息被成功的接收。如果应用了重传过程,CPE确定Binding Request仍然失败,则它不能发送包含BINDING-CHANGEBinding Request(直到绑定随后再次更改)。

如果IP/PORT发生了转换,当CPE确定绑定更改时(以及第一次CPE确定绑定时),CPE必须更新TR069ManagementServer对象中的UDPConnectionRequestAddress参数的值。特别的:

 

TR069UDPConnectionRequestAddress的主机部分,必须设置为与UDP连接请求关联的绑定通道的公网IP地址。

TR069UDPConnectionRequestAddress的端口部分,必须设置为与UDP连接请求关联的绑定通道的公网PORT

如果CPE确定IP/PORT发生了转换,CPE必须把TR069ManagementServer对象的NATDetected参数设置为true

如果ACSTR069UDPConnectionRequestAddress参数上的通知属性,设置为Active Notification,那么每当绑定通道信息发生变化,CPE必须建立一个到ACS的连接,并且包含UDPConnectionRequestAddress参数在Inform消息中。

TR069UDPConnectionRequestAddress参数变更时,如果上次发送Notification的时间距现在小于TR069 UDPConnectionRequestAddressNotificationLimit参数,那么本次Notification必须推迟,直到达到指定的最小时间间隔。

注意:除了指定的最小通知周期外,CPE也可以根据自己的判断来延迟通知,以避免通知消息过多。这样的延迟仅用在CPE认为绑定通道会在一个较短的时间内再次变更时。例如,在主动发现绑定超时的过程中,可以合理地预期频繁的绑定更改。类似地,CPE检测到安全攻击导致频繁的绑定更改,并限制通知的数量,直到攻击停止。

如果CPE判断出IP/PORT都没有发生转换,那么也必须通知ACS,通知的方法是,将TR069NATDetected参数设置为false,并且,将UDPConnectionRequestAddress设置为本地IP/PORT,这个本地IP/PORT也就是CPE监听UDP Connection Request消息的地址。

G.2.1.4 UDP Connection Requests

符合本附录规定的CPE,必须在指定的端口上的临听UDP Connection Request。无论CPE是否检测到IP/PORT转换,以及是否启用了STUN,都必须如此。

注意:CPE必须继续监听基于TCPConnection Request,定义在3.2.1.2

UDP Connection Request消息的格式定义在Section G.2.2.3。当CPE接收到一个UDP Connection Request消息时,必须进行鉴权和验证。

当且仅当如下条件满足时,一个UDP Connection Request消息是有效的:

不得违反[6]HTTP 1.1请求消息的要求。

Request Line中给出的方法必须是GET

ts查询参数的值,时间戳,必须严格大于最新收到的、有效的、鉴权通过的UDP Connection Request消息。

为了保证上述的比较可以执行,CPE必须维护一个持久化记录,保存最新成功验证和鉴权的UDP Connection Request时间戳(除了CPE发生重启)。验证或鉴权失败的UDP Connection Request消息的时间戳不得保存。CPE可以在重启过程中保留这个值,如果没有保留,在重启之后应立即使用0值。

CPE对时间戳的要求可以比上面所述的更严格。例如,CPE可以另外验证时间戳是否在一个时间窗口内(相对于CPE的当前时间)。如果CPE选择这样做,它应该避免时间窗口过窄,以便在CPEACS中都允许一个合理的误差范围。

id参数,即Message ID,必须与最近收到的、有效的、鉴权成功的UDP Connection Request消息不同。

un参数,即Username,值必须与TR069ManagementServer对象的ConnectionRequestUsername参数一致。

当且仅当如下条件满足时,一个UDP Connection Request消息是鉴权通过的:

sig参数,即Signature,必须与CPE根据Section G.2.2.3使用TR069ManagementServer对象的ConnectionRequestPassword参数计算出的签名一致。

每当CPE接收并成功地验证和鉴权UDP Connection Request时,它必须遵循与3.2.1.2节中定义的基于tcp的连接请求相同的要求。

CPE必须忽略验证或鉴权不成功的UDP Connection Request

CPE必须忽略UDP Connection Request中可能出现的,任何非空消息体的内容(这些消息体是为协议的未来版本预留的)。

因为STUN响应和UDP Connection Request将在同一个UDP端口上接收,CPE必须使用消息本身的内容区分STUN消息和UDP Connection Request

因为[21]中定义的所有STUN消息的第一个字节都是01,而UDP Connection Request第一个字节始终是ASCII编码的字母,所以CPE可以使用这种方式来区分消息类型。

端口7547已经被IANA分配给CWMP(见[17]),CPE可以使用这个端口来处理UDP连接请求。

G.2.2ACS的要求

ACS必须与一个符合此附录要求STUN服务器关联起来

G.2.2.1STUN服务器的要求

STUN服务器必须符合[21]中定义的所有要求,但以下要求除外,STUN服务器可以选择不实现这些要求:

STUN服务器不需要支持在[21]中定义的共享秘密交换机制。如果使用消息完整性,则必须静态地提供共享秘密,并与CPE TR069参数中的STUNUsernameSTUNPassword参数对应。

STUN服务器不需要支持用于发送绑定响应(A2/P2)的辅助源IP地址或端口。如果没有,使用主地址和端口(A1/P1)填充CHANGE-ADDRESS属性即可,如果在绑定请求中收到CHANGE-REQUEST属性,则STUN服务器可以忽略该属性。

通过使用错误代码401(未经授权)Binding Error Response来响应请求,STUN服务器可以对任何接收到的Binding Request要求消息完整性。

G.2.2.2 判断绑定通道信息

ACS可以通过两种方式来判定绑定通道信息。

G.2.2.2.1 基于STUN消息的方式

如果ACS选择使用这种方式,那么它应该在每个CPEManagementServer对象中设置一个非空的STUNUsernameSTUNPassword。在ACS所管理的所有CPE中,STUNUsername必须是唯一的,以确保可以此唯一关联CPE。在ACS所管理的所有CPE中,STUNPassword应该是唯一的,并且应该符合[21]规定的密码强度规则。

每当STUN服务器收到一个Binding Request,并且消息中同时包含BINDING-CHANGECONNECTION-REQUEST-BINDING属性:

STUN服务器应该响应回401错误,强制CPE重发附带消息完整性的Binding Request

STUN服务器接收到重发的具有消息完整性的Binding Request时,应该对请求者进行身份验证。如果ACSSTUN服务器不是整合在一起的,这可能涉及到STUN服务器和ACS之间的通信。

如果身份验证失败,则STUN服务器必须响应[21]中定义的Binding Request Error,并且不再进行后续的操作。

如果身份验证成功,STUN服务器应该从Binding Request消息中提取出源IP/PORT,并且将其记录下来,用于发送UDP Connection Request消息。根据实现的不同,这可能涉及STUN服务器将IP/PORTTR069参数STUNUsername的对应关系发送给ACSACS将根据CPE对应的STUNUsername保存这些关系。即ACS可据此得知,可用于向特定CPE发送UDP Connection Request消息的IP/PORT

对于一个Binding Request消息中包含的Transaction IDSTUN服务器仅执行一次上述操作。应该忽略具有相同事务ID的绑定请求的冗余副本(为保障消息一定能被ACS接收,CPE可能发送多次)。

使用这种方法,STUN服务器也可以选择不要求消息完整性或对绑定请求进行身份验证,除非它遵循上述过程来确定绑定信息。

ACS可以在任何时间判定当前绑定通道,即使没有携带CONNECTION-REQUEST-BINDING属性的Binding Request来通知变更(这句翻译的可能有问题,原句是The ACS MAY determine the current binding at any time even if no change was notified by following the above procedure on any received Binding Request for which the CONNECTION-REQUEST-BINDING attribute is present )。在这些Binding Request中的USERNAME属性,可在后续的身份验证之前,供ACS暂时的判定CPE的身份。这允许ACS定期验证绑定信息,以确保在绑定通道更改的消息未到达ACS时,该信息是最新的。

如果ACS确定CPE不再位于正在进行IP/PORT转换的NAT之后,那么ACS可以使用3.2.1.2节中定义的基于TCP的连接请求。

G.2.2.2.2 基于TR069 Notification的方式

如果ACS选择在TR069UDPConnectionRequestAddress参数上使用Active Notification,它应该执行以下操作:

设置UDPConnectionRequestAddress参数的Notification属性,以激活通知功能。

每当Inform参数中包含UDPConnectionRequestAddress参数时,记录其变更,并且使用最近记录的地址,作为发送UDP Connection Request消息的目标。特别的,目标的IP地址由此参数的host部分得来,PORT由此参数的port部分得来。如果,host部分给出的是一个域名,ACS必须使用DNS判定对应的IP地址。如果端口没有在UDPConnectionRequestAddress参数中明确指明,则默认使用80端口。

观察TR069NATDetected参数的值(可以在UDPConnectionRequestAddress发生变化时读取它,也可以在该参数上启用通知功能)。当该参数为false时,ACS可以使用3.2.1.2节中定义的基于TCPConnection Request

使用这种方法,ACS可以选择不要求消息完整性或验证STUN绑定请求,因为这些请求不用于向ACS传递信息。在这种情况下,ACS不需要在CPE中设置STUNUsernameSTUNPassword

G.2.2.3 UDP Connection Request

ACS必须从与STUN服务器相同的源IP地址和端口发送UDP连接请求消息。

一个UDP Connection Request必须在单个数据包中传输。

ACS应该对同一个UDP Connection Request应该发送多次,以避免丢包。当ACS发送相同UDP Connection Request时,消息的内容(包括Message IDTimestampcnonce)必须相同。

UDP Connection Request没有对应的响应消息。

UDP Connection Request消息的格式派生自HTTP 1.1 [6] GET消息的格式,尽管不使用HTTP 1.1协议本身。

特别的,UDP Connection Request消息必须满足下列要求:

必须是一个有效的HTTP 1.1 GET消息。

必须不包含消息体。

如果包含Content-Length Header,值必须为0

Request Line中的Method必须为GET

Request Line中给出的Request-URI必须是Absolute-URIURI必须满足如下格式:

Scheme部分必须是http或者HTTP

Authority部分必须如[12]中定义的一样。ACS可以将这个值设为TR069UDPConnectionRequestAddress(如果这个参数有值的话)。否则,ACS必须从实际的目的IP/PORT中派生此字符串。port部分必须存在,除非目标port80(默认值)。

URIPath部分必须为空。

URIQuery部分,必须包含一个查询字符串,按照[23]中关于“application/x-www-form-urlencoded”的方式进行编码。查询字符串必须包含如下的键值对:

Name

Value

ts

Timestamp。从Unix纪元到创建消息时的秒数(标准Unix时间戳)。

id

Message ID。一个无符号整数,消息重传时必须相同,后续发送的不同的UDP Connection Request消息必须不同。

un

UsernameTR069 ManagementServer.ConnectionRequestUsername参数的值,此参数的值是从CPE读取的。

cn

Cnonce。一个随机的字符串,由ACS决定。

sig

Signature。由HMAC-SHA1 (Key, Text) [19]40个字符十六进制表示(不区分大小写)组成,满足如下要求:

key的值是TR069 ManagementServer.ConnectionRequestPassword参数的值。

Text是一个字符串,它由以下元素连接而成,按照如下列出的顺序,且各项之间没有空格:

ts的值

id的值

un的值

cn的值

如下是一个URI示例:

http://10.1.1.1:8080?ts=1120673700&id=1234&un=CPE57689&cn=XTGRWIPC6D3IPXS3&sig=3545F7B5820D76A3DF45A3A509DA8D8C38F13512

G.2.3 消息流程

Figure 12 Binding discovery / maintenance from the primary source port

技术图片

Figure 12是一个消息流示例。

在所有的示例中,所有的ip/port显示为(A,P)符号,A表示IPP表示PORT。在示例中,(A1,P1)CPE的主端口,用于监听UDP Connection Request消息,(A1,P2)CPE的辅助端口,用于探测绑定超时时间。穿过NAT后,地址分别转换成了(A1‘,P1‘)(A2‘,P2‘)。在所有的示例中,都假设STUN服务器没有辅助的IP/PORT,所以Binding Response中的CHANGED-ADDRESS属性(CPE不需要使用)内容是STUN服务器的主IP/PORT,也就是(A3,P3)

Figure 12展示了周期性的探知绑定通道、维持绑定通道流程,即CPE发送Binding Request消息(使用主IP/PORT)携带CONNECTION-REQUEST-BINDING属性和USERNAME属性(如果Username有值的话)。在这个示例中,假定STUN服务器不对请求进行身份验证。

 

Figure 13 Binding Request from secondary source port for binding timeout discovery

技术图片

Figure 13展示了CPE从辅端口发送Binding Request消息,用于发现主IP/PORT的绑定是否超时了。在此示例中,Binding Request消息中没有包含CONNECTION-REQUEST-BINDING属性,因为这个消息不是从主端口发出的。如果主IP/PORT绑定未超时最后一步的消息(灰色箭头)将不会出现。(CPE没有实现这个流程)

Figure 14 Binding change notification authenticated by the ACS

技术图片

Figure 14展示了当STUN服务器选择使用基于STUN的通知方式时,Binding Change的通知流程。这种情况下,STUN服务器在存储绑定信息前,要先对Binding Request进行身份验证。

Figure 15 Binding change notification not authenticated by the ACS

技术图片

Figure 15展示了当STUN选择使用基于TR069 Notification的通知方式时,Binding Change的通知流程。这种情况下,不需要对Binding Request消息进行身份验证,因为ACS使用CWMP TR069通知去更新绑定信息。

Figure 16 UDP Connection Request

技术图片

Figure 16展示了ACSCPE发送一个UDP Connection Request,来触发一个CWMP TR069会话的流程。此示例中,STUN服务器发送了多次相同的UDP Connection Request,以保障消息能被CPE成功接收。

G.3 安全方面

  • STUN协议描述了几种使用STUN机制进行攻击的可能性。相关详述,请参考Section 12 of RFC 3489 [21]
  • 因为绑定变更,会触发ACSCPE进行身份验证,数据库更新,还可能需要建立CMWP TR069会话从而接收Inform消息,攻击者可以使NAT绑定频繁变更,从而导致ACS负荷加大。当使用TR069 Notification方式的通知方式时,ACS可以设置一个最小通知周期来避免过于频繁的变更通知。但是,要权衡好最大通知速率,和绑定信息过期时间,否则可能导致ACS因绑定信息过期,而无法向CPE发送Connection Request消息。

 

以上是关于TR-069_Amendment-4:附录G.穿越NAT网关的连接请求方式的主要内容,如果未能解决你的问题,请参考以下文章

TR069协议

TR069网管协议应用在Android系统开发的前言

宽带保 CwmpBox TR069协议解决方案 - ACS免费云服务

Android学习——移植tr069程序到Android平台

开源免费 TR069 协议 CPE 代理程序对比

已经拿到电信路由的超级密码怎么删除TR069