系统代理模式/TUN 模式和全局/分流模式完全是正交的,即下面四种情况都可能出现:
- 系统代理模式,全局模式
- 系统代理模式、分流模式
- TUN 模式、全局模式
- TUN 模式、分流模式
GUI 进行配置改动以后,对应的 CVR 配置文件会马上更新,然后给 clash 内核的配置文件也会更新。
CVR 配置文件改动以后,对应的 GUI 配置界面不会更新,给 clash 内核的配置文件也不会更新。
关闭 CVR 的时候,GUI 的配置,会强制写到 CVR 配置文件。
Clash Verge Rev 配置文件夹:
~/Library/Application Support/io.github.clash-verge-rev.clash-verge-rev
$ ls -al
total 69304
drwxr-xr-x@ 18 juhan staff 576 Dec 22 06:34 .
drwx------+ 108 juhan staff 3456 Dec 27 09:43 ..
-rw-r--r--@ 1 juhan staff 217 Oct 28 03:15 .window-state.json
-rw-r--r--@ 1 root staff 32768 Jan 1 23:50 cache.db
-rw-r--r--@ 1 juhan staff 200807 Jan 5 21:15 clash-verge-check.yaml
drwxr-xr-x@ 21 juhan staff 672 Jan 1 23:50 clash-verge-rev-backup
-rw-r--r--@ 1 juhan staff 200807 Jan 5 21:15 clash-verge.yaml
-rw-r--r--@ 1 juhan staff 508 Jan 1 23:48 config.yaml
-rw-r--r--@ 1 juhan staff 10341253 Dec 19 16:35 Country.mmdb
-rw-r--r--@ 1 juhan staff 886 May 31 2025 dns_config.yaml
-rw-r--r--@ 1 juhan staff 20521588 Dec 19 16:35 geoip.dat
-rw-r--r--@ 1 juhan staff 4143284 Dec 19 16:35 geosite.dat
drwxr-xr-x@ 13 juhan staff 416 Jan 1 23:48 logs
drwxr-xr-x@ 22 juhan staff 704 Jan 1 23:47 profiles
-rw-r--r--@ 1 juhan staff 4070 Jan 5 22:12 profiles.yaml
drwxr-xr-x@ 5 juhan staff 160 Jan 25 2025 test
-rw-r--r--@ 1 juhan staff 4617 Jan 5 21:15 verge.yaml
-rw-r--r--@ 1 juhan staff 215 Jan 1 23:48 window_state.json-
CVR 配置文件
-
config.yaml对应 Clash Verge Rev 设置页面,「Clash 设置」那个板块的配置,很短,只有二三十行。
该文件不包括「Clash 设置」中「DNS 覆写」中的配置。
tun的dns-hijack表示将匹配到的连接导入内部 dns 模块,即dns_config.yaml。tun的stack最好用mixed,即 tcp 使用 system 栈,udp 使用 gvisor 栈,使用体验可能相对更好。 -
dns_config.yaml对应 Clash Verge Rev 设置页面,「Clash 设置」的「DNS 覆写」的配置。很短,只有五十行。
enhanced-mode尽量用fake-ip,不要使用redir-host模式。 -
profiles.yaml主要记录和订阅有关的信息。
-
profiles文件夹和订阅有关的具体文件。
-
verge.yamlCVR 基础设置。
-
-
Clash 内核配置文件
clash-verge.yaml/clash-verge-check.yaml这两个文件内容一样,是最后给 Mihomo 内核的配置文件。
同时,CVR 设置页面,「Verge 高级设置」里,「当前配置」的内容,和这两个文件内容一样。
-
两者关系
用 profiles 文件夹里面的订阅 yaml 文件做基础,叠加 config.yaml 和 dns_config.yaml 里的设置,最后得到
clash-verge.yaml。
-
「DNS 覆写」关闭,「启用 DNS」关闭
如果「启用 DNS」被关闭,
dns_config.yaml中的enable会变为 false。如果「DNS 覆写」关闭,那么节点配置文件的 dns 设置会在
clash-verge.yaml中出现。如果 tun 模式开启,可能会:- Overwrite
dns.ipv6with top-level ipv6 value - Add
use-system-hosts - Add
dns.enhanced-mode= "fake-ip" if missing - Add
dns.fake-ip-range= "198.18.0.1/16" if missing
- Overwrite
-
「DNS 覆写」关闭,「启用 DNS」打开
如果「启用 DNS」被打开,
dns_config.yaml中的enable会变为 true。如果「DNS 覆写」关闭,那么节点配置文件的 dns 设置会在
clash-verge.yaml中出现。如果 tun 模式开启,可能会:- Overwrite
dns.ipv6with top-level ipv6 value - Add
use-system-hosts - Add
dns.enhanced-mode= "fake-ip" if missing - Add
dns.fake-ip-range= "198.18.0.1/16" if missing
「DNS 覆写」关闭「启用 DNS」关闭、「DNS 覆写」关闭「启用 DNS」打开,这两种情况,
clash-verge.yaml内容完全是一样的。 - Overwrite
-
「DNS 覆写」打开,「启用 DNS」关闭
如果「启用 DNS」被关闭,
dns_config.yaml中的enable会变为 false。如果「DNS 覆写」打开,那么
clash-verge.yaml的 dns 内容会完全采用dns_config.yaml的内容。 -
「DNS 覆写」打开,「启用 DNS」打开
如果「启用 DNS」被打开,
dns_config.yaml中的enable会变为 true。如果「DNS 覆写」打开,那么
clash-verge.yaml的 dns 内容会完全采用dns_config.yaml的内容。
// Define main function (script entry)
function main(config) {
// 1. 确保开启 GEOSITE/GEOIP 也就是 Meta 内核模式 (防止某些订阅没开)
config["geodata-mode"] = true;
config["geodata-loader"] = "standard";
config["geo-auto-update"] = true;
config["geo-update-interval"] = 24;
config["geox-url"] = {
"geosite": "https://testingcf.jsdelivr.net/gh/v2fly/domain-list-community@release/dlc.dat",
};
// 2. 【核心】直接暴力覆盖所有分流规则
// 不管机场原来写了什么,统统替换成下面这套“LoyalSoldier精简版”
config.rules = [
// "AND,((DST-PORT,3389),(NETWORK,UDP)),REJECT",
"DOMAIn-SUFFIX,xygj.pro,DIRECT",
"DOMAIN-SUFFIX,goofish.pro,DIRECT",
"DOMAIN-SUFFIX,bastionglobal.azure.com,DIRECT",
"PROCESS-NAME,Windows App,DIRECT",
"PROCESS-NAME,Telegram,Proxies",
// 域名匹配
"GEOSITE,private,DIRECT",
"GEOSITE,geolocation-!cn@cn,DIRECT",
"GEOSITE,geolocation-!cn,Proxies",
"GEOSITE,geolocation-cn@!cn,Proxies",
"GEOSITE,geolocation-cn,DIRECT",
"GEOSITE,tld-cn,DIRECT",
// IP 匹配
"GEOIP,telegram,Proxies,no-resolve",
"GEOIP,cn,DIRECT,no-resolve",
"GEOIP,lan,DIRECT,no-resolve",
"MATCH,Proxies"
];
// 返回修改后的配置
return config;
}-
什么是 DNS 泄漏
DNS 泄漏的说法只有在我们使用代理之后才存在。
只有当我们通过代理访问目标网站时,电脑在使用加密代理通道之前,给互联网发送了请求目标网站 IP 地址的明文 DNS 请求,这样才叫 DNS 泄漏。
-
谁会看到 DNS 请求
DNS 请求的 DNS 服务器可以是国内的,也可以是国外的。
只要电脑给互联网发送 DNS 请求以后,运营商和防火墙就能很清楚地看到。运营商看到你问了谷歌的 ip,他可能不阻断你,但它会记录下来。防火墙会直接识别出谷歌的域名,然后给你一个假的 IP。
所以 DNS 泄漏实际上是隐私泄漏。
-
DNS 泄漏泄漏了什么
对具有检测能力的网站来说,DNS 泄漏的并不是你的电脑 ip,而是你上游的 DNS 服务器 ip。
对运营商和防火墙来说,DNS 既泄漏了你的电脑 ip,又泄漏了你想要访问的网站域名,比如谷歌。
-
如何判定 DNS 是否泄漏
访问 ipleak.net。如果列表中有国内的 DNS 服务器,那么肯定泄漏了。
即使没有国内的 DNS 服务器,如果同一个节点使用全局模式和分流模式的检测结果不同,出现新的 DNS 提供商,也大概率泄漏了。
DNS 泄漏有两种情况,一种是你的 DNS 请求发给了国内 DNS 服务器,一种是国外 DNS 服务器。
如果有些网站检测到你在解析他们域名的时候使用的是国内的 DNS 服务器,但是你的代理 IP 在美国,这种不一致性会让网站对你的身份产生怀疑,甚至直接封禁你。
全局模式、系统代理模式下,一些不走系统代理的应用,可能还是会在本地发起 DNS。
全局模式、TUN 模式下,代理软件(如 Clash)会强制把所有流量(包括 DNS 请求)封装进加密通道,直接发给美国代理服务器。你的电脑本地完全闭嘴,不发任何 DNS 请求。
在 Windows 上,如果是 TUN 模式,即使是全局模式,也还是会发起 DNS 请求。Windows 默认会将 DNS 请求发给所有网卡上配置的 DNS 服务器。要把这个设置关掉。
浏览器要访问谷歌,由于配置了系统代理,浏览器不再进行 DNS 查询,而是直接将访问网站的请求交给我们的代理客户端。
代理客户端拿到请求之后,此时会有两种情况:
一种是不发起 DNS 请求就能判断走直连还是走代理(按域名进行分流),这种情况基本不存在 DNS 泄露;
如果使用按 IP 进行分流的规则,代理软件为了判断一个域名该走代理还是直连,往往会先在本地发起一次 DNS 查询拿到 IP,再根据 IP 决定怎么走。只要在本地发起 DNS 查询,不管发给国内还是国外,都经过了运营商和防火墙,这就是泄漏。
实际例子:
你的分流规则里写着“国内 IP 走直连,国外 IP 走代理”。
矛盾点:既然要按 IP 分流,那 Clash 必须先知道 www.google.com 的 IP 是多少,才能判断它是国内还是国外,对吧?
死结:为了拿到 IP,Clash 必须先在本地发起一次 DNS 请求(这就是之前说的泄漏源)。一旦在本地发起了,就被运营商和防火墙看到了。然后懂的都懂。
在 Clash 使用域名匹配按 ip 分流的规则时,会在本地进行一次 DNS 请求(泄漏),获取域名的 ip 地址。但是这个 ip 只是用来进行 ip 分流规则的匹配,没有别的作用。你发给节点的数据包中,存的还是域名。
那么如何解决这个 DNS 泄漏?
一种办法是给所有基于 IP 分流的匹配规则都加上 no-resolve,这样就不会触发 DNS 请求。但是会有一个问题:如果 GEOIP,CN,DIRECT 加上了 no-resolve,那么国内小众网站在看到这条时,会直接跳过,如果最后兜底的是 MATCH, proxy,那么国内小众网站就会走代理了。
另一种方式,就是在 IP 规则前,先把所有的黑名单网站的匹配规则先加上,比如 google youtube facebook twitter 等等。这样就可以优先匹配到域名规则,直接交给节点处理,不会再往下匹配,也就不会触发 IP 规则的 DNS 请求了。
前面主要在讲系统代理模式下的情况,TUN 模式下的分流情况要复杂一些。现在主要使用 fake-ip。
-
浏览器访问谷歌,先发起 DNS 请求
当我们把DNS配置为fake-ip之后,此时浏览器访问谷歌,浏览器首先发起DNS请求,获取谷歌的IP。
-
路由器把 DNS 请求劫持到 clash 中
请求会来到路由器,路由器会将DNS请求劫持到clash中。
-
clash 直接生成一个假的 ip 给浏览器
clash收到浏览器的DNS请求,他也不知道谷歌的IP是多少。再看看自己的DNS配置是fake-ip,fake-ip并不需要给浏览器返回一个真实的IP,clash会心一笑,直接从配置的私有IP段中选择一个假的IP,生成DNS响应返回给浏览器。并且记录了IP和域名的映射关系
-
浏览器用假的 ip 访问谷歌
浏览器拿到这个假的IP之后,向这个IP发起访问谷歌的HTTP请求。
-
clash 查看 ip 对应的域名,用域名进行规则匹配
请求来到路由器的clash,clash查看映射表中IP对应的域名,用域名进行规则匹配。
匹配到了第一条规则,于是将请求交给节点组1的香港节点处理。交给节点处理的还是谷歌的域名,由远程的节点服务器进行DNS解析,获取谷歌的正确IP。
可以看到本地,并不需要进行DNS解析,也就不存在DNS泄露了,延迟也会降低。并且解决了多域名指向同一个IP的情况。因为返回的都是假的IP,clash可以控制每个IP只对应一个域名。
-
还是有一些问题
如果此时再访问DNS泄露网站,首先会返回一个假IP给浏览器。
浏览器在发起http请求,clash拿到映射的域名进行匹配。
由于没有匹配到上面任何规则,会来到GEOIP这条没加no-resolve的IP规则。
此时clash也不知道这个域名的IP,于是同时向上游的三个DNS服务器和fallback中的DNS服务器发起DNS请求。实际上还是泄漏了。
clash得到IP后,发现归属地不是国内,于是会继续向下匹配。
最终匹配MATCH走了代理。
-
UDP
目前clash处理udp流量的域名,即使是使用fake-ip模式,也一定会发起DNS请求。比如基于UDP的QUIC协议,也就是浏览器用的HTTP3。
启用了QUIC的浏览器访问youtube这种支持QUIC的网站,就会发起DNS请求,导致DNS泄露。
解决办法是禁用浏览器的QUIC功能。
一个真正高手的规则列表顺序应该是这样的(优先级从高到低):
- 进程规则 (Process) —— 最高优先级,最精准,零泄露。
- Telegram -> Proxy
- 迅雷 -> Direct
- 域名规则 (Domain/Geosite) —— 主力军,零泄露。
- google.com -> Proxy
- baidu.com -> Direct
- GEOSITE, cn -> Direct (这就是我们刚才说的白名单)
- IP 规则 (GeoIP) —— 最后的防线,有风险。
- Private IP (局域网) -> Direct
- GEOIP, CN, Direct, no-resolve (加 no-resolve 防止泄露)
- 兜底 (Match)
- Match -> Proxy
-
来源
来源很多,这里选用 metacubex 的。
-
相关文件
- country.mmdb
- country-lite.mmdb
- geoip.dat
- geoip.db
- geoip-lite.dat
- geoip-lite.db
- geoip.metadb
- geoip-lite.metadb
- geosite.dat
- geosite.db
- geosite-lite.dat
- geosite-lite.db
- GeoLite2-ASN.mmdb
- BundleMRS.7z
-
文件格式
- db:MetaCubeX 为 sing-box/SagerNet 生态提供的产物。
.db并不代表统一的底层格式。本 Mihomo 配置不用,忽略。
- db:MetaCubeX 为 sing-box/SagerNet 生态提供的产物。
-
去掉 lite、db、metadb、bundlemrs,剩下这些文件
- country.mmdb / geoip.dat
- geosite.dat
- GeoLite2-ASN.mmdb
-
相关配置
-
geodata-mode:更改 geoip 使用文件,country.mmdb或者geoip.dat,可选 false/true,默认 false用
country.mmdb就可以,不用改。 -
geodata-loader:geo 文件加载模式使用默认值就可以,不用改。
-
geo-auto-update:geo 文件自动更新 -
geo-update-interval:geo 文件更新间隔 -
geox-url:geo 文件下载地址使用默认值就可以,不用改。
-
-
文件本质
我们只需要使用 GEOIP GEOSITE 规则。现在的问题是搞清楚,GEOIP GEOSITE 后面能跟什么东西。那么就要搞清楚
country.mmdb和geosite.dat里面有什么东西。-
country.mmdbcountry.mmdb 是一个符合 MaxMind DB(MMDB)规范的数据库文件,记录了 IP 到 data section 的映射。
可以用 maxmind 的 mmdbinspect 查全部 data section 的情况。
mmdbinspect -jsonl -db country.mmdb ::/0 \ | jq -r ' [ .record | paths(scalars) | map(tostring) | join(".") ] | sort | join(" | ") ' \ | awk ' { count[$0]++ total++ if (total % 100000 == 0) print "processed:", total > "/dev/stderr" } END { for (schema in count) print count[schema] "\t" schema } ' \ | sort -nr得到:
615430 continent.code | continent.geoname_id | continent.names.de | continent.names.en | continent.names.es | continent.names.fr | continent.names.ja | continent.names.pt-BR | continent.names.ru | continent.names.zh-CN | country.geoname_id | country.iso_code | country.names.de | country.names.en | country.names.es | country.names.fr | country.names.ja | country.names.pt-BR | country.names.ru | country.names.zh-CN 334596 continent.code | continent.geoname_id | continent.names.de | continent.names.en | continent.names.es | continent.names.fr | continent.names.ja | continent.names.pt-BR | continent.names.ru | continent.names.zh-CN | country.geoname_id | country.is_in_european_union | country.iso_code | country.names.de | country.names.en | country.names.es | country.names.fr | country.names.ja | country.names.pt-BR | country.names.ru | country.names.zh-CN 15382 country.geoname_id | country.iso_code | country.names.de | country.names.en | country.names.es | country.names.fr | country.names.ja | country.names.pt-BR | country.names.ru | country.names.zh-CN 9915 country.iso_code完美,下一步,获取所有的
country.iso_code。~/go/bin/mmdbinspect -jsonl -db country.mmdb ::/0 \ | jq -r '.record.country.iso_code // empty' \ | sort -u除了国家代码以外,还有:
CLOUDFLARE CLOUDFRONT FACEBOOK FASTLY GOOGLE NETFLIX PRIVATE TELEGRAM TOR TWITTER -
geosite.datgeosite.dat 本质上是一份 Protocol Buffers 二进制文件。最外层是 GeoSiteList,里面有很多 GeoSite;每个 GeoSite 有一个 code/分类名,再包含很多 Domain 条目。每个域名条目除了域名和匹配类型,还可以带若干 Attribute。
可以把它抽象成:
geosite.dat │ ├── google │ ├── google.com │ ├── googleapis.com │ ├── doubleclick.net [ads] │ └── google.cn [cn] │ ├── steam │ ├── steampowered.com │ ├── steamcontent.com [cn] │ └── ... │ ├── youtube │ └── ... │ └── cn └── ...google、steam、youtube 就是 GeoSite code。
安装 metacubex 的 geo 工具,用命令
geo unpack site ./geosite.dat -d output获得geosite.dat所有数据。
-
-
具体规则
- GEOIP 后面跟 country.iso_code,另外还有 LAN 特例
- GEOSITE 后面跟 geosite code,可跟 attribute
-
DNS 将域名转换成 IP,只对域名请求有效。
-
DNS 不同类型
传统 DNS 53 UDP / TCP 明文 DNS over TLS 853 TCP + TLS 密文 DNS over HTTP 443 TCP + TLS + HTTP 密文 DNS over QUIC 853 UDP + QUIC (TLS 1.3) 密文 DNS over HTTP3 443 UDP + QUIC (TLS 1.3) + HTTP/3 密文 -
DNS 不同类型在配置中的写法
传统 UDP DNS 223.5.5.5 / udp://223.5.5.5 传统 TCP DNS tcp://8.8.8.8 DNS over TLS tls://1.1.1.1 DNS over HTTP https://doh.pub/dns-query DNS over QUIC quic://dns.adguard.com:784 DNS over HTTP3 只能通过 prefer-h3 配置,使 https://doh.pub/dns-query 走 HTTP3 -
fake-ip 的流程(先分流,再根据结果进行 DNS)
应用第一次做 DNS 查询时,Mihomo 先检查 hosts 配置和
/etc/hosts,如果有映射,马上得到 IP。如果没有,不告诉它真实 IP,而是给它一个假的 IP;等应用真的去连接这个假 IP 时,Mihomo 再把这个连接还原成原始域名,然后按规则决定 DIRECT 还是 PROXY。
如果是 PROXY,那么 DNS 工作直接交给代理完成。
如果是 DIRECT,那么需要获得真实 IP,于是 mihomo 用
direct-nameserver查真实 IP。
例外情况:
- fake-ip-filter 中的域名不返回 fake-ip
- 如果一个域名遇到没有 no-resolve 的 GEOIP 规则,那么会用
nameserver进行 IP 查询。 - 解析代理节点自己的域名,会用
proxy-server-nameserver - 解析其他 nameserver 里的域名,对应
default-nameserver,必须为 ip
-
配置建议
fallback 是老版 clash 逻辑。逻辑复杂且容易误判。不使用。
policy 是高级的分流(比如:baidu.com 走 114 DNS,jd.com 走阿里 DNS)。普通人根本用不到这么细。
direct-nameserver可以用 DoH。proxy-server-nameserver也可以用 DoH。nameserver也可以用 DoH。default-nameserver里放解析 DoH 域名的 DNS 服务器。
https://www.aloxaf.com/2025/04/how_to_use_geosite
dns:
enable: true
ipv6: false
enhanced-mode: fake-ip
fake-ip-range: 198.18.0.1/16
fake-ip-filter:
- 'rule-set:fake-ip-filter'
prefer-h3: false
default-nameserver:
- 223.5.5.5
proxy-server-nameserver:
- 223.5.5.5
direct-nameserver:
- 'https://doh.pub/dns-query'
- 'https://223.5.5.5/dns-query'
- 'https://doh.360.cn/dns-query'
nameserver:
- 'https://dns.google/dns-query#PROXY&ecs=120.76.0.0/14&ecs-override=true'
# - 由于国外 DoH 普遍被墙,这里填的实际上是自建的 DoH
domain_rule: &domain_rule
type: http
behavior: domain
format: text
interval: 86400
rule-providers:
reject-list:
<<: *domain_rule
url: https://cdn.jsdelivr.net/gh/Loyalsoldier/v2ray-rules-dat@release/reject-list.txt
path: ./ruleset/reject-list.txt
fake-ip-filter:
<<: *domain_rule
url: https://cdn.jsdelivr.net/gh/juewuy/ShellCrash@dev/public/fake_ip_filter.list
path: ./ruleset/fake_ip_filter.list
rules:
- DOMAIN-SUFFIX,steamserver.net,DIRECT
##### 域名匹配 #####
- GEOSITE,private,DIRECT
- RULE-SET,reject-list,REJECT
- GEOSITE,category-ai-!cn,🤖AIGC
- GEOSITE,category-pt,DIRECT
- GEOSITE,category-public-tracker,DIRECT
- GEOSITE,category-number-verification-cn,DIRECT
- GEOSITE,category-speedtest,PROXY
- GEOSITE,geolocation-!cn@cn,DIRECT
- GEOSITE,geolocation-!cn,PROXY
- GEOSITE,geolocation-cn@!cn,PROXY
- GEOSITE,geolocation-cn,DIRECT
- GEOSITE,tld-cn,DIRECT
##### IP 匹配 #####
- GEOIP,telegram,PROXY,no-resolve
- GEOIP,lan,DIRECT
- GEOIP,cn,DIRECT
- NOT,((DST-PORT,80/443/8080/8888)),❓其他端口
- MATCH,PROXY