IPv4 协议定义网络与网络之间的数据交换方式,具体来说,它定义了网络地址的概念,并且描述了网络设备之间如何根据网络地址来进行通信。IPv4 协议定义的网络地址也被称为 IPv4 地址,一个 IPv4 地址用一个 32 位的二进制数表示,因此 IPv4 地址的数量是有限的,随着网络设备数量的增加,IPv4 地址会变得不那么够用。
IPv6 同样是用于定义网络与网络之间的通信方式的,而且它也有网络地址的概念,但是与 IPv4 不同的是,它的网络地址长达 128 位,它的提出能够解决 IPv4 地址不够用的问题,换句话说,假如一下子把所有运行着 IPv4 协议的网络设备一下子升级成运行 IPv6 协议,那么网络地址是绝对够用的。
我们考察这样一种情形:设备 A 同时可触达 IPv6 网络和 IPv4 网络,设备 B 不能触及到 IPv6 网络上的任何一台但是能够接触 IPv4 网络上的设备 A, 可否在设备 A 和设备 B 之间建立一个隧道连接,使得设备 B 能够访问 IPv6 网络上的资源?
为了让一个 IPv4 only 网络中的某台设备也获得 IPv6 地址并且能够访问 IPv6 网络上的资源,我们使用 Linux 内核 sit 模块提供的 sit 隧道功能,它支持把 IPv6 分组封装在一个 IP 分组中:
从这个意义上说,它有那么一点点类似于 ipip 隧道协议,只不过它还还支持封装 IPv6 分组,而不只是 IPv4 分组。
思路是这样的,当一个无法直接触达 IPv6 网络的主机 A 想访问一个位于 IPv6 网络中的主机 C 时,它利用一个同时 IPv4, IPv6 可达的主机 B, 它事先向 B 获取到一个 IPv6 地址,比如说让 B 把自己多余用不完的地址拿出一个给 A 用,然后当 A 需要跟 C 通信时,它生成一个 IPv6 分组,sender 写自己(从 B 那借到的)IPv6 地址,receiver 写 C 的 IPv6 地址,以此生成 Inner IP(v6) Header, 然后数据作为 Inner IP(v6) Payload, 然后在 Outer IP Header 的 sender 写自己的真实 IPv4 地址,receiver 写 B 的 IPv4 地址,然后把这个包发给 B, B 再把这个包发给 C。当 C 需要和 A 通信时,C 不需要做任何封装。
这种方法要求:
为了验证这个方案是可行的,我们在 AWS 云平台上通过建立 VPC, Subnet 和 EC2 实例来模拟这个环境,然后使用 ip 命令行工具建立隧道、分配地址并设置路由来实现上文中 A 与 C 的双向联通。
完成这个实验需要我们创建如下资源: