PVE 网络配置:网络桥接、DHCP 与端口转发

2055 字7 分钟阅读18 次阅读

一、确认公网网关和物理网卡

在 PVE 宿主机执行:

ip route

示例:default via 103.254.63.1 dev enp3s0

记录以下信息:

  • 公网网卡:enp3s0
  • 公网 IP:103.254.63.80/25
  • 公网网关:103.254.63.1

二、配置 PVE 网络

  • 执行,然后清空内容
nano /etc/network/interfaces
  • 把示例配置内容,修改为你的!
  • 公网网卡:enp3s0
  • 公网 IP:103.254.63.80/25
  • 公网网关:103.254.63.1
auto lo
iface lo inet loopback

# 物理网卡
auto enp3s0
iface enp3s0 inet manual

# 公网桥
auto vmbr0
iface vmbr0 inet static
    address 103.254.63.80/25
    gateway 103.254.63.1
    bridge-ports enp3s0
    bridge-stp off
    bridge-fd 0

# NAT 内网桥
auto vmbr1
iface vmbr1 inet static
    address 192.168.100.1/24
    bridge-ports none
    bridge-stp off
    bridge-fd 0

应用配置:

ifreload -a

远程操作时建议保留当前 SSH 会话,避免网络配置错误后失联。

检查:

ip -br addr
ip route

应看到:

vmbr0    103.254.63.80/25
vmbr1    192.168.100.1/24

默认路由应为:

default via 103.254.63.1 dev vmbr0

三、开启 IPv4 转发

创建配置:

cat >/etc/sysctl.d/99-pve-forward.conf <<'EOF'
net.ipv4.ip_forward=1
EOF

立即生效:

sysctl --system

检查:

sysctl net.ipv4.ip_forward

应显示:net.ipv4.ip_forward = 1

只需配置一次,重启后自动生效。


四、安装 iptables 持久化工具

apt update
apt install iptables-persistent -y

安装时如询问是否保存当前规则,可以选择:Yes


五、配置内网 NAT 上网

  1. 添加 MASQUERADE

先检查规则是否存在,避免重复添加:

iptables -t nat -C POSTROUTING \
  -s 192.168.100.0/24 \
  -o vmbr0 \
  -j MASQUERADE 2>/dev/null || \
iptables -t nat -A POSTROUTING \
  -s 192.168.100.0/24 \
  -o vmbr0 \
  -j MASQUERADE
  1. 允许内网访问公网
iptables -C FORWARD \
  -i vmbr1 -o vmbr0 \
  -s 192.168.100.0/24 \
  -m conntrack --ctstate NEW,ESTABLISHED,RELATED \
  -j ACCEPT 2>/dev/null || \
iptables -A FORWARD \
  -i vmbr1 -o vmbr0 \
  -s 192.168.100.0/24 \
  -m conntrack --ctstate NEW,ESTABLISHED,RELATED \
  -j ACCEPT

允许公网返回数据:

iptables -C FORWARD \
  -i vmbr0 -o vmbr1 \
  -d 192.168.100.0/24 \
  -m conntrack --ctstate ESTABLISHED,RELATED \
  -j ACCEPT 2>/dev/null || \
iptables -A FORWARD \
  -i vmbr0 -o vmbr1 \
  -d 192.168.100.0/24 \
  -m conntrack --ctstate ESTABLISHED,RELATED \
  -j ACCEPT
  1. 保存规则
netfilter-persistent save

检查:

iptables -t nat -L POSTROUTING -n -v
iptables -L FORWARD -n -v

应看到:

MASQUERADE  all  --  192.168.100.0/24  0.0.0.0/0

检查持久化文件:

grep -E 'MASQUERADE|192\.168\.100' /etc/iptables/rules.v4

六、安装并配置 DHCP

安装:

apt install dnsmasq -y

创建配置文件:

cat >/etc/dnsmasq.d/vmbr1.conf <<'EOF'
interface=vmbr1
bind-dynamic

dhcp-range=192.168.100.10,192.168.100.200,255.255.255.0,12h
dhcp-option=option:router,192.168.100.1
dhcp-option=option:dns-server,223.5.5.5,8.8.8.8
EOF

检查配置:

dnsmasq --test

正常应显示:dnsmasq: syntax check OK

启动并设置开机启动:

systemctl enable --now dnsmasq

重启:

systemctl restart dnsmasq

检查:

systemctl status dnsmasq --no-pager

应显示:Active: active (running)

查看 DHCP 日志:

journalctl -u dnsmasq -n 50 --no-pager


七、添加 TCP 端口转发

示例:

  • 公网端口:25701
  • VM IP:192.168.100.185
  • VM 端口:2002
  • 协议:TCP
  1. 添加 DNAT
iptables -t nat -C PREROUTING \
  -i vmbr0 \
  -p tcp \
  --dport 25701 \
  -j DNAT \
  --to-destination 192.168.100.185:2002 2>/dev/null || \
iptables -t nat -A PREROUTING \
  -i vmbr0 \
  -p tcp \
  --dport 25701 \
  -j DNAT \
  --to-destination 192.168.100.185:2002
  1. 允许公网访问 VM
iptables -C FORWARD \
  -i vmbr0 -o vmbr1 \
  -p tcp \
  -d 192.168.100.185 \
  --dport 2002 \
  -m conntrack --ctstate NEW,ESTABLISHED,RELATED \
  -j ACCEPT 2>/dev/null || \
iptables -A FORWARD \
  -i vmbr0 -o vmbr1 \
  -p tcp \
  -d 192.168.100.185 \
  --dport 2002 \
  -m conntrack --ctstate NEW,ESTABLISHED,RELATED \
  -j ACCEPT

返回流量已经由前面的通用规则允许:

vmbr1 → vmbr0,ESTABLISHED,RELATED

因此通常不需要再为每个端口单独添加返回规则。

保存:

netfilter-persistent save

检查:

iptables -t nat -L PREROUTING -n -v --line-numbers
iptables -L FORWARD -n -v --line-numbers

八、端口转发模板

只需要修改以下内容:

  1. 公网端口
  2. VM IP
  3. VM 内部端口
  4. TCP 或 UDP

TCP 模板:

PUBLIC_PORT=25701
VM_IP=192.168.100.185
VM_PORT=2002

iptables -t nat -A PREROUTING \
  -i vmbr0 \
  -p tcp \
  --dport "$PUBLIC_PORT" \
  -j DNAT \
  --to-destination "$VM_IP:$VM_PORT"

iptables -A FORWARD \
  -i vmbr0 -o vmbr1 \
  -p tcp \
  -d "$VM_IP" \
  --dport "$VM_PORT" \
  -m conntrack --ctstate NEW,ESTABLISHED,RELATED \
  -j ACCEPT

netfilter-persistent save

九、删除端口转发规则

方法一:按完整规则删除

删除 DNAT:

iptables -t nat -D PREROUTING \
  -i vmbr0 \
  -p tcp \
  --dport 25701 \
  -j DNAT \
  --to-destination 192.168.100.185:2002

删除 FORWARD:

iptables -D FORWARD \
  -i vmbr0 -o vmbr1 \
  -p tcp \
  -d 192.168.100.185 \
  --dport 2002 \
  -m conntrack --ctstate NEW,ESTABLISHED,RELATED \
  -j ACCEPT

保存:

netfilter-persistent save

方法二:按行号删除

先查看行号:

iptables -t nat -L PREROUTING -n -v --line-numbers
iptables -t nat -L POSTROUTING -n -v --line-numbers
iptables -L FORWARD -n -v --line-numbers

删除第一条 DNAT 规则,执行以下命令:

iptables -t nat -D PREROUTING 1

验证结果

iptables -t nat -L PREROUTING -n -v --line-numbers

例如:删除 PREROUTING 第 5和4 条:必须先删序号大的,再删序号小的

iptables -D FORWARD 5
iptables -D FORWARD 4

删除后保存:

netfilter-persistent save

十、注意事项

所有命令都在 PVE 宿主机执行,VM 网络测试命令除外。 每次新增、删除或修改 iptables 规则后,都要执行:

netfilter-persistent save

常见问题

PVE虚拟机网络超时、容器端口映射及ZFS磁盘容量问题的排查与解决方法如下。已为您整理为留档保存的格式。

一、PVE虚拟机网络超时排查与解决

(以构建Docker错误为例)

当PVE虚拟机内部使用NAT/桥接映射时,网络超时通常由以下三个原因引起。请按优先级依次排查与解决:

  • 配置 Docker 镜像加速源

在VM终端中执行以下命令,直接复制整段命令并按回车:

mkdir -p /etc/docker
cat <<EOF > /etc/docker/daemon.json
{
"registry-mirrors": [
"https://docker.m.daocloud.io",
"https://dockerproxy.net",
"https://mirror.gcr.io"
]
}
EOF
systemctl daemon-reload
systemctl restart docker
  • 修改 DNS 解析

在VM终端中执行以下命令,直接复制整段命令并按回车:

cat <<EOF > /etc/resolv.conf
nameserver 223.5.5.5
nameserver 119.29.29.29
nameserver 8.8.8.8
EOF
  • 修改 Dockerfile(避免拉取语法插件)

进入项目目录(例如 /opt/pan):

cd /opt/pan
nano Dockerfile

在编辑器中找到 # syntax=docker/dockerfile:1.7 这一行,并将其完全删除。保存并退出编辑器后,重新运行构建命令。


二、容器端口映射问题

  • 如果容器的端口映射显示为 127.0.0.1:8080->8080/tcp,这意味着该端口仅能被容器宿主机自身访问,外部无法访问。

解决方法: 将端口映射中的 127.0.0.1 修改为 0.0.0.0

  • 宿主机使用 Caddy 反向代理 VM

推荐直接使用 Caddy 反向代理到虚拟机的内部 IP 和端口:

os.abc.xyz {
    encode zstd gzip

    reverse_proxy http://192.168.100.50:8080 {
        transport http {
            read_timeout 1h
            write_timeout 1h
        }
    }
}

三、前端仅显示单块硬盘容量

示例:OVH 16THDD 安装 PVE9 组 RAID 10,前端仅显示单块硬盘容量,这是因为 ZFS 文件系统设置了配额(quota)

解决方法: 取消 data/zd0 的配额,使其能够使用整个 ZFS 池的容量:

zfs set quota=none data/zd0

执行后,再次运行 zfs list 命令进行确认。如果不成功,继续往下操作!

也就是说,你前面并没有真正执行成功 growpart,或者根本还没执行它。当前这一步还没到 ZFS 扩容,必须先把四个 part5 从约 1.8T 扩到约 3.6T。

先执行:

which growpart

如果没有任何输出,就安装:

apt update
apt install -y cloud-guest-utils

接下来执行:

growpart /dev/sda 5
growpart /dev/sdb 5
growpart /dev/sdc 5
growpart /dev/sdd 5

正常成功时应该看到类似:CHANGED: partition=5 ...

执行完先不要马上做 zpool online -e,先检查:

fdisk -l /dev/sda
fdisk -l /dev/sdb
fdisk -l /dev/sdc
fdisk -l /dev/sdd

我们希望看到 sda5/sdb5/sdc5/sdd5 从:1.8T 变成约:3.6T

如果这一步成功,再执行:

zpool set autoexpand=on data

然后:

zpool online -e data wwn-0x5000cca0bcd72307-part5
zpool online -e data wwn-0x5000cca250d68821-part5
zpool online -e data wwn-0x5000cca0bcdaa5a5-part5
zpool online -e data wwn-0x5000cca097cffe88-part5

最后检查:

zpool list
zfs list

目标应该接近:

data SIZE ≈ 7.2T
data/zd0 AVAIL ≈ 7.0T

后建议你再执行一次:

zpool status
zpool get autoexpand data
zfs get quota data/zd0

正常应该分别看到:

state: ONLINE
autoexpand: on
quota: none

如果是这样,这部分就彻底处理完成了。