最近弄了一台资源比较充沛的服务器,提供一个 IPv4 地址和/64 子网的 IPv6 地址,所以就装个 Proxmox VE 来开小鸡玩玩。在配置的过程中学到了很多新知识,这里特此记录一下。
安装
Proxmox VE 是一个类似 VMware ESXi 的软件,用于服务器上的虚拟机管理,和 ESXi 一样提供 Web 面板。但与之不同的是,Proxmox 是开源软件,并且基于 Debian 技术栈,因此可定制程度更高。可以直接安装官方提供的 ISO 镜像,也可以先安装 Debian 系统后再根据官方教程安装软件本体。
配置网卡
安装完之后就是进行网络配置了。我参考了这个一键脚本的网络配置,如下:
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
30
31
32
33
34
35
36
37
38
|
auto lo
iface lo inet loopback
auto vmbr0
iface vmbr0 inet static
address 202.194.15.228/24
gateway 202.194.15.254
bridge_ports ens33
bridge_stp off
bridge_fd 0
iface vmbr0 inet6 static
address 2001:da8:7000:15:20c:29ff:feff:e247/128
gateway fe80::5298:b8ff:fed2:3001
auto vmbr1
iface vmbr1 inet static
address 172.16.1.1/24
bridge_ports none
bridge_stp off
bridge_fd 0
post-up echo 1 > /proc/sys/net/ipv4/ip_forward
post-up echo 1 > /proc/sys/net/ipv4/conf/vmbr1/proxy_arp
post-up iptables -t nat -A POSTROUTING -s '172.16.1.0/24' -o vmbr0 -j MASQUERADE
post-down iptables -t nat -D POSTROUTING -s '172.16.1.0/24' -o vmbr0 -j MASQUERADE
iface vmbr1 inet6 static
address 2001:db8:1::1/64
post-up sysctl -w net.ipv6.conf.all.forwarding=1
post-up ip6tables -t nat -A POSTROUTING -s 2001:db8:1::/64 -o vmbr0 -j MASQUERADE
post-down sysctl -w net.ipv6.conf.all.forwarding=0
post-down ip6tables -t nat -D POSTROUTING -s 2001:db8:1::/64 -o vmbr0 -j MASQUERADE
auto vmbr2
iface vmbr2 inet6 static
address 2001:da8:7000:15:20c:29ff:feff:e247/64
bridge_ports none
bridge_stp off
bridge_fd 0
|
由于对于这种 IPv4 和 IPv6 双栈的机器,网络配置起来还是比较复杂的。比如因为只有一个 IPv4,所以需要做 NAT;而 IPv6 有一个子网,所以可以从其中取出/128 的 IP 地址分配给小鸡。那么这样就需要配置多网卡,用来区分各种网络配置情况。
可以提前学习一下官方文档中配置网络的部分。不过官方文档写的太简单了,不支持很多复杂的情况。可以了解一下其中的概念,比如桥接、路由、伪装各种模式等等。
下面就来详细解析一下这份配置。
原始网络
Debian 12 机器安装好,还没有安装 PVE 的原始网络配置如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
# This file describes the network interfaces available on your system
# and how to activate them. For more information, see interfaces(5).
source /etc/network/interfaces.d/*
# The loopback network interface
auto lo
iface lo inet loopback
# The primary network interface
# This is an autoconfigured IPv6 interface
allow-hotplug ens33
iface ens33 inet static
address 202.194.15.228/24
gateway 202.194.15.254
|
我们给机器配置了一个 202.194.15.228 的静态 IP,属于/24 网段。实际上在这个机房里可以拿到 202.194.15.x 的任何一个 IP(没有 MAC 地址绑定),只要不被别人占用。
配置文件中没有 IPv6,但使用 ip a 命令查看还是有 IPv6 的,也能访问 IPv6 的网站。这是因为机房网络启用了 SLACC 来自动进行配置。在这种情况下,我们自动拿到 IPv6 的后缀就是主机 MAC 地址的变种。比如 MAC 地址是 00:0c:29:ff:e2:47,那么拿到的 IPv6 是 2001:da8:7000:15:20c:29ff:feff:e247。
有关 SLACC 的内容,可以看下面几篇博文,非常精彩:
[译]理解 IPv6:Link-Local 地址的魔法
[译]理解 IPv6:组播 MAC 地址
[译]理解 IPv6:什么是被请求节点 (solicited-node) 组播 (预备知识)
[译]理解 IPv6:什么是被请求节点 (solicited-node) 组播
[译]理解 IPv6:Ping 过程与被请求节点 (solicited-node) 组播的联系
ens33 网卡
ens33 相当于机器本身的物理网卡。在 PVE 的配置中就没有对其进行额外配置了。实际上是把它作为了 manual 模式,相当于以下配置:
1
|
iface ens33 inet manual
|
相关资料:https://askubuntu.com/questions/645000/what-is-the-difference-between-iface-eth0-inet-manual-and-iface-eth0-inet-static
vmbr0 网卡
我们把 ens33 作为 manual 模式,实际上就是要把其原本的功能转移到 vmbr0 这个 PVE 创建的虚拟网卡上。
1
2
3
4
5
6
|
iface vmbr0 inet static
address 202.194.15.228/24
gateway 202.194.15.254
bridge_ports ens33
bridge_stp off
bridge_fd 0
|
可以看到我们为它配置了 static IP,将原始配置中本来为 ens33 配置的 address 和 gateway 放到这里了。并且指定了bridge_ports ens33
,意思是桥接到 ens33 网卡上。
我们知道现在家里办宽带运营商都会发给你一个光猫。这个光猫在默认配置下承担了光纤信号调制解调和路由器两个功能。比如电信的光猫,会开启一个前缀是 ChinaNet 的 WiFi。但我们可以打电话要求客服远程将我们的光猫改成「桥接模式」,然后我们在光猫的网络接口上接一个自己的路由器,用路由器拨号和发射 WiFi 信号,而光猫只作为调制解调的用途。这样就可以在路由器上做一些自己的定制了,比如安装广告屏蔽插件等等。这边虚拟网卡的桥接模式也是同样的道理。因为我们使用桥接模式,因此原来的 ens33 就不应该配置自己的 IP 和网关了,而是全权交给 vmbr0。
vmbr0 网卡同样配置 IPv6:
1
2
3
|
iface vmbr0 inet6 static
address 2001:da8:7000:15:20c:29ff:feff:e247/128
gateway fe80::5298:b8ff:fed2:3001
|
可以看到这里的 IPv6 地址设的就是我们刚刚 SLACC 自动获取到的那个 IPv6 地址。当然,如果你的机器拥有一整个 IPv6 子网所有 IP 的使用权限的话,也可以自己设置,比如设成 2001:da8:7000:15::1。
网关这里我们手动配置了。而在原始配置中是通过 SLACC 的 RA(Router Advertisement)自动获取的。这里的网关就是在原始配置里运行ip -6 r
命令,会看到这样一行,就是获取到的 IPv6 网关了:
1
|
default via fe80::5298:b8ff:fed2:3001 dev vmbr0 proto kernel metric 1024 onlink pref medium
|
这里的网关以 fe80 开头,是 link local 的地址。有关 link local,前面贴的一串博文中已经详细介绍了。
vmbr1 网卡
vmbr1 网卡是用于 NAT 的,划分了一个 IPv4 内部子网和一个 IPv6 内部子网,并且分别使用 iptables 配置了 NAT4 和 NAT6:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
auto vmbr1
iface vmbr1 inet static
address 172.16.1.1/24
bridge_ports none
bridge_stp off
bridge_fd 0
post-up echo 1 > /proc/sys/net/ipv4/ip_forward
post-up echo 1 > /proc/sys/net/ipv4/conf/vmbr1/proxy_arp
post-up iptables -t nat -A POSTROUTING -s '172.16.1.0/24' -o vmbr0 -j MASQUERADE
post-down iptables -t nat -D POSTROUTING -s '172.16.1.0/24' -o vmbr0 -j MASQUERADE
iface vmbr1 inet6 static
address 2001:db8:1::1/64
post-up sysctl -w net.ipv6.conf.all.forwarding=1
post-up ip6tables -t nat -A POSTROUTING -s 2001:db8:1::/64 -o vmbr0 -j MASQUERADE
post-down sysctl -w net.ipv6.conf.all.forwarding=0
post-down ip6tables -t nat -D POSTROUTING -s 2001:db8:1::/64 -o vmbr0 -j MASQUERADE
|
所有小鸡,如果接入这个虚拟网卡,都需要使用 172.16.1.1 作为 IPv4 的网关,使用 2001:db8:1::1 作为 IPv6 的网关,以便 NAT 转发流量。
IPv6 按照设计标准其实是不必使用 NAT 的,但为什么这里还是配置了 NAT6?因为在有些网络情况下小鸡无法分配到独立的 IPv6 地址,这一点我们在下面一节来看。
vmbr2 网卡
接下来我们配置 vmbr2 网卡,用于把机器拥有的/64 网段中的 IP 分给小鸡。
1
2
3
4
5
6
|
auto vmbr2
iface vmbr2 inet6 static
address 2001:da8:7000:15:20c:29ff:feff:e247/64
bridge_ports none
bridge_stp off
bridge_fd 0
|
这里的子网掩码配置的是/64,代表该网卡管理/64 段的 IP 地址。同时将 2001:da8:7000:15:20c:29ff:feff:e247 本机 IP 作为网关。小鸡需要分配 IP 时需要将其设置为自己的网关。
此时还有一个问题,就是我们可能拿到了/64 段的 IP(即:通过 SLACC 路由器发送给我们的信息是子网前缀为 64),但实际上不能自由分配其中的 IP,即实际上我们拿到的仅仅是一个与我们 MAC 地址对应的/128 的 IP。到底是否可以自由分配,可以通过下面这个脚本验证:
https://github.com/spiritLHLS/ecs/blob/main/archive/eo6s.sh
其实原理就是用 ip addr add 命令随便拿一个子网下的 IP 附加到机器上,然后访问 IP 地址查询看看出网 IP 是否是新附加的这个 IP。如果是的话,说明我们附加新 IP 成功了,也就是可以自由地拿到子网下任何一个 IP。那么我们当然就也可以从中给小鸡自由分配 IPv6 地址了。
而如果显示子网掩码为 128 的话,就不能自由分配了。这时候 vmbr2 网卡就失去了存在的意义,我们就只能用 vmbr1 网卡给小鸡开 NAT6 的 IP 了。
网络生效
改动网络配置文件后,一般我们使用这样的命令使其生效:
1
2
|
service networking restart
systemctl restart networking.service
|
官方文档提供的命令是:
但实际上测试发现很多情况下单纯这些命令不能生效,必须要重启机器才行。可能是缓存或者路由表没有刷新的问题。
内核参数
这是/etc/network/interfaces 中新增的参数:
1
2
3
4
5
6
7
|
net.ipv6.conf.all.forwarding=1
net.ipv6.conf.all.proxy_ndp=1
net.ipv6.conf.default.proxy_ndp=1
net.ipv6.conf.vmbr0.proxy_ndp=1
net.ipv6.conf.vmbr1.proxy_ndp=1
net.ipv6.conf.vmbr2.proxy_ndp=1
net.ipv4.ip_forward=1
|
其中 proxy_ndp 是为了在网卡上代理小鸡的 NDP(Neighbor Discovery Protocol)协议。关于这个协议可以自行谷歌。
运行 ndpresponder
在一些情况下 NDP 协议可能没法被完全代理,可以参考这篇博文。因此可以使用这个软件:
https://github.com/yoursunny/ndpresponder
这是一个用户态的 NDP 代理工具。配置 systemd 服务(/etc/systemd/system/ndpresponder.service)如下:
1
2
3
4
5
6
7
8
9
10
11
|
[Unit]
Description=NDPPD Daemon
After=network.target
[Service]
ExecStart=/usr/local/bin/ndpresponder -i vmbr0 -n 2001:da8:7000:15:20c:29ff:feff::/64
Restart=on-failure
RestartSec=2
[Install]
WantedBy=multi-user.target
|
小鸡配置
完全使用 NAT4 和 NAT6 只需要配置一个 vmbr1 网卡就行,如下:
当然如果不使用 IPv6,可以不用填。
如果还需要独立 IPv6 的话,需要增加一个 vmbr2 网卡:
注意如果没有设置防火墙策略的话,默认是屏蔽所有端口的。所以还不如直接在这里把防火墙的对勾去掉。