IPv6 邻居发现协议

发布于 2019-04-29  61 次阅读


在配置我的内网 NAS 的时候,遇到了一些问题(详情请看 Docker Container 分配独立 IPv6 地址)。主要是校园网分配给我的是一个 /64 前缀的地址,我不能继续往下分。为了使位于路由后的几台机子(容器)获得 IPv6 地址,我进行了如下配置。

适用范围

如果你的 ISP 通过 SLAAC 方式分配了唯一的 /64 地址给你,你又不想使用 NAT66,不妨看下去。如果不想看废话,请直接跳到最后。

前置科技

不想看的可以跳过。

IPv6 NDP

The Neighbor Discovery Protocol (NDP, ND) is a protocol in the Internet protocol suite used with Internet Protocol Version 6 (IPv6). It operates at the link layer of the Internet model (RFC 1122), and is responsible for gathering various information required for internet communication, including the configuration of local connections and the domain name servers and gateways used to communicate with more distant systems.

简单来讲就是 Host 机可以告知网络上的其它机器,某个 IPv6 公网地址在我这/在我旁边。举个栗子:我的本地地址是 2001:da8:215:d573:3055:2165:A:B,拥有地址 2001:da8:215:d573:3055:2165:A:C 的主机在物理拓扑上“躲”在我后面。通过 NDP,我们就可以告诉互联网上的其他主机,2001:da8:215:d573:3055:2165:A:C 在我这里,来找我,我帮你们转发数据包。在 Linux 上,配合 IPv6 Forwarding,就可以达到“IPv6 穿透”的目的。

NAT

Network address translation (NAT) is a method of remapping one IP address space into another by modifying network address information in the IP header of packets while they are in transit across a traffic routing device. The technique was originally used as a shortcut to avoid the need to readdress every host when a network was moved. It has become a popular and essential tool in conserving global address space in the face of IPv4 address exhaustion. One Internet-routable IP address of a NAT gateway can be used for an entire private network.

简单来说就是在 IPv4 时代构建局域网的技术。比如你把网线插在无线路由器的 WAN 口,你就可以上网了。这一技术在 IPv6 时代也是存在的,但是然并卵。IPv6 地址足够多,据称可以给地球上的每个沙子都分一个公网地址。所以在 IPv6 时代,通过组件内网来节约地址就没有必要。在任何时候 NAT66 都不应该作为你的选项。NAT66 的搭建方法在上一篇文章提到过,这里就不再赘述。

问题分析

我需要在母鸡只有一个物理网卡的情况下,给每个 Docker 容器分配公网 IPv6 地址。这就要用到上文的 NDP 协议了。每个地址都应该在原本的 /64 网络内,通过 NDP 协议“暴露” 给其它机器。Host 机打开 IPv6 转发,实现路由功能。

解决方案

我本地是 Debian Buster。首先安装 NDPPD 来自动管理“邻居”。当然如果你不想,通过 ip -6 neigh add 来手动管理也没问题。

apt install ndppd

然后,通过 Docker 自带的 IPv6 功能给每个容器分配一个合适的地址。其实使用 radvd 也不是不可以,但很显然 Docker 更快一点。Docker 配置文件 daemon.json 如下:

{
  "dns": ["101.6.6.6", "2001:da8::666"],
  "registry-mirrors": ["https://docker.mirrors.ustc.edu.cn/"],
  "ipv6": true,
  "fixed-cidr-v6": "2001:da8:215:A:B::/80"
}

然后是配置 NDP 协议。相应的 ndppd 配置如下:

proxy enp1s0 {
    autowire yes
    rule 2001:da8:215:A:B::/80 {
        auto
    }
}

重启相关服务之后,位于 Host 机之后的机器(容器)就能取得 IPv6 地址了。

写在最后

相比于简单的 IPv4 协议,IPv6 的配置无疑更加困难。但是 IPv6 的便利性也是 IPv4 无法媲美的。在这里真诚的建议大家尽快将自己的网络环境升级到 IPv6 以获取更方便快捷的网络体验。


一沙一世界,一花一天堂。君掌盛无边,刹那成永恒。