起因
最近因为工作需要,在宿舍用一台闲置的电脑搭了一个demo
环境;但是坑爹的上海电信10M光线猫还无法破解(持续寻找光纤猫破解方法中!),因此无法设置端口映射将端口发布出去从公网访问;
因此在我的VPS
上搭了PPTP VPN
服务器,然后宿舍的Demo
机拨VPN
持续连接到VPS
,获得与VPS
相同网段的虚拟IP
建立点到点的虚拟加密隧道;然后在VPS
的iptables
防火墙做NAT
,通过VPN
隧道,将宿舍demo
机的虚拟IP
地址上的服务端口发布出去,这样从Internet
上访问我VPS
公网IP
上的对应端口,就可以访问放在宿舍内部的demo
机了;
网络架构如下图:
在这个环境中,我为了尽量节省在PPTP-VPN Tunnel
上传输的流量,实际我也只需要在VPN
上传输当客户访问Demo
时的请求,和返回所请求的数据即可;并不希望Demo
机自己上网访问Internet
的流量也通过VPN
通道传输,避免系统更新下载时,占用VPN
通道的带宽,影响客户访问Demo
的速度;因此我特别配置了Demo
机的pptp
连接属性,取消了“在远程网络上使用默认网关”的选项,如下:
这样配置后,在Demo
机拨上了VPN连接后,就不会将Default Gateway
指向到VPN的对端IP,依然还是使用系统设置的默认网关指向电信光猫路由器,所以Demo
机的上网的流量就还是走电信光猫路由器直接NAT
出去,而不会经过VPN
通道从我的VPS
传输;
但是Demo
机取消了远程网络上的默认网关后,就会造成VPN
虽然拨接成功了,但也只能在点到点之间进行通讯,无法跨网段进行路由;简单讲也就是仅仅只能192.168.0.102
和192.168.0.1
之间可以互相访问;那么想让在Internet
上的客户能顺利访问到Demo
的虚拟IP 192.168.0.102
,就需要在VPS
的iptables
上做NAT
规则了!
首先考虑客户发起的访问请求数据包:客户公网IP ==> VPS公网IP:202.168.X.X:3389 ==> Demo机虚拟IP:192.168.0.102:3389
但实际添加这如上这一条DNAT
规则后,是无法访问到Demo
机的3389
服务的,为什么呢?
因为我的Demo
机取消了VPN
网络上的默认网关,使用的是系统设定的默认网关电信光猫路由,因此Demo
机会将回应的数据包通过我宿舍电信宽带的公网IP
直接返回给客户电脑;客户电脑会发现自己收到数据包并不是自己发出去的目标地址返回的,因此会丢弃这个垃圾响应包,从而导致TCP
连接无法三次握手成功,自然也就无法和Demo
机的3389
端口建立TCP
连接;
因此需要让Demo
机将响应包按原路从VPN
通道返回才行,既然不能将Demo
机的默认网关指向VPN
网络;那么还可以用iptables
对客户请求的数据包进行SNAT
转换,也就是同时将数据包中的源地址(客户公网IP)修改为VPS
的虚拟IP
(192.168.0.1)后再发给Demo
机;这样Demo
机收到请求包后,看到是从192.168.0.1
发送过来的请求,因此会将响应包直接返回给192.168.0.1
;然后iptables
依据所保存的数据包会话状态,将数据包的源和目标地址还原后发送给客户的公网IP
,这时候客户电脑就不会丢弃了,因为收到的响应包的原地址和开始发出去的请求包目标地址是一致的!
设置以上2条Iptables
规则后,成功实现从公网任何地方访问VPS
服务器公网IP
202.168.X.X的3389端口,就能正常连接到位于宿舍内网的Demo机
上的3389服务!并且Demo机
的其它流量也不会在VPN
通道上传输;
PS:
其实对请求数据包的源地址SNAT
和目标地址DNAT
同时进行转换后的转发,这种特性就跟在专业防火墙上发布安全的应用服务端口是一样的;防火墙并不会将外网真正请求的来源地址传递给服务器,而是替换成防火墙自己的IP
去访问应用服务器,这样应用服务器就不需要跟外网地址进行交互和握手,应用服务器甚至都不需要上网,访问外网的权限;只需要回应防火墙的请求即可提供服务;因此可以大大提高应用服务器的安全性;
如果发布的应用服务器有需要记录和统计真实的客户来源IP
地址,那么就不能发布安全的服务端口,防火墙必须要传递真实的请求源IP给应用服务器;通常这种场景下,应用服务器的默认网关通常都是直接指向防火墙的!