自用IPv6网络走起

前言

2019年11月27日,通过欧洲网络协调中心(RIPE NCC)的邮件确认,全球所有43亿个 IPv4 地址已全部分配完毕。事实上,IPv4 地址的数量是非常有限的,算起来全球60多亿人每个人平均不到1个。由于 IP 地址是由国际上的几大网络协调中心统一进行分配,必须由单位向所在区域的网络协调中心提出申请,并每年缴纳一定的费用。这笔费用对于单位来说算不了什么,对于个人来说就比较高。因此,在每个国家基本上是由国家网络中心进行国内的 IP 地址分配,分配的单位一般是政府、国家机构、高校、基础通信服务商、数据中心或企业等。我们通常家用的宽带主要是由中国移动、中国联通、中国电信三大基础通信服务商提供的。近年来也有由广播电视提供的家用宽带。在学校、国家科技机构单位,一般使用的是教育网、教育科技网,也有很多学校采用的基础通信服务商提供的商用网络。不管是学校,还是家里,基础通信服务商为了节约 IP 地址的使用,在进行基础通信网络搭建的时候,大部分采用了内部局域网共享一个公网 IP 地址代理上网的方式。现有家用使用的宽带网络基本上无法获取到公网 IPv4 地址,只能获得一个以100开头的通信专用的局域网地址。

随着中国 IPv6 的不断部署推进,家用宽带大部分也拥有了 IPv6 地址。相比 IPv4 地址来说,IPv6 地址的数量则非常庞大,全世界人口人均分配几十个都绰绰有余。因此,IPv6 地址在使用上比 IPv4 地址就显得非常大度。通常来说,基础通信服务商会直接分配给每一个家用账户一个/64段的 IPv6 地址段。

个人所知中国移动宽带只有在使用了中国移动的专用路由器光纤接入后会分配 IPv6 地址。

由于考虑到分配的 IPv6 地址直接就是公网 IP 地址,如果知道设备的 IPv6 地址,即可通过IPv6 网络直接进入设备,这对于一般没有安全意识的家用用户来说不是一件好事,所以基础通信服务商一般会在两三天内重新分配 IPv6 地址段,以此确保家用用户不可能长时间拥有同一个 IPv6 地址。

IPv6 地址的 DHCP 几乎没有强制性,通常来说如果知道网络段号,可以自定义 IPv6 地址的后面位数。 比如被分配到的 IPv6 段是”2409:470:88:80::/64”,则用户可以设置自己的 IPv6 地址静态为”2409:470:88:80::8/64”。 这样一来安全性会变得更低。

但对于喜欢“搞事情”的小伙伴来说,这就有很大的限制了。如果有内网的服务器想要暴露在公网,或者想要使用 IPv6 进行管理,就需要有静态公网可达的地址来提供服务。想要实现这一目标,有很多方法来实现。

这里,就来尝试使用方法三来实现管理和对外服务。

实践

环境

申请 IPv6 网段

目前,全球范围内除了由基础通信服务商、数据中心、高校等拥有一大批可用的 IPv6 网段外,基本上无法个人进行申请。唯一可用的无限制 IPv6 网段申请就是He.net提供的 6to4 IPv6 隧道服务。可访问网站进行注册登录,登录后在左上方的User Functions 里选择 Create Regular Tunnel,然后在 You are viewing from 这个位置会显示出你访问时所用的公网 IP 地址。此处的 IPv4 Endpoint 填的是 ECS 服务器的公网 IPv4 地址,至于以下的 Tunnel Server 应该选择哪个需要在 ECS 服务器上ping 各个服务器来确定延迟,选取延迟最低的一个位置。

此处需要注意的,由于 He.net 的全球网络与阿里云的全球网络之间的路由不是直接到达的,往往会绕很大一圈,所以建议不要选择香港的 Tunnel Server,体验下来 Fremont,CA,US 的 Tunnel Server 效果较好。

vgy.me vgy.me

选择好 Tunnel Server 之后,点击最下方的 Create Tunnel 按钮即可获得一个 ::/64 的 IPv6 网段。以下为创建完成后获得 Tunnel 详情。实际上,He.net 是支持申请 ::/48 的 IPv6 网段的,只需要点击以下图片的 Assign/48 按钮即可。

vgy.me vgy.me

如上所示,现在获得了2001:470:811d::/48网段。

配置 ECS 服务器的 IPv6

由于ECS服务器是由Ubuntu 16.04升级的18.04,网络配置仍使用networking进行管理,配置比较简单。编辑/etc/network/interfaces文件,添加如下内容。

auto he-ipv6
iface he-ipv6 inet6 v4tunnel
    address 2001:470:811d::80
    netmask 64
    endpoint 72.52.104.74
    local ECS_INTERNAL_IP
    ttl 255
    gateway 2001:470:811d::1

此处需要注意的是,local 地址一定要填写 ECS 服务器的内网 IP,直接填写公网 IP 会无法认证。如果使用的公网服务器使用 ifconfig 能够直接看到公网 IP,那么一定要填成公网 IP。只要保持与本地的 IP一致即可。

修改网卡配置文件完成后,执行sudo service networking restart来启用 IPv6 隧道。至此,公网 ECS 服务器就拥有了 IPv6 地址。

配置 zerotier

zerotier 是一款先进的 SDN (软件定义网络)软件,通过发现路由来找到两台机器之间的通路。显然,如果两台机器在不同的内部局域网当中,由 zerotier 中心服务节点发现的路由通路就会非常漫长,尤其是客户端访问到 zerotier 中心服务节点的路由通路可能千差万别,造成 zerotier 本身理解建立两个客户端之间最短通路的方法也会变得无效。由此,zerotier 开放了 moon 功能,任何一台 zerotier 客户端都可以成为 moon 节点。 moon 节点可以作为辅助甚至是缩短路由通路的发现者,在国内的不同基础通信服务商的网路中就格外有用。此处就尝试将ECS 服务器加入 zerotier,成为 moon 节点不在此赘述。

安装 zerotier

zerotier 的安装比较简单,Mac 操作系统、Windows 操作系统可以直接访问zerotier官网获取安装包。Linux 操作系统上则只需要使用官方提供的一键脚本即可,如下所示。

curl -s https://install.zerotier.com | sudo bash

安装完成后,使用sudo zerotier-cli info命令获取10位的唯一设备识别码,如 1f23c0dd99

配置 zerotier 网络

访问zerotier web配置面板,注册一个 zerotier 账户并登录。由于 zerotie r的免费套餐允许100台设备同时连入到 zerotier 网络中,所以可以放心大胆使用。登录后选择 Networks 创建一个新的网络,并进入开始配置。网络默认是隐秘网络,需要通过验证后才可以加入,这样也比较安全。此处创建完成后会获得一个网络 ID,在 ECS 服务器上执行以下命令申请加入到该 zerotier 网络。

sudo zerotier-cli join 159924d6308e1d7e

以下的配置主要是配置 zerotier 网络的路由和 IPv6 地址分配。网络创建完成后本身会自动创建一个10.147.17.0/24的局域网 IPv4 网段,并添加默认路由。由于刚才已经在 ECS 服务器上申请加入了,现在需要在 Memebers 里勾选最前面的 Auth 选项。过几秒后,ECS 服务器会被自动分配在设定好的 IPv4 网段中的一个地址,这里也可以自定义某一个段内地址。

vgy.me vgy.me vgy.me

接下来需要做的就是配置 zerotier 可用的 IPv6 网段及相关路由。开启 zerotier IPv6,并添加可用网段2001:470:811d::/48到可分配地址池中,如下图所示。

vgy.me vgy.me

如下图所示,读取 zerotier 根据 RFC4193 文档分配给 ECS 服务器的局域网 IPv6 地址。此处为fd15:9924:d630:8e1d:7e99:9333:8a13:b4bb

vgy.me

接下来添加两条 IPv6 的路由到 zerotier 的默认路由中。一条是设置 ECS 服务器为 zerotier 网络中的网关,如下图所示。

vgy.me

另一条是添加公网 IPv6 网段的默认路由,如下图所示。

vgy.me vgy.me

完成以上步骤可以看到如下图所示的 ECS 服务器也被分配到了一个可用的公网 IPv6 地址。 vgy.me

为了让 zerotier 可以在 ECS 服务器上成功创建公网 IPv6 地址以及添加默认路由,需要在 ECS 服务器上做如下设置。设置成功后会看到网卡上出现上图中分配的公网 IPv6 地址。所有 zerotier 初次连入都需要进行此步骤。

sudo zerotier-cli set 159924d6308e1d7e allowGlobal=true
sudo zerotier-cli set 159924d6308e1d7e allowDefault=1

配置 IPv6 广播

经过以上步骤,IPv6 网络的基本框架已经搭建好了,现在任何一台通过该 zerotier 网络认证的客户端都会获得一个可用的公网 IPv6 地址,它们彼此之间可以通信。但是现在为止除 ECS 服务器外,其他客户端依然无法访问外部 IPv6 地址及被其他 IPv6 地址访问。这是因为zerotier 申明的公网 IPv6 地址未进行正常的 IPv6 广播,不能被其他的 IPv6 地址知道。

配置 NDPPD 广播

在 ECS 服务器上安装 ndppd 软件以支持 IPv6 地址广播,安装后的 /etc/ndppd.conf 配置文件内容如下。eth0 修改为 ECS 服务器的默认网卡,rule 修改为对应 IPv6 地址网段。

sudo apt install -y ndppd
route-ttl 30000

address-ttl 30000

proxy eth0 {
	router yes
	timeout 500
	autowire no
	keepalive yes
	retries 3
	ttl 30000
	rule 2001:470:811d::/48 {
		auto
		autovia no
	}
}
#安装完成后
#使用以下命令重启 ndppd 服务。
sudo systemctl restart ndppd

配置其他客户端

Linux 客户端

仿照上述步骤安装 zerotier 并加入到 zeoriter 网络中。

curl -s https://install.zerotier.com | sudo bash
sudo zerotier-cli join 159924d6308e1d7e
sudo zerotier-cli set 159924d6308e1d7e allowGlobal=true
sudo zerotier-cli set 159924d6308e1d7e allowDefault=1

Mac 客户端

下载安装包后加入到 zerotier 网络中,并在界面上允许 Global 和 Default,再勾选 connected。正常情况下能够获取到公网 IPv6 地址并添加好 IPv6 路由。如果发生能够 ping 通包括 ECS 服务器的 zerotier 网卡在内的该段公网 IPv6 地址,但无法访问其他 IPv6 地址。那么需要手动添加一条全局 IPv6 路由,命令如下。此处设置的网关是 ECS 服务器的 zerotier 网卡的根据 RFC4193 文档生成的局域网 IPv6 地址。

sudo route add -inet6 -prefixlen 0 default fd15:9924:d630:8e1d:7e99:9333:8a13:b4bb

测试及问题解决

执行完上述步骤可以看到获取到了一个公网 IPv6 地址,尝试是否与外界相通。

ping6 -c 10 ip.sb
ping6 -c 2001:470:811d::80

如果发现网络不通,就将 zerotier web 控制面板上节点使用的公网 IPv6 段换成一个::/64段就可以了,比如2001:470:811d:8::/64

结语

根据实践部分的各个步骤,我们可以搭建一个自主可控的公网 IPv6 网络来进行管理和对外服务。由于公网 IPv6 网络会被全世界 IPv6 地址访问到,每一台连入的客户端的安全都需要提前保证,如果存在弱密码或者无密码服务,就很容易被攻破。当然,zerotier web 控制面板是允许自定义 IPv6 地址的,可以根据自己的喜好将所有连入网络的地址进行更改。

由于 He.net 的 Tunnel Server 不在国内,所获取到的 IPv6 地址在访问国内的 IPv6 地址时延迟会比较高,毕竟需要绕一个大圈。但是对于 zerotier 网络内的客户端之间来说,通信的延迟应该还是比较低的,完全取决于原本到 ECS 服务器的延迟。ECS 服务器在这里也起到了一个路由转发、地址广播的交换机作用。

欢迎走进 IPv6 的世界!