# 【NO.151】p2p之网络穿透NAT，NAT、穿透的原理

## 1.p2p是什么？

p2p是对等网络（peer-to-peer networking）其可以定义为：端对端的资源共享，每一端即可是服务端，也可以是客户端。既可以是资源的提供者，也可以是资源的共享者。

传统C/S模型需要实现端和端的资源共享， 需要将资源上传到中转服务器。另外一端再去中转服务器下载，如下图：

![img](https://pic3.zhimg.com/80/v2-b02447c4cd4ead9cb6169e86dfff507e_720w.webp)

传统CS架构，客户端1和客户端2之间是无直接交互.png

而P2P则不需要将资源上传到服务器，它是端对端传输，每一个端既可以是服务器，也可以是客户端

![img](https://pic4.zhimg.com/80/v2-8b4235fc0df3291ebf4bc91396a594fb_720w.webp)

p2p架构，无需中转服务器.png

优势：实时性最高，流量少，更加安全。在视频直播，在线教育，视频安防行业用的比较多
劣势：一旦进行p2p传输之后，用户之间的内容将无法监管，浪费用户带宽，频繁进行读写磁盘

客户端1和客户端2这样交互是p2p最理想的情况
图中客户端1和客户端2直接连接， 假如他们处于两个不同的内网呢?

## 2.NAT是什么？

NAT俗称网络地址转换，它是一种把内部私有网络地址（IP地址）转换成公网网络IP地址的技术。比如我们电脑里面网卡地址是192.168.1.100，但是我们再百度搜索“IP”却显示220.112.224.53，这就是NAT的功能。
**NAT主要是部署在路由器或者交换机上。**

## 3.为什么需要NAT？

主要还是IP地址的不足，使用少量的公有IP 地址代表较多的私有IP 地址的方式，将有助于减缓可用的IP地址空间的枯竭。用大白话：比如你有一个路由器（家用的那种就可以）这个路由器本身连接了公网（被分配到了一个公网的IP地址）。路由器后面有接了N多个设备，每个设备都分配到了一个私有的地址（内网地址），这些地址可以通过这个路由器和外网交互。

其次能够有效地避免来自网络外部的攻击，隐藏并保护网络内部的计算机。
RFC3489 中将 NAT 的实现分为四大类：

- Full Cone NAT(完全圆锥型)
- Address Restricted Cone NAT(地址限制圆锥型 )
- Port Restricted Cone NAT(端口限制圆锥型)
- Symmetric NAT(对称型)

## 4.完全圆锥型NAT

在完全圆锥型NAT（Full Cone NAT）中，NAT会将客户机地址{X:y}转换成公网地址{A:b}并绑定。任何包都可以通过地址{A:b}送到客户主机的{X:y}地址上。如图所示：

![img](https://pic3.zhimg.com/80/v2-b84f4a39e311e786608cf01f7d62cf62_720w.webp)

RFC3581——完全锥型NAT

## 5. 地址限制圆锥型NAT

地址限制圆锥型NAT（Address Restricted Cone NAT）会将客户机地址{X:y}转换成公网地址{A:b}并绑定，只有来自主机{P}的包才能和主机{X:y}通信。如下图所示：

![img](https://pic4.zhimg.com/80/v2-a329e90e007c0a1ce406349b47819c93_720w.webp)

RFC3581——地址限制型NAT

## 6.端口限制圆锥型NAT

端口限制圆锥型NAT(Port Restricted Cone NAT)会将客户机地址{X:y}转换成公网地址{A:b}并绑定，只有来自主机{P,q}的包才能和主机{X:y}通信。如下图所示：

![img](https://pic1.zhimg.com/80/v2-baaea3df8eccf4422cd8c688889e4d04_720w.webp)

RFC3581——端口限制型NAT

## 7.对称型NAT

对称型NAT（Symmetric NAT）会将客户机地址{X:y}转换成公网地址{A:b}并绑定为{X:y}|{A:b}<->{P:q}。对称型NAT只接受来自{P:q}的连接，将它转给{X:y} ，每次客户机请求一个不同的公网地址和端口，NAT会新分配一个端口号{C,d} 。如下图所示：

![img](https://pic4.zhimg.com/80/v2-beb4537f62e9b1897b1ccee19e945747_720w.webp)

RFC3581——对称型NAT

**其中完全最上层的完全圆锥形NAT的穿透性最好，而最下层的对称形NAT的安全性最高。**

## 8.如何穿透NAT？

事实上两个客户端相互通信还需要一个辅助服务器(p2pserver) 来保存两个用户的外网地址端口。
当用户A连接B时、或者B连接A时， 会向辅助服务器询问对方的外网地址和端口

![img](https://pic3.zhimg.com/80/v2-00c8c5a560148ae21565b5f8ee1dc5aa_720w.webp)

NAT穿透组合情况.png

从上面的NAT类型中可以看出，有4种NAT，一共10种组合

**1. 完全圆锥型NAT和完全圆锥型NAT**
这种最简单， 只需要B从辅助服务器拿到A的内外网信息， 就可以和A进行连接
**2. 完全圆锥型NAT和地址限制型NAT**
同上
**3. 完全圆锥型NAT和端口限制性NAT**
同上
**4. 完全圆锥型NAT和对称型NAT**
同上
**5.地址限制型NAT和地址限制型NAT**

- 当B从辅助服务器拿到A的内外网信息， B向A发送连接， 这个时候NAT A设备会丢弃掉B发送过来的连接。
- 这个时候B就向辅助服务器发送请求，让A连接B一次， 连完后B就可以连接到A了，NAT A不再拦截B过来的连接。

**6.地址限制型NAT和端口限制型NAT**
同上
**7.地址限制性NAT和对称型NAT**
同上
**8.端口限制型NAT和端口限制型NAT**
同上
**9.端口限制型NAT和对称型NAT**
这种无法穿透， 因为A需要连过B，B才能连到A，但是A无法连接到B，因为B的是对称型NAT，端口一直在变
**10.对称型NAT和对称型NAT**
这种也无法穿透，因为客户机每次请求一个不同的公网地址和端口， NAT会新分配一个端口号，所以从辅助服务器拿到的端口号是无效的（只是针对和服务器相连的端口号）。
eg:A和辅助服务器相连，NAT A会分配一个端口 8081。
A和B相连， NAT A会分配一个端口号10020，所以B连A并不知道A需要从10020进，所以无法穿透过NAT A。不过也有人通过端口预测算法成功连接， 但是这种并不可靠。

![img](https://pic1.zhimg.com/80/v2-80b87d01775cd205828d9a651ab6b48c_720w.webp)

## 9.为什么需要保活链路？

因为一个连接经过NAT设备之后，在NAT设备上面绑定的端口是有时效性的，一般是30分钟，但是最少的三五分钟就失效了，所以要不停的发送心跳包来保活NAT上的这个“洞”。

## 10.移动、联通网络为什么没有电信快？

原因是电信拨号之后分配的是公网IP。而联通、移动拨号之后还是内网IP，也就是NAT设备上面还有多层NAT， 多次转发并且最终的出口只有一个，所以总体来说比较慢

原文链接：https://zhuanlan.zhihu.com/p/299524798

作者：[Hu先生的Linux](https://www.zhihu.com/people/huhu520-10)