实现NAT

NAT基本原理

NAT的基本工作原理是,当私有网主机和公共网主机通信的IP包经过NAT网关时,将IP包中的源IP或目的IP在私有IP和NAT的公共IP之间进行转换。

实现NAT

如上图所示,NAT网关有2个网络端口,其中公共网络端口的IP地址是统一分配的公共 IP,为10.0.1.11;私有网络端口的IP地址是保留地址为172.64.3.1。私有网中的主机Server1:172.64.3.21向公共网中的主机Client:10.0.1.100发送了1个IP包(Dst=10.0.1.100,Src=172.64.3.21)。

当IP包经过NAT网关时,NAT Gateway会将IP包的源IP转换为NAT Gateway的公共IP并转发到公共网,此时IP包(Dst=10.0.1.100,Src=10.0.1.11)中已经不含任何私有网IP的信息。由于IP包的源IP已经被转换成NAT Gateway的公共IP,WebServer发出的响应IP包(Dst=10.0.1.11,Src=10.0.1.100)将被发送到NAT Gateway。

这时,NATGateway会将IP包的目的IP转换成私有网中主机的IP,然后将IP包(Dst=172.64.3.21,Src=10.0.1.100)转发到私有网。对于通信双方而言,这种地址的转换过程是完全透明的。

如果内网主机发出的请求包未经过NAT,那么当Web Server收到请求包,回复的响应包中的目的地址就是私有网络IP地址,在Internet上无法正确送达,导致连接失败。

在上述过程中,NAT Gateway在收到响应包后,就需要判断将数据包转发给谁。此时如果子网内仅有少量客户机,可以用静态NAT手工指定;但如果内网有多台客户机,并且各自访问不同网站,这时候就需要连接跟踪(connectiontrack)。

在NATGateway收到客户机发来的请求包后,做源地址转换,并且将该连接记录保存下来,当NAT Gateway收到服务器来的响应包后,查找Track Table,确定转发目标,做目的地址转换,转发给客户机。

以上述客户机访问服务器为例,当仅有一台客户机访问服务器时,NAT Gateway只须更改数据包的源IP或目的IP即可正常通讯。但是如果Client A和Client B同时访问Web Server,那么当NAT Gateway收到响应包的时候,就无法判断将数据包转发给哪台客户机。此时,NATGateway会在Connection Track中加入端口信息加以区分。如果两客户机访问同一服务器的源端口不同,那么在Track Table里加入端口信息即可区分,如果源端口正好相同,那么在实行SNAT和DNAT的同时对源端口也要做相应的转换。

实现NAT

1.从网站下载代码

> cd ~

> git clonehttps://[email protected]/huangty/cs144_lab5.git

> cd cs144_lab5

> git checkout --trackremotes/origin/standalone

将cs144_lab5中的route删除(代码删不掉,就手动删除),然后将cs144_lab3中的route拷贝到route中,并将sr_nat_table.tar解压,sr_nat.c、sr_nat.h和rtable拷贝到cs144_lab5中。


实现NAT

实现NAT

2.配置环境

> ./config.sh

此时又会有一些包没找到,需要手动安装。sudo pipinstall XXX对应包安装即可。

实现NAT

实现NAT

实现NAT

3. 更改lab5.py

由于是python2.7,所以要对该文件部分进行更改,否则会有如下报错现象:

实现NAT

将lab5.py中的add_host改为addHost, add_switch改为addSwitch, add_list改为addList,即可。

4.> ./run_mininet.sh

实现NAT

实现NAT

5.运行pox

> ./run_pox.sh

实现NAT

6.开启NAT

> ./sr_nat -n

实现NAT

如图,显示了目的地址,网关,掩码和接口,为了仔细观察NAT如何进行的转换,进行如下操作:

mininet> xterm server1

然后在开启的server1终端进行:> tcpdump -n -i server1-eth0

然后用client ping Server1:mininet> client ping -c 3 172.64.3.21

实现NAT

可以观察到,三个包都已成功接收。

实现NAT

注意到,Server1接收的包来自网关172.64.3.1而不是10.0.1.100这个是NAT的外部接口IP,对比上一个实现简单路由器的实验,那个实验的IP传送是直接的Client和Server1两个IP。

接收到的包的信息如下:

可以看到,首先受到ARP Request,然后回复ARP Reply,然后使用NAT开始复写ICMP和IP后继续发送ARP Request当收到回复后开始发送数据包。

实现NAT

让我们关闭这个NAT,运行如下命令:
> ./sr_nat

重复上述操作,可以看到:

实现NAT

此时IP地址即为Client和Server1的IP,而非NAT转换后Server1和网关的IP。接收到的数据包的信息也不再有[NAT]字样。只进行一次ARP Request和ARP Reply就可以发送数据包。

实现NAT

尝试如下操作:
> ./sr -s localhost -p 8888 -n -I 70 -R 40

该操作意图是开启NAT,70秒超时后进行ICMP、7440秒后至少有一个已建立连接的TCP,以及40秒后只有短暂连接的TCP。显示结果和最初开启NAT的结果一样。