NAT穿越
NAT穿越技术
随着IPv4地址的枯竭,不管是在家庭网络还是在运营商网络越来越多地部署NAT功能。为了避免来自外部网络的攻击,保护网络内部的主机,NAT会过滤掉一些外网主动发送到内网的报文。因此,NAT技术虽然在一定程度上解决了IPv4地址短缺的问题,并在保证网络安全方面发挥了一定的作用,却破坏了某些点到点网络的通信,例如P2P网络。因为P2P网络要求通信双方都能主动发起访问,所以NAT的大规模部署阻碍了P2P应用的正常运行。
NAT映射和过滤
NAT映射和NAT过滤是NAT穿越解决方案里经常用到的两个概念,例如在SIP的NAT ALG场景里,需要同时配置“外部地址和端口相关的映射”和“与外部地址和端口相关的过滤”,才能使SIP代理软件正常穿越NAT;又例如NAT STUN里,需要通过NAT映射和NAT过滤类型来判断NAT行为类型,从而确定NAT STUN是否能正常工作。因此,在介绍NAT穿越技术之前,先介绍下NAT映射和NAT过滤的基本概念以及分类。
基本概念
Endpoint:指一对IP地址和端口号信息的组合。Endpoint是NAT地址转换中的一个基本概念。
NAT映射:指NAT设备对内网主动发到外网的报文进行映射。当内网主机向外网主机发起访问时,NAT设备会建立内网Endpoint和外网Endpoint之间的映射关系表,并根据该映射关系将报文的内网Endpoint转换成外网Endpoint转发出去。Router支持三种NAT映射。
NAT过滤:指NAT设备对外网主动发到内网的报文进行过滤。为了防止内网主机受到攻击,NAT设备会对外网主动发到内网的报文进行选择性过滤,即过滤非法报文,转发正常通信报文。Router支持三种NAT过滤。
NAT映射类型
EIM(Endpoint-Independent Mapping)外部地址无关映射:对于一个内网Endpoint(X,x),其映射的外网Endpoint(M,m)是固定的。即从相同的Endpoint(X,x)发送到任何外部IP地址和任何外部端口的报文在NAT设备上使用相同的映射。
ADM(Address-Dependent Mapping)外部地址相关映射:对于一个内网Endpoint(X,x),发往目的Endpoint(D1,d1)的报文,Endpoint(X,x)被映射成Endpoint(M1,m1);发往目的Endpoint(D2,d2)的报文,Endpoint(X,x)被映射成Endpoint(M2,m2)。只要D1=D2,不管d1和d2是多少,都有Endpoint(M1,m1)=Endpoint(M2,m2)。即从相同的Endpoint(X,x)发送到相同外部IP地址和任何外部端口的报文在NAT设备上使用相同的映射。
APDM(Address and Port-Dependent Mapping)外部地址和端口相关映射:对于一个内网Endpoint(X,x),发往目的Endpoint(D1,d1)的报文,Endpoint(X,x)被映射成Endpoint(M1,m1);发往目的Endpoint(D2,d2)的报文,Endpoint(X,x)被映射成Endpoint(M2,m2)。只有当D1=D2,且d1=d2,才有Endpoint(M1,m1)=Endpoint(M2,m2)。即从相同的Endpoint(X,x)发送到相同外部IP地址和相同外部端口的报文在NAT设备上使用相同的映射。
NAT过滤类型
EIF(Endpoint-Independent Filtering)外部地址无关过滤:对于一个内网Endpoint(X,x),只要它曾经向外网发送过数据,外网主机就可以获取到它经NAT映射后的外网Endpoint(M,m)。那么只要是发给Endpoint(M,m)的报文,不管来源于D1还是D2,都能被转换并发往内网,其他报文被过滤掉。
ADF(Address-Dependent Filtering)外部地址相关过滤:对于一个内网Endpoint(X,x),只有它曾经向IP地址为D1的外网主机发送过报文,那么来自外网HostD1返回的任何端口的报文,都能被转换并发往内网,其他报文被过滤掉。
APDF(Address and Port-Dependent Filtering)外部地址和端口相关过滤:对于一个内网Endpoint(X,x),只有它曾经向IP地址为D1,端口号为d1的外网目的Endpoint(D1,d1)发送过报文,那么也只有外网HostD1中来自Endpoint(D1,d1)返回的报文,才能被转换并发往内网,其他报文被过滤掉。
NAT ALG
ALG作为一种常用的点到点网络的NAT穿越技术,主要解决NAT对应用层协议无感知问题。在某些特殊协议报文的数据部分可能包含IP地址或端口信息,例如FTP协议等。由于NAT只能对IP报文的头部地址和TCP/UDP头部的端口信息进行转换,所以这些特殊协议的报文不能被NAT转换。例如,一个内网FTP服务器在和外网主机建立会话时,将自己的内网IP地址放到了IP报文的数据部分,发送给对方。NAT无法对该IP地址进行转换,当外网主机接收了这个IP地址并使用它访问FTP服务器时,会访问失败。NAT ALG可以解决这些特殊协议的NAT转换问题。
NAT ALG原理
NAT ALG的原理是利用带有ALG功能的NAT设备对特定应用层协议的支持,当设备检测到新的连接请求时,先根据传输层端口信息判断是否为已知应用类型。如果判断为已知应用,则调用该应用协议的ALG功能对报文的深层内容进行检查。若发现任何形式表达的IP地址和端口信息,NAT都会将这些信息同步进行转换,并为这个新的连接建立一个附加的转换表项。当报文到达外网侧的目的主机时,应用层协议中携带的信息就是NAT设备转换后的IP地址和端口号,这样,就可以解决某些应用协议的报文穿越NAT问题。
应用协议 |
做NAT变换的字段 |
---|---|
DNS |
响应报文中的IP和Port |
FTP |
|
SIP |
|
PPTP |
分PPTP Client在私网还是PPTP Server在私网两种场景:
|
RTSP |
setup/reply OK报文中的端口字段 |
NAT STUN
STUN简介
定义
NAT会话穿越应用程序STUN(Session Traversal Utilities for NAT)是一种由RFC定义的网络协议,作为其他协议(例如SIP、FTP、DNS)处理NAT穿越问题的一个工具。其可以用于检查网络中NAT设备的存在,并确定两个通信端点被NAT设备分配的IP地址和端口号。然后,通过ICE(Interactive Connectivity Establishment),自动创建一条能够进行NAT穿越的数据通道。
目的
在现实Internet网络中,大多数计算机主机都位于NAT设备之后,只有少部分主机能够直接接入Internet。很多时候,希望网络中的两台主机能够直接进行通信,而不需要其他设备的中转。由于主机位于NAT设备之后,在进行通信之前,需要进行NAT设备存在的检测以确认通信时需要进行NAT穿越。
目前,虽然有些协议提供了NAT设备存在的检测和NAT穿越的方法,但是这种实现方式与网络业务选择的连接建立协议强相关。因此,需要一种通用的方案来解决NAT穿越问题。为了解决上述问题,STUN技术应运而生。它允许位于NAT设备后的设备找出NAT设备为其分配的IP地址和端口号。这些信息被用来在两个同时处于NAT之后的主机之间创建UDP通信。
在SD-WAN解决方案中,为了节省IP地址资源,分支站点的用户经常会使用私网IP地址,通过NAT转换后访问总部。总部与分支、分支与分支之间的流量经常需要穿越NAT。为了实现分支之间业务流量的NAT穿越,在SD-WAN EVPN功能里增加了STUN的NAT探测功能。
受益
STUN技术具有以下优点:
- 自动发现网络中是否存在NAT设备。
- 通过ICE(Interactive Connectivity Establishment),自动创建一条能够进行NAT穿越的数据通道。
STUN基本概念
了解STUN之前,需要先了解STUN典型组网和NAT类型。
典型组网
STUN采用客户端/服务器通信模式,由STUN客户端(STUN Client)和STUN服务器(STUN Server)组成。其典型组网如图5-14所示。
STUN客户端:是一个发送STUN绑定请求和接受STUN绑定响应的实体,例如路由器。
STUN服务器:是一个发送STUN绑定响应和接受STUN绑定请求的实体,例如路由器。STUN服务器通常部署在公网上。
通过STUN客户端与STUN服务器之间的报文交互,可以发现NAT设备的存在,并确定NAT设备分配的IP地址和端口号。STUN客户端之间建立好数据通道之后,PC间可以相互访问。具体报文交互过程,请参见STUN工作机制。
目前,STUN不支持STUN服务器位于NAT设备之后的场景。
NAT类型
STUN标准中,根据私网IP地址和端口到NAT出口的公网IP地址和端口的映射方式,把NAT分为四种类型,具体如图5-15所示。
Full Cone NAT(完全锥型NAT)
所有从同一个私网IP地址和端口(IP1:Port1)发送过来的请求都会被映射成同一个公网IP地址和端口(IP:Port)。并且,任何外部主机通过向映射的公网IP地址和端口发送报文,都可以实现和内部主机进行通信。
这是一种比较宽松的策略,只要建立了私网IP地址和端口与公网IP地址和端口的映射关系,所有的Internet上的主机都可以访问该NAT之后的主机。
Restricted Cone NAT(限制锥型NAT)
所有从同一个私网IP地址和端口(IP1:Port1)发送过来的请求都会被映射成同一个公网IP和端口号(IP:Port)。与完全锥型NAT不同的是,当且仅当内部主机之前已经向公网主机发送过报文,此时公网主机才能向私网主机发送报文。
Port Restricted Cone NAT(端口限制锥型NAT)
与限制锥型NAT很相似,只不过它包括端口号。也就是说,一台公网主机(IP2:Port2)想给私网主机发送报文,必须是这台私网主机先前已经给这个IP地址和端口发送过报文。
Symmetric NAT(对称NAT)
所有从同一个私网IP地址和端口发送到一个特定的目的IP地址和端口的请求,都会被映射到同一个IP地址和端口。如果同一台主机使用相同的源地址和端口号发送报文,但是发往不同的目的地,NAT将会使用不同的映射。此外,只有收到数据的公网主机才可以反过来向私网主机发送报文。
这和端口限制锥型NAT不同,端口限制锥型NAT是所有请求映射到相同的公网IP地址和端口,而对称NAT是不同的请求有不同的映射。
- 一端是Port Restricted Cone NAT,另一端是Symmetric NAT。
- 两端都是Symmetric NAT。
NAT类型检测
STUN是一种NAT类型敏感的协议,只支持Full Cone NAT、Restricted Cone NAT、Port Restricted Cone NAT,不支持Symmetric NAT。因此,检测NAT类型是使用STUN协议实现NAT穿越的前提条件。而且不同NAT类型对应的NAT映射和过滤方式也不同。
NAT类型对应的映射和过滤方式
Full Cone NAT是EIM和EIF的组合。
Restricted Cone NAT是EIM和ADF的组合。
Port Restricted Cone NAT是EIM和APDF的组合。
Symmetric NAT是APDM和APDF的组合。
为了检测NAT类型,需要部署专门的STUN服务器,且要求STUN服务器有两个外网IP地址。本文中,假设STUN服务器的两个外网IP地址分别为A和B,对应的端口号分别为a和b。客户端X的内网IP地址为X,端口号为x,经过NAT映射后的外网IP地址为M,端口号为m。为方便描述,将STUN服务器对应的两个外网Endpoint记为Endpoint(A,a)和Endpoint(B,b),将客户端X的内网Endpoint记为Endpoint(X,x),经NAT映射后的外网Endpoint记为Endpoint(M,m)。下面分别介绍NAT映射类型检测过程和NAT过滤类型检测过程。
NAT映射类型检测
- 客户端X以Endpoint(X,x)给STUN服务器的外网Endpoint(A,a)发送一个绑定请求。STUN服务器使用Endpoint(A,a)给客户端X回复响应,响应内容包括:STUN服务器观察到的客户端内网Endpoint(X,x)经NAT映射后的外网Endpoint(M1,m1),以及STUN服务器的另外一个外网Endpoint(B,b)。客户端X收到响应报文后进行如下判断:
如果Endpoint(X,x)=Endpoint(M1,m1),则认为自己没有经过NAT转换,NAT类型检测结束。
如果Endpoint(X,x)!=Endpoint(M1,m1),则认为自己经过NAT转换,继续进行第二步测试。
- 客户端X以Endpoint(X,x)给STUN服务器的外网Endpoint(B,a)发送一个绑定请求,此时Endpoint(B,a)相对于步骤1改变了外网的IP地址。STUN服务器使用Endpoint(B,a)给客户端X回复响应,响应内容包括:STUN服务器观察到的客户端内网Endpoint(X,x)经NAT映射后的外网Endpoint(M2,m2)。客户端X收到响应报文后进行如下判断:
如果Endpoint(M1,m1)=Endpoint(M2,m2),则认为是EIM映射。因为相同的内网Endpoint(X,x)经过EIM映射后的Endpoint(M,m)是相同的。
如果Endpoint(M1,m1)!=Endpoint(M2,m2),则进行第三步测试。
- 客户端X以Endpoint(X,x)给STUN服务器的外网Endpoint(B,b)发送一个绑定请求,此时Endpoint(B,b)相对于步骤2改变了端口号。STUN服务器使用Endpoint(B,b)给客户端X回复响应,响应内容包括:STUN服务器观察到的客户端内网Endpoint(X,x)经NAT映射后的外网Endpoint(M3,m3)。客户端X收到响应报文后进行如下判断:
如果Endpoint(M2,m2)=Endpoint(M3,m3),则认为是ADM映射。因为只要目的主机IP地址相同,不管端口号是什么,相同的内网Endpoint(X,x)经过ADM映射后的Endpoint(M,m)是相同的。
如果Endpoint(M2,m2)!=Endpoint(M3,m3),则认为是APDM映射。因为只有目的主机IP地址和端口号都相同,相同的内网Endpoint(X,x)经过APDM映射后的Endpoint(M,m)才相同。
NAT过滤类型检测
- 客户端X以Endpoint(X,x)给STUN服务器的外网Endpoint(A,a)发送一个绑定请求,请求中携带CHANGE-REQUEST Attribute属性,要求STUN服务器改变IP地址和端口号来响应。STUN服务器以Endpoint(B,b)给客户端映射后的外网Endpoint(M,m)回复响应。客户端根据是否能收到响应报文,进行如下判断:
如果客户端收到响应报文,则认为是EIF过滤。因为只要是给客户端映射后的Endpoint(M,m)发送的报文都能到达客户端,不管来源是什么。
如果客户端收不到响应报文,则进行第二步测试。
- 客户端X以Endpoint(X,x)给STUN服务器的外网Endpoint(A,a)发送一个绑定请求,请求中携带CHANGE-REQUEST Attribute属性,要求STUN服务器改变端口号来响应。STUN服务器以Endpoint(A,b)给客户端映射后的外网Endpoint(M,m)回复响应。客户端根据是否能收到响应报文,进行如下判断:
如果客户端收到响应报文,则认为是ADF过滤。因为只要客户端Endpoint(X,x)之前给IP地址为A的主机发送过报文,那么,IP地址为A的主机以任何端口给客户端映射后的Endpoint(M,m)发送的报文都能达客户端。
如果客户端收不到响应,则认为是APDF过滤。因为只有客户端Endpoint(X,x)之前给IP地址为A,端口为a的主机发送过报文,那么,也只有IP地址为A,端口为a的主机给客户端映射后的Endpoint(M,m)发送的报文才能到达客户端。
STUN报文结构
报文头
STUN报文头长度为20字节,后面紧跟0或多个属性。如图5-16所示,STUN报文头包含STUN Message Type、Message Length、Magic Cookie和Transaction ID四个字段。
每个STUN报文的最高2位必须为0,这可以在当STUN和其它协议使用同一个端口时,用来区分STUN和其它协议报文。
STUN Message Type
STUN报文类型,长度为14位,目前仅支持STUN绑定请求报文和STUN绑定响应报文,其取值分别为0x0001、0x0101。
Message Length
STUN报文长度,长度为16位,不包括报文头长度。
Magic Cookie
魔术字,长度为32位。其包含固定的值0x2112A442,可以用于STUN服务器判断STUN客户端是否能识别特定的属性,还可以用于STUN与其它协议使用相同端口时区分STUN和其它协议报文。
Transaction ID
事物ID,长度为96位,用于唯一标识STUN事务。对于请求/响应事务,事务ID由STUN客户端来选择,STUN服务器收到后以同样的事务ID返回响应报文,同时,STUN服务器根据事物ID来唯一标识客户端的每一个事务。
报文属性
在STUN报文头之后,后面紧跟0或多个属性,每个属性都采用TLV(Type-Length-Value)格式。其中Type和Length字段长度都是16位,Value字段长度可变。其报文属性结构如图5-17所示。
目前支持的报文属性类型如表5-2所示。
属性类型(Type) | 取值 | 描述 |
---|---|---|
MAPPED-ADDRESS | 0x0001 | 客户端NAT映射后的IP地址和端口。这个属性用于服务器向后兼容RFC3489的客户端。 |
XOR-MAPPED-ADDRESS | 0x0020 | 客户端NAT映射后的IP地址和端口,与MAPPED-ADDRESS作用相同。不同点是IP地址经过了异或(XOR)处理。 |
RESPONSE-ORIGIN | 0x802b | 服务器使用的IP地址和端口,可以用于判断服务器前是否存在NAT设备。 |
SOFTWARE | 0x8022 | 软件版本信息。 |
PATHSET | 0xb001 | 华为扩展属性,用来唯一标识一个EVPN隧道。 |
STUN工作机制
STUN报文交互过程,如图5-18所示。
- STUN客户端向STUN服务器发送STUN绑定请求报文(Binding Request)。
- STUN服务器收到STUN绑定请求报文后,获取该报文中的源IP地址和源端口;并构建STUN绑定响应报文(Binding Response)发送给客户端,报文中携带MAPPED-ADDRESS、XOR-MAPPED-ADDRESS、RESPONSE-ORIGIN属性。
- STUN客户端收到STUN绑定响应报文后,根据该报文中的MAPPED-ADDRESS或XOR-MAPPED-ADDRESS属性,获取IP地址和端口,与之前发送的STUN绑定请求报文中的源IP地址和源端口比较,如果不一致,则STUN客户端前面存在NAT设备。
- STUN客户端之间通过BGP学习对端的NAT信息(NAT前的IP地址和端口、NAT后的IP地址和端口)。
- Client1使用本端NAT前的IP地址和端口与Client2 NAT前的IP地址和端口,构建STUN绑定请求报文发送给Client2;同时Client1使用本端NAT前的IP地址和端口与Client2 NAT后的IP地址和端口,构建STUN绑定请求报文发送给Client2。Client2也同样进行相应的操作。
- Client2收到STUN绑定请求报文后,向Client1发送STUN绑定响应报文。Client1也同样进行相应的操作。
完成以上报文交互后,STUN客户端之间成功建立可NAT穿越的数据通道。
STUN报文中DSCP值为48。