Featured image of post 用 Incus/LXD 在 VPS 上开小鸡,给虚拟机分发 /64 的独立 IPv6

用 Incus/LXD 在 VPS 上开小鸡,给虚拟机分发 /64 的独立 IPv6

使用 Incus 在拥有整段/64 的 IPv6 的 Ubuntu 主机上开虚拟机(Container、容器),配置虚拟网卡的 IPv6 地址分发,让虚拟机和主机能够使用独立的 IPv6 地址。原理与之前介绍的 Proxmox VE 上配置的相同。

如果手上有 /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 的网卡:

image-20250114094226086

关闭 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:

image-20250114112232264

虚拟机(容器)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) 和转发规则:

  1. ip6tables -A FORWARD -i vmv6 -j ACCEPT
    • 允许从 vmv6 接口进入的流量转发
    • -A FORWARD: 在 FORWARD 链上添加规则
    • -i vmv6: 匹配从 vmv6 接口进入的流量
    • -j ACCEPT: 接受这些流量
  2. ip6tables -A FORWARD -o vmv6 -j ACCEPT
    • 允许转发到 vmv6 接口的流量
    • -o vmv6: 匹配发往 vmv6 接口的流量
    • -j ACCEPT: 接受这些流量

这两条规则一起工作:

  1. 允许内部网络 (vmv6) 的流量转发到外网 (eth0)
  2. 允许外网的响应流量返回到内部网络

运行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 都是可以联通的。

Licensed under CC BY-NC-SA 4.0