关于Openwrt NAT环回问题的解决方法

发布于 2023-01-23  186 次阅读


前些天Blog服务器因某种原因被防火墙ban掉了,仅剩ssh可访问;20多G的数据加上龟速的下载速度简直折磨死人。为了避免服务器再次被ban,我把blog挪到家里的服务器上,直接套个CDN完事儿,省心省力

1.1 NAT Loopback是啥

NAT Loopback,直译 NAT环回,它可以解决内网用户无法通过公网映射访问同内网服务器的问题

对于一个NAT映射

如果打开了NAT环回,那么内网用户将可以通过此映射访问内网服务器;反之,则无法访问

For example:

外部IP:100.64.10.50
Server IP:192.168.31.2

存在一个NAT映射关系:192.168.31.2:80 <------> 100.64.10.50:8080

开了NAT环回,Client将可以通过100.64.10.50:8080访问内网服务器192.168.31.2位于80端口上的服务

1.2 工作原理

上面说了NAT环回是用来解决内网用户无法通过公网映射访问同内网服务器的问题,那么它的原理又是啥?不如先看看为何没了它内网用户便无法访问内网服务器


沿用上面的参数

外部IP:100.64.10.50
Router:192.168.31.1
Client IP:192.168.31.64
Server IP:192.168.31.2
Server NAT映射:192.168.31.2:80 <------> 100.64.10.50:8080

假设Client想要通过外部IP获取Server上的资源,此时路由便会对Client产生一条新的临时NAT映射关系:

Clinet NAT映射: 192.168.31.64:80 <------> 100.64.10.50:6443

按照正常的流程是这样的,但严格来说,访问100.64.10.50:8080并不会产生新的NAT映射关系,因为路由一看咦目的IP是我自己,数据包就不会转发到WAN,而是触发DNAT,并发送给Server;此时发往Server是这样的:

目的IP:192.168.31.2:80
源IP:192.168.31.64:80

Server收到数据包并处理完后,一看源IP,和自己处于同一个网段,脑子一热就往外发;到了交换机,交换机一看目的IP的MAC在MAC表里面,也脑子一热往Client发;Client收到包一看,人都傻了,这源IP自己都不认识,扔掉扔掉(你会随便接陌生电话吗),反映出来的结果便是Time Out,Client永远等不到正确的回复包


为了解决这个问题,NAT环回就出来了,它实质就是个SNAT

开启NAT环回后,本应发给Server的包将变成:

目的IP:192.168.31.2:80
源IP:192.168.31.1:80

Server收到数据包并处理完后,一看源IP,又和自己处于同一个网段,继续往外发;到了路由,路由一查NAT表,发现这个包存在映射关系,便动下手脚,再发往Client:

目的IP:192.168.31.64:80
源IP:100.64.10.50:6443

Client一看,可算收到正确的回复包了,于是Connection Succeeded


整理一下包的转发路径:

                NAT Loopback
发包:Client -> |DNAT -> SNAT| -> Server
收包:Server -> |SNAT -> DNAT| -> Client

简的来说,便是发包时路由先将包的目的IP修改为192.168.31.2:80(DNAT),再将包的源IP修改为192.168.31.1:80(SNAT);服务器回包时路由根据NAT表将目的IP修改为192.168.31.64:80(unSNAT),再将源IP修改为100.64.10.50:6443(unDNAT),最后发往Client

2. 解决方法

搞了这么多铺垫,我们知道了NAT环回是基于SNAT实现的,那么Openwrt上的NAT环回问题也就好解决了

Openwrt R9.8.17后的版本NAT环回均无法正常运行

首先,先打开左侧的菜单 网络->防火墙,再在上面选择通信规则

在下面选择新建Source NAT

名称:自己起
源区域:WAN
目标区域:LAN
到源IP:选你自己的路由IP
到源端口:你端口映射的外部端口

填好后点击添加并编辑,滑到下面,对目的IP目的端口进行修改

目标IP地址:写你内网的服务器
目标端口:写你内网服务器的端口

修改完毕后,点击保存并应用,内网设备即可通过公网IP访问内网服务器了


世界上本没有博客,直到有了程序员