NAT 与IPSec ××× 的裂痕

 

在多数情况下NAT 的处理对用户使用是完全透明的,但是当希望使用IPSec 技术组建××× 网络时,NAT 却带来了很大的麻烦。IPSec协议的主要目标是保护IP数据包的完整性,这意味着IPSec会禁止任何对数据包的修改。但是NAT 处理过程是需要修改IP 数据包的IP 头数据、传输层报文头数据甚至传输数据的内容(如FTP 应用),才能够正常工作。所以一旦经过IPSec 处理的IP 包穿过NAT设备时,包内容被NAT 设备所改动,修改后的数据包到达目的主机后其解密或完整性认证处理就会失败,于是这个报文被认为是非法数据而被丢弃。这就是组建××× 网关最常见的“IPSec 与NAT 协调工作”的问题。那么我们在什么时候会遇到这个问题呢?如果我们的××× 设备在NAT设备的后面,如果我们在外地上网需要通过×××客户端访问公司内网,如果我们没有合法的公网地址,只能通过服务商接入Internet 等等,都会遇到这个问题。

无论传输模式还是隧道模式,AH都会认证整个数据包。不同于ESP 的是,AH还会认证位于AH头之前的IP 头。当NAT 设备修改了IP 头之后,IPSec 就会认为这是对数据包完整性的破坏,从而丢弃数据包。因此AH 是绝对不可能和NAT 在一起工作的。

我们再来看看使用ESP时的情况。ESP在传输模式时会保护TCP/UDP头,但是并不保护IP 头,因此修改IP 地址并不会破坏整个数据包的完整性。但是如果数据包是TCP/UDP数据包,NAT设备就需要修改数据包的校验值,而这个校验值是被ESP 所保护的,这样却会导致完整性校验失败。 所以最终可能和NAT一起工作的只能是隧道模式下的ESP。但是IKE和NAT工作时却有存在着冲突。

缝合旧创伤

现在有许多的解决方案来解决NAT 和IPSec 共存问题,这里我们主要讨论一种最主要的解决方法:NAT-T和NAT穿越。NAT-T设计简单,不需要改动已有的设备或者协议,只需要边界设备支持即可。这个技术的基本思路是在IPSec 封装好的数据包外再进行一次UDP 的数据封装。这样,当此数据包穿过NAT 网关时,被修改的只是最外层的IP/UDP 数据,而对其内部真正的IPSec 数据没有进行改动;在目的主机处再把外层的IP/UDP 封装去掉,就可以获得完整的IPSec 数据包。NAT-T在实际运作时,第一步是判断通信的双方是否支持NAT-T,这主要通过IKE协商时彼此发送的第一个数据包来判断。在判断双方均支持NAT-T后,进入到第二步,去发现在上方的链路中间是否存在NAT设备,这一步通常成为NAT发现。NAT发现的原理实际上就是判断通信双发的IP 地址或者端口是否发生了改变。当发现NAT 设备以后,NAT-T 双方开始协商所采用的数据包封装方式,至此完成协商过程。

当在×××之间的链路中发现NAT设备之后,除对数据包进行ESP 处理外,还需要额外的进行一些其他的处理和封装。即对IPSec 通信数据采用UDP 和IKE端口的包头进行封装,因此这种封装后的数据包实际上和正常的IKE 协商数据包有相同的包头(IP 头和UDP头),从而避免防火墙对IPSec 通信数据和IKE协商数据使用不同的安全策略。NAT-T 后数据包的封装格式如图3 所示。通过在IP 头后,ESP 包头之前插入一个UDP 包头来完成NAT-T 的UDP 封装。这样的数据包在经过NAT 设备时就会被认为是一个正常的UDP数据包,从而完成NAPT转换,数据包到达×××网关时也不会校验设备。

显然,NAT-T加大了数据包的长度和负载,大约为每个数据包增加了20B 的长度。这增加了设备处理的时间和负担。但是对应NAT-T的实现简单和安全而言,这是非常值得的,因此NAT-T实际上已成为×××设备的必备功能,由于NAT 技术在国内的广泛应用,不具备这种功能的IPSec ×××使用环境会大大受到限制,所以用户在选用××× 设备时应该将这一功能作为一个重要的考核指标。