OpenVPN 和 Clash TUN mode 共存的一个方案

在边缘的临时办公场景,发现无法保持 Clash 开启 TUN mode 时与 OpenVPN 同时生效,必须关掉 TUN mode 才能正常生效。

蹲坑的时候浏览到了 LINUX DO 上的这个帖子并解决了问题。我更详细地记录下我的操作流程和一些思考。

先执行lian的1和2,验证可以正常访问目标站点后,先关闭 OpenVPN。

找到目标虚拟网卡

执行 ifconfig|grep -i utun,记住现有的虚拟网卡名称。

例如我的机器,目前只有这5个。

开启 OpenVPN 的代理,再次输入刚刚的指令,会发现多了一个虚拟网卡,在我的机器上是 utun4

找到对应路由表信息

由于我的机器是 utun4 所以后续使用 utun4 查询,老哥们记得自行更换。

执行 netstat -rn|grep -i utun4 获取 utun4 的路由表信息。

推理出 ovpn 的配置

netstat 给出的是 CIDR 表示法,需要转换回 .ovpn 支持的传统的网络地址+子网掩码的写法。

我在这里记录一下推理,不感兴趣的可以跳过,看不懂也没关系直接跳过,可能写的人类不一定能看懂lol

# 10.10.128/17
-> 10.10.128.0/17
-> /17
   => 11111111.11111111.10000000.00000000
   => 255.255.128.0
-> 10.10.128.0 255.255.128.0

# 10.10.128.248/30
-> 10.10.128.248/30
-> /30
   => 11111111.11111111.11111111.11111100
   => 2个0
   => 2^2 = 4
   => 248 % 4 = 0
   => {
        10.10.128.248:网络地址
        10.10.128.249:VPN 服务器端(网关)
        10.10.128.250:VPN 客户端端(你的设备)
        10.10.128.251:广播地址
      }
-> 点对点链路配置,不用手动配,OpenVPN 会自动管理

# 10.10.128.249
-> UH
-> H = Host,主机标识,不用手动配,OpenVPN 会自动创建

# 10.20/16
-> 10.20.0.0/16
-> /16
   => 11111111.1111111.00000000.00000000
   => 255.255.0.0
-> 10.20.0.0 255.255.0.0

# 10.120/16
同上推理 -> 10.120.0.0 255.255.0.0

最后得到

route 10.10.128.0 255.255.128.0 vpn_gateway
route 10.120.0.0 255.255.0.0 vpn_gateway
route 10.20.0.0 255.255.0.0 vpn_gateway
route 10.10.128.248 255.255.255.252 vpn_gateway
route 10.10.128.249 255.255.255.255 vpn_gateway

补充 route-nopull 设置阻止推送所有路由以后,完整配置:

route-nopull

route 10.10.128.0 255.255.128.0 vpn_gateway
route 10.120.0.0 255.255.0.0 vpn_gateway
route 10.20.0.0 255.255.0.0 vpn_gateway
route 10.10.128.248 255.255.255.252 vpn_gateway
route 10.10.128.249 255.255.255.255 vpn_gateway

老哥们应该也感觉到,这种简单的推理是不是可以交给 LLM,还真是XD

我用了下面的 prompt,得到的信息和我推理得到可用的完全一致。

${这里贴自己的路由表信息}
根据上面的路由表信息,生成适用于设置了 route-nopull 的 .ovpn 的配置。每一个 route 的最后一定要标记 vpn_gateway。

Clash 的设置

这部分是隔壁没有提到的,巧合的是,我也使用的是 Clash Verge Rev,内核是 Clash Meta。不同的是,隔壁老哥没开 TUN mode,开的是 System proxy,我则是反过来。

在这个情况下,Clash Meta 其实还是劫持了流量,应该由 OpenVPN 代理的域名指向的地址还是被 Clash Meta 带走了。

我在这一步卡住了。

思来想去,如果我开启一下 DNS Overwrite 并找到一些过滤呢?于是我开启它,再点一下旁边的螺帽,把目标域名放在 Fake IP Filter,域名脱敏处理成 dota2 相关了:

这时再打开 OpenVPN 发现嵌套代理正常工作了:D

另外

我没有注意过带宽和性能上会不会有什么问题,有日用需求的老哥感兴趣的话可能要单独测下。我相信这套方案绝对不是坐在麦当劳办公的最优解XD

备注个没玩明白的点,我有尝试在 rules 中设置需要走 OpenVPN 代理的域名和 OpenVPN 相关的 PROCESS-NAME,试图让它们“绕过” Clash Meta,但其实没有效果。这是我的配置

- PROCESS-NAME,openvpn,DIRECT
- PROCESS-NAME,ovpnagent,DIRECT
- PROCESS-PATH-REGEX,.*OpenVPN Connect.*,DIRECT

再备注个有趣的点,在探索的过程中,我尝试了:

  • Tunnelblick,它更糟糕,GUI 也很卡
  • Pritunl,干脆无法进行代理
  • Viscosity,30天免费,后续收费,但是它竟然不需要做任何的 .ovpn 改动,只要 Clash 改动的步骤即可

由于是在 LINUX DO 找到的解决方案,所以先把这次有趣的实践丢这里,未来再发布到其他地方:)

5 个赞

牛的大佬!如果clash 部署在路由器上,openvpn在windows有解吗?

听起来我提到的方案也是可以应用上的,只是从 GUI 上填写变成在配置目录根目录下的 config.yaml 中进行配置,大致这样的内容:

dns:
  enable: true
  enhanced-mode: fake-ip
  fake-ip-range: 198.18.0.1/16
  fake-ip-filter:
    - '*.lan'
    - '*.localdomain'
    - localhost.ptlogin2.qq.com
    - localhost.sec.qq.com
    - '+.msftncsi.com'
    - '+.msftconnecttest.com'
    - 'dns.msftncsi.com'
    - 'www.msftncsi.com'
    - 'www.msftconnecttest.com'
    - '*.dota2.*'

然后再重启内核的代理。

我暂时没有设备使用这套路由方案,所以仅是一些意淫猜测X(

1 个赞

我晚上回去又尝试了一下,route-nopull 会导致 Viscosity 进入一个奇怪的 connect loop,日志上是大面积的 Options error: option 'route' cannot be used in this context。OpenVPN 则不会产生这个问题。

考虑到兼容性,这里搜搜那里查查,看到了这个帖子,于是改动成

pull-filter ignore "redirect-gateway"
pull-filter ignore "dhcp-option"

引用上的完整配置也就变成

pull-filter ignore "redirect-gateway"
pull-filter ignore "dhcp-option"

route 10.10.128.0 255.255.128.0 vpn_gateway
route 10.120.0.0 255.255.0.0 vpn_gateway
route 10.20.0.0 255.255.0.0 vpn_gateway
route 10.10.128.248 255.255.255.252 vpn_gateway
route 10.10.128.249 255.255.255.255 vpn_gateway
1 个赞

公司 VPN 客户端我用的是 OpenConnect,代理软件用的是 Clash X Pro。我开启 tun 模式(增强模式) 然后再开启 VPN,访问公司内网和外网都可以正常访问,但是一旦断开OpenConnect,我观察 Clash 的日志,我发现一些网址都变成 IP 了,这样没办法命中域名规则, 只能命中 IP 规则。这会导致我特定的代理组域名规则无法使用特定代理节点, 佬知道这是为什么吗?

2025/12/04 23:51:06.477  [info] /Users/runner/work/ClashXPro/ClashXPro/ClashX/AppDelegate.swift  [TCP] connected lAddr=198.18.0.1:60506 rAddr=101.227.131.1xx:80 mode=rule rule=RuleSet(cncidr) proxy=DIRECT

举个例子,比如我访问 claude,我想使用特定家宽代理节点,我写了一个代理组,使用一些域名规则,让它只访问特定加宽节点。我的默认兜底规则集是日本节点。如果像上面我断开 openconnect,将导致它访问日本节点,而不是家宽节点。 断开VPN会导致我之后使用 clash 无法准确命中规则, 这个问题,佬知道该如何解决吗

一旦断开OpenConnect..一些网址都变成 IP..断开VPN会导致

哥们可能要看看 OpenConnect 有没有勾选类似断开以后重置 DNS 的选项,我能想到的就是类似这样的后续操作导致地址解析错误。如果没有的话,我也没有更好的解决方案X(

非常有用的提醒:+1: