1.NAT技术背景

在ipv4的协议中一共有32位用来表示ip地址,所以理论上ip地址是42亿9千万,再去除某些特殊ip无法使用,ip地址是远不足42亿,所以NAT技术是为了解决ip地址不足问题的技术,也是路由器的一个重要功能。

2.NAT工作原理

NAT维护一个地址映射表,记录内容为内网主机地址iAddr、映射地址eAddr和外网主机地址hAddr,表初始为空

内网主机主机A发送数据包给服务器A,10.0.1.10:1111 -> 203.22.22.22:6000;

NAT在映射表里没找到源地址等于10.0.1.10:1111的记录,于是新建一条记录1,分配外网端口2000

NAT修改数据包的源地址再发到外网,202.11.11.11:2000 -> 203.22.22.22:6000;

后续所有源地址为10.0.1.10:1111,目标地址为203.22.22.22:6000都做同样的修改

服务器A发送数据包回给内网主机A,203.22.22.22:6000 -> 202.11.11.11:2000

NAT发现外网地址202.11.11.11:2000映射的内网地址为10.0.1.10:1111

NAT修改数据包的目的地址再发到内网,203.22.22.22:6000 -> 10.0.1.10:1111

内网主机B和服务器B通讯的过程也类似A,只是分配的外网端口是3000

从上面NAT的工作过程可以看出,NAT通过修改数据包的源地址或目的地址来实现地址映射的。NAT修改数据包对内网主机是透明的,不需要内网主机做任何配置,方便简单。

NAT工作原理可以总结为:

只有内网主机主动向外网发送数据,外网才有可能发送数据给内网主机
内网发送到外网的数据包会被修改源地址,外网发送给内网的数据包会被修改目的地址

很显然,第1条原理保护了内网主机免受外网的攻击,但却违背了网络端到端的设计原则。如果两台主机在不同的NAT后面,是没有办法穿越NAT直接端到(P2P))通讯的。幸运的是,在大部分情况下,我们可以在服务器的协助下实现NAT穿越。

在讲NAT穿越之前,我们先来分析NAT的类型。由于没有强制性的NAT标准,在实际应用中NAT有多种类型。根据内网地址到外网地址的映射是1对1,还是1对多,NAT可以分成两大类:Cone NAT(锥型)和Symmetric NAT(对称型)

NAT维护一个地址映射表,记录内容为内网主机地址iAddr、映射地址eAddr和外网主机地址hAddr,表初始为空

从图中的淡紫色形状应该可以看出来它们名字的来历(呕心沥血独家原创图)。锥型NAT把一个内网地址固定的转换成一个外网地址,即1对1映射;对称型NAT的一个内网地址可以转换成多个外网地址,即1对多映射。从锥型NAT和对称型NAT的定义我们可以推测出他们的映射表内容。

锥型映射表应该是这样的:
  

NAT维护一个地址映射表,记录内容为内网主机地址iAddr、映射地址eAddr和外网主机地址hAddr,表初始为空

对称型映射表应该是这样的:

NAT维护一个地址映射表,记录内容为内网主机地址iAddr、映射地址eAddr和外网主机地址hAddr,表初始为空

Cone NAT子类型

锥型NAT还可以再继续细分类型。外网主机发送给内网主机的数据包在通过NAT时,NAT会根据映射表的外网主机地址限制条件来允许或限制数据包通过。根据这个限制条件,锥型NAT还可以分成三种子类型:

Full-cone NAT,全锥型

一旦某内网地址向外网发送过数据包,NAT允许任意外网地址发送数据给此内网地址。

(Address)-restricted-cone NAT,(地址)限制锥型

一旦某内网地址向某外网主机发送过数据包,NAT允许此外网主机发送数据给此内网地址。换句话说,只限制ip,不限制端口。

Port-restricted cone NAT,端口限制锥型

只有从内网地址发送过的外网地址,NAT才允许此外网地址发送数据给此内网地址。换句话说,同时限制ip和端口。

穿越NAT

通过上面对NAT的分析可以看出,在不同NAT后面的两个客户端A和B,如果知道对方的NAT映射后的外网地址,就有可能直接发送UDP包给对方外网地址进行通讯。但是这里有一个问题,客户端不能直接获取自身的NAT外网地址,解决的办法就是引入一个服务器S来协助客户端获取自身的外网地址。NAT的类型有多种,类型两两组合有很多种,不是每种组合都可以被穿越的,我们来分析两个典型的组合。

锥型 vs 锥型

NAT维护一个地址映射表,记录内容为内网主机地址iAddr、映射地址eAddr和外网主机地址hAddr,表初始为空

A发送数据包给S询问自身地址,S把A的外网地址eA返回给A

B发送数据包给S询问自身地址,S把B的外网地址eB返回给B

S把B的外网地址eB发送给A

S把A的外网地址eA发送给B

A发送数据包给eB,B发送数据包给eA,建立P2P通道

端口限制锥型 vs 对称型

NAT维护一个地址映射表,记录内容为内网主机地址iAddr、映射地址eAddr和外网主机地址hAddr,表初始为空

A发送数据包给S询问自身地址,S把A的外网地址eA返回给A

B发送数据包给S询问自身地址,S把B的外网地址eB1返回给B

S把B的外网地址eB1发送给A

S把A的外网地址eA发送给B

A发送数据包给eB1,因为eB1只接受来自S的数据,所以A的数据被NATB丢弃

B通过发送数据包给eA,因为eA是新的目标地址,NATB 创建新的映射地址eB2,而eA只接受来自S和eB1的数据,所以B的数据被NATA丢弃,无法建立P2P通道

这里就不一一分析其他组合,各位看官可以自行分析,这里直接给出结论:
  

NAT维护一个地址映射表,记录内容为内网主机地址iAddr、映射地址eAddr和外网主机地址hAddr,表初始为空

现实中的NAT

在穿越NAT的结论里,只有两种组合不能穿越,即对称型vs对称型、端口限制锥型vs对称型,占比并不高,看起来结论还不错。但是,理论是美好的,现实是残酷的,生活中对称型NAT的数量并不少。只要是大型组织的网络,一般都采用对称型NAT,因为这类NAT安全性最好。我们团队曾经对常用的网络做过调查研究,以下是调研结果:

有公网IP的宽带:比如联通的ADSL,这类宽带会给每个用户分配一个公网IP,所以其NAT类型取决于用户所选用的路由器,大部分家用路由器都是端口限制锥型NAT;

无公网IP的宽带:比如宽带通,这类宽带给用户分配的是局域网IP,连接公网的NAT是运营商的,一般都是对称型NAT;

移动互联网:跟“无公网IP的宽带”类似,分配给手机的是局域网IP,出口基本都是对称型NAT;

大公司路由器:大部分都把路由器配置成对称型NAT;

比较可惜的是移动互联网也是对称型NAT,也就是说,如果通讯双方都走3G或4G的话,是很难直接P2P通讯的。我们的产品可以穿越部分对称型NAT,当碰到无法穿越的NAT时,为用户提供relay服务,保证接通率。

奇葩的NAT

我们现在知道NAT分为1种对称型和3种锥型,那还有没有其他类型的NAT呢?答案是YES。这个NAT各位看官应该并不陌生,它就是大名鼎鼎的netfilter/iptables。大家接触最多的iptables,是运行在ring3层用户态的配置程序,而运行在ring0内核态的netfilter才是真正实现NAT功能的程序。在大部分情况下,netfilter表现出来的是人见人爱的锥型NAT,但是在某种条件刺激下,它就华丽丽地变身成高贵冷漠的对称型NAT!

先上图:
  

NAT维护一个地址映射表,记录内容为内网主机地址iAddr、映射地址eAddr和外网主机地址hAddr,表初始为空

在穿越时,假如右边B发给A的包比左边A发给B的包先到达netfilter,netfilter会用之前的映射地址eB把B的包发出去,这时候netfilter表现出来的是锥型NAT,穿越成功。反过来,假如A发给B的包先到达netfilter,那么B发给A的包就会被netfilter映射成新的地址eB",这时候netfilter表现出来的是对称型NAT,导致穿越失败。见下图。

NAT维护一个地址映射表,记录内容为内网主机地址iAddr、映射地址eAddr和外网主机地址hAddr,表初始为空

netfilter不分内网和外网,它会跟踪内网和外网所有协议的连接(conntrack),包括tcp和udp。当外网的数据先到达netfilter时,netfilter创建一条conntrack,内网的数据后到达netfilter,netfilter发现conntrack1已经占用了端口,就会选择另外一个外网端口作为映射端口。看官如果想了解详细情况,请阅读博大精深的netfilter源码,这里提示一下,看get_unique_tuple函数就可以了。虽然netfilter很奇葩,但我们的产品依然能够轻松的穿越它。

网络基础---NAT穿越技术相关推荐

  1. 5.网络基础-NAT技术

    NAT概述 随着接入Internet的计算机数量的不断猛增,早期网络通信协议和标准的组织已经意识到了IPv4地址马上被耗尽的危机,因此制定了短期措施,其中就包含NAT. NAT(Network Add ...

  2. NAT 穿越技术(一)

    转自:https://g.hacking8.com/urlsa=t&rct=j&q=&esrc=s&source=web&cd=4&cad=rja&am ...

  3. SIP协议的NAT穿越技术

    作者: Diana Cionoiu 原文: http://freshmeat.net/articles/view/2079/ 翻译:Karl Ma NAT 指的是网络地址转换(Netword Addr ...

  4. WebRTC -- P2P及NAT穿越技术介绍

    一. P2P(peer to peer) P2P是一个"点对点传输技术",也就是2台计算机之间不需要第三台机器作为服务端就能实现数据的传输.每台计算机即是客户端又是服务端.如果每台 ...

  5. P2P技术详解(三):P2P中的NAT穿越(打洞)方案详解(进阶分析篇)

    目录 1.NAT和NAPT 2.NAT带来的问题 3.P2P通信穿越NAT的技术.方法 4.NAT穿越技术1:应用层网关 4.1.原理 4.2.限制 5.NAT穿越技术2:中间件技术 5.1.原理 5 ...

  6. 环信即时通讯云技术博客——P2P实时音视频之NAT穿越

    在P2P实时音视频领域,NAT穿越是一个非常重要的技术.NAT穿越技术使得客户端和客户端直接进行通讯,从而减少了端到端的延迟,并大大减轻了服务器的压力,降低成本. NAT是什么 NAT的全称Netwo ...

  7. p2p网络中的NAT穿透技术----常见NAT穿越解决方案

    p2p网络中的NAT穿透技术----常见NAT穿越解决方案 常见NA丁穿越解决方案 NAT技术在缓解IPv4地址紧缺问题.构建防火墙.保证网络安全等方面都发挥了重要 作用.然而,NAT设备的广一泛存在 ...

  8. P2P网络穿越 NAT穿越

    http://blog.csdn.net/mazidao2008/article/details/4933730 ------------------------------------------- ...

  9. P2P技术详解(二):P2P中的NAT穿越(打洞)方案详解

    目录 1.内容概述 2.反向链接技术:一种特殊的P2P场景(通信双方中只有一方位于NAT设备之后) 3.基于UDP协议的P2P打洞技术详解 3.1.原理概述 3.2.典型P2P情景1: 两客户端位于同 ...

  10. 视频监控p2p android,网络视频监控P2P解决方案:NAT穿越

    NAT的穿越并非安防监控领域的技术,是目前VOIP以及即时通信等产品的基础性技术,目前来讲已经比较成熟,且有完整的技术标准RFC,同时也有众多的实现方案,包括许多已经得到广泛应用的开源项目. 简单来讲 ...

最新文章

  1. 理解Promise (4)
  2. ICC_lab总结——ICC_lab2:设计规划
  3. STM8单片机串口发送引脚和接收引脚分开使用
  4. python离线录音转文字_python3实现语音转文字(语音识别)和文字转语音(语音合成)...
  5. 利用iMazing将iOS设备的录音文件拷贝到电脑
  6. 三维医学图像数据标注 3D Slicer
  7. linux网络端口失效( Device eth0 does not seem to be present,delaying initialization)解决方法
  8. Win10系统下安装CAD2006与CASS
  9. Java实现读Chuck数据
  10. flv.js播放报错
  11. 结庐在人境,而无车马喧
  12. 为提高 SDLC 安全,GitHub 发布新功能|GitHub Universe 2022
  13. Primitives vs Objects
  14. 哪个CMS建站系统更利于seo优化
  15. RT-AC87U华硕路由器外网登陆
  16. 各种矩阵(向量)求导
  17. 学习Python的建议
  18. oracle区块链开源项目,区块链Oracle原理及实现
  19. 自制天平一架自制饮料
  20. 2019天池大数据-全球城市计算AI挑战赛经验分享

热门文章

  1. Mac电脑Android模拟器连不上网,mac 解决安卓模拟器链接不上网络
  2. 如何在 CSS 中将表格居中?
  3. 针对宝塔面板一个站点多个域名使用SSL证书的解决方案
  4. java文档生成器_最好用的数据库文档生成工具
  5. 开机黑屏显示html,开机黑屏显示“This Product is covered by”解决方法
  6. FOI 2019 游记
  7. .netcore获取微信openid与unionid方法
  8. mysql 数据库update_[数据库]MySQL 常用的UPDATE操作
  9. 电脑显示RPC服务器不可用是什么意思,rpc服务器不可用怎么办?rpc服务器不可用是什么意思...
  10. 关于Pycharm进行pytorch分布式训练代码