access internal server

只缘身在此山中?内网域名解析问题

配置完Nginx之后虽然还没有添加任何网页内容,但是web服务器确实已经在运行了。但是这时候在浏览器上输入自己的域名很可能并不能显示正常的网页。
其实这种现象很普遍,并不是Nginx有问题,只是我们的PC正好和服务器在同一个局域网。
为了弄清楚其中的原理,我们假设访问PC的IP地址为192.168.0.10, 服务器的内网IP为192.168.0.11,DNS上登录的外网ip为1.1.1.1.

分析原因

在浏览器上输入域名之后,首先会通过DNS服务器进行域名解析,获得域名对应的IP地址,这里是1.1.1.1。之后会生成一个来自PC,发送到域名对应地址的IP报头。

from 192.168.0.10
to 1.1.1.1
port 80

这个包没有问题,可以正确地被发送到外网端口。到达外网端口之后由于是对80端口的访问,会触发NAT地址映射,将报头改写为

from 192.168.0.10
to 192.168.0.11
port 80

服务器收到这个数据之后进行相应,返回的数据报头为

from 192.168.0.11
to 192.168.0.10
port 80

这里问题来了,路由器识别出这是LAN内的流量,所以不经过WAN口,直接将这个包转发到发出请求的PC,也就是192.168.0.10。但是PC的浏览器在等待来自“服务器”,也就是1.1.1.1的数据,所以会将这个包丢弃。最终表现为连接超时,访问失败。

解决方法

知道了原因,就可以从出问题的步骤来设计解决方案了。

使用IP地址访问

既然是内网通信,我们当然可以不经过外网端口直接访问服务器,这样就可以正确的将来自服务器内网地址的报文识别为返回的信息,从而正常通信了。要实现通过内网地址访问服务器,最简单的方法就是直接在浏览器中输入服务器的内网IP。
但是这样有一个问题,就是HTTPS的认证是基于域名的,如果网站应用了SSL,通过IP的访问会被认为是不安全的。这样虽然不影响正常访问服务器的内容,但是在https普及的今天,通过这种方法访问会收到无数来自浏览器的安全警告和打断,着实不便。

内网DNS

既然可以通过内网IP正常访问,那么只要在网络内部设立内网DNS,将域名解析为服务器的内网IP地址即可。而且很多操作系统都提供了覆盖DNS的方法,比如windows系统会在发送DNS请求之前先检查hosts文件中的映射项目。

在hosts文件(C:\Windows\System32\drivers\etc\hosts)中添加自己的域名到内网IP的映射即可覆盖外部的DNS记录,通过域名访问内部网站。

在路由器中配置双向端口映射

还有一种解决办法,是解决路由器返回信息时不通过外网端口直接在内部转发这一环节。
在路由器的Vlan上添加类似

nat server protocol tcp global 1.1.1.1 80 inside 192.168.0.11 80

的配置,使得路由器返回的信息也先经由端口映射发送到外网端口,然后以1.1.1.1作为来源返回给浏览器,自然就可以正常的建立连接了。

Ads