NAT穿之TCP

STUN#1 :双方发送SYN握手请求(低TTL),此请求通过已方NAT后即被丢弃,双方将自己的SYN握手请求的序号(通过侦听经过RAW-socket或PCAP向外发送的SYN,终端可以得知初始TCP的序号)发给服务器,服务器各伪造一个ACK发给另一端,做为SYN的回应,然后其它ACK继续按照正常方式穿过网络。
这种方法有四个潜在的问题:第一,它需要终端确定一个TTL,该TTL足够大,大到可以穿透自己的NAT,但又要足够小,小到不能到达对方的NAT;第二,作为SYN包的回应,比TTL优先的ICMP错误是可能产生的,而且,也可能被NAT认为是致命的错误;第三,NAT可能改变初始SYN的TCP序号,这样就可能导致基于原始序号的欺骗SYNACK到达NAT时,被当作窗口之外的包;第四,它需要一个第三方为一个任意地址产生一个欺骗包,而该欺骗包很可能被网络中各种各样的进出过滤器丢弃。

STUN#2 : 只有一端发送SYN握手请求(低TTL)并且取消连接,此请求通过已方NAT后即被丢弃。并在相同的地址和端口创建一个被动的TCP套接字。然后,另一个终端初始化一个正常的TCP连接。
与STUN#1一样,终端需要挑选一个恰当的TTL,而且NAT也不能把ICMP错误当作致命错误。它也需要NAT在一个向外发的SYN后,接收一个向内发的SYN,但包的序号也不是普通的那种。

NATBlaster : 与第一种STUN方法类似但取消了IP欺骗需要的方法。每个终端发出一个低TTL的SYN,并记住协议栈所使用的TCP序号。与前面的类似,SYN包在网络中被丢弃。两台主机之间交换各自的序号,并且每台主机手工产生一个对方期望收到的SYNACK包。手工产生的包通过RAW socket注入网络。然而,这并不等同于欺骗,因为该包中的源地址与注入该包的终端地址匹配。一旦收到SYNACK,ACK就被交换了,从而完成了连接建立。与第一种STUNT方法一样,该方法也需要终端准确地选择TTL值,也需要NAT忽略ICMP错误和NAT改变SYN包序号的失败。而且,(该方法)也需要NAT允许一个外发的SYN之后紧跟一个外发的SYNACK——非正常的另一个序号的包。

P2PNAT :利用了TCP规范[13]中定义的同时打开方案,两个终端都通过发送SYN包来创建一个连接。如果SYN包在网络中交叉(穿过),这两个终端协议栈都用SYNACK包应答从而建立连接。如果在对方的SYN包离开它的NAT之前,一个终端的SYN包到达该终端的NAT而被丢弃,那么,第一个终端的协议栈会在TCP同时打开之后而结束(关闭),而另一个终端则会按照正常流程打开。接下来的情况,链路中的包看起来像第二种STUNT方法,没有底TTL,也没有相关的ICMP。然而,该方法并没有用端口预测,如果使用的话,该方法可以从中获益。与第二种STUNT方法一样,该方法需要NAT允许在一个外发的SYN之后紧跟一个内发的SYN,而且,该方法需要终端在一个循环中不停的尝试重连,直到超时。如果不是SYN包被丢弃,而是NAT返回一个TCP RST,那这种方法将陷入包泛滥的境地,直到超时。

net, P2P
P2P