折腾 NAT64 实现 ipv6 only 内网

Posted on February 13, 2019

一直以来,虽然启用了 ipv6, 但是都是以 Dual Stack 模式运行。 你不知道,是服务器端不支持 ipv6 呢,还是客户端不支持,亦或二者皆有之。

而且Dual Stack虽然解决了互联问题,但是看起来非常的丑陋,多个协议一起跑什么的,才不要呢!

于是就有了搞 IPv6 Only 的想法。为了解决互联问题,还需要一台翻译的设备执行 NAT64。

所谓 NAT64 就是让一台网关充当 ipv6 和 ipv4 的桥梁,把 ipv4 主机模拟成 ipv6 主机,供 IPv6 Only 的主机访问。 之所以可以这么做到,是因为 ipv6 拥有巨大的地址集。只要其中拿一小部分出来就可以包含所有的 ipv4 地址了。可以做到 ipv6 地址和 ipv4 地址一一对应,然后为这个一一对应执行 NAT 转换。

只需要一台网关设备提供 Dual Stack 即可,LAN 内的机器都只要 IPv6 Only 了。

要实现 NAT64 , 首先 需要 DNS64 的帮忙。 何为 DNS64 ? 要让 ipv4 的机器被访问到,首先需要他被转换为 ipv6 地址,做到这一点的就是 DNS64 。

当向 DNS64 查询 dns 的时候,dns64 会检查域名是否有 AAAA 记录,如果有,就用他自己的 AAAA 记录里的 ipv6 地址,客户端就可以直接访问了,完美。 如果他没有 AAAA 记录,但是有 A 记录,就把这个 A记录里的 ipv4 地址给转换为一个 ipv6 地址,然后返回这个假的 AAAA 记录。

客户端访问这个假的 ipv6 地址,自然就被路由到了 NAT64 设备上,然后 NAT64 就充当中间人角色完成地址转换。

对 ipv6 的客户端来说,一切都是透明的。

说了半天,咋个实现呢?

首先,你需要一台设备,低功耗24小时运行,性能又不会太差的那种。 嗯,没错,一台基于 Linux 的路由器(openwrt啊,梅林啊,当然,也可以像我一样,用 ubiquiti 的 EdgeMax 系列的路由器)

但是,因为我最近拔仓库的时候发现了吃灰很久的一个树梅派,所以我决定在派上面安装这些东西。好处就是 EdgeOS 更新的时候不用重新折腾了。

首先需要 DNS64, 这个DNS64 的存在,使得我之前折腾的ChinaDNS 瞬间毫无意义啦。因为 dns64 我用的 unbound 这个软件,而这个软件支持 DNSSEC 加密。意味着我只要打开 DNSSEC 就对 dns 污染说 good bye 了。于是只要 pacman -S unbound && systemctl start unbound 简单的命令就把 unbound 跑起来了。

当然,还是要 edit 一下 /etc/unbound/unbound.conf 文件才能启用 DNS64 和 DNSSEC 的。

DNS64 的伪造AAAA记录用的前缀呢,我就用 8964::/96 了。这样 1.1.1.1 就会被转换成 8964::1.1.1.1 ( 或者 8964::101:101 这种写法)。

把 DNS 设置到 rpi 上后, nslookup 一下

$nslookup www.baidu.com 240e:f0:63b:83b1:2e0:4cff:fe68:2846   
Server:         240e:f0:63b:83b1:2e0:4cff:fe68:2846
Address:        240e:f0:63b:83b1:2e0:4cff:fe68:2846#53

Non-authoritative answer:
www.baidu.com   canonical name = www.a.shifen.com.
Name:   www.a.shifen.com
Address: 115.239.211.112
Name:   www.a.shifen.com
Address: 115.239.210.27
Name:   www.a.shifen.com
Address: 8964::73ef:d21b
Name:   www.a.shifen.com
Address: 8964::73ef:d370

顺利的看到了 8964:: 开头的 伪 AAAA 记录。然后把路由器的 pppoe 拨号自动获取 dns 给关了,手工指定 dns 为 rpi。 这样 LAN 内的机器还是用的路由器来解析 dns。而路由器再转发给 rpi。因为必须要用路由器的 dnsmasq 解析才能正确的把某些域名的 ip 地址给填入 ipset ,用来进行基于匹配的智能路由。。。你懂的!

然后开始折腾 NAT64.

NAT64 使用 tayga 软件。这个软件 pacman 里没有。只好自己编译了。(折腾的时候忘记了用 yay !)

然后按照 wiki 把 tayga 跑起来,done!

当然,要记得在路由器里配置下静态路由,把 8964::/96 的下一跳指向 rpi.

试试看

$ ping www.baidu.com
PING www.baidu.com(8964::73ef:d21b (8964::73ef:d21b)) 56 data bytes
64 bytes from 8964::73ef:d21b (8964::73ef:d21b): icmp_seq=1 ttl=52 time=7.88 ms
64 bytes from 8964::73ef:d21b (8964::73ef:d21b): icmp_seq=2 ttl=52 time=8.28 ms
64 bytes from 8964::73ef:d21b (8964::73ef:d21b): icmp_seq=3 ttl=52 time=8.28 ms
64 bytes from 8964::73ef:d21b (8964::73ef:d21b): icmp_seq=4 ttl=52 time=7.84 ms
^C
--- www.baidu.com ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 6ms
rtt min/avg/max/mdev = 7.836/8.069/8.282/0.212 ms

wow, very nice 啊!

然后果断 NetworManager 设置打开,禁用 IPv4,重新启用下 eth0.

然后,就只有ipv6 地址了(还是公网地址,哈哈!)

然后,打开浏览器,wow,网能正常使用。

Linux 上除了硬编码 ipv4 地址的客户端外,都能正常使用了。

至于 Windows 嘛,呵呵,有太多的天朝系的垃圾软件,用 C 写的各种以为自己很牛逼的网络库,各种鄙视 boost.asio 的存在,导致这些垃圾网络库都是 ipv4 only 的。所以,没有 ipv4 地址,这些软件就统统歇菜了。

but,意外的发现 酷狗音乐啊,网易音乐啊,都还是能用的。。。。。 果然玩音乐的网络代码写的比腾讯阿里好啊!

Comments