" 本文基于已经实现内网穿透的前提,例如外网服务器端口8090,已经映射到了某台内网服务器的80上 "

多说

这是撒?

这里的内网外入是指什么?比如我在外网服务器上面有一个网站,该网站有一个页面,页面很简单,就只有一个输入框,当我们在这个输入框输入一个内网地址的后,按下访问后,就可以访问到内网中相应的资源。当然访问到内网地址的模式有很多,也不是说完全需要以网页输入内网地址的形式进行。这里想要表达的仅仅是:我们可以输入某个已经穿透的内网中的任意地址然后获取相应的服务。在做这个之前也问过一些人,可能因为表述问题很多人给我推荐的是如何实现内网穿透,然后某个推荐:使用lua+nginx,我觉得挺不错的。在了解这个东西后才发现又是一片新大陆,用这个肯定能实现我想要的东西。但是心里总觉得用lua+nginx做这个是不是有点小题大做了,还要去学习哈lua,还要再给nginx添加lua的模块,不,我选择懒 😑,于是就开始瞎捉摸。不过好在经过无数次改配置中,直接通过nginx的配置文件外实现了想要的功能。

我的思路!

最开始我的第一想法是通过域名带个值为内网地址的url参数,然后通过nginx捕获,再实现转发,但是经过一系列操作后我发现这种方式最后获取到的只有目标网站的html,没有其他静态资源。几经尝试无果后放弃!

然后还有想法是通过自定义请求头,将要访问的地址放入到请求头中访问,然后nginx获取,但是这种方式在写前端的时候折戟了,对于只会原生ajax请求的我,面对自定义请求头后的跨域问题一脸懵逼!于是再度放弃!😰 😪

然后我又开始想,既然参数,请求头都不行的话,那么我就直接使用域名(内网地址+外网域名的形式),然后在nginx中实现捕获内网地址,再通过变量将捕获到的地址保存,最后通过代理到该变量的值的地址上!

实现

1.实现内网外入

因为要实现内网外入,所以首先第一步肯定是实现内网穿透,现在实现内网穿透的工具有很多,比如花生壳呀什么的,但是不太建议这种。如果有需要我建议直接去github拉一个,这里推荐一个netagent,这是之前在b3log仓库里面发现的,b3log的现在失效了,贴了一个我fork的。这个工具比较小巧,还是比较好用的。如果技术够好的话,那就直接自己写一个吧~~。

2.泛域名解析

因为我们需要通过内网地址+域名这种形式来访问,所以那么 内网地址+域名本身应该就是一个域名,这样才能确保到达我的服务器。而我们不知道用户将要请求什么内网地址,所以这里我们需要在你的域名提供商提供商那里将你的域名实现泛域名解析。比如我的域名是zhqy.xyz,那么在经过泛域名解析后,就可以输入类似于172.22.4.2.zhqy.xyz这样的域名到达我的服务器,然后我服务器在对该域名进行正则匹配提取目的地址。

3.提取目的地址与访问

当请求到达服务器后,就需要对请求进行判断是不是想要内网外入的请求,如果是内网外入的请求就将内网目的地址提取出来,然后进行后续操作,这里服务器的nginx配置如下:

server {

	#监听80端口
        listen       80;

	#这里进行泛域名匹配,确保所有的以 .zhqy.xyz 结尾的域名都可以解析到本机,需要配合域名服务商进行泛域名解析
        server_name  ~^(.+)\.zhqy\.xyz$; 

        #提取域名 *.zhqy.xyz 的前一部分存入$cqupt
        set $cqupt $1;

	
        location /{
        # echo "cqupt: $cqupt";  可以此语句验证是否捕获匹配的域名

	#跳转到已经经过内网穿透的端口去访问
        proxy_pass http://127.0.0.1:8090; 
        proxy_redirect off;
          
 	#这里将捕获到的地址存入host,然后在穿透的主机上直接重定向到 $host即可
        proxy_set_header   Host    $cqupt; 
        proxy_set_header   X-Real-IP   $remote_addr;
        proxy_set_header   X-Forwarded-For $proxy_add_x_forwarded_for;
}
}

这里因为我不是穿透的80端口,所以proxy_pass的时候要先去8090端口,然后在内网主机中nginx对请求请求代理到$host就可以了。这里需要注意的是,内网地址为域名的时候,你要先指定内网的DNS,这样才能正常访问到。内网主机的nginx配置如下:

 server {
	#这里填写内网中映射的端口
        listen       80;

        #这是添加DNS,其中第一个就是内网服务器的DNS
        resolver 202.202.32.33 114.114.114.114 8.8.8.8 valid=3600s;

        location / {
      	proxy_pass http://$host;
	    proxy_redirect off;
 		proxy_set_header   Host    $host;
		proxy_set_header   X-Real-IP   $remote_addr;
		proxy_set_header   X-Forwarded-For $proxy_add_x_forwarded_for;
        }

这里如果你是穿透的外网服务器的80端口,那么就只需要在上面的第一个nginx配置中添加一句 resolve DNS的语句,然后将proxy_pass中的地址改为你的目的地址就可以,这样就不用做后面的内网服务器nginx这一步操作了。

效果演示

在配好所有的东西后,我们就可以通过我们的方法’畅游‘内网世界了。比如我现在有一个内网地址172.22.4.2,先通过内网中的机器正常的访问,结果如下:
image.png
然后通过我们的内网外入来访问,结果如下:
image.png

就这样通过一顿操作后,就终于实现了所谓的内网外入了!!!

写在最后

经过上述配置已经简单的实现了一个内网外入的功能,但是有一点值得注意的就是安全问题了。既然别人屏蔽了内网中的站点,那么我们对内网开了一个口子总归是不好的。在这份配置文件中还有很多值得去完善的问题,例如禁止抓跑,爬取呀什么的,还有应当对内网地址确定一个白名单,哪些是可以通过访问的,哪些是一定不能通过外网访问的。


标题:Nginx与泛域名实现内网外入
作者:geektomya
地址:https://blog.zhqy.xyz/articles/2019/12/16/1576502421990.html
彧语:乾坤未定,你我皆是黑马!!!

评论列表

取消