Nginx 与泛域名实现内网外入

本贴最后更新于 1802 天前,其中的信息可能已经时过境迁

" 本文基于已经实现内网穿透的前提,例如外网服务器端口 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

    NGINX 是一个高性能的 HTTP 和反向代理服务器,也是一个 IMAP/POP3/SMTP 代理服务器。 NGINX 是由 Igor Sysoev 为俄罗斯访问量第二的 Rambler.ru 站点开发的,第一个公开版本 0.1.0 发布于 2004 年 10 月 4 日。

    311 引用 • 546 回帖
  • 内网穿透
    26 引用 • 146 回帖 • 2 关注

相关帖子

欢迎来到这里!

我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。

注册 关于
请输入回帖内容 ...