type
status
date
slug
summary
tags
category
icon
password
OpenClash的“实验性:绕过中国大陆IP“功能是通过Dnsmasq进行实现,旨在将国内IP通过防火墙转发规则,国内IPv4和IPv6的流量不经过Clash(Mihomo)内核处理,增强直连性能,降低OpenWRT软路由的资源占用。对于进阶使用用户来说,在使用上存在诸多不便,例如无法与MosDNS、Adguard Home完美配合。我作为一个只能看懂一部分代码,完全不会写的选手,在ChatGPT和Cursor的帮助下,尝试找到一个不依赖于Dnsmasq,也可以使中国大陆IP流量不经过Clash(Mihomo)内核的方法。
本篇的配置项目前还未经过长时间生产环境使用,可能存在不稳定、规则冲突、未知问题等可能。在操作之前,请进行备份,避免无法恢复的网络宕机。
实验环境
- 旁路由(旁路网关):OpenWRT(
ImmortalWrt 23.05.4 r28061-399f9a1db3 / LuCI openwrt-23.05 branch git-24.265.44782-0ff45d8
) - 接口为
br-lan
,网关为主路由IP地址 - 运行OpenClash作为科学服务
- 内核版本为
5.15.167
(stable) - 架构
X86_64
📝 实验性:绕过中国大陆IP的原理
OpenClash的大部分核心外功能实现基本都是通过
/etc/init.d/openclash
这个启动文件实现。在文件中,涉及实验性:绕过中国大陆IP的主要功能部分包括:ip set/nft set
管理,也就是IP集合管理
China_ip_route
规则匹配及重定向
- 利用Dnsmasq进行国内域名列表(
/etc/openclash/accelerated-domains.china.conf
)内的域名解析
IP集合
OpenClash内置了两个IP集合,分别为
China_ip_route
集合和China_ip_route_pass
集合,通过插件设置 - 大陆白名单订阅
进行维护,没有使用GeoIP:CN
进行维护。China_ip_route规则匹配
在Openclash选择绕过大陆IP时,通过fw4进行进行流量检测,当检测到目标IP地址属于中国大陆时,通过
openclash
链、openclash_mangle
链、以及openclash_mangle_out
链进行return
操作,使流量按原链继续进行,不再经由clash内核进行处理。openclash_mangle链
openclash_mangle链的作用是用于修改流量的特性,通常用于更改数据包的标记、TTL(生存时间)等,对流量进行细颗粒度控制,标记流量进行后续处理等。
- 条件判断:检查变量 china_ip_route 是否等于 1。如果是,表示启用了绕过中国大陆IP。
- 嵌套条件判断:检查变量 enable_redirect_dns 是否不等于 2。这里0是不劫持DNS,1是通过dnsmasq劫持,2是通过防火墙劫持。
- 如果不等于2,即不使用防火墙劫持:
nft 'add rule inet fw4 openclash_mangle ip daddr @china_ip_route ip daddr != @china_ip_route_pass counter return’
- 如果等于2:
nft 'add rule inet fw4 openclash_mangle ip daddr @china_ip_route counter return’
openclash链
openclash链主要用于处理进入的流量。这个链通常用于根据特定的规则对流量进行分类和处理。
- 条件判断:检查变量 china_ip_route 是否等于 1。如果是,表示启用了绕过中国大陆IP。
- 嵌套条件判断:检查变量 enable_redirect_dns 是否不等于 2。这里0是不劫持DNS,1是通过dnsmasq劫持,2是通过防火墙劫持。
- 如果不等于2,即不使用防火墙劫持:
nft 'add rule inet fw4 openclash ip daddr @china_ip_route ip daddr != @china_ip_route_pass counter return'
- 如果等于2:
nft 'add rule inet fw4 openclash ip daddr @china_ip_route counter return'
openclash_mangle_output链
openclash_mangle_output链专门用于处理输出流量,即从本地系统发出的流量(路由器本机流量)。之前我只配置了mangle链和openclash链,没有对openclash_mangle_output链进行防火墙配置,导致mosdns的还是会经过clash(mihomo)核心,也造成在多并发进行DNS请求时,
upstream error
和exchange failed
等错误,同时由于本来应该直连的DNS公众服务器,绕到Clash(Mihomo)核心走了一圈,所以解析速度也有所下降。- 条件判断:检查变量
china_ip_route
是否等于 1。如果是,表示启用了绕过中国大陆IP。
- 嵌套条件判断:检查变量
enable_redirect_dns
是否不等于 2。这里0是不劫持DNS,1是通过dnsmasq劫持,2是通过防火墙劫持。其中,skuid≠65534
为非特权用户,即nobody
用户 - 如果不等于2,即不使用防火墙劫持:
nft 'add rule inet fw4 openclash_mangle_output skuid != 65534 ip daddr @china_ip_route ip daddr != @china_ip_route_pass counter return'
- 如果等于2:
nft 'add rule inet fw4 openclash_mangle_output skuid != 65534 ip daddr @china_ip_route counter return'
China_ip_route_pass规则匹配
China_ip_route_pass这个IP集是通过劫持Dnsmasq,使用设定的dns对国内常见域名(也就是
/etc/openclash/accelerated-domains.china.conf
文件内域名)进行解析并生成的IP集。这部分非常依赖于Dnsmasq,但在我们这里由于已经有MosDNS进行分流,所以不用过于关注。📝 配置流程
China_ip_route的nft规则配置
通过对上面fw4表内openclash链、openclash_mangle链以及openclash_mangle_output链的分析,可以基本明确我们要进行带操作。
- 首先我们需要处于fake-ip模式
- 关闭实验性绕过中国大陆IP选项,因为我们要手动添加防火墙规则进行绕过
- 关闭DNS劫持
在关闭DNS劫持的同时,我们符合
enable_redirect_dns
选项,即没有使用防火墙劫持DNS,所以我们采用if下的第一条判断结果。添加防火墙规则
由于防火墙规则采用顺序匹配,如果我们采用add的方式,无论如何只会附加规则至每条防火墙规则链的底部,所以这里采用insert方式。
openclash链
openclash_mangle链
openclash_mangle_output链
添加完成之后,在Openclash的页面进行重置所有链接,同时观察是否有匹配国内IP的流量进入列表,如果没有即表示成功。同时在OpenWRT的防火墙页面,应该可以找到我们添加的规则以及对应规则匹配的计数,通过这个也可以观察是否绕过成功。
配置OpenClash自定义防火墙规则
为了避免每次OpenClash重启或者路由器重启后需要手动重复执行
nft
命令,我们可以将上述三条规则写入到openclash的自定义规则里面。配置位置位于:插件设置 - 开发者选项
关于IPV6
由于openclash的实验性:绕过中国大陆IPv6不完全依赖于dnsmasq,所以可以放心开启,不用做特别的配置。
关于规则更新
由于目前使用的是大陆白名单提供的IP地址集,所以可以通过OpenClash提供的Web端页面进行更新,也可以在页面配置定时更新,不必过多担心IP地址变化带来的白名单错乱。之后我也会尝试使用
GEOIP:CN
作为IP集进行研究。已知问题
会使之前配置的DNS防泄漏无效,目前还在研究是哪个环节出现的问题。
🤗 总结归纳
这次主要折腾的原因在于很羡慕Dae的直连性能,但是还没有把Dae放在生产环境真正的使用过,所以想看看有没有什么办法在不使用dnsmasq,仅通过防火墙进行一些修改,让mosdns+openclash这套配置更为完善,同时也能让自己更为熟悉fw4、nftable以及OpenWRT的防火墙配置。
通过上面对nft命令以及规则的了解,也可以通过nft进行局域网设备的黑名单配置,使特定设备流量不进入到Clash(Mihomo)内核,避免违反机场的TOS规则,例如BT、PCDN等等。
📎 参考文章
有关OpenWRT安装或者使用上的问题,欢迎您在底部评论区留言,一起交流~