You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将所有QEMU-KVM/Libvirt虚拟机流量通过主机上的V2Ray代理转发?

如何将所有QEMU-KVM/Libvirt虚拟机流量通过主机上的V2Ray代理转发?

我之前也碰到过一模一样的需求——让KVM虚拟机完全不用做任何配置,所有流量自动走主机的V2Ray代理。你之前的问题主要是只处理了TCP的80/443端口,像DNS这类UDP流量根本没被覆盖,而且普通的HTTP代理本来就没法处理UDP,得用透明代理方案才行。下面给你两种可行的方法,一种是用v2raya一键搞定,另一种是手动配置V2Ray和iptables,你可以选适合自己的:

方法一:用v2raya一键配置(最适合新手)

既然你已经用过v2raya,那这个方法最省心,它会自动帮你搞定所有规则:

  1. 打开v2raya的Web界面,进入「设置」页面
  2. 找到「全局透明代理」选项,选择「网卡模式」
  3. 在下拉菜单里选中virbr0(就是libvirt默认的虚拟机网桥)
  4. 保存设置,v2raya会自动配置iptables规则和V2Ray的透明代理参数

这样一来,所有通过virbr0进出的虚拟机流量(包括TCP和UDP)都会被自动转发到V2Ray代理,虚拟机里不用改任何设置,不管是浏览器还是dig命令,都会显示代理后的公网IP。

方法二:手动配置V2Ray+iptables(适合想深入了解的用户)

如果不想用v2raya,我们可以手动配置透明代理,步骤如下:

第一步:修改V2Ray配置文件,添加透明代理入口

找到你的V2Ray配置文件(通常是/etc/v2ray/config.json或者~/.config/v2ray/config.json),在inbounds里添加一个支持TCP/UDP的透明代理入口,同时调整路由规则:

{
  "inbounds": [
    // 保留你原来的SOCKS和HTTP代理入口
    {
      "port": 10808,
      "protocol": "socks",
      "settings": {
        "auth": "noauth",
        "udp": true,
        "ip": "127.0.0.1"
      }
    },
    {
      "port": 10809,
      "protocol": "http",
      "settings": {
        "auth": "noauth"
      }
    },
    // 新增透明代理入口,端口自定义(比如12345)
    {
      "port": 12345,
      "protocol": "dokodemo-door",
      "settings": {
        "network": "tcp,udp",
        "followRedirect": true
      },
      "streamSettings": {
        "sockopt": {
          "tproxy": "tproxy"
        }
      },
      "tag": "transparent"
    }
  ],
  "outbounds": [
    // 保留你原来的V2Ray服务器出口配置
    {
      "protocol": "vmess", // 换成你实际用的协议,比如vless、trojan等
      "settings": {
        "vnext": [
          {
            "address": "你的V2Ray服务器IP",
            "port": 你的服务器端口,
            "users": [
              {
                "id": "你的UUID",
                "alterId": 0,
                "security": "auto"
              }
            ]
          }
        ]
      },
      "streamSettings": {
        "network": "tcp", // 换成你实际的传输方式,比如ws、grpc等
        "security": "tls"
      },
      "tag": "proxy"
    },
    // 可选:添加直连出口,用于本地非代理流量
    {
      "protocol": "freedom",
      "settings": {},
      "tag": "direct"
    }
  ],
  "routing": {
    "rules": [
      // 把透明代理入口的流量全部转发到V2Ray服务器
      {
        "type": "field",
        "inboundTag": ["transparent"],
        "outboundTag": "proxy"
      }
    ]
  }
}

修改完后重启V2Ray服务:

sudo systemctl restart v2ray

第二步:配置iptables规则,接管虚拟机所有流量

首先开启IP转发并保存配置(确保重启后生效):

sudo sysctl -w net.ipv4.ip_forward=1
sudo sysctl -w net.ipv6.conf.all.forwarding=1
sudo sysctl -w net.ipv4.conf.all.send_redirects=0
# 写入配置文件
echo "net.ipv4.ip_forward=1" | sudo tee -a /etc/sysctl.conf
echo "net.ipv6.conf.all.forwarding=1" | sudo tee -a /etc/sysctl.conf
echo "net.ipv4.conf.all.send_redirects=0" | sudo tee -a /etc/sysctl.conf
sudo sysctl -p

然后配置TCP流量转发:

# 把virbr0进来的所有TCP流量重定向到透明代理端口
sudo iptables -t nat -A PREROUTING -i virbr0 -p tcp -j REDIRECT --to-port 12345

再配置UDP流量的TProxy转发(因为UDP不能直接用REDIRECT,需要用TProxy):

sudo iptables -t mangle -A PREROUTING -i virbr0 -p udp -j TPROXY --on-port 12345 --tproxy-mark 0x1/0x1
# 添加路由规则,让标记过的UDP流量走本地路由
sudo ip rule add fwmark 0x1 lookup 100
sudo ip route add local 0.0.0.0/0 dev lo table 100

如果需要支持IPv6,执行类似的IPv6规则:

sudo ip6tables -t mangle -A PREROUTING -i virbr0 -p udp -j TPROXY --on-port 12345 --tproxy-mark 0x1/0x1
sudo ip -6 rule add fwmark 0x1 lookup 100
sudo ip -6 route add local ::/0 dev lo table 100

第三步:测试效果

在虚拟机里执行以下命令,检查公网IP是否为代理IP:

# 测试TCP流量
curl ifconfig.me
# 测试DNS流量
dig +short myip.opendns.com @resolver1.opendns.com

如果两者都显示代理后的IP,说明配置成功了!

备注:内容来源于stack exchange,提问作者Malvo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.22 15:51:59