教程 · 预计阅读 17 分钟

QEMU KVM 虚拟机走 Linux Mihomo:
NAT 端口转发与用户网络代理两种配法

宿主机上 Mihomo 或 Clash 兼容客户端已经分流正常,一进 virt-manager 里的客户机,apt update 或拉容器镜像又卡住;有人照搬 Windows 教程去改默认网关,有人只知道填 127.0.0.1。本文针对 Linux 宿主机 + QEMU/KVM:先把 libvirt 默认 NAT用户模式网络里「宿主机可达地址」讲清楚,再对比虚拟机内直连代理端口宿主机做端口映射两条路径,并交代 bind-address、防火墙与验证顺序。

QEMU · KVM · Mihomo · NAT · 用户模式网络

1 先纠正两个误区:TUN 在宿主机上,不等于虚拟机自动分流

在 Linux 宿主机上给 Mihomo 或 Clash 兼容内核开 TUN,接管的是宿主机本机发出的 IP 包路径;QEMU/KVM 客户机拥有独立的网络命名空间与路由表,其流量先经过虚拟网卡与 libvirt 定义的转发域,再出到物理网络。除非你在宿主机上做额外的转发、策略路由或透明代理,否则「宿主机 TUN 已开」并不能让虚拟机里的 aptdocker pull 自动获得与桌面浏览器相同的策略。

第二个误区是把默认网关当成「代理开关」。在 libvirt 默认 NAT 里,客户机的默认网关通常指向 virbr0 上的宿主机侧地址(常见为 192.168.122.1),它负责把私网地址做 SNAT 后转发出去;这与「把 HTTP 交给 Mihomo 的混合端口」不是同一层功能。你要的是:虚拟机进程能否TCP 连到宿主机上监听的 7890(示例端口,以你配置为准)一类入站,并在应用层把代理指过去。

因此与站内《Hyper-V 虚拟机走宿主机 Clash》《VMware NAT 与桥接》等文一致:先定拓扑(NAT 还是用户态),再定代理地址写谁,最后才考虑要不要动路由或做 DNAT。

2 libvirt 默认 NAT(virbr0):虚拟机里「宿主机」通常是谁

virt-manager 新建虚拟机时若选用默认网络,一般会挂到名为 default 的 libvirt 网络上,宿主机侧接口多为 virbr0,网段常见为 192.168.122.0/24网关地址常为 192.168.122.1。对客户机而言,这就是默认路由下一跳;同时,它也是你从客户机访问宿主机上服务时最常填写的「宿主机 IP」(与 Windows Hyper-V 默认交换机里「网关即 NAT 端」同一逻辑)。

在宿主机上可用下面命令核对当前 default 网络的 XML 与地址分配(输出以你机器为准):

Shell
virsh net-info default
ip -br addr show virbr0

若你自定义过网络名称或网段,请以 virsh net-dumpxml 中的 ip address 为准,不要死记文档里的示例数字。桥接到物理网卡时,客户机与宿主机可能在同一局域网网段,此时应改用宿主机在物理网段上的 IPv4 作为代理目标,并同样保证 Mihomo 监听在可达接口上。

3 用户模式网络(user / slirp):记住 10.0.2.2

当虚拟机使用 QEMU user networking(旧称 slirp)而非 libvirt 的 NAT 网桥时,客户机常见地址在 10.0.2.0/24,其中 10.0.2.2 是 QEMU 约定给宿主机的别名。此时你应把代理写成 http://10.0.2.2:端口 一类形式,而不是 192.168.122.1,也不要写 127.0.0.1——在客户机内部环回永远指向客户机自己。

用户模式网络的局限是性能与协议支持不如 tap/bridge,且端口映射需通过 hostfwd 等参数显式声明;但它不依赖宿主机桥接权限,在笔记本或受限环境做快速开发机时很常见。virt-manager 里若选择「NAT」而非「用户态」,通常走的是 libvirt 管理的网桥,与上一节的 virbr0 模型更一致,二者不要混用教程里的 IP。

如何快速判断自己属于哪种 在客户机内执行 ip route show default:若下一跳是 192.168.122.1 一类私网且能 ping 通 virbr0 网段,多半是 libvirt NAT;若网卡地址落在 10.0.2.0/24 且文档提到 user,优先尝试 10.0.2.2

4 宿主机 Mihomo:bind-address、Allow LAN 与 Linux 防火墙

在改虚拟机之前,请先在宿主机确认 Mihomo(或图形客户端包装的同一内核)是否对虚拟网卡所在网段开放入站。配置文件中的 bind-address 若为 127.0.0.1,则只有本机环回可连;需要客户机访问时,应使用 0.0.0.0 或明确写成 192.168.122.1 等可达地址,并打开界面中的 Allow LAN 或等价选项,使混合端口监听在非环回地址上。

Linux 宿主机若启用 nftablesfirewalld 或发行版自带防火墙,可能默认丢弃来自 virbr0 转发面的入站 TCP。可用 ss -tlnp | grep 7890(端口替换为你的混合端口)确认监听范围,再在防火墙中为该端口做最小放行,仅面向 192.168.122.0/24 等信任网段。systemd 常驻与最小 YAML 可参考本站《Linux 安装 Mihomo 并开机自启》

若 Mihomo 只跑在 Docker 里,还要注意 published port 是否绑定在 0.0.0.0,以及客户机到 docker0 或宿主机 published 地址的路径是否与 libvirt 路由冲突——这类组合拓扑建议画一张简图再改规则,避免「宿主机 curl 通、虚拟机不通」的假象。

5 配法一(推荐):在虚拟机内显式使用宿主机代理

适用场景:aptcurlgit、浏览器、以及尊重 HTTP_PROXY 环境变量的容器构建;不要求客户机内每一个原始 IP 包都经宿主机策略路由。

在 Linux 客户机中为当前会话导出环境变量(将 HOST 替换为 192.168.122.110.0.2.2,端口以 Mihomo 为准):

Shell
export http_proxy="http://HOST:7890"
export https_proxy="http://HOST:7890"
curl -I --proxy "$http_proxy" https://www.google.com

apt 建议在 /etc/apt/apt.conf.d/95proxy.conf 中写入 Acquire::http::ProxyAcquire::https::Proxy,不要假设 http_proxy 一定被所有后端使用。Podman/Docker 拉镜像可在 /etc/systemd/system/docker.service.d/ 下用 Environment=HTTP_PROXY=... 注入,或为 docker pull 单次加 --build-arg 一类机制,与 CI 文档保持一致。

图形桌面可在「网络代理」中填写同一宿主机地址;与 Windows 虚拟机教程不同,Linux 客户机没有 WinHTTP,但不走代理的守护进程仍然大量存在,需按应用单独配置。

为什么优先这条路径 不动客户机默认路由,排错链条短;宿主机 Mihomo 日志里可直接看到源 IP 是否来自 virbr0 网段,便于对照规则与 DNS 是否命中。

6 配法二:宿主机端口转发(hostfwd / DNAT)何时用

有时你希望客户机内某应用硬编码连本机环回(例如只认 127.0.0.1:7890),或需要在 user 网络下把宿主机某端口映射进客户机。可以在 QEMU 参数中使用 hostfwd=tcp::17890-:7890 这类语法,把宿主机 TCP 17890 转到客户机内 7890;方向与端口请以官方文档为准,这里只强调转发与代理是两条不同管道,不要与「客户机直连宿主机混合端口」混谈。

在 libvirt NAT 场景,更常见需求是反向:外网或局域网访问虚拟机服务,用 libvirt 的 hookiptables/nftvirbr0 上做 DNAT。若你坚持让客户机内应用访问「宿主机上的 127.0.0.1 服务」,可在宿主机用 socatvirbr0 地址上的 TCP 转发到环回口的 Mihomo——这属于进阶运维,需自行评估暴露面与认证。

对大多数「复用宿主机已配好的 Mihomo」的开发需求,配法一已足够;只有在应用无法改代理地址、或需要与现有编排模板对齐时,才值得引入 hostfwd/DNAT 的维护成本。

不要随意改客户机默认网关去「指向 Mihomo」 除非宿主机对该网段承担合法路由器角色并完成转发,否则把网关改成错误地址会直接导致客户机断网;透明代理与旁路网关应单独设计,不在本文展开。

7 virt-manager 与桥接:和 Windows 宿主机场景区分

virt-manager 中切换「NAT」「桥接到 eth0」「macvtap」等选项,本质是更换客户机虚拟网卡后端:桥接时客户机像插在交换机上的第二台物理机,宿主机 IP 应取物理网卡地址;NAT 与用户态则取上一节所述约定网关侧地址。这与 Hyper-V、VMware 系列文章中的「默认 NAT vs 桥接」叙述一一对应,只是 Linux 侧工具换成了 libvirt 与 ip route

若你在同一台机器上同时跑 Kubernetes、Docker 与 KVM,注意多条默认路由与策略路由表是否互相覆盖;Mihomo TUN 与 CNI 网桥并存时,建议先用「客户机显式代理」验证连通,再考虑更复杂的宿主侧转发。

8 验证步骤与常见失败原因

建议按顺序执行,避免同时修改防火墙、YAML 与客户机环境变量后无法归因。

  1. 客户机内 ip route show default,确认下一跳与本文拓扑判断一致。
  2. 客户机 curl -v --proxy http://GATEWAY_IP:PORT https://example.com,确认 TCP 与 TLS 成功。
  3. 宿主机 ss -tlnp 核对 Mihomo 监听地址是否包含 0.0.0.0:PORT 或网关 IP。
  4. 查看 Mihomo 日志是否有来自客户机网段的入站;若无,优先查防火墙与 bind-address。
  5. DNS 异常时对照《DNS 防泄漏》,确认客户机未绕过 Mihomo 的 DNS 入口。

高频失败原因包括:把代理写成 127.0.0.1;未开 Allow LAN;用户态与 libvirt NAT 的 IP 混用;仅设置了 shell 环境变量但 sudo apt 清空了代理;以及 firewalld 拒绝 virbr0 入站。

9 总结

QEMU/KVM 在 Linux 宿主机上复用 Mihomo,关键是先分清libvirt NAT用户模式网络:前者多在 virbr0 网段用网关地址访问宿主机,后者常用 10.0.2.2。宿主机的 TUN 不会自动替客户机分流;最稳妥的路径是在客户机内为 apt、容器引擎与终端显式配置 HTTP(S) 代理,并保证宿主机混合端口对虚拟网段监听且防火墙放行。

端口转发与 DNAT 适合无法改代理地址或需要与现有端口编排对齐的场景,但维护成本更高。与站内 WSL2、Hyper-V、VMware、Parallels 等专题并列,本文补齐了裸机 Linux + KVM这一常见栈,便于你在同一套 Mihomo 规则下覆盖桌面、服务器与虚拟机开发环境。

相比在客户机里反复试错默认路由,在宿主机用图形或 YAML 把监听地址、Allow LAN 与日志一次理顺,再配合客户机侧最小代理配置,整体排障时间通常更短;Clash 兼容内核在规则可读性上的优势,也会延续到多虚拟机并行开发场景。

相比其他同类工具,Mihomo 与 Clash 系在 Linux 服务端与桌面端的文档与社区实践都更连贯;把宿主机监听接口与客户机代理地址对齐后,apt 与镜像拉取会稳定很多。

→ 立即免费下载 Clash,开启流畅上网新体验

标签: QEMU KVM virt-manager Linux Mihomo NAT 用户模式网络 端口转发
Clash Verge Rev 与 QEMU KVM Linux 宿主机代理协同

Clash Verge Rev

新一代 Clash 客户端 · 免费开源

在 Linux 宿主机上统一管理 Mihomo 混合端口、bind-address 与防火墙;KVM 客户机侧用 virbr0 网关或 10.0.2.2 指向同一入站,即可与桌面分流策略对齐。安装包请从本站下载页获取。

TUN 全流量接管 Mihomo 高性能内核 精准规则分流 DNS 防泄漏 多订阅管理

相关阅读