IPv6-only VPS通过NAT64访问IPv4域名
背景
最近从德国euserv买了一台IPv6-only的VPS,定期免费续期就能一直使用。
但IPv4的域名就没法访问了。
所以看了下DNS64和NAT64,实现了访问IPv4的需求。
理论知识
IPv6提出后,矛盾在于:
- 一方面我们希望整个互联网底层是基于IPv6构建的,增量也尽量接入IPv6。
- 另一方面,原有的很多IPv4地址无法通过IPv6访问,还是要保留、新增IPv4的基础设施。
NAT64
由于IPv6地址超级多,自然而然的,我们为什么不能将IPv6地址的一部分“抠出来”,映射到IPv4网络呢?
比如192.0.2.1
地址,映射到地址64:ff9b::192.0.2.1
。
然后所有到达64:ff9b::192.0.2.1
的请求,我们都原样转发给192.0.2.1
,这样就能实现IPv6访问IPv4了。
DNS64
上面我们解决了IP地址映射的问题,那么访问某一个IPv6网站的时候,DNS返回的仍然是IPv4地址,很多域名还是无法通过IPv6访问。
问题只解决了一半?
很简单,我们只需要在DNS上替换掉这个IPv4地址就可以了。这就叫DNS64服务。
一个例子
我们以ip4only.me为例,看看如何通过DNS64和NAT64服务进行访问:
- 发送AAAA解析请求到DNS64服务器,DNS64服务器先是获取ip4only.me的IPv4地址,然后通过转换规则转换为NAT64的IPv6地址。
- 我们的请求通过IPv6网络到达这个NAT64 IPv6地址的时候,NAT64服务会把这个请求通过IPv4网络发送到真正的网站服务器。
当然,缺点也是有的,那就是网络速度会受限于NAT64服务器的速度。
但好处是,构建了一个原生的IPv6网络,同时兼容了IPv4网络,我们在新增的网络设备中,就无需部署IPv4设施了。
好了,理论知识OK了,我们开始实战。
手动测试下DNS64&NAT64
nat64.net 提供了免费的NAT64服务,我们先尝试解析一个IPv4域名:
1 | dig @2a00:1098:2b::1 ip4only.me aaaa |
其实这个域名是没有AAAA记录的,也就是说没有对应的IPv6地址。
上面的IPv6地址,仅仅是nat64.net在自己的地址范围内做了一个IPv4到IPv6地址的映射的结果。
那我们任选一个IP访问看看:
1 | curl -v 'https://ip4only.me/api/' \ |
可以看到,我们通过这个IPv6地址访问的时候,网站仍然认为我们是通过IPv4访问的。
那么,对于支持IPv4和IPv6的双栈网站域名,是什么表现呢,我们来试一试:
1 | dig @2a00:1098:2b::1 ip6.me aaaa |
对于双栈网站,nat64.net解析的结果和google dns一样,都是本来的IPv6地址,没有经过代理。
OK,nat64.net工作的很完美,那么如何用上呢?总不能每次都要改命令吧。
如何让IPv6-only的VPS用上呢?
很简单,对于通过域名访问的服务,只需要将DNS服务器替换为nat64.net的DNS服务就可以了。
比如以Debian GNU/Linux 12 (bookworm)
为例,resolv.conf
配置由systemd-resolved管理,我们只需要修改systemd-resolved的配置就可以了:
在/etc/systemd/resolved.conf
中指定:
1 | [Resolve] |
然后通过systemctl restart systemd-resolved
应用变更。
最后测试下:
1 | curl -6 -v 'https://ip4only.me/api/' |
另外,还有一个bonus:
这时候,你可以在VPS上访问GitHub了(不管是HTTPS方式,还是SSH方式)。
备注
已经有电信运营商开始用类似的方式,向IPv6迁移了
- Telstra分配给客户端一个正常的IPv6地址,加上一个mock的IPv4地址
192.0.0.8
- 访问IPv4网站时,DNS返回一个NAT64地址,通过这个地址,可以访问IPv4网站
来源:https://www.zhihu.com/question/577859676/answer/3245843113
如何使用新版本技术,替换老版本技术
不管是IPv6(尝试)替换IPv4,还是Golang中,math/rand/v2
取代math/rand
,都会遇到新版本的优点和旧版本的兼容阻力两个冲突。
这时候,Golang官方整理了新旧版本演进的原则(有修改):
- v1 和 v2 可以在同一个系统中共存,这对于逐步转换到新版本至关重要。
- 所有更改都必须以尊重现有用法和用户为基础:我们绝不能引入不必要的变化,无论是对现有软件包的不必要更改,还是必须学习的全新软件包。
- v2版本v1用户抛在后面,完全不管了。在理想情况下,v2版本应该能做v1版本能做的一切事情。当v2发布时,v1软件包应被重写为v2的薄封装。这将确保现有的v1版本继续受益于v2中的错误修复和性能优化,也保证了v1的兼容性。
Golang的math/rand/v2
,和本文中的NAT64,都是这个原则的例子。
这种新旧版本演进的方式,能够在最大程度上避免技术债,能够比较优雅的迁移到新版本。
当然,这种方式也会有薄封装本身稳定性的问题。
anyway,这是另外一个话题了,改天聊。
参考资料
IPv6-only VPS通过NAT64访问IPv4域名