如何利用nginx从外网访问内网的站点

现在很多公司都是区分内外网的,而从外网是无法直接访问内网部署的站点与API的,当一个部署在内网的站点(比如官网)需要向外部开放的时候就需要利用Nginx来进行代理转发。

以一个vue+springboot项目为例

【注】:本文假定前端以IP的形式访问后端api,例如:172.16.2.2:8081/a/b

外网(云)服务器IP:114.251.x.x

站点域名:a.aaa.com.cn(当前映射到172.16.2.1)
内网前端服务器IP:172.16.2.1
内网后端服务器IP:172.16.2.2

该项目的前后端都是部署在内网的,所以在内网直接访问不会有问题,而从外网访问当然也就访问不到。

步骤一:将域名在DNS上的IP映射由内网IP改为外网服务器IP,然后配置Nginx

a.aaa.com.cn 在DNS上的映射由内网IP(172.16.2.1)更改为外网服务器的IP(114.251.x.x),这样外网客户对 a.aaa.com.cn 的访问请求会被映射到 114.251.x.x 的80端口(域名映射到IP而不是端口,http默认访问80端口),而该服务器上的nginx会将打到80端口上的请求转发(配置监听转发即可)到内网前端服务器约定好的端口,比如 172.16.2.1:8080 ,这种方式可以通过80端口这一个外网端口用nginx把外网流量打到多个端口。

如果内网前端服务器上vue部署的tomcat/nginx监听的是8080端口,那这时已经可以通过域名访问到页面并看到页面的静态内容了。

但是请注意,当前是无法在前端直接以IP的形式(172.16.2.2:8081/a/b)调用api的,因为提供api的后端服务器是内网服务器,而此时在前端向后端发起的请求的host是a.aaa.com.cn(解析到外网IP),也就无法访问到后端服务器。

步骤二:更改vue中api请求形式,然后配置nginx

这一步的根本目的是改变请求的host。

假定原先vue中某个api的请求方式是 172.16.2.2:8081/a/b ,现在把它替换为 a.aaa.com.cn/a/b

const ipAddr = '172.16.2.2', domainAddr = 'a.aaa.com.cn';
export var demo = `${ipAddr}:8081/a/b`  ===>  export var demo = `${domainAddr}/a/b`

用这种域名的形式替换掉ip形式,把前端发出的请求打到前端172.16.2.1上唯一的公网端口,然后配置nginx,将路径为 /a/b 的请求转发到 172.16.2.2:8081/a/b 。这样,请求的host就从172.16.2.1变成了a.aaa.com.cn,这也就避免了内外网不通或是跨域的问题。

所以,整个过程的公网数据流向是:

外网域名 -> 外网服务器:80 -> 内网前端:8080(前端显示) -> (发出请求) -> 外网域名 -> 外网服务器:80 -> 内网前端:8080 -> nginx分发 -> 内网后端

(图片下面还有一种方案,也可以看一下)

数据流向

补充另外一种类似的思路(未验证):

这种方案的根本目的也是通过代理的方式更改host

基于webpack的vue自带代理,可以直接用,就不需要额外配置代理了,否则用node.js写一个简单的express也可以。webpack的代理配置在/config/index.js中,示例配置如下:

assetsSubDirectory: 'static',
assetsPublicPath: '/',
proxyTable: {
  '/a': {
      target: 'http://172.16.2.2:8081',//目标接口地址
      changeOrigin: true,//是否跨域
      pathRewrite: {
      '/a': '/a'//重写接口
        }
      }
}

这种方案理论上是可行的,而且更简单一些。然而手里暂时没有可以做验证的资源,后续验证了再来更新吧。

你可能感兴趣的:(如何利用nginx从外网访问内网的站点)