在 Proxmox VE 9 上创建虚拟局域网并通过宿主公网 NAT 上网

在 Proxmox VE 9 上创建虚拟局域网并通过宿主公网 NAT 上网

环境示例:
系统版本:Proxmox VE 9.0.3
公网 IP:192.140.182.104
外网网关:192.140.182.1
外网物理口:enp96s0f0np0
默认桥接口:vmbr0
新增内网桥接:vmbr1
内网网段:10.10.0.0/24


一、创建虚拟局域网 Bridge(vmbr1)

PVE 的网络核心是 Linux Bridge。
我们创建一个 不绑定物理网卡 的虚拟桥接,用于虚拟机互联。

编辑网络配置文件:

nano /etc/network/interfaces

添加以下内容:

auto vmbr1
iface vmbr1 inet static
    address 10.10.0.1/24
    bridge-ports none
    bridge-stp off
    bridge-fd 0

保存并应用:

ifreload -a

验证:

ip a show vmbr1

应看到:

inet 10.10.0.1/24

二、启用 IPv4 转发

PVE 默认不转发内外网流量,我们需手动开启。

echo 1 > /proc/sys/net/ipv4/ip_forward

永久生效:

echo "net.ipv4.ip_forward=1" > /etc/sysctl.d/99-pve-nat.conf
sysctl --system

三、配置 NAT 出网(nftables 方式)

PVE 9 默认使用 nftables 替代传统 iptables。

我们要做的就是在 NAT 表的 postrouting 链上添加 SNAT 规则,让虚拟机流量伪装成宿主机公网 IP。

注意:PVE 的默认路由出接口是 vmbr0,不是物理网卡!

创建或替换 /etc/nftables.conf

cat >/etc/nftables.conf <<'EOF'#!/usr/sbin/nft -fflush ruleset# 放行转发流量table inet filter {
  chain forward {    type filter hook forward priority 0;
    policy accept;
  }
}# NAT 出网规则table ip nat {
  chain postrouting {    type nat hook postrouting priority 100;
    policy accept;    # 内网通过 vmbr0 出公网
    ip saddr 10.10.0.0/24 oif "vmbr0" snat to 192.140.182.104    # 可选备用规则(直接物理口出)
    ip saddr 10.10.0.0/24 oif "enp96s0f0np0" snat to 192.140.182.104
  }
}
EOF

启动并启用:

systemctl enable nftables
systemctl restart nftables

验证:

nft list ruleset

输出应包含:

ip saddr 10.10.0.0/24 oif "vmbr0" snat to 192.140.182.104

四、虚拟机网络配置

创建虚拟机时,网卡桥接选择 vmbr1,模式 virtio

在虚拟机中配置静态网络:

参数
IP 地址10.10.0.10
子网掩码255.255.255.0
网关10.10.0.1
DNS8.8.8.8

Linux 示例:

ip addr add 10.10.0.10/24 dev eth0
ip route add default via 10.10.0.1echo "nameserver 8.8.8.8" > /etc/resolv.conf

五、验证

1️⃣ 宿主机连通性

ping -c 3 8.8.8.8

2️⃣ 虚拟机到宿主机

ping 10.10.0.1

3️⃣ 虚拟机上网测试

ping -c 3 8.8.8.8
curl -s https://ifconfig.me

返回的公网 IP 应为 192.140.182.104,说明 NAT 成功。


六、可选:给 vmbr1 加上 DHCP 服务(自动分配 IP)

安装 dnsmasq:

apt install -y dnsmasq

配置文件 /etc/dnsmasq.d/vmbr1.conf

interface=vmbr1
bind-interfaces
dhcp-range=10.10.0.100,10.10.0.200,255.255.255.0,12h
dhcp-option=3,10.10.0.1
dhcp-option=6,223.5.5.5,8.8.8.8

启动服务:

systemctl enable dnsmasq
systemctl restart dnsmasq

虚拟机网络改为 DHCP 即可自动获取 IP。


七、常见问题

现象原因解决
VM 能 ping 网关但上不了网NAT 未命中(出接口错误)改成 oif "vmbr0"
宿主机能上网但 VM 不行转发未开echo 1 > /proc/sys/net/ipv4/ip_forward
ping 8.8.8.8 不通上级路由防火墙拦截snat to 公网IP 替换 masquerade
PVE 防火墙开启丢弃转发流量pve-firewall stop 测试

八、最终效果


九、完整配置总结

/etc/network/interfaces

auto lo
iface lo inet loopback

iface enp96s0f0np0 inet manual

auto vmbr0
iface vmbr0 inet static
    address 192.140.182.104/24
    gateway 192.140.182.1
    bridge-ports enp96s0f0np0
    bridge-stp off
    bridge-fd 0

iface enp96s0f1np1 inet manual

auto vmbr1
iface vmbr1 inet static
    address 10.10.0.1/24
    bridge-ports none
    bridge-stp off
    bridge-fd 0source /etc/network/interfaces.d/*

/etc/nftables.conf

#!/usr/sbin/nft -fflush ruleset

table inet filter {
  chain forward {    type filter hook forward priority 0;
    policy accept;
  }
}

table ip nat {
  chain postrouting {    type nat hook postrouting priority 100;
    policy accept;
    ip saddr 10.10.0.0/24 oif "vmbr0" snat to 192.140.182.104
    ip saddr 10.10.0.0/24 oif "enp96s0f0np0" snat to 192.140.182.104
  }
}

如果重启后无网络,执行以下命令:


# 1. 重新加载网络接口

ifreload -a


# 2. 确保内核开启转发

sysctl -w net.ipv4.ip_forward=1


# 3. 手动重载 nftables 规则

systemctl restart nftables


# 4. 暂停 PVE 自带防火墙(若启用过)

pve-firewall stop


# 5. 验证 NAT 是否生效

nft list ruleset | grep -E "snat|masquerade"


发表评论

必填

选填

选填

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。