用nginx配合Zerotier实现内网主机公有化
我有一台nas在老家,只有公网ipv6,虽说现在的手机流量上网默认就有ipv6,可是大部分人的办公网络还是ipv4,这就会造成你搭建的一些服务别人访问不了,所以就只能自己玩一玩,所以我想到用云主机做反向代理实现公网访问nas内网服务,阿里云的ipv6流量虽说是收费的但是只收从主机发出的流量,进来的流量是不收费的,具体可以参考阿里云收费规则,所以反向代理出去的那点流量可以略不记,重要的是ipv6的速度是不会影响价钱的(计量模式)。
准备工作
- 具有公网访问能力的主机,要有ipv4+ipv6,下面用主机a代替。
- 内网主机一台,在任何地方的内网都行,只要你要控制它的权限,下面用主机b代替。
- 域名一个,这里以blog.icoding.fun为例。
- 内网服务,这里以http://192.168.31.208:8090为例。
直接反向代理域名
首先我们要配置域名的解析记录,配置blog.icoding.fun的A记录指向主机a的公网ipv4,blog.icoding.fun的AAAA记录指向主机b的公网ipv6.
配置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访问
按照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 地址变化带来的影响。
通过这些方法,我们成功地实现了内网主机的公开访问,同时保证了访问速度和稳定性。
评论区