在搭建NSX环境的过程,起先没有在Edge路由器上设置NAT,导致VM无法访问外网。经查阅资料后发现,需要配置NAT,配置完SNAT后,比较疑惑的是没有配置DNAT,响应包是怎么把数据包中目的地址修改为VM的地址呢????
抱着这个疑惑,查阅了各种资料后,大致了解其原理,下面将举例子进行介绍
例如:局域网内的A:192.168.0.2/24 B:192.168.0.3/24
路由器两块网卡:192.168.0.1/24 188.10.1.2(公网地址)
Intenet上web 服务器C: 200.10.2.1
比如A想访问C的web服务,便会发送HTTP请求,请求的源IP、源端口、目的IP和目的端口如下
源IP | 源端口 | 目的IP | 目的端口 |
192.168.0.2 | 54333 | 200.10.2.1 | 80 |
当HTTP请求达到路由器的时候,回进行SNAT转换,转换的结果如下
源IP | 源端口 | 目的IP | 目的端口 |
188.10.1.2 | 54333 | 200.10.2.1 | 80 |
这时候路由器上的NAT表回添加一行
源IP | 源端口 | 协议 | 目的IP | 目的端口 |
192.168.0.2 | 54333 | HTTP | 188.10.1.2 | 54333 |
解释一下:NAT表通常是五元组,源IP和源端口就是发送HTTP请求的IP和端口,即A的IP和端口,而目的IP和目的端口则是指转换后的IP地址和端口,即进行SNAT后的源IP和源端口。
当Web服务器C收到HTTP请求后,会发送响应报文,报文的信息如下:
源IP | 源端口 | 目的IP | 目的端口 |
200.10.2.1 | 80 | 188.10.1.2 | 54333 |
当报文到达路由器后,会参照NAT表进行DNAT,参考依据,会在NAT表中查找目的IP和目的端口为188.10.1.2和54333的一行,然后用192.168.0.2和54333替换目的IP和目的端口,替换后的报文信息如下:
源IP | 源端口 | 目的IP | 目的端口 |
200.10.2.1 | 80 | 192.168.0.2 | 54333 |
然后发往局域网内的A。通过浏览器呈现web网页。
以上就是局域网内机器访问外网的一个流程。从这个流程中可以得出,尽管只配置SNAT,但是在进行源地址和源端口转换的时候,会在路由器的NAT表中插入一行,当响应报文到达路由器的时候,参照NAT表中的信息,进行目的地址和目的端口的转换,所以在不配置DNAT的时候,目的地址和目的端口仍然可以被转换。但是这个过程,只能是局域网内的用户发起请求,响应报文的目的地址和目的端口才会被转换为局域网地址。外网的主机是不能直接访问局域网中的主机的。
当局域网中的A和B都想访问C的web服务器,这时候会怎么转换,如果A和B的源端口不同时,就直接将源IP地址转换为路由器的公网地址。如果A和B的源端口也相同,这时候就要将源端口也要替换,例如:A和B都是通过54333端口访问C的web服务。
A:
原报文
源IP | 源端口 | 目的IP | 目的端口 |
192.168.0.2 | 54333 | 200.10.2.1 | 80 |
SNAT后的报文
源IP | 源端口 | 目的IP | 目的端口 |
188.10.1.2 | 54333 | 200.10.2.1 | 80 |
NAT表
源IP | 源端口 | 协议 | 目的IP | 目的端口 |
192.168.0.2 | 54333 | HTTP | 188.10.1.2 | 54333 |
B:
原报文
源IP | 源端口 | 目的IP | 目的端口 |
192.168.0.3 | 54333 | 200.10.2.1 | 80 |
SNAT后的报文
源IP | 源端口 | 目的IP | 目的端口 |
188.10.1.2 | 54334 | 200.10.2.1 | 80 |
NAT表
源IP | 源端口 | 协议 | 目的IP | 目的端口 |
192.168.0.3 | 54333 | HTTP | 188.10.1.2 | 54334 |
这样就可以根据端口号的不同,将响应报文发送给正确的主机。
问题来了,如果A和B都想ping C,大家都知道ping是基于ICMP的,是没有端口的,那么这样是怎么来实现的呢???
没有端口,那就创造端口,首先ICMP的报文格式如下
类型(Type) | 代码(Code) | 检验和(Checksum) |
标识符(Identifier) | 序列号(Sequence number) | |
选项(Option) |
在A发送ICMP报文的时候,会根据(Type+Code)的值生成源端口号,根据Identifier的值生成目的端口号,即发送到路由器的报文如下:
源报文:
源IP | 源端口 | 目的IP | 目的端口 |
192.168.0.2 | (Type+Code) | 200.10.2.1 | Identifier |
在路由器上进行SNAT,源IP更改后ICMP报文中的Identifier会改变,记作IDENTIFIER。这时候的报文如下:
源IP | 源端口 | 目的IP | 目的端口 |
188.10.1.2 | IDENTIFIER | 200.10.2.1 | Identifier |
Nat表
源IP | 源端口 | 协议 | 目的IP | 目的端口 |
192.168.0.2 | (Type+Code) | ICMP | 188.10.1.2 | IDENTIFIER |
在web服务器C收到ICMP请求后,生成ICMP响应报文,响应报文中的(Type+Code)会作为源端口,IDENTIFIER作为目的端口
源报文
源IP | 源端口 | 目的IP | 目的端口 |
200.10.2.1 | (Type+Code) | 188.10.1.2 | IDENTIFIER |
报文到达路由器后,根据NAT表中,查询目的IP和目的端口为188.10.1.2和IDENTIFIER的信息。将目的IP和目的端口换为
192.168.0.2和(Type+Code),这样报文就可以成功的到达A了。
所以ICMP报文的NAT大致是根据ICMP报文的字段,形成伪端口,然后根据TCP报文的流程来处理。
以上是个人查阅资料后总结,有不正确的,还请指出。
<li class="tool-item tool-active is-like "><a href="javascript:;"><svg class="icon" aria-hidden="true"> <use xlink:href="#csdnc-thumbsup"></use> </svg><span class="name">点赞</span> <span class="count">2</span> </a></li> <li class="tool-item tool-active is-collection "><a href="javascript:;" data-report-click="{"mod":"popu_824"}"><svg class="icon" aria-hidden="true"> <use xlink:href="#icon-csdnc-Collection-G"></use> </svg><span class="name">收藏</span></a></li> <li class="tool-item tool-active is-share"><a href="javascript:;" data-report-click="{"mod":"1582594662_002"}"><svg class="icon" aria-hidden="true"> <use xlink:href="#icon-csdnc-fenxiang"></use> </svg>分享</a></li> <!--打赏开始--> <!--打赏结束--> <li class="tool-item tool-more"> <a> <svg t="1575545411852" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="5717" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css"></style></defs><path d="M179.176 499.222m-113.245 0a113.245 113.245 0 1 0 226.49 0 113.245 113.245 0 1 0-226.49 0Z" p-id="5718"></path><path d="M509.684 499.222m-113.245 0a113.245 113.245 0 1 0 226.49 0 113.245 113.245 0 1 0-226.49 0Z" p-id="5719"></path><path d="M846.175 499.222m-113.245 0a113.245 113.245 0 1 0 226.49 0 113.245 113.245 0 1 0-226.49 0Z" p-id="5720"></path></svg> </a> <ul class="more-box"> <li class="item"><a class="article-report">文章举报</a></li> </ul> </li> </ul> </div> </div> <div class="person-messagebox"> <div class="left-message"><a href="https://blog.csdn.net/sinat_33822516"> <img src="https://profile.csdnimg.cn/E/B/3/3_sinat_33822516" class="avatar_pic" username="sinat_33822516"> <img src="https://g.csdnimg.cn/static/user-reg-year/1x/4.png" class="user-years"> </a></div> <div class="middle-message"> <div class="title"><span class="tit"><a href="https://blog.csdn.net/sinat_33822516" data-report-click="{"mod":"popu_379"}" target="_blank">Obito_uchiha</a></span> </div> <div class="text"><span>发布了15 篇原创文章</span> · <span>获赞 2</span> · <span>访问量 1万+</span></div> </div> <div class="right-message"> <a href="https://im.csdn.net/im/main.html?userName=sinat_33822516" target="_blank" class="btn btn-sm btn-red-hollow bt-button personal-letter">私信 </a> <a class="btn btn-sm bt-button personal-watch" data-report-click="{"mod":"popu_379"}">关注</a> </div> </div> </div>