`

NAT穿透 (和UDP打洞实验)【维基】

 
阅读更多

一、NAT穿透

(重定向自NAT穿越

       在计算机科学中,NAT穿越(NAT traversal)涉及TCP/IP网络中的一个常见问题,即在处于使用了NAT设备的私有TCP/IP网络中的主机之间建立连接的问题。

       会遇到这个问题的通常是那些客户端网络交互应用程序的开发人员,尤其是在对等网络VoIP领域中。IPsec VPN客户普遍使用NAT-T来达到使ESP包通过NAT的目的。

       尽管有许多穿越NAT的技术,但没有一项是完美的,这是因为NAT的行为是非标准化的。这些技术中的大多数都要求有一个公共服务器,而且这个服务器 使用的是一个众所周知的、从全球任何地方都能访问得到的IP地址。一些方法仅在建立连接时需要使用这个服务器,而其它的方法则通过这个服务器中继所有的数 据——这就引入了带宽开销的问题。

       两种常用的NAT穿越技术是:UDP打洞STUN。除此之外,还有TURN, ICE, ALG,以及SBC

NAT traversal 与 IPsec

       为了实现IPsec应用于NAT之上, 下列的协议必须实作于 firewall:

  • Internet Key Exchange (IKE) - User Datagram Protocol (UDP) port 500
  • Encapsulating Security Payload (ESP) - IP protocol number 50

       或者是 NAT-T 之例:

  • IPsec NAT-T - UDP port 4500

       在家庭路由器上,这通常通过启用"IPsec穿透"来实现。

IETF 文献

  • RFC 1579 - Firewall Friendly FTP
  • RFC 2663 - IP Network Address Translator (NAT) Terminology and Considerations
  • RFC 2709 - Security Model with Tunnel-mode IPsec for NAT Domains
  • RFC 2993 - Architectural Implications of NAT
  • RFC 3022 - Traditional IP Network Address Translator (Traditional NAT)
  • RFC 3027 - Protocol Complications with the IP Network Address Translator (NAT)
  • RFC 3235 - Network Address Translator (NAT)-Friendly Application Design Guidelines
  • RFC 3715 - IPsec-Network Address Translation (NAT) Compatibility
  • RFC 3947 - Negotiation of NAT-Traversal in the IKE
  • RFC 5128 - State of Peer-to-Peer (P2P) Communication across Network Address Translators (NATs)

相关技术

NAT 穿透技术与 NAT 行为

NAT 穿透基于 NAT 控制

NAT 穿透整合技术

University research papers

外部链接

 

二、UDP打洞

       在计算机科学中,UDP打洞指的是一种普遍使用的NAT穿越技术。

描述

       通过UDP打洞实现NAT穿越是一种在处于使用了NAT的私有网络中的Internet主机之间建立双向UDP连接的方法。由于NAT的行为是非标准化的,因此它并不能应用于所有类型的NAT。

       其基本思想是这样的:让位于NAT后的两台主机都与处于公共地址空间的、众所周知的第三台服务器相连,然后,一旦NAT设备建立好UDP状态信息就转为直接通信,并寄希望于NAT设备会在分组其实是从另外一个主机传送过来的情况下仍然保持当前状态。

       这项技术需要一个圆锥型NAT设备才能够正常工作。对称型NAT不能使用这项技术。

       这项技术在P2P软件和VoIP电话领域被广泛采用。它是Skype用以绕过防火墙和NAT设备的技术之一。

       相同的技术有时还被用于TCP连接——尽管远没有UDP成功。

算法

       假设有两台分别处于各自的私有网络中的主机:A和B;N1和N2是两个网络的NAT设备,分别拥有IP地址P1和P2;S是一个使用了一个众所周知的、从全球任何地方都能访问得到的IP地址的公共服务器

       步骤一:A和B分别和S建立UDP连接;NAT设备N1和N2创建UDP转换状态并分配临时的外部端口号

       步骤二:S检查UDP包,看A和B的端口是否是正在被使用的(否则的话N1和N2应该是应用了端口随机分配,这会让打洞变得更麻烦)

       步骤三:如果端口不是随机化的,那么A和B各自选择端口X和Y,并告知S。S会让A发送UDP包到P2:Y,让B发送UDP包到P1:X

       步骤四:A和B通过转换好的IP地址和端口直接联系到对方的NAT设备;

 

UDP打洞实验

       两台没有外网 IP、在 NAT 后边的主机如何直连?UDP打洞通常可行,但是需要第三方服务器。方法如下:
       在服务器 S 上监听一个 UDP 端口,在收到 UDP 数据包后把源地址发回去。代码如下(github):

import sys
import time
import socket
 
def main(port):
  s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
  s.bind(('', port))
  try:
    while True:
      data, addr = s.recvfrom(4096)
      back = 'Your address is %r\n' % (addr,)
      s.sendto(back.encode(), addr)
      print(time.strftime('%Y-%m-%d %H:%M:%S'), addr, 'just sent us a message:', data.decode('utf-8', 'replace'), end='')
  except KeyboardInterrupt:
    print()
 
if __name__ == '__main__':
  try:
    main(int(sys.argv[1]))
  except (ValueError, IndexError):
    sys.exit('which port to listen?')

        主机 A 发送数据包:

$ socat readline udp:xmpp.vim-cn.com:2727,sourceport=4567
my addr?
Your address is ('a.b.c.d', 40060)

       输入任意消息并回车,一个 UDP 就从本地的 4567 发送出去了。从上述示例我们可以看到,NAT 设备转发时是从 40060 端口发送出去的。为了让服务器返回的数据能够到达内网主机,在一段时间内,NAT 设备会记住外网来自 40060 端口的 UDP 数据包要发送给主机 a.b.c.d 的 4567 端口。完全圆锥型NAT不会在意外部数据包是从什么地方发回来的。受限圆锥型NAT会忽略掉其它主机的数据包,上例中只认可来自 xmpp.vim-cn.com 的数据包。端口受限圆锥型NAT更进一步地要求源端口(上例中是 2727)必须跟之前发出的数据包的目的端口一致。当然,「之前发出的数据包」不必是最后一个。所以,除了最后一种——对称NAT——之外,其它类型的NAT都是有可能成功穿透的。参见维基百科条目网络地址转换STUN

       后来通过 pystun 程序,我得知我所处的 NAT 是完全圆锥型的。

       在知道 A 的发送地址后,主机 B 就可以向这个地址发送数据了。接下来的操作使用 socat 命令就是:

 

# host A
$ socat readline udp-listen:4567
# host B
$ socat readline udp:A:4567

       然后 B 先发送数据让 A 知道 B 的地址(socat 会 connect 到这个地址),双方就可以相互通信了。当然,因为是 UDP 协议,所以通信是不可靠的,丢包啊乱序啊都有可能

 

 

参考文献:

udp打洞实验         http://lilydjwg.is-programmer.com/2012/8/28/udp-hole-punching-experiment.35350.html

 

 

分享到:
评论

相关推荐

    UDP穿越NAT,UDP打洞

    ### UDP穿越NAT与UDP打洞技术解析及C#实现 ...综上所述,UDP穿越NAT和UDP打洞技术为解决跨NAT环境下的UDP通信提供了有效方案。通过对上述原理和技术的深入理解与实践,可以有效地解决实际网络环境中遇到的各种问题。

    UDP打洞原理,Delphi演示

    UDP打洞是一种网络技术,主要用于穿透NAT(网络地址转换)网络,使位于不同NAT后的设备能够直接通信。在互联网环境中,许多设备都通过NAT连接,这使得它们拥有私有IP地址,无法直接相互连接。UDP打洞解决了这个问题...

    udp.zip_ICE NAT_UDP nat java_nat_udp打洞_最新防火墙

    就是非常有名的“UDP打洞技术”,UDP打洞技术依赖于由公共防火墙和cone NAT,允许适当的有计划的端对端应用程序通过NAT“打洞”,即使当双方的主机都处于NAT之后。这种技术在 RFC3027的5.1节[NAT PROT] 中进行了重点...

    C# UDP穿越NAT,UDP打洞,UDP Hole Punching源代码

    C# UDP穿越NAT,UDP打洞,UDP Hole Punching源代码

    P2P之UDP打洞穿透NAT的源代码

    在NAT穿透过程中,主要有两种方法:TCP打洞和UDP打洞。TCP打洞相对复杂,因为TCP的三次握手和状态管理机制,而UDP打洞则相对简单,因为其无连接性。本项目采用的是UDP打洞,具体步骤如下: 1. **建立初始连接**:...

    UDP_MakeHole.rar_NAT 打洞_NAT 打洞udp_udp 打洞_udp打洞_透传

    udp 穿透, 传透NAT,打洞。不仅有文档的介绍,将原理介绍清楚,而且有可以直接运行的源码。学习udp打洞的好资料。

    C#UDP打洞UDP打洞C#UDP打洞UDP打洞UDP打洞UDP打洞

    以上代码仅为示例,实际的UDP打洞实现将更复杂,需要考虑各种NAT类型、错误处理和心跳机制。在实际项目中,可以使用现成的库如libnatpunch或P2PNet来简化这一过程。 总之,UDP打洞是解决NAT环境下设备间直接通信的...

    java udp p2p nat 等打洞技术实现通信,已测试成功

    UDP打洞技术是一种在NAT(网络地址转换)环境下实现P2P(点对点)通信的方法,尤其在处理子网间通信时非常有用。在Java中,我们可以利用其强大的网络编程API来实现这一功能。以下是对这个技术的详细解释。 ### UDP...

    P2P打洞 UDP穿墙NAT 源代码

    PeerToPeer打洞 UDP穿墙NAT c源代码

    UDP打洞demo

    UDP打洞(UDP Hole Punching)是一种通过网络地址转换(NAT)技术,使位于不同内网中的两台设备能够直接通信的技术。在通常情况下,由于NAT的存在,内部网络中的设备不能直接与外部网络中的设备通信,除非有一个固定...

    UDPNAT-UDP穿越NAT,UDP打洞,UDP

    UDP穿越NAT,UDP打洞,UDP Hole Punching 本程序分为客户端和服务端,服务端需要放在一台公用的外网服务器上,客户端运行前需要修改ip.ini文件的外网服务器信息。 Licenses /// <summary> /// 聊天消息 ///...

    UDP打洞的p2p聊天程序

    UDP打洞技术是一种在NAT(网络地址转换)环境下实现P2P(点对点)通信的方法,尤其在建立直接连接以提高传输效率和降低服务器压力方面显得尤为重要。在这个场景中,我们有一个由服务器和客户端组成的聊天程序,利用...

    UDP打洞软件

    UDP打洞的关键在于“穿透”NAT,实现这一目标通常有两种方法:被动打洞和主动打洞。被动打洞依赖于外部服务器作为中介,由其中一个内网设备(A)向服务器发送请求,服务器将这个请求转发给另一个内网设备(B),B...

    C#UDP打洞NAT

    UDP打洞是NAT穿透的一种方式,它利用UDP协议的特性,通过在客户端和服务器之间创建双向通信通道。在打洞过程中,客户端会尝试向服务器发送特殊的数据包,使服务器能够记住客户端的公网IP和端口,从而建立一个连接。...

    udp打洞源码服务端和客户端C# 实现

    UDP打洞技术是一种在NAT(网络地址转换)环境下实现两个私有网络主机之间直接通信的方法,常用于P2P应用、多人在线游戏等场景。本文将深入探讨C#实现的UDP打洞服务端和客户端的关键知识点。 1. **UDP基础**: UDP...

    UDP-NAT.rar_nat_nat udp_udp 防火墙_udp打洞_打洞

    UDP穿越防火墙的例子,有助于学习UDP打洞原理哦。

    C语言实现UDP打洞代码

    UDP打洞技术是一种在NAT(网络地址转换)环境下实现两个私有IP地址之间直接通信的方法,常用于P2P(点对点)通信。在本文中,我们将深入探讨C语言实现UDP打洞的原理、步骤以及代码实现的关键点。 首先,理解UDP打洞...

    udp 打洞示例代码 包含服务器 客户端

    UDP打洞技术是一种在NAT(网络地址转换)环境下实现两个私有网络内的主机之间直接通信的方法。在互联网上,许多设备由于连接到ISP时采用了NAT,它们的公网IP实际上是路由器分配的内部IP,因此不能直接与其他网络的...

    UDP用打洞技术穿透NAT的原理与实现

    NAT技术诞生的背景是在IPv4地址稀缺的环境下,为了解决...对于那些想要深入理解和实现UDP打洞技术的开发者来说,掌握NAT的工作原理、不同类型的NAT行为模式,以及如何在实践中结合现有技术方案,是实现穿透的关键所在。

Global site tag (gtag.js) - Google Analytics