Featured image of post Proxmox VE 配置 NAT IPv4+IPv6、分发独立 IPv6 之网络配置模板和理解

Proxmox VE 配置 NAT IPv4+IPv6、分发独立 IPv6 之网络配置模板和理解

PVE 的配置,包括三个网卡(一个处理独立 IPv4,一个处理 NAT4 和 NAT6,一个处理独立 IPv6),适合有一个独立 IPv4 和一个子网 IPv6 的机器。文章详细解析了/etc/network/interfaces 网络配置文件中的各个参数和网卡的作用,适合有一定网络知识和 Proxmox VE 使用经验的读者阅读。

最近弄了一台资源比较充沛的服务器,提供一个 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

官方文档提供的命令是:

1
ifreload -a

但实际上测试发现很多情况下单纯这些命令不能生效,必须要重启机器才行。可能是缓存或者路由表没有刷新的问题。

内核参数

这是/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 网卡:

注意如果没有设置防火墙策略的话,默认是屏蔽所有端口的。所以还不如直接在这里把防火墙的对勾去掉。

Licensed under CC BY-NC-SA 4.0