NAT和NAT打洞基本原理

NAT

基本概念

NAT(Network Address Translation,网络地址转换)技术从名字看很好理解,就是对数据包的IP地址进行修改;
一个常见的网络数据从网络流量角度来看可以分为五部分:源IP、源端口、协议、目的IP、目的端口;这就是常说的五元组,如果不算协议的话就是四元组,IP通信能正常运行的关键就是这五元组。
img
由于公网IPv4地址早已经耗尽,以现在的大众上网的终端数量来看IP地址已经不够用,但现在看起来好像也没受什么影响,这个就得益于一种NAT技术--NAPT也称为PAT,即端口转换。
NAPT是一种IP地址复用技术,由于大多数网络流量都基于TCP和UDP,这种传输层协议的寻址使用端口,端口号为1~65535,端口号是充裕的,“复用IP地址”+“改写端口号”是PAT技术的理论基础。
设想两台内网电脑复用一个公网地址访问server的80端口:

PC1:IP1-port1-tcp-Server-80
PC2:IP2-port2-tcp-Server-80

由于内网地址无法在公网路由,NAT设备将内网IP转换为公网IP,并配合修改端口号以达成复用公网IP目的:

PC1:IP-portA-tcp-Server-80
PC2:IP-portB-tcp-Server-80

此时就能使用portA和B对回包数据进行区分,并分别转发给内网的PC1和PC2;
但是PAT也也引发了一些问题,PAT打破了IP地址的点对点可达性,导致处于NAT后的终端只能主动向外发起网络通信,无法由外向内主动访问。

NAPT/PAT的分类

从PAT的原理看,PAT只能在通信一端应用,双方均处于NAT后面的话无法通信;但如果再深入研究还是能发现一些解决方案。根据转换策略不同,PAT还有更细的分类,常见的分类如下图:

img

图中描述了四种分类:FullCone、Restricted、Port-Restricted、Symmetric四种;有时候也会叫做NAT1/2/3/4。

从发起方的 NAT 设备角度来看,为了不影响通信,五元组中协议目的IP目的端口肯定无法更改,能够修改的只有源IP源端口
图中分类方式基于两方面,第一.回包的安全限制;第二.转换后端口受那些因素影响;

  • NAT1/FullCone:转换端口仅和源IP及源端口有关,安全限制基本没有,只要是发往转换后IP和端口的报文均转发给内网。
  • NAT2/Restricted:转换端口仅和源IP及源端口有关,限制回包地址为发包的目的地址,回包源端口不限制。
  • NAT3/Port-Restricted:转换端口仅和源IP及源端口有关,限制回包地址为发包的目的地址,回包源端口也必须为发包的目的端口。
  • NAT4/Symmetric:转换端口与源IP、源端口、目的IP、目的端口即四元组均有关,限制回包地址为发包的目的地址,回包源端口也必须为发包的目的端口。

NAT打洞

所谓NAT打洞就是在通信双方都处于NAT后面时候,使用某种方式使得通信双方可以正常端到端通信。
基于TCP的NAT打洞基本放弃,TCP协议本是有状态的,NAT设备一般只允许outbound发起syn,所以 NAT 打洞技术基本都是基于UDP协议的。
这里先说一下结论,在仅能控制终端无法控制NAT设备,通信双方都实施PAT的情况下,能够实现UDP打洞的关键为:

任一端NAT会话中的内容可以被预测

STUN协议是一个专门用于NAT打洞的协议,但是打洞两侧的NAT类型是有要求的,如下表:

NAT1 NAT2 NAT3 NAT4
NAT1
NAT2
NAT3 ×
NAT4 × ×

这里不讨论STUN协议的细节和应用,只讨论其原理。

  • NAT1:对回包没有安全限制,所以其NAT会话中只包含转换后的源IP和源端口,且转换后端口仅和内网源IP+源端口有关;
  • NAT2:回包仅限制IP,所以其NAT会话中只包含转换后的源IP、源端口、目的IP,且转换后端口仅和内网源IP+源端口有关;
  • NAT3:回包仅限制IP和端口,所以其NAT会话中只包含转换后的源IP、源端口、目的IP、目的端口,且转换后端口仅和内网源IP+源端口有关;
  • NAT4:回包仅限制IP和端口,所以其NAT会话中只包含转换后的源IP、源端口、目的IP、目的端口,转换后端口仅和上述四元组均有关;

img
设想这样一个场景,user1和user2分别处于两个NAT后面,NAT设备出接口有一个公网地址,server为有公网地址的第三方用于预测打洞时NAT会话。

  • USER1为NAT1场景:user1 使用 addr1 和 port1 访问server,从server处获知转换后addr 和 port,user2无论是什么种类的NAT,直接访问user1 转换后的addr和port即可通信。

  • USER1为NAT2,USER2不用区分种类,user1使用addr1 和port 1访问server获取转化后地址address和端口port,user2 访问server 获取user2公网地址addr2,这时候user1再使用addr 1 port 1 访问目的地址为addr2的任意端口,创建NAT会话,然后user2再访问address/port即可完成通信。

  • 双方均为NAT3情况,user1使用addr1/port1访问server得到转换后addrA/portA,user2使用addr2/port2访问server获知转换后addrB/portB,user1和user2先后使用先前访问server的端口访问对方转换后的地址即可完成通信。

  • 其余情况由于转换后端口受影响的因素过多,导致无法准确预测,也就无法实现NAT打洞。

例子

从上得知NAT3加NAT4情况无法打洞,但是如果开一个上帝视角,从NAT设备中或者其他位置“偷窥”到NAT4转换后的端口还是可以打洞成功的。

wireguard协议是基于UDP的,正好方便演示UDP打洞,通信结果也好演示即隧道通了就可以。

下图演示设备:PC1 PC2 使用vyos,其余均为H3C VSR1000,VSR的NAT为NAT4即Symmetric模式。

配置见下面。Site1模拟NAT3,Site2为NAT4

img

#PC1-Vyos
set interfaces ethernet eth0 address '192.168.1.1/24'
set interfaces wireguard wg0 address '1.1.1.1/30'
set interfaces wireguard wg0 peer PC2 address '20.0.0.2'
set interfaces wireguard wg0 peer PC2 allowed-ips '1.1.1.2/32'
set interfaces wireguard wg0 peer PC2 persistent-keepalive '1'
set interfaces wireguard wg0 peer PC2 port 'XXXX' #此处端口为关键
set interfaces wireguard wg0 peer PC2 public-key 'eGiqJUIJ2mUcJ3KqHx3QUqzAwZQh+bJ1f2MAE5MIxQM='
set interfaces wireguard wg0 port '7777'
set interfaces wireguard wg0 private-key 'gEIzQTyKfPV7RHc0VLcMgfPhXp6jGBHwmNLwlnISFlM='
set protocols static route 0.0.0.0/0 next-hop 192.168.1.254
commit
==============
#PC2-Vyos
set interfaces ethernet eth0 address '192.168.2.1/24'
set interfaces wireguard wg0 address '1.1.1.2/30'
set interfaces wireguard wg0 peer PC1 address '10.0.0.2'
set interfaces wireguard wg0 peer PC1 allowed-ips '1.1.1.1/32'
set interfaces wireguard wg0 peer PC1 persistent-keepalive '1'
set interfaces wireguard wg0 peer PC1 port '7777' #此处端口为对端peer监听端口,可以预知
set interfaces wireguard wg0 peer PC1 public-key 'FxnXVWEqo2Glzkl252Mx2BrsEQjt7pxd/SYHeOGHMzE='
set interfaces wireguard wg0 port '8888' #此处端口随意,由于会被NAT设备转换,找出转换后端口是关键
set interfaces wireguard wg0 private-key 'CNw5iTyTQ2O9FoA/zO5wcXStIUwXNhHKxBsUdehgYXk='
set protocols static route 0.0.0.0/0 next-hop 192.168.2.254
commit
==============
#Site1-H3C VSR1000

#
acl basic 2000
 rule 10 permit
#
interface GigabitEthernet1/0
 port link-mode route
 ip address 10.0.0.2 255.255.255.0
 nat outbound 2000 port-preserved #配置端口保留,使本端转换后的端口可以预知,模拟NAT3情况
#
interface GigabitEthernet7/0
 port link-mode route
 ip address 192.168.1.254 255.255.255.0
#
 ip route-static 0.0.0.0 0 10.0.0.1
#
==============
#Site2-H3C VSR1000

interface GigabitEthernet1/0
 port link-mode route
 ip address 20.0.0.2 255.255.255.0
 nat outbound
#
interface GigabitEthernet7/0
 port link-mode route
 ip address 192.168.2.254 255.255.255.0
#
 ip route-static 0.0.0.0 0 20.0.0.1
#
==============
Internet

#
interface GigabitEthernet1/0
 port link-mode route
 ip address 10.0.0.1 255.255.255.0
#
interface GigabitEthernet2/0
 port link-mode route
 ip address 30.0.0.1 255.255.255.0
#
 ip route-static 0.0.0.0 0 30.0.0.2

==============
Internet2

interface GigabitEthernet1/0
 port link-mode route
 ip address 30.0.0.2 255.255.255.0
#
interface GigabitEthernet2/0
 port link-mode route
 ip address 20.0.0.1 255.255.255.0
#
 ip route-static 0.0.0.0 0 30.0.0.1

此时从Site2的G1/0口“偷看”到PC2转换后端口为1025,将PC1对端port改为1025(就是PC1配置中的"XXXX"),即可完成通信。
img
测试结果:

admin@PC1:~$ show int
Codes: S - State, L - Link, u - Up, D - Down, A - Admin Down
Interface        IP Address                        S/L  Description
---------        ----------                        ---  -----------
eth0             192.168.1.1/24                    u/u
eth1             -                                 u/D
eth2             -                                 u/D
lo               127.0.0.1/8                       u/u
                 ::1/128
wg0              1.1.1.1/30                        u/u

admin@PC1:~$ ping 1.1.1.2
PING 1.1.1.2 (1.1.1.2) 56(84) bytes of data.
64 bytes from 1.1.1.2: icmp_seq=1 ttl=64 time=2.90 ms
64 bytes from 1.1.1.2: icmp_seq=2 ttl=64 time=3.38 ms
64 bytes from 1.1.1.2: icmp_seq=3 ttl=64 time=3.25 ms
64 bytes from 1.1.1.2: icmp_seq=4 ttl=64 time=3.26 ms
64 bytes from 1.1.1.2: icmp_seq=5 ttl=64 time=3.28 ms
64 bytes from 1.1.1.2: icmp_seq=6 ttl=64 time=3.23 ms
^C
--- 1.1.1.2 ping statistics ---
6 packets transmitted, 6 received, 0% packet loss, time 5008ms
rtt min/avg/max/mdev = 2.904/3.216/3.378/0.147 ms

admin@PC2:~$ show int
Codes: S - State, L - Link, u - Up, D - Down, A - Admin Down
Interface        IP Address                        S/L  Description
---------        ----------                        ---  -----------
eth0             192.168.2.1/24                    u/u
eth1             -                                 u/D
eth2             -                                 u/D
lo               127.0.0.1/8                       u/u
                 ::1/128
wg0              1.1.1.2/30                        u/u
admin@PC2:~$ ping 1.1.1.1
PING 1.1.1.1 (1.1.1.1) 56(84) bytes of data.
64 bytes from 1.1.1.1: icmp_seq=1 ttl=64 time=3.13 ms
64 bytes from 1.1.1.1: icmp_seq=2 ttl=64 time=3.36 ms
64 bytes from 1.1.1.1: icmp_seq=3 ttl=64 time=2.81 ms
64 bytes from 1.1.1.1: icmp_seq=4 ttl=64 time=3.41 ms
64 bytes from 1.1.1.1: icmp_seq=5 ttl=64 time=2.94 ms
64 bytes from 1.1.1.1: icmp_seq=6 ttl=64 time=3.05 ms
64 bytes from 1.1.1.1: icmp_seq=7 ttl=64 time=3.15 ms
64 bytes from 1.1.1.1: icmp_seq=8 ttl=64 time=3.15 ms
^C
--- 1.1.1.1 ping statistics ---
8 packets transmitted, 8 received, 0% packet loss, time 7010ms
rtt min/avg/max/mdev = 2.813/3.124/3.411/0.185 ms

此时隧道已经建立,抓包来看也均为加密流量
img
两侧的NAT会话,NAT工作正常;

本实验没有什么实际意义只是为了说明NAT打洞的基本原理和必要条件。

img
img

注意事项:此实验若想做成功有一点需要注意,一开始不要让site1收到site2转换后的流量,如果Site1在PC1的NAT会话生成之前收到目的为7777的流量,nat port-preserved就失效了,变成随机端口了,Site1就不再是NAT3模式了,这里使用这个功能模拟NAT3。

posted @ 2024-04-03 15:23  bfhyqy  阅读(700)  评论(0编辑  收藏  举报