开始设计转发的服务器和客户端时,以为客户端可以使用服务器内网ip进行访问。然而,实际测试发现,客户端数据包可以被服务器处理,但是服务器数据包无法被客户端处理。
首先,我测试了icmp。客户端ping服务器(内网ip)和服务器ping客户端(转发ip)都是可达的。
之后,我再测试了udp和tcp。客户端发送的数据包都可以被服务器处理,然而,服务器发送的数据包,客户端都无法处理。
总结就是,服务器使用内网ip,而客户端使用转发ip,除了icmp双方都可达,udp和tcp只能客户端发送给服务器(并处理),服务器发给客户端的数据包无法处理(丢弃)。
这个问题还是挺好理解的。一般,不同局域网间(网络区域不同,主机不限制)是无法通信的。而客户端的udp和tcp刚好做了可达性判断,结果其它网络区域的数据包都丢弃了。
由于我服务器只建立了nat规则,没有创建虚拟网卡,所以我的服务器是没有对应转发ip的。我可以把客户端的转发ip网络区域定义成跟服务器内网ip一样,这样它们就可以互相访问。但是,出于安全问题,转发一般是建立虚拟局域网来隔离两个网络的,所以这个方案只能备选。
后来,我只能自己对数据包进行nat处理。首先,客户端发送给服务器的数据包,使用一个虚拟ip,这个ip跟客户端的转发ip是同一个网络区域,其实就是常说的网关ip。下发给服务器网卡时,把网关ip换成服务器内网ip,这样就可以被服务器识别并处理。然后,服务器转发的数据包,只要是来自内网ip,统一换成网关ip再下发给客户端。经过上面的dnat和snat就可以互相通信了。客户端和服务器间形成了一个虚拟网络。
最后谈一下nat时,需要注意的问题。改变数据包的ip地址时,除了要更新ip头部的checksum,还要更新上层相关协议checksum!udp和tcp的checksum都加了伪头部,而这里面就包含ip地址。所以改变ip时,要根据协议更新它们checksum,否则会导致数据包检验失败,而出现丢包。