在 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 |
| DNS | 8.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 测试 |
八、最终效果
虚拟机之间通过
vmbr1局域网互通所有虚拟机上网流量通过宿主 NAT 转发
宿主机对外出口为单一公网 IP(192.140.182.104)
九、完整配置总结
/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"
发表评论