侧边栏壁纸
博主头像
Fonda's Lab 博主等级

关山难越,谁悲失路之人?萍水相逢,尽是他乡之客。

  • 累计撰写 49 篇文章
  • 累计创建 27 个标签
  • 累计收到 1 条评论

目 录CONTENT

文章目录

用nginx配合Zerotier实现内网主机公有化

LouisFonda
2024-06-03 / 0 评论 / 0 点赞 / 26 阅读 / 0 字 / 正在检测是否收录...

用nginx配合Zerotier实现内网主机公有化

我有一台nas在老家,只有公网ipv6,虽说现在的手机流量上网默认就有ipv6,可是大部分人的办公网络还是ipv4,这就会造成你搭建的一些服务别人访问不了,所以就只能自己玩一玩,所以我想到用云主机做反向代理实现公网访问nas内网服务,阿里云的ipv6流量虽说是收费的但是只收从主机发出的流量,进来的流量是不收费的,具体可以参考阿里云收费规则,所以反向代理出去的那点流量可以略不记,重要的是ipv6的速度是不会影响价钱的(计量模式)。

准备工作

  1. 具有公网访问能力的主机,要有ipv4+ipv6,下面用主机a代替。
  2. 内网主机一台,在任何地方的内网都行,只要你要控制它的权限,下面用主机b代替。
  3. 域名一个,这里以blog.icoding.fun为例。
  4. 内网服务,这里以http://192.168.31.208:8090为例。

直接反向代理域名

首先我们要配置域名的解析记录,配置blog.icoding.fun的A记录指向主机a的公网ipv4,blog.icoding.fun的AAAA记录指向主机b的公网ipv6.

IMG_0177.jpeg

配置nginx反向代理

server {
  listen 80 ; 
  listen 443 ssl http2 ; 
  server_name blog.icoding.fun;
  # 其它配置略。。。
  location ^~ / {
    proxy_pass https://blog.icoding.fun; # 主机b提供的服务,只能ipv6访问
    # 其它配置略。。。。
  }
}

现在可以用ipv4访问https://blog.icoding.fun试一试,如果可以那么就成功了。

DNS解析配置

这样做的却可以实现通过ipv4访问到内网的ipv6服务,可是有一个非常大的问题,因为内网的ipv6是通过ddns绑定到域名上的,也就是说过一段时间就会变化,而nginx会缓存域名,等下一次域名更新之后再访问就会抱503错误,所以我们要配置一下域名解析有效期。

http{
    resolver 223.5.5.5 valid=600s;  # 更新地址解析,防止动态域名地址更新后请求老地址
    resolver_timeout 1s;
}

这里我们设置成域名解析结果的有效期是10分钟,这样就算ipv6的解析结果变化也不会影响到ipv4的访问了。

使用zerotier访问

我们仔细想一想这个过程,我们访问https://blog.icoding.fun发生了什么,首先我们我从DNS那里获取真实的ip,假设用户只有ipv4,那么我们获取的就是ipv4地址,然后我们带着ipv4地址和域名去访问nginx,nginx看了一下没问题,就帮我们去请求后端的真实服务,看了一下`proxy_pass`是https://blog.icoding.fun,于是向DNS索要真实的ip地址,域名会优先解析ipv6,这个时候主机a就会拿着这个ipv6地址去访问主机b的nginx,主机b的nginx看了一下,域名和ip都对上了,于是查看自己的proxy_pass是`http://192.168.31.208:8090`,然后请求服务返回给客户端,这里面发生了两次dns解析,请求同一个域名2次,要是什么东西能让我们在a主机上访问到`http://192.168.31.208:8090`这个服务就好了,还真有这种技术,我们称呼这种技术叫**异地组网**,这种技术的实现有很多,这里以zerotier来实现,因为它真的好用。

按照zerotier

按照zerotier官网的方式安装,一条命令直接解决

curl -s https://install.zerotier.com | sudo bash

配置直接看这个视频吧!

主机a和主机b都要加入到网络中,如果主机b在软路由下面,则软路由需要加入网络,并且配置好子网,如果不是就两台主机都要加入网络中。

zerotier-cli join 你的zerotier网络id

加入之后是ping不通的,要到zerotier网络列表中给这个网络勾选上,勾选上之后,现在主机a直接可以通过内网地址访问主机b了

测试对比

我们先来通过域名访问一下

域名访问

root@iZwz90jud7u5ictip63qciZ:~# ping blog.icoding.fun -c 10
PING blog.icoding.fun(240e:381:53e2:e00::b4f (240e:381:53e2:e00::b4f)) 56 data bytes
64 bytes from 240e:381:53e2:e00::b4f (240e:381:53e2:e00::b4f): icmp_seq=1 ttl=54 time=24.4 ms
64 bytes from 240e:381:53e2:e00::b4f (240e:381:53e2:e00::b4f): icmp_seq=2 ttl=54 time=24.8 ms
64 bytes from 240e:381:53e2:e00::b4f (240e:381:53e2:e00::b4f): icmp_seq=3 ttl=54 time=24.7 ms
64 bytes from 240e:381:53e2:e00::b4f (240e:381:53e2:e00::b4f): icmp_seq=4 ttl=54 time=25.0 ms
64 bytes from 240e:381:53e2:e00::b4f (240e:381:53e2:e00::b4f): icmp_seq=5 ttl=54 time=24.1 ms
64 bytes from 240e:381:53e2:e00::b4f (240e:381:53e2:e00::b4f): icmp_seq=6 ttl=54 time=25.4 ms
64 bytes from 240e:381:53e2:e00::b4f (240e:381:53e2:e00::b4f): icmp_seq=7 ttl=54 time=25.5 ms
64 bytes from 240e:381:53e2:e00::b4f (240e:381:53e2:e00::b4f): icmp_seq=8 ttl=54 time=24.3 ms
64 bytes from 240e:381:53e2:e00::b4f (240e:381:53e2:e00::b4f): icmp_seq=9 ttl=54 time=23.9 ms
64 bytes from 240e:381:53e2:e00::b4f (240e:381:53e2:e00::b4f): icmp_seq=10 ttl=54 time=25.4 ms

--- blog.icoding.fun ping statistics ---
10 packets transmitted, 10 received, 0% packet loss, time 9013ms
rtt min/avg/max/mdev = 23.896/24.750/25.516/0.561 ms

平均24还行,但是考虑到会被解析两次,加上ssl认证会更慢

内网地址访问

PING 192.168.31.208 (192.168.31.208) 56(84) bytes of data.
64 bytes from 192.168.31.208: icmp_seq=1 ttl=63 time=23.3 ms
64 bytes from 192.168.31.208: icmp_seq=2 ttl=63 time=19.4 ms
64 bytes from 192.168.31.208: icmp_seq=3 ttl=63 time=20.5 ms
64 bytes from 192.168.31.208: icmp_seq=4 ttl=63 time=20.4 ms
64 bytes from 192.168.31.208: icmp_seq=5 ttl=63 time=19.7 ms
64 bytes from 192.168.31.208: icmp_seq=6 ttl=63 time=19.6 ms
64 bytes from 192.168.31.208: icmp_seq=7 ttl=63 time=18.3 ms
64 bytes from 192.168.31.208: icmp_seq=8 ttl=63 time=18.2 ms
64 bytes from 192.168.31.208: icmp_seq=9 ttl=63 time=18.5 ms
64 bytes from 192.168.31.208: icmp_seq=10 ttl=63 time=19.0 ms

--- 192.168.31.208 ping statistics ---
10 packets transmitted, 10 received, 0% packet loss, time 9012ms
rtt min/avg/max/mdev = 18.200/19.689/23.282/1.414 ms

第一次由于要向zerotier服务器发起一次查询所以比较慢,有时候会飚到100多ms,之后会直接使用ipv6来访问,这样比通过域名访问快太多了,而且只有一次解析,一次ssl认证。

替换nginx配置

现在把proxy_pass改成内网服务就行了

server {
proxy_pass http://192.168.31.208:8090
}

总结

我们探讨了如何通过云主机的反向代理以及 ZeroTier 等工具,实现内网主机的公开访问。首先,我们配置了域名的解析记录,将域名的 IPv4 记录指向主机 A 的公网 IPv4 地址,将域名的 IPv6 记录指向主机 B 的公网 IPv6 地址。然后,通过 Nginx 的反向代理功能,将主机 A 接收到的 IPv4 请求代理转发给主机 B 提供的服务。为了避免 IPv6 地址变化导致访问异常,我们配置了 DNS 解析结果的有效期为 10 分钟。

进一步地,我们介绍了如何使用 ZeroTier 实现内网主机的访问。通过加入相同的 ZeroTier 网络,我们使主机 A 和主机 B 在同一个虚拟局域网中,从而可以直接通过内网地址访问主机 B 提供的服务,避免了 DNS 解析的延迟和可能的 IPv6 地址变化带来的影响。

通过这些方法,我们成功地实现了内网主机的公开访问,同时保证了访问速度和稳定性。

0

评论区