如果手上有 /64 这种整段 IPv6 的 KVM 虚拟机的话,可以玩一下用这种方式开小鸡。
这篇之前的博文介绍了 Proxmox VE 配置 IPv6 的情况,其实原理都是一样的。不过这里操作的是 Ubuntu,主要用 netplan。
Incus/LXD 是另一个虚拟机管理平台,对比 Proxmox VE 的优点是可以在任意 Linux 系统上安装,且不需要更换内核,也更节省资源。缺点是功能不如 PVE 多。关于 Incus 的安装和 Web UI 的使用可以去网上搜搜教程。
Incus 是 LXD 的一个社区版 Fork,两者没什么大的区别。但由于 LXD 改用了 Canonical 的许可证,且需要 snap 安装,所以一般建议用 Incus。
母鸡配置:
网关:2403:71c0:2000::1
拥有的子网:2403:71c0:2000:a217::/64
首先在/etc/sysctl.conf 里开启 IPv6 转发:
1
|
net.ipv6.conf.all.forwarding=1
|
然后 sysctl -p 生效。
在 Incus UI 里加一个 vmv6 的网卡:
关闭 IPv4 地址和 IPv6 的 NAT。这里给的 vmv6 网卡是/64 整个子网,网关是 2403:71c0:2000:a217::1212(母鸡本机 IPv6)。
母鸡 netplan:
1
2
3
4
5
6
7
8
9
10
11
|
network:
version: 2
ethernets:
eth0:
addresses:
- 2403:71c0:2000:a217::1212/128
routes:
- to: "2403:71c0:2000::1/128"
scope: link
- to: "::/0"
via: "2403:71c0:2000::1"
|
几个地方需要注意:
-
母鸡上的 eth0 实际上相当于物理网卡,我们虽然用 incus vmv6 代理了 IPv6 的子网分发,但真正最终上网要经过的还是这个物理网卡。
-
母鸡 IPv6 是 2403:71c0:2000:a217::1212/128,只分配单个/128 的,防止和 vmv6 的冲突。2403:71c0:2000:a217::1212 是母鸡的本机 IPv6,也相当于作为小鸡的网关。
-
走物理网关地址单个 2403:71c0:2000::1/128 配置直接 link,不需要路由转发。
-
母鸡上网直接走物理网关 2403:71c0:2000::1,vmv6 上网实际上最终的流量也还是会被路由到这个物理网关,正如前面所说的。
效果:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
|
root@anontokyo:~# ip a
...
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
link/ether 00:16:3c:ad:57:5d brd ff:ff:ff:ff:ff:ff
altname enp0s3
altname ens3
inet6 2403:71c0:2000:a217::1212/128 scope global
valid_lft forever preferred_lft forever
inet6 fe80::216:3cff:fead:575d/64 scope link
valid_lft forever preferred_lft forever
...
19: vmv6: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
link/ether 00:16:3e:b0:8e:a5 brd ff:ff:ff:ff:ff:ff
inet6 2403:71c0:2000:a217::1212/64 scope global
valid_lft forever preferred_lft forever
inet6 fe80::216:3eff:feb0:8ea5/64 scope link
valid_lft forever preferred_lft forever
root@anontokyo:~# ip -6 r
2403:71c0:2000::1 dev eth0 proto static metric 1024 pref medium
2403:71c0:2000:a217::1212 dev eth0 proto kernel metric 256 pref medium
2403:71c0:2000:a217::/64 dev vmv6 proto kernel metric 256 pref medium
fe80::/64 dev eth0 proto kernel metric 256 pref medium
fe80::/64 dev veth478de25 proto kernel metric 256 pref medium
fe80::/64 dev br-9714ce2fd96a proto kernel metric 256 pref medium
fe80::/64 dev veth62aa42c proto kernel metric 256 pref medium
fe80::/64 dev docker0 proto kernel metric 256 pref medium
fe80::/64 dev vmv6 proto kernel metric 256 pref medium
default via 2403:71c0:2000::1 dev eth0 proto static metric 1024 pref medium
|
给虚拟机(容器)增加 vmv6 网卡,内部映射的名称为 eth0:
虚拟机(容器)netplan:
1
2
3
4
5
6
7
8
9
10
|
network:
version: 2
ethernets:
eth0:
dhcp6: false
addresses:
- 2403:71c0:2000:a217::114/64
routes:
- to: default
via: "2403:71c0:2000::1212"
|
注意:
- 小鸡 IPv6 配置 2403:71c0:2000:a217::114/128,这里写/128 或/64 都无所谓,反正子网内 IPv6 都能随便拿。
- 配置所有 IPv6 走 2403:71c0:2000::1212 网关,也就是母鸡的 IPv6 地址,由母鸡作为路由器帮我们代理上网。
效果:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
root@ubuntu:~# ip a
...
22: eth0@if23: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
link/ether 00:16:3e:27:b9:5a brd ff:ff:ff:ff:ff:ff link-netnsid 0
inet6 2403:71c0:2000:a217:216:3eff:fe27:b95a/64 scope global mngtmpaddr noprefixroute
valid_lft forever preferred_lft forever
inet6 2403:71c0:2000:a217::114/64 scope global
valid_lft forever preferred_lft forever
inet6 fe80::216:3eff:fe27:b95a/64 scope link
valid_lft forever preferred_lft forever
root@ubuntu:~# ip -6 r
2403:71c0:2000:a217::/64 dev eth0 proto kernel metric 256 pref medium
2403:71c0:2000:a217::/64 dev eth0 proto ra metric 1024 mtu 1500 hoplimit 64 pref medium
fe80::/64 dev eth0 proto kernel metric 256 pref medium
default via fe80::216:3eff:feb0:8ea5 dev eth0 proto ra metric 1024 expires 1727sec mtu 1500 hoplimit 64 pref medium
|
可以看到小鸡除了我们配置的 IPv6 之外还通过 SLAAC 自己拿到了一个 IPv6。另外这里走网关 2403:71c0:2000::1212 配置好像没生效,走的是 fe80::216:3eff:feb0:8ea5 这个母鸡 vmv6 网卡的本地链路地址,不过没关系,和走公网 IPv6 效果是一样的。
修改完 netplan 都要记得 netplan apply。
然后配置母鸡的 iptables:
1
2
3
4
|
ip6tables -A FORWARD -i vmv6 -j ACCEPT
ip6tables -A FORWARD -o vmv6 -j ACCEPT
netfilter-persistent save # 持久化iptables规则
|
(这里用 AI 帮忙解释一下)这两条 ip6tables 命令配置了 IPv6 的网络地址转换 (NAT) 和转发规则:
ip6tables -A FORWARD -i vmv6 -j ACCEPT
- 允许从 vmv6 接口进入的流量转发
-A FORWARD
: 在 FORWARD 链上添加规则
-i vmv6
: 匹配从 vmv6 接口进入的流量
-j ACCEPT
: 接受这些流量
ip6tables -A FORWARD -o vmv6 -j ACCEPT
- 允许转发到 vmv6 接口的流量
-o vmv6
: 匹配发往 vmv6 接口的流量
-j ACCEPT
: 接受这些流量
这两条规则一起工作:
- 允许内部网络 (vmv6) 的流量转发到外网 (eth0)
- 允许外网的响应流量返回到内部网络
运行ndpresponder:
1
|
ndpresponder -i eth0 -n 2403:71c0:2000:a217::/64
|
这里的配置是在 eth0 物理网卡上回应我们母鸡的整个 IPv6 段,让物理网关把发给我们这个 IP 段底下任何一个 IP 地址的数据包都转发给我们。
测试小鸡能否上网:
1
2
|
root@ubuntu:~# curl ipv6.ip.sb
2403:71c0:2000:a217:216:3eff:fe27:b95a
|
测试外网能否能联通小鸡(换一台 VPS 运行):
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
root@dev:~# ping 2403:71c0:2000:a217:216:3eff:fe27:b95a
PING 2403:71c0:2000:a217:216:3eff:fe27:b95a(2403:71c0:2000:a217:216:3eff:fe27:b95a) 56 data bytes
64 bytes from 2403:71c0:2000:a217:216:3eff:fe27:b95a: icmp_seq=1 ttl=54 time=2.18 ms
64 bytes from 2403:71c0:2000:a217:216:3eff:fe27:b95a: icmp_seq=2 ttl=54 time=1.66 ms
^C
--- 2403:71c0:2000:a217:216:3eff:fe27:b95a ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1001ms
rtt min/avg/max/mdev = 1.658/1.919/2.180/0.261 ms
root@dev:~# ping 2403:71c0:2000:a217::114
PING 2403:71c0:2000:a217::114(2403:71c0:2000:a217::114) 56 data bytes
64 bytes from 2403:71c0:2000:a217::114: icmp_seq=1 ttl=54 time=1.69 ms
64 bytes from 2403:71c0:2000:a217::114: icmp_seq=2 ttl=54 time=1.59 ms
^C
--- 2403:71c0:2000:a217::114 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1002ms
rtt min/avg/max/mdev = 1.591/1.642/1.694/0.051 ms
|
不管是我们自己配上的 IPv6 还是 SLAAC 拿到的 IPv6 都是可以联通的。