为了节省 ipv4 地址的分配和使用,我决定为主机分配 IPv6。

这一次我装了台 Ubuntu 18,准备用来配置 code-server,就是网页版的 VS Code,这样,我就可以在 iPad 上面写作了。

为宿主机系统 Proxmox 配置 IPv6 可以参考之前的教程哦~

为服务器配置 IPv6 地址

参考:https://www.snel.com/support/how-to-configure-ipv6-with-netplan-on-ubuntu-18-04/

这台服务器安装的时候,我给配的是 IPv4,也可以安装的时候就配成 IPv6 的地址,SSH 用 Cloudflare Spectrum 中转即可。

Ubuntu 18 使用的是 netplan 工具配置网络。

配置文件:/etc/netplan/01-netcfg.yaml

现在刚安装好系统的配置如下

1
2
3
4
5
6
7
8
9
10
11
network:
version: 2
renderer: networkd
ethernets:
ens18:
dhcp6: yes
addresses: [ 192.xxx.xxx.51/29 ]
gateway4: 192.xxx.xxx.49
nameservers:
addresses:
- "1.1.1.1"

主要进行以下改动:

  1. 在 addresses 添加 IPv6 地址 及 对应 CIDR,这里可以配置多个地址。

  2. gateway4 是 IPv4 的网关,IPv6 地址的网关是 gateway6.

  3. IPv6 DNS。如果要解析得到 IPv6 的地址,还需要配置 IPv6 DNS,开始我就是忘了。

两大权威的 IPv6 DNS 如下,任选其一即可:

  • Google, 来源
    • 2001:4860:4860::8888
    • 2001:4860:4860::8844
  • Cloudflare,来源
    • 2606:4700:4700::1111
    • 2606:4700:4700::1001

修改好的配置文件如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
network:
version: 2
renderer: networkd
ethernets:
ens18:
dhcp6: yes
addresses:
- 192.xxx.xxx.51/29
- 2604:xxxx:xxxx:xxxx::3/64
- 2604:xxxx:xxxx:xxxx::4/64
gateway4: 192.xxx.xxx.49
gateway6: 2604:xxxx:xxxx:xxxx::1
nameservers:
addresses:
- "1.1.1.1"
- "2606:4700:4700::1111"
- "2606:4700:4700::1001"

配置好了后,使用以下命令检查语法:

1
netplan try

如果有语法问题,会提示
没问题的话就应用更改

1
netplan apply

测试一下

1
curl ip.sb

会优先显示 IPv6 的地址

如果显示无法解析,可以看看是不是 DNS 解析服务器的问题,测试一下是否连通

1
ping6 2606:4700:4700::1111

为 docker 配置 IPv6

参考:https://medium.com/@skleeschulte/how-to-enable-ipv6-for-docker-containers-on-ubuntu-18-04-c68394a219a2

如果你按官方文档配置 /etc/docker/daemon.json,重启 docker 守护进程会报错的。

这篇参考已经帮我们踩好了坑了,照着参考中的做。

docker 默认不启用 IPv6 网络配置,对于 IPv4,docker 会默认生成一个 172.17.0.1 虚拟子网。

可以通过 ifconfig 查看

1
2
3
4
root@ubuntu:/home/ubuntu# ifconfig
docker0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 172.17.0.1 netmask 255.255.0.0 broadcast 172.17.255.255
inet6 fd00::1 prefixlen 80 scopeid 0x0<global>

对于 IPv6 ,需要手动在配置文件中增加一个虚拟子网。

还是修改这个配置文件 /etc/docker/daemon.json,这个文件默认不存在:

1
2
3
4
{
"ipv6": true,
"fixed-cidr-v6": "fd00::/80"
}

fixed-cidr-v6 就是 IPv6 网络的虚拟子网。

然后重启 docker

1
systemctl restart docker

配置 IPv6 NAT

1
ip6tables -t nat -A POSTROUTING -s fd00::/80 ! -o docker0 -j MASQUERADE

iptables 会将 fd00::/80 网络的请求转发到 docker0 接口

现在,我们可以在 docker 容器中测试 IPv6 的网络连通性

1
docker run --rm -t busybox ping6 -c 4 google.com

运行 IPv6 容器

docker 运行容器时,可以在映射端口时指定某个 IP 地址

比如运行 code-server 时
127.0.0.1:80是宿主机的端口,8080是容器的端口

1
docker run -it -d -p 127.0.0.1:80:8080  -v "$PWD:/home/coder/project"   -u "$(id -u):$(id -g)"   codercom/code-server:latest

或者是 IPv4 公网地址

1
docker run -it -d -p 192.xxx.xxx.52:80:8080  -v "$PWD:/home/coder/project"   -u "$(id -u):$(id -g)"   codercom/code-server:latest

类比 IPv6 时运行方式:

1
docker run -it -d -p [2604:xxxx:xxxx:xxxx::3]:80:8080  -v "$PWD:/home/coder/project"   -u "$(id -u):$(id -g)"   codercom/code-server:latest

第二个 IPv6

1
docker run -it -d -p [2604:xxxx:xxxx:xxxx::4]:80:8080  -v "$PWD:/home/coder/project"   -u "$(id -u):$(id -g)"   codercom/code-server:latest

两个互不影响。

再到 Cloudflare 上配置两个 AAAA 记录,开启 CDN proxy,即使本地没有 IPv6 地址,也可以通过域名访问了,这就是通过 Cloudflare 中转 IPv6 到 IPv4.

其实,通过不同域名进入不同容器,可以使用 nginx 的反向代理来实现,我这也是一种不太优雅的方式,单纯想要试(玩)下(玩) IPv6 罢了。

后来,我索性把虚拟机的 IPv4 地址撤掉了,使用了一段时间,发现纯 IPv6 地址会有点问题,code-server 无法安装拓展。

将 IPv4 地址配置回 netplan 后就可以了,即使 docker 监听的还是 IPv6 地址,也可以安装上拓展了。