软路由相关

PVE 部署 mihomo 旁路由(透明代理)详细教程:从零开始,只需 PVE 和订阅链接

2026-08-08 58 次阅读 3703 字 · 10 分钟

PVE LXC 部署 mihomo 旁路由(透明代理)详细教程



> 目标:用一台 PVE 上的轻量 LXC 容器跑 mihomo,做成"旁路由"。指定设备把网关和 DNS 指向它,就能实现国内直连、国外走机场节点,并且可以按应用分流。
> 适用版本:PVE 7 / 8 / 9(本文命令在 PVE 9.2.10 实测通过);容器用 Debian 12 模板。
> 你只需要:一台 PVE、一个 Clash 格式的节点订阅链接、一台支持 DHCP 的主路由(爱快 / OpenWrt / 任意路由器)。

> ⚠️ 先说清楚地址问题:下文所有 http://10.10.10.2/... 是作者内网服务器上存放配套文件的地址。你在自己的环境里,要把这些配套文件放到你自己能访问的位置,并把所有 10.10.10.2 替换成你自己的地址。

一、准备清单



1. 配套文件(要放到你自己能访问的 Web 服务器上)



文件用途说明
pgw-install.sh容器内一键安装脚本(mihomo + 面板 + 配置 + 开机自启)必装
pgw-mihomo.yaml基础版配置:国内直连,国外统一走选中节点安装脚本内置,无需手动下载
pgw-mihomo-split.yaml分流版配置:TikTok / AI 固定新加坡,各应用独立分组可选,第十节用
pgw-deploy.zip以上文件打包方便一次性下载
pve-mihomo-oneclick.shPVE 宿主机一键部署脚本(自动建 LXC + 放行 TUN + 装 mihomo)下载


> 注意:pgw-deploy.zip 里的分流版配置可能比单独文件旧,需要最新版请单独下载 pgw-mihomo-split.yaml。

2. 节点订阅



一个 Clash 格式的订阅链接(机场后台复制的那种),例如本文用 http://10.10.10.2/yaml/sub-clash.yaml。请换成你自己的。

3. 主路由



任意支持 DHCP 的路由器即可。本文用爱快做示例。

> 不需要会 PHP、不需要编译、不需要写 Clash 规则——下面的命令全部复制即可。

二、架构原理



flowchart LR
    A[客户端设备] -->|网关/DNS 指向旁路由| B[PVE LXC 容器<br/>mihomo TUN 透明代理]
    B --> C[主路由]
    C --> D[国内直连]
    C --> E[境外走选中节点]


  • 主路由:负责 DHCP 和正常上网,平时什么都不用改;

  • 旁路由(LXC 里的 mihomo):用 TUN 设备透明接管"被指了网关"的设备的流量,按规则分流;

  • 节点:来自订阅链接,在面板里手动选,或自动选延迟最低的。


  • 三、快速方式:一键脚本(推荐)



    不想手动一步步来?PVE 宿主机上一条命令跑完"建 LXC + 放行 TUN + 安装 mihomo + 面板":

    # PVE 宿主机(root 执行)
    wget -qO /tmp/pve-mihomo-oneclick.sh http://10.10.10.2/blog/uploads/yaml/pve-mihomo-oneclick.sh
    bash /tmp/pve-mihomo-oneclick.sh --check    # 先只读检查环境,不会创建任何东西
    bash /tmp/pve-mihomo-oneclick.sh 200 pgw-2026 pgw vmbr0
    


    参数依次是:容器 ID、面板密码、主机名、网桥。脚本会自动探测模板和存储,完成:

  • 选择 / 下载 Debian 12/11 模板

  • 创建 LXC(512M 内存、4G 磁盘、DHCP 拿 IP)

  • 放行 TUN 设备并配置开机自启

  • 容器内一键安装 mihomo + 面板 + geo 数据 + systemd 服务

  • 打印旁路由 IP 和面板地址


  • 跑完直接跳到第八节配主路由即可。想手动一步步来,继续看下面第四~六节。

    > 默认用 DHCP 自动拿 IP;想要固定 IP,就在最后加一个参数,例如 bash /tmp/pve-mihomo-oneclick.sh 200 pgw-2026 pgw vmbr0 10.10.10.200。固定 IP 时网关自动取 PVE 的默认网关,也可用环境变量 PGW_GW 覆盖。

    四、PVE 宿主机:创建 LXC 容器



    以下命令在 PVE 宿主机的 shell(网页控制台或 SSH)执行。模板名和存储名不要手写死,让命令自动找:

    # 1. 更新模板源,自动选一个 Debian 12/11 模板
    pveam update
    TPL=$(pveam available | tr ' ' '\n' | grep -E '^debian-1[12]-standard.*amd64\.tar\.zst$' | head -n1)
    echo "选用模板: $TPL"
    pveam download local "$TPL"
    
    # 2. 自动找一个能放容器磁盘的存储
    STORE=$(pvesm status -content rootdir | awk 'NR>1{print $1; exit}')
    echo "选用存储: $STORE"
    
    # 3. 创建容器:eth0 桥接 vmbr0,DHCP 从主路由自动拿地址
    pct create 200 "local:vztmpl/$TPL" \
      --hostname pgw \
      --memory 512 --swap 0 --cores 1 \
      --net0 name=eth0,bridge=vmbr0,ip=dhcp \
      --rootfs "$STORE:4" \
      --features nesting=1 \
      --unprivileged 0
    
    # 4. 启动
    pct start 200
    


    说明:

  • --unprivileged 0 是特权容器。旁路由需要 TUN 设备,特权容器最省事(本文方案基于特权容器)。

  • 容器 ID 用 200,hostname 用 pgw,都可以按喜好改。


  • 常见报错:

    报错处理
    template: no such template模板版本号不对,用上面的自动选择即可
    storage 'local-lvm' does not exist你的存储不叫这个名字,用 pvesm status -content rootdir 找实际可用的
    bridge vmbr0 相关报错用 ip a 看你实际的网桥名,把 vmbr0 替换掉


    五、PVE 宿主机:放行 TUN 设备(必做,跳过则透明代理不生效)



    这一步在 PVE 宿主机执行。注意:刚创建好的容器里本来就没有 /dev/net/tun,这是正常的,先把配置加上再重启验证:

    # 1. 确保宿主机有 tun 模块和设备
    modprobe tun
    ls -l /dev/net/tun
    
    # 2. tun 模块开机自动加载
    echo tun >> /etc/modules-load.d/tun.conf
    
    # 3. 给容器放行 TUN 设备并挂载(永久生效)
    cat >> /etc/pve/lxc/200.conf <<'EOF'
    lxc.cgroup2.devices.allow: c 10:200 rwm
    lxc.mount.entry: /dev/net/tun dev/net/tun none bind,create=file
    EOF
    
    # 4. 重启容器
    pct reboot 200
    


    重启后验证(在 PVE 宿主机执行):

    pct exec 200 -- ls -l /dev/net/tun
    


    能看到 /dev/net/tun 设备即成功。

    > 如果不做这一步,mihomo 日志会报 Start TUN listening error: configure tun interface: no such file or directory,面板能开但透明代理不生效。

    六、容器内:一键安装 mihomo + 面板



    先在 PVE 宿主机进入容器,再执行安装:

    pct enter 200
    


    在 容器内执行(把最后的 pgw-2026 换成你自己的面板密码,建议只用字母数字):

    wget -qO /tmp/pgw-install.sh http://10.10.10.2/blog/uploads/yaml/pgw-install.sh && bash /tmp/pgw-install.sh pgw-2026
    


    脚本会自动完成 7 步:

  • 安装依赖(curl / unzip / ca-certificates)

  • 下载最新 mihomo 内核(GitHub 失败自动换 gh-proxy 镜像)

  • 下载 metacubexd 节点面板

  • 下载 geo 数据(国内直连规则用)

  • 写入基础配置(节点源指向你的订阅)

  • 开启内核转发 net.ipv4.ip_forward=1

  • 安装 systemd 服务并开机自启


  • 跑完会打印类似这样的信息:

    旁路由 IP   : 10.10.10.100
    节点面板    : http://10.10.10.100:9090/ui   密码: pgw-2026
    客户端设置  : 网关 = 10.10.10.100 , DNS = 10.10.10.100
    


    (IP 是你的容器从 DHCP 实际拿到的地址,示例里的 10.10.10.100 换成你自己的。)

    安装后马上确认三件事(容器内):

    systemctl is-active mihomo        # 应输出 active
    /usr/local/bin/mihomo -v          # 显示内核版本
    curl -s -H "Authorization: Bearer pgw-2026" http://127.0.0.1:9090/version
    


    最后一条应返回类似 {"meta":true,"version":"v1.19.30"}。如果面板密钥不是 pgw-2026,Bearer 后面换成你的密码。

    七、连接面板



    浏览器打开 http://旁路由IP:9090/ui,在弹出的设置里填:

  • 后端地址:http://旁路由IP:9090

  • 密钥:安装时设的密码


  • 如果面板提示"后端无法连接 / unauthorized",都是这两个值不对,改对即可。

    连上后能看到订阅里的全部节点(按协议分组)和两个策略组:🚀 节点选择(手动选)、♻️ 自动选择(自动测速)。

    八、主路由配置(爱快示例):把设备指到旁路由



    这一步在主路由(爱快)里做:

  • 爱快 → 网络设置 → DHCP 服务端 → 静态分配:给旁路由 MAC 绑定固定 IP(避免容器重启后 IP 变了);

  • 需要走代理的设备:在静态分配里,单独把该设备的网关和 DNS 填成旁路由 IP(爱快支持每台设备自定义网关/DNS);

  • 其他设备不动,继续走主路由直连。


  • > 其他路由器同理:要么把某台设备的默认网关/DNS 手动改成旁路由 IP,要么在 DHCP 里按设备指定。

    九、验证



    在被指了网关的设备上:

  • 打开 ipinfo.io,出口 IP 应是你选的节点所在地区;

  • 访问百度等国内网站,应直连、延迟正常;

  • 打开面板的"连接"页,能看到实时流量和命中的规则。


  • 在旁路由容器内也可以直接测代理链路:

    curl -s -o /dev/null -w "%{http_code}\n" -x http://127.0.0.1:7890 https://www.gstatic.com/generate_204
    


    返回 204 说明节点链路正常。

    十、按应用分流(可选)



    基础版只有一个总开关(国外统一走选中节点)。想按应用分流,换成 pgw-mihomo-split.yaml:

    # 容器内执行
    cp /etc/mihomo/config.yaml /etc/mihomo/config.yaml.bak
    wget -qO /etc/mihomo/config.yaml http://10.10.10.2/blog/uploads/yaml/pgw-mihomo-split.yaml
    sed -i 's/CHANGEME/pgw-2026/' /etc/mihomo/config.yaml
    /usr/local/bin/mihomo -t -d /etc/mihomo -f /etc/mihomo/config.yaml   # 校验配置,无输出即通过
    systemctl restart mihomo
    


    > sed 里的 pgw-2026 换成你自己的密码。密码含 / 或 & 会导致替换出错,所以建议用纯字母数字。

    分流版分组:

    分组默认出口
    🎵 TikTok、🤖 AI🇸🇬 新加坡
    🍀 Google/YouTube、👨🏿‍💻 GitHub、📲 Telegram、🪟 Microsoft/OneDrive、💶 PayPal🚀 默认代理(自动测速)
    🐟 漏网之鱼🚀 节点选择
    国内域名/IP直连


    十一、故障排查



    现象原因与处理
    mihomo 报 TUN 错误没放行 /dev/net/tun,回第五节操作
    面板提示后端无法连接后端地址要填 http://旁路由IP:9090,不是 127.0.0.1;密钥要和安装时一致
    面板里没有节点容器里先测订阅是否可达:curl -I http://10.10.10.2/yaml/sub-clash.yaml
    改了配置没变化记得 systemctl restart mihomo
    设备提示无 Internet确认 TUN 已启用、msftconnecttest / msftncsi 直连规则在(基础配置已内置)
    某些节点连不上换协议试试(vless / vmess 兼容性最好),或等节点恢复
    nslookup 超时 / SERVFAILDNS 没监听 53 或上游不可达。检查配置里 dns.listen: 0.0.0.0:53,上游用国内可达的阿里 DoH(dns.alidns.com),不要用 dns.google
    Windows 显示"IPv4 未连接"NCSI 探测走了代理,把 131.107.255.255 加入直连规则(基础配置已内置)


    十二、回滚 / 卸载



  • 只撤销某台设备的代理:把它的 DHCP 静态分配里的网关/DNS 改回主路由即可,旁路由不动;

  • 停用代理:容器内 systemctl disable --now mihomo;

  • 彻底删除:PVE 宿主机上 pct stop 200 && pct destroy 200(会连同容器磁盘一起删,建议先备份配置)。


附录:基础版配置全文(与 pgw-mihomo.yaml 一致)



mixed-port: 7890
allow-lan: true
bind-address: "*"
mode: rule
log-level: info
ipv6: false
unified-delay: true
tcp-concurrent: true

external-controller: 0.0.0.0:9090
external-ui: /etc/mihomo/ui
secret: "改成你的面板密码"

geodata-mode: true
geo-auto-update: true
geox-url:
  geoip: "https://testingcf.jsdelivr.net/gh/MetaCubeX/meta-rules-dat@release/geoip.dat"
  geosite: "https://testingcf.jsdelivr.net/gh/MetaCubeX/meta-rules-dat@release/geosite.dat"
  mmdb: "https://testingcf.jsdelivr.net/gh/MetaCubeX/meta-rules-dat@release/country.mmdb"

profile:
  store-selected: true
  store-fake-ip: true

tun:
  enable: true
  stack: system
  dns-hijack: ["any:53", "tcp://any:53"]
  auto-route: true
  auto-redirect: true
  auto-detect-interface: true

dns:
  enable: true
  listen: 0.0.0.0:53
  enhanced-mode: fake-ip
  fake-ip-range: 198.18.0.1/16
  default-nameserver: [223.5.5.5, 114.114.114.114]
  nameserver:
    - https://dns.alidns.com/dns-query
    - 223.5.5.5
  proxy-server-nameserver:
    - https://dns.alidns.com/dns-query
  direct-nameserver:
    - 223.5.5.5
    - 114.114.114.114
  respect-rules: true
  fake-ip-filter:
    - "+.msftconnecttest.com"
    - "+.msftncsi.com"

proxy-providers:
  airport:
    type: http
    url: "http://10.10.10.2/yaml/sub-clash.yaml"
    interval: 86400
    health-check: {enable: true, url: "https://www.gstatic.com/generate_204", interval: 300}
    path: ./providers/airport.yaml

proxies:
  - {name: 直连, type: direct}
  - {name: dns, type: dns}

proxy-groups:
  - name: 🚀 节点选择
    type: select
    include-all: true
    filter: "(?i)^((?!(直连|dns)).)*$"
  - name: ♻️ 自动选择
    type: url-test
    url: "https://www.gstatic.com/generate_204"
    interval: 300
    tolerance: 50
    include-all: true
    filter: "(?i)^((?!(直连|dns)).)*$"

rules:
  # Windows / 手机连通性探测必须直连,避免"无 Internet"误报
  - DOMAIN-SUFFIX,msftconnecttest.com,DIRECT
  - DOMAIN-SUFFIX,msftncsi.com,DIRECT
  - IP-CIDR,131.107.255.255/32,DIRECT,no-resolve
  - IP-CIDR6,fd3e:4f5a:5b81::1/128,DIRECT,no-resolve
  # 国内直连
  - GEOSITE,cn,直连
  - GEOIP,CN,直连
  # 其余全部走你选的节点
  - MATCH,🚀 节点选择


需要改的就两处:secret(面板密码)和 proxy-providers.airport.url(你的订阅地址)。

评论(0)

5 + 6 =
← 返回首页