一:IPV4地址富裕的情况,无需NAT,直接让虚拟机拥有公网IP。
让你的 PVE 虚拟机获得与宿主机同网段(192.168.1.x)的独立 IP 地址(如 192.168.1.3),这样它就和宿主机以及其他内网设备处于平等的地位,可以直接被网络中的其他设备访问。
这种方法通常被称为桥接模式(Bridged Mode)。下面是详细的步骤和解释。
核心原理
默认情况下,PVE 会为虚拟机创建一个名为 `vmbr0` 的桥接设备(Bridge),但这个桥默认可能只绑定了你的物理网卡用于对外通信,而其自身则使用 NAT 模式。我们需要将其配置为**纯桥接**,不设置 NAT,让虚拟机直接获取你内网的 IP 地址。
网络拓扑简图:
[ 物理网络 ] (192.168.1.0/24)
|
[ 物理网卡 (eth0/enpXsY) ] <---> [ 网桥 (vmbr0) ] <---> [ 宿主机系统 (192.168.1.2) ]
|
+---> [ 虚拟机A (192.168.1.3) ]
|
+---> [ 虚拟机B (192.168.1.4) ]
网桥 `vmbr0` 就像一个虚拟交换机,宿主机和所有虚拟机都连接到这个“交换机”上,从而处在同一个局域网中。
---
步骤一:检查当前网络配置
1. 登录 PVE 宿主机的 Shell(通过网页界面点击节点 -> `Shell`,或使用 SSH)。
2. 查看当前的网络配置:
cat /etc/network/interfaces
3. 你可能会看到类似下面的配置(这是常见的默认 NAT 配置):
auto lo
iface lo inet loopback
auto eth0
iface eth0 inet manual
auto vmbr0
iface vmbr0 inet static
address 192.168.1.2/24
gateway 192.168.1.1
bridge-ports eth0
bridge-stp off
bridge-fd 0
# 下面这两行是 NAT 配置,需要删除
bridge-nf-call-iptables 0 # 这行不一定需要删,但下面那行必须删
post-up echo 1 > /proc/sys/net/ipv4/ip_forward
post-up iptables -t nat -A POSTROUTING -s '192.168.1.0/24' -o eth0 -j MASQUERADE
post-down iptables -t nat -D POSTROUTING -s '192.168.1.0/24' -o eth0 -j MASQUERADE
步骤二:修改 PVE 宿主机的网络配置
我们需要编辑 `/etc/network/interfaces` 文件,移除 NAT 相关的配置,将其变为一个纯粹的桥接。
1. 使用文本编辑器(如 `nano`)编辑网络配置文件:
nano /etc/network/interfaces
2. 将 `vmbr0` 的配置修改为如下所示(**重点关注被注释掉和删除的部分**):
auto lo
iface lo inet loopback
# 物理网卡,无需IP,交给桥接
auto eth0
iface eth0 inet manual
# 纯桥接配置
auto vmbr0
iface vmbr0 inet static
address 192.168.1.2/24 # 宿主机的IP
gateway 192.168.1.1 # 你的路由器网关
bridge-ports eth0 # 将物理网卡 eth0 加入桥接
bridge-stp off # 禁用生成树协议
bridge-fd 0 # 转发延迟设置为0
# !!! 确保删除了以下 NAT 和防火墙伪装规则 !!!
# post-up echo 1 > /proc/sys/net/ipv4/ip_forward
# post-up iptables -t nat -A POSTROUTING -s '192.168.1.0/24' -o eth0 -j MASQUERADE
# post-down iptables -t nat -D POSTROUTING -s '192.168.1.0/24' -o eth0 -j MASQUERADE
重要说明:
`bridge-ports eth0`:这行是关键,它把物理网卡和虚拟桥接器连接起来。请确保 `eth0` 是你的正确物理网卡名称(也可能是 `enp3s0`, `ens18` 等,可以用 `ip a` 命令查看)。
一定要删除或注释掉(`#`) 那三行 `post-up` 和 `post-down` 的 iptables 规则,它们负责 NAT 转发。如果不删除,虚拟机可能仍然能通过 NAT 上网,但无法获得独立的 IP。
3. 保存并退出编辑器(在 nano 中按 `Ctrl+X`,然后按 `Y`,最后按 `Enter`)。
步骤三:应用新的网络配置
警告:这一步可能会暂时中断你的网络连接。强烈建议你通过物理控制台(显示器键盘直接连接宿主机)操作,或者确保你有其他方式能访问主机(例如 iDRAC, iLO 等带外管理)。
1. 使用以下命令重启网络服务(如果连接断开,稍等片刻重新连接):
systemctl restart networking
或者更彻底地重启整个网络栈:
ifdown --all && ifup --all
2. 检查网络是否恢复正常:
ping 192.168.1.1 # 尝试ping你的路由器
如果宿主机本身还能正常上网,说明桥接配置正确。
步骤四:配置虚拟机
现在,你需要修改虚拟机的硬件和网络设置。
1. 在 PVE 网页界面中,关闭你的虚拟机。
2. 进入虚拟机的 “硬件”选项卡。
3. 找到你的 “网络设备”(通常是 `net0`)。
4. 点击 “编辑”。
5. 确保配置如下:
桥接(Bridge):`vmbr0` (这就是我们刚才配置的纯桥接)
模型:根据客户机系统选择,如 `VirtIO (半虚拟化)`(性能最佳)、`E1000`(Intel 兼容)等。
VLAN tag:如果你的网络有 VLAN,在这里设置,否则留空。
防火墙:按需勾选。
它应该看起来像:`Bridge: vmbr0, Model: VirtIO (paravirtualized), Firewall: No`
6. 点击 “确定”。
步骤五:启动虚拟机并配置其网络
现在启动虚拟机。在虚拟机操作系统内部,你需要像配置一台物理机一样配置它的网络。
以 Linux 虚拟机(使用 netplan/systemd-networkd)为例:**
编辑网络配置文件(路径可能因发行版而异):
# 例如 Ubuntu 18.04+ / Debian 使用 netplan
sudo nano /etc/netplan/01-netcfg.yaml
配置内容如下(使用你的静态 IP 192.168.1.3):
network:
version: 2
ethernets:
ens18: # 这是虚拟机内的网卡名,请用 `ip a` 命令查看实际名称
dhcp4: no
addresses: [192.168.1.3/24]
gateway4: 192.168.1.1
nameservers:
addresses: [192.168.1.1, 8.8.8.8] # 你的路由器和公共DNS
应用配置:
sudo netplan apply
以 Windows 虚拟机为例:
1. 打开“控制面板” -> “网络和 Internet” -> “网络和共享中心”。
2. 点击“更改适配器设置”。
3. 右键点击你的以太网卡,选择“属性”。
4. 双击 “Internet 协议版本 4 (TCP/IPv4)”。
5. 选择“使用下面的 IP 地址”:
IP 地址: 192.168.1.3
子网掩码: 255.255.255.0 (会自动填充)
默认网关: 192.168.1.1
6. 选择“使用下面的 DNS 服务器地址”:
首选 DNS 服务器:192.168.1.1 (或你的路由器地址)
备用 DNS 服务器:8.8.8.8 (可选)
7. 点击“确定”保存。
验证
完成以上所有步骤后:
1. 在虚拟机中,尝试 `ping 192.168.1.1`(网关)和 `ping 192.168.1.2`(宿主机)。
2. 在你的宿主机或网络中的其他电脑上,尝试 `ping 192.168.1.3`(虚拟机)。
3. 虚拟机应该可以正常访问互联网。
如果一切顺利,你的虚拟机现在已经拥有了一个独立的局域网 IP 地址,不再通过 NAT 转换。
二:宿主机只有一个IPV4。虚拟机使用SNAT上网及端口转发实现对外业务。
让一台只有一个公网IP的PVE主机上的虚拟机上网,并配置端口转发,使用SDN的SNAT功能和iptables-persistent是一个不错的方案。下面我将为你梳理配置步骤。
首先,我用一个表格来汇总主要的配置步骤,以便你有一个整体的认识:
| 步骤编号 | 配置内容 | 主要操作/文件 | 说明 |
| :------- | :----------------- | :------------------------------------------------- | :----------------------------------------------------------- |
| 1 | 安装SDN及相关组件 | `apt install libpve-network-perl dnsmasq frr-pythontools` | 确保PVE具备SDN功能 |
| 2 | 修改宿主机网络配置 | `/etc/network/interfaces` 末尾添加 `source /etc/network/interfaces.d/*` | 使SDN生成的配置生效 |
| 3 | 创建SDN区域 (Zone) | PVE Web界面 -> 数据中心 -> SDN -> 区域 -> 创建 | 类型选择 "Simple" (适用于单节点) |
| 4 | 创建虚拟网络 (VNet) | PVE Web界面 -> 数据中心 -> SDN -> Vnets -> 创建 | 关联上述区域,**勾选SNAT** |
| 5 | 应用SDN配置 | PVE Web界面 -> 数据中心 -> SDN -> "应用" | 在所有节点上生成并激活网络配置 |
| 6 | 虚拟机连接VNet | 虚拟机硬件设置 -> 网络设备 -> 桥接到创建的VNet | |
| 7 | 配置虚拟机网络 | 虚拟机内部设置静态IP或DHCP | 网关指向VNet的IP |
| 8 | 确认宿主机IP转发 | `/etc/sysctl.conf` 中 `net.ipv4.ip_forward=1` | 执行 `sysctl -p` 生效 |
| 9 | 设置端口转发规则 | `iptables -t nat -A PREROUTING` 等命令 | 将公网端口映射到虚拟机内网IP和端口 |
| 10 | 持久化iptables规则 | `netfilter-persistent save` | 安装 `iptables-persistent` 后使用 |
下面我们来详细看看这些步骤。
配置SDN实现虚拟机上网(SNAT)
1. 安装SDN组件:首先确保你的PVE主机(通常是8.x版本)已安装必要的SDN软件包。通过SSH登录PVE宿主机,执行:
apt update
apt install libpve-network-perl dnsmasq frr-pythontools
对于PVE 7.x,也需要安装这些包。
2. 修改宿主机网络配置:编辑PVE宿主机的网络配置文件 `/etc/network/interfaces`,在文件末尾添加一行:
source /etc/network/interfaces.d/*
或者更加精确的
source /etc/network/interfaces.d/sdn
这行配置用于包含SDN自动生成的网络配置文件。保存后,建议通过物理控制台或确保有其他方式访问主机,然后运行 `systemctl restart networking` 重启网络服务使更改生效。
3. 创建SDN区域 (Zone):
* 在PVE的Web管理界面中,进入 "数据中心"*级别。
* 选择 SDN 标签页,然后进入 "区域" (Zones)子选项卡。
* 点击"创建",选择类型为"Simple"(这种类型适合单节点环境)。
* 为此区域设置一个名称(例如 `my_snat_zone`),其他设置可根据需要保持默认或调整。
* 点击 "创建"完成区域的添加。
4. 创建虚拟网络 (VNet) 并启用SNAT:
* 仍在 SDN 标签页下,进入 "Vnets"子选项卡。
* 点击 "创建"。
* 为此Vnet设置一个名称(例如 `my_vnet`)。
* 在 "Zone"下拉菜单中,选择上一步创建的SDN区域(如 `my_snat_zone`)。
* 重要:在 "IPv4" 和 "IPv6" 设置部分,填写你计划为虚拟机分配的内网网段(例如 `192.168.99.0/24`)和网关地址(例如 `192.168.99.1`)。
* 最关键的一步:勾选"SNAT" (Source NAT) 选项。这将自动设置源地址转换,使虚拟机的流量能够通过宿主机的外网IP出去。
* 点击 "创建"完成Vnet的添加。
5. 应用SDN配置:在 SDN 主标签页的右上角,点击 "应用" (Apply) 按钮。这会在所有节点上生成并激活SDN配置。你可以在 `/etc/network/interfaces.d/` 目录下查看生成的配置文件(如 `sdn` 文件)。
6. 将虚拟机连接到VNet:
* 关闭你的虚拟机。
* 在虚拟机的 "硬件"配置中,编辑其网络设备。
* 将 "桥接"选项改为你刚才创建的VNet(例如 `my_vnet`)。
* 保存配置并启动虚拟机。
7. 配置虚拟机内部网络:
* 在虚拟机操作系统中,为其网卡设置静态IP地址,该地址需在你在VNet中定义的网段内(例如 `192.168.99.100`),并将网关指向VNet的网关地址(例如 `192.168.99.1`)。或者,如果VNet配置了DHCP(SDN的IPAM功能),虚拟机也可以自动获取IP地址。
* 配置完成后,虚拟机通常应该已经能够通过宿主机的外网IP访问互联网了。
🔧 配置端口转发 (DNAT)
如果你的虚拟机提供了Web服务(80端口)、SSH服务(22端口)等,并希望外部网络能够访问,就需要配置端口转发(DNAT)。
1. 确保宿主机启用IP转发:检查 `/etc/sysctl.conf` 文件中是否有 `net.ipv4.ip_forward=1`。如果没有,请添加或修改,然后执行 `sysctl -p` 使其生效。
2. 设置iptables端口转发规则:假设你要将宿主机的公网IP的TCP 8080端口转发到内网虚拟机 `192.168.99.100` 的80端口(Web服务),在PVE宿主机上执行:
# 目的地址转换 (DNAT):将到达宿主机外网IP8080端口的流量转发给虚拟机的80端口
iptables -t nat -A PREROUTING -p tcp --dport 8080 -j DNAT --to-destination 192.168.99.100:80
# 源地址转换 (SNAT/MASQUERADE):使返回的流量能够正确经过宿主机发往请求者
iptables -t nat -A POSTROUTING -p tcp -d 192.168.99.100 --dport 80 -j MASQUERADE
# 允许转发到的目标虚拟机的流量
iptables -A FORWARD -d 192.168.99.100 -p tcp --dport 80 -j ACCEPT
请根据你的实际情况修改公网端口、虚拟机内网IP和目标端口。
3. 安装并配置iptables-persistent以保存规则:为了避免重启后iptables规则丢失,需要持久化规则。
# 安装 iptables-persistent,安装过程中可能会询问是否保存当前规则,可以选择是
apt install iptables-persistent
# 手动保存当前的iptables规则(包括NAT表和FILTER表中FORWARD链的规则)
netfilter-persistent save
这样,规则会被保存到 `/etc/iptables/rules.v4` 和 `rules.v6`,并在系统启动时自动恢复。
💎一些提醒
防火墙:如果PVE或虚拟机系统开启了防火墙,需要确保相应的端口(如你转发的8080端口)是开放的。
安全:端口转发会将内部服务暴露到公网,请务必做好服务本身的安全防护(如使用强密码、及时更新软件、配置防火墙等)。
SDN的灵活性:上述基于SDN Simple区域的配置适合单节点。如果你有多个PVE节点组成的集群,可以考虑使用SDN的VLAN或VxLAN等其他区域类型,它们能提供更复杂的网络隔离和路由功能。
故障排查:
* 在各个环节使用 `ping` 和 `traceroute` 命令检查网络连通性。
* 在PVE宿主机上使用 `iptables -t nat -L -n -v` 检查NAT规则是否正确配置和匹配流量。
* 查看虚拟机内服务是否确实在预期的端口上监听(`netstat -tulnp`)。
* 查看系统日志(如 `/var/log/syslog`)获取错误信息。
三:宿主机只有一个IPV4。使用SNAT实现IPV4上网及端口转发实现对外业务。及拥有一个段的ipv6实现虚拟机拥有独立公网IPV6。同时支持ipv4及ipv6网络。(IPV4为SNAT,IPV6为独立IP)
为宿主机配置IPv4 SDN SNAT + 端口转发 和 IPv6 直接分配公网地址是一个非常经典且高效的方案。下面是详细的配置步骤。
网络架构概述
* IPv4: 虚拟机通过SDN获得私有IPv4地址(如 `192.168.10.0/24`),通过SNAT共享宿主机的单一公网IPv4上网。入站流量通过`iptables`进行DNAT端口转发。
* IPv6: 虚拟机直接配置来自你的 `/64` 公网IPv6段的地址,每个虚拟机都拥有独立的公网IPv6地址,无需NAT,可实现端到端的直接通信。
第一部分:配置 SDN 实现 IPv4 SNAT
这部分的配置与上前面一、二中的类似,是IPv4上网的基础。
1. 安装SDN组件(如果尚未安装):
apt update && apt install libpve-network-perl
2. 确保加载接口目录:检查 `/etc/network/interfaces` 文件末尾是否有 `source /etc/network/interfaces.d/*`,如果没有则添加并重启网络。
3. 创建SDN区域和VNet:
* 区域 (Zone): 在 数据中心 -> SDN -> 区域 中创建。类型选择 `simple`,名称如 `ipv4-snat-zone`。
* VNet: 在 数据中心 -> SDN -> Vnets 中创建。
* 名称:如 `ipv4-vnet`
* 区域:选择刚创建的 `ipv4-snat-zone`
* IPv4/CIDR:设置一个内网网段,例如 `192.168.10.1/24`。这将自动设置网关为 `192.168.10.1`。
* 务必勾选 `SNAT`选项。
* 点击 “应用” 使SDN配置生效。
4. 将虚拟机连接到VNet:在虚拟机的硬件设置中,将网络设备桥接到新创建的 `ipv4-vnet`。
5. 配置虚拟机内部IPv4网络:在虚拟机内,手动设置静态IP(如 `192.168.10.100`,网关 `192.168.10.1`,DNS `8.8.8.8`)或确认它已通过DHCP获取到地址。此时虚拟机应能通过SNAT访问IPv4互联网。
第二部分:配置宿主机 IPv6 桥接和支持
这是实现IPv6直通的关键。我们需要将宿主的IPv6公网段直接桥接到虚拟机上。
1. 编辑宿主机网络配置:
编辑 `/etc/network/interfaces`,找到你的主网桥(通常是 `vmbr0`)的配置部分。
auto vmbr0
iface vmbr0 inet static
address 你的公网IPv4地址/子网掩码 # 例如 203.0.113.10/24
gateway 你的IPv4网关 # 例如 203.0.113.1
bridge-ports eth0 # 你的物理网卡
bridge-stp off
bridge-fd 0
# --- 添加以下IPv6配置 ---
iface vmbr0 inet6 static
address 你的公网IPv6地址/64 # 宿主机的固定IPv6地址,例如 2001:db8:abcd::10/64
gateway 你的IPv6网关 # 通常是网段的第一个地址,例如 fe80::1 或 2001:db8:abcd::1
# 关键:启用IPv6路由转发和无状态地址自动配置(SLAAC)
accept-ra 2
autoconf 0
重要参数解释:
* `accept-ra 2`: 接受路由器通告(Router Advertisements),即使主机配置了静态IPv6地址也需要此设置,这对于SLAAC工作是必需的。
* `autoconf 0`: 禁用自动配置,因为我们使用静态地址。
2. 启用IPv6转发:
编辑 `/etc/sysctl.conf`,确保包含以下行:
net.ipv6.conf.all.forwarding=1
net.ipv6.conf.default.forwarding=1
应用更改:`sysctl -p`
3. 重启宿主机网络:
systemctl restart networking
重启后,用 `ip a show vmbr0` 检查IPv6地址是否配置成功。
---
第三部分:为虚拟机分配公网 IPv6 地址
现在宿主机已经准备好了,我们需要让虚拟机也能获得IPv6地址。
1. 编辑虚拟机配置:
对于需要公网IPv6的虚拟机,关闭后编辑其配置文件(位于 `/etc/pve/qemu-server/VMID.conf`)。
找到网络配置行(如 `net0`),在其末尾添加 `ipconfig6` 选项。
修改前:
`net0: virtio=BC:24:11:...,bridge=ipv4-vnet`
修改后:
`net0: virtio=BC:24:11:...,bridge=vmbr0,ipconfig6=2001:db8:abcd::100/64`
参数解释:
* `bridge=vmbr0`: 至关重要!虚拟机必须连接到物理网桥 `vmbr0`,而不是SDN的 `ipv4-vnet`,才能直接获取IPv6。
* `ipconfig6=2001:db8:abcd::100/64`: 为虚拟机指定一个静态的公网IPv6地址。你可以从你的 `/64` 段中任意分配。
替代方案(推荐用于灵活性):你也可以在PVE网页界面的虚拟机 “选项”选项卡中,使用 “IP配置” 来设置IPv6地址,而无需手动编辑配置文件。
2. 配置虚拟机内部IPv6网络:
* Linux虚拟机:通常无需额外配置。Proxmox会在启动虚拟机时通过cloud-init或直接配置将指定的IPv6地址设置到虚拟机的网卡上。你可以启动后使用 `ip a` 命令检查。
* Windows虚拟机:需要进入系统后,在网卡的IPv6属性中手动设置你在上一步中分配的IPv6地址、子网前缀长度(`64`)和默认网关(通常是网段的第一个地址,如 `2001:db8:abcd::1`)。
3. 测试虚拟机IPv6:
启动虚拟机,在内部测试:
ping6 google.com
ping6 2001:4860:4860::8888 # Google IPv6 DNS
第四部分:配置 IPv4 端口转发 (DNAT)
由于虚拟机IPv4是内网地址,外部访问需要端口转发。
1. 设置转发规则(例如将宿主机的TCP 80端口转发到虚拟机 `192.168.10.100` 的80端口):
iptables -t nat -A PREROUTING -p tcp --dport 80 -j DNAT --to-destination 192.168.10.100:80
iptables -A FORWARD -p tcp -d 192.168.10.100 --dport 80 -j ACCEPT
# 如果出站接口不是eth0,请替换
iptables -t nat -A POSTROUTING -s 192.168.10.0/24 -o eth0 -j MASQUERADE
2. 安装并保存iptables规则:
apt install iptables-persistent
# 安装过程中询问是否保存当前规则时,选择“是”
# 或之后手动保存
netfilter-persistent save
最终配置总结
* 虚拟机网络硬件:应有两个网络设备(网卡)。
1. 一个连接至 `ipv4-vnet` (用于IPv4 SNAT上网和端口转发)。
2. 一个连接至 `vmbr0` (用于获取公网IPv6地址)。如果你的虚拟机只需要IPv6,可以只保留连接至 `vmbr0` 的网卡,并在其 `ipconfig` 中同时配置IPv4和IPv6地址。
3.netfilter-persistent新增后需要重启或者重载
1.重新加载规则 netfilter-persistent reload 2.重启服务 sudo iptables-restore < /etc/iptables/rules.v4 # 或者重启 netfilter-persistent 服务 sudo systemctl restart netfilter-persistent # 或者 sudo service netfilter-persistent restart
* 防火墙:确保宿主机和虚拟机的防火墙(如 `pve-firewall`、`ufw`、`firewalld`)允许转发的流量以及相关的端口。
这个方案完美地结合了IPv4的便利性(解决公网IPv4不足)和IPv6的先进性(每个设备都有公网地址),是目前最理想的网络配置方式之一。