PVE + ImmortalWrt 专用出口网关 + VM 默认翻墙 + 公网 SSH 回程修复(策略路由)
写在前面:这篇文章解决什么问题
这是一个真实 Homelab 场景:
-
家庭主路由:小米 AX3600(
192.168.31.1/24) -
PVE 宿主机在家庭 LAN 中
-
PVE 内额外创建一张 仅供虚拟机使用的专用出口网络
10.10.10.0/24 -
使用 ImmortalWrt VM 作为该网段的出口网关(运行 Passwall 透明代理)
-
指定 Linux VM(示例名:
cn-pek-home)- 管理流量走家庭 LAN
- 业务流量默认走 ImmortalWrt 翻墙出口
同时还有一个非常现实的需求:
我需要从公网通过端口转发 SSH 到这台 VM。
这正是本文的核心难点:
默认翻墙 + 公网 DNAT SSH = 非对称路由(SSH 会断)
本文给出的是工程级、可长期运行的最终解法。
网络拓扑总览
1️⃣ 家庭物理网络(LAN)
-
网段:
192.168.31.0/24 -
网关:
192.168.31.1 -
包含:
- PVE 宿主机
- 家中设备
- VM 的管理网卡
2️⃣ PVE 专用出口网络(虚拟)
- 网段:
10.10.10.0/24 - 网关:
10.10.10.1(ImmortalWrt) - 仅用于需要翻墙的 VM
第 1 步:在 PVE 中创建专用网桥 vmbr1
编辑 PVE 宿主机网络配置:
nano /etc/network/interfaces
添加:
auto vmbr1
iface vmbr1 inet manual
bridge-ports none
bridge-stp off
bridge-fd 0
应用并检查:
ifreload -a
ip link show vmbr1
第 2 步:创建 ImmortalWrt VM(双网口)
网卡规划(非常重要)
| 网卡 | PVE 网桥 | 角色 | 地址 |
|---|---|---|---|
| eth0 | vmbr1 | LAN(内侧) | 10.10.10.1/24 |
| eth1 | vmbr0 | WAN(外侧) | 192.168.31.x |
ImmortalWrt 内配置要点:
- LAN:
10.10.10.1/24,可开 DHCP - WAN:DHCP 获取
192.168.31.x - Passwall:按个人节点配置(本文不展开)
第 3 步:业务 VM(cn-pek-home)双网卡配置
示例 VM 网卡:
eth0→192.168.31.5/24(管理)eth1→10.10.10.165/24(出口)
3.1 切换默认出口为 ImmortalWrt(翻墙)
ip route replace 192.168.31.0/24 dev eth0
ip route replace default via 10.10.10.1 dev eth1
验证:
ip route
curl -4 https://ipinfo.io/ip
第 4 步:问题出现 —— 公网 SSH 突然失效
公网做了端口转发:
公网:522 → 192.168.31.5:22
现象:
- 内网 SSH 正常
- 公网 SSH 卡住 / 直接断
原因(非常关键)
- SSH 流量 进来 走
eth0(DNAT) - 回包 却走默认路由
eth1 → 10.10.10.1 - NAT 状态无法闭环 → 连接失败
这是经典的:
非对称路由(Asymmetric Routing)
第 5 步:正确解法 —— 策略路由(mgmt 表)
目标拆解:
- 业务流量:继续默认翻墙(eth1)
- 管理回包(SSH):强制走 eth0 → 192.168.31.1
5.1 创建路由表
mkdir -p /etc/iproute2
touch /etc/iproute2/rt_tables
echo "100 mgmt" >> /etc/iproute2/rt_tables
5.2 配置 mgmt 路由表(必须包含直连网段)
ip route replace 192.168.31.0/24 dev eth0 scope link table mgmt
ip route replace default via 192.168.31.1 dev eth0 table mgmt
5.3 策略规则(核心)
ip rule add from 192.168.31.5/32 table mgmt priority 100
ip route flush cache
验证铁证:
ip rule
ip route get 1.1.1.1 from 192.168.31.5
应看到:
via 192.168.31.1 dev eth0 table mgmt
第 6 步:rp_filter(必做)
sysctl -w net.ipv4.conf.all.rp_filter=2
sysctl -w net.ipv4.conf.default.rp_filter=2
sysctl -w net.ipv4.conf.eth0.rp_filter=2
sysctl -w net.ipv4.conf.eth1.rp_filter=2
第 7 步:持久化(systemd)
脚本
nano /usr/local/sbin/mgmt-routing.sh
#!/usr/bin/env bash
sleep 2
ip route replace 192.168.31.0/24 dev eth0 scope link table mgmt
ip route replace default via 192.168.31.1 dev eth0 table mgmt
ip rule add from 192.168.31.5/32 table mgmt priority 100 2>/dev/null || true
sysctl -w net.ipv4.conf.all.rp_filter=2
sysctl -w net.ipv4.conf.default.rp_filter=2
sysctl -w net.ipv4.conf.eth0.rp_filter=2
sysctl -w net.ipv4.conf.eth1.rp_filter=2
ip route flush cache
chmod +x /usr/local/sbin/mgmt-routing.sh
systemd 服务
nano /etc/systemd/system/mgmt-routing.service
[Unit]
Description=Management policy routing
After=network-online.target
Wants=network-online.target
[Service]
Type=oneshot
ExecStart=/usr/local/sbin/mgmt-routing.sh
RemainAfterExit=yes
[Install]
WantedBy=multi-user.target
systemctl daemon-reload
systemctl enable mgmt-routing.service
systemctl start mgmt-routing.service
最终验收清单
-
公网 SSH:
ssh -p 522 [email protected] -
内网 SSH:
ssh [email protected] -
默认翻墙:
curl -4 ipinfo.io/ip -
回程路径:
ip route get 1.1.1.1 from 192.168.31.5
总结
这套方案解决的是一个真实生产级问题:
在同一台 VM 上,同时满足「默认翻墙」与「公网管理入口稳定」。
关键不是代理软件,而是:
- Linux 策略路由
- 正确拆分“业务流量”和“管理流量”
至此,这个坑算是真正填平了。
#PVE #ImmortalWrt #OpenWrt #Passwall #Policy Routing #Ip Rule #DNAT #Homelab