背景
全局代理: 简单粗暴, 打包所有流量送到代理服务器; 访问国内网站速度奇慢
PAC (Proxy Auto-Config): 一段JS代码, 在发请求前判断一下域名, 局限于浏览器
随着网络请求变得极其复杂(不仅是浏览器, 还有APP, 后台服务器, 甚至操作系统底层的请求), 我们需要一种在网络层/传输层直接进行毫秒级”管制”的技术.
mohomo 中的 “规则”, 本质是一套基于特征识别的 if-this-then-that 的路由决策系统. 它决定了你的每一网络请求, 到底该走哪一条物理/逻辑通道
rules
原则: 顺序优先, 规则自上而下匹配, 上边的优先级高于下边的
- 越具体的规则放越前边
- 越宽泛的规则放越后边
- MATCH 永远放最后
rules:
- DOMAIN,ad.com,REJECT # 精确匹配域名
- DOMAIN-SUFFIX,google.com,auto # 域名后缀匹配
- DOMAIN-KEYWORD,google,auto # 域名关键词匹配
# 域名通配符匹配, 只支持 * 和 ?
# *: 零个/多个字符, ?: 一个字符
- DOMAIN-WILDCARD,*.google.com,auto
- DOMAIN-REGEX,^abc.*com,PROXY # 正则匹配域名
- GEOSITE,youtube,PROXY # 按geosite数据集匹配域名集合
- IP-CIDR,127.0.0.0/8,DIRECT,no-resolve # 匹配ip地址范围
- IP-CIDR6,2620:0:2d0:200::7/32,auto
- IP-SUFFIX,8.8.8.8/24,PROXY # 匹配ip后缀范围
- IP-ASN,13335,DIRECT # 匹配ip所属ASN
- GEOIP,CN,DIRECT # 匹配ip所属国家代码
- SRC-GEOIP,cn,DIRECT # 匹配来源ip
- SRC-IP-ASN,9808,DIRECT
- SRC-IP-CIDR,192.168.1.201/32,DIRECT
- SRC-IP-SUFFIX,192.168.1.201/8,DIRECT
- DST-PORT,80,DIRECT # 匹配请求目标端口范围
- SRC-PORT,7777,DIRECT # 匹配请求来源端口范围
- IN-PORT,7890,PROXY # 匹配入站端口
- IN-TYPE,SOCKS/HTTP,PROXY
- IN-USER,mihomo,PROXY # 匹配入站用户名, 支持 / 分隔多个名
- IN-NAME,ss,PROXY # 匹配入站名称 (listeners -> name)
- PROCESS-PATH,/usr/bin/wget,PROXY # 通过进程匹配
- PROCESS-PATH,C:\Program Files\Google\Chrome\Application\chrome.exe,PROXY
- PROCESS-PATH-WILDCARD,/usr/*/wget,PROXY
- PROCESS-PATH-REGEX,.*bin/wget,PROXY
- PROCESS-PATH-REGEX,(?i).*Application\\chrome.*,PROXY
- PROCESS-NAME,curl,PROXY
- PROCESS-NAME,chrome.exe,PROXY
- PROCESS-NAME,com.termux,PROXY
- PROCESS-NAME-WILDCARD,*telegram*,PROXY
- PROCESS-NAME-REGEX,curl$,PROXY
- PROCESS-NAME-REGEX,(?i)Telegram,PROXY
- PROCESS-NAME-REGEX,.*telegram.*,PROXY
- UID,1001,DIRECT # 匹配 linux user id
- NETWORK,udp,DIRECT
- DSCP,4,DIRECT
- RULE-SET,providername,proxy # 引用规则集合, 见 rule-provider
# 逻辑运算符
- AND,((DOMAIN,baidu.com),(NETWORK,UDP)),DIRECT
- OR,((NETWORK,UDP),(DOMAIN,baidu.com)),REJECT
- NOT,((DOMAIN,baidu.com)),PROXY
- SUB-RULE,(NETWORK,tcp),sub-rule # 匹配至子规则
- MATCH,auto # 匹配所有请求, 一般放最后附加参数
no-resolve
默认行为
当一个请求一开始拿到域名, 而后边规则中有
IP-CIDR、GEOIP这类看 “目标ip” 的规则时, mihomo 为了判断 “这个域名对应的目标IP是否命中这些规则”, 会主动触发 dns 解析
no-resolve 作用: 在匹配 “目标ip” 类规则时, 禁止 mihomo 为了匹配这些规则而额外去做一次 DNS 解析
# 这条目标IP规则不要为了匹配而临时解析域名
- IP-CIDR, 127.0.0.0/8, DIRECT, no-resolve注意:
- no-relove 不是 “彻底禁止这条规则匹配ip”
- 如果更早的匹配过程中已经触发过 DNS 解析, 那么即使这条目标ip规则带了 no-resolve, 它仍参与匹配
# 如下第一条规则没有添加 no-resolve
# 因此当一个域名请求开始匹配规则时, 主动触发 dns 解析
# 若第一个规则未命中, 此时继续向下
# 即使第二个规则携带 no-resolve, 由于已触发过 dns解析, 此时仍会匹配
- GEOIP,cn,DIRECT
- IP-CIDR,127.0.0.0/8,DIRECT,no-resolveGEO 数据库
巨头们 (例:谷歌) 的域名和IP成千上万, 如果你的规则文件有几十万行, 每次打开网页, 都从头到尾进行字符串比对, 性能极差
为了解决 “规则无限膨胀和硬件算力有限” 的矛盾, 引入 .dat/.mrs 格式的二进制数据库
- GEOSITE: 域名数据库
- GEOIP: IP数据库
优点:
- 空间复杂度骤降: 十万行文本可能要几十MB, 但编译为二进制字典后, 体积急剧缩小, 且 mihimo 可直接将其映射到内存中
- 时间复杂度趋近O(1): mihomo不需要循环对比十万次, 通过底层数据结构, 只需要几次哈希运算, 微秒级就能判断某个域名是否属于谷歌
- 开源共建: 全球开发者在 github 上进行维护 v2fly/domain-list-community
使用:
- GEOSITE, cn, DIRECT
- GEOSITE, netflix, PROXY
- GEOIP, telegram, PROXY由于 GEOIP 可能对域名做额外DNS解析, 因此优先使用 GEOSITE
rule-provider
类似 proxy-provider, 引入外部规则集合
rule-providers:
google: # name, 不能重复
type: http # provider类型, http / file / inline
path: ./rule1.yaml
url: "https://raw.githubusercontent.com/../Google.yaml"
interval: 600 # 更新时间, 单位 秒
proxy: DIRECT # 指定代理进行下载/更新
behavior: classical # 行为, 可选 domain/ipcidr/classical, 对应不同文件格式
format: yaml # 可选 yaml/text/mrs
size-limit: 0
header:
User-Agent:
- "mihomo/1.18.3"
Authorization:
- 'token 1231231'
payload: # 仅 type=inline 时生效
- 'DOMAIN-SUFFIX,google.com'behavior
不同选项对应不同的文件格式, 可选: classical / domain / ipcidr
classical
支持规则的全部类型 (rule-set / sub-rule 除外)
payload:
- DOMAIN-SUFFIX,google.com
- DOMAIN-KEYWORD,google
- DOMAIN,ad.com
- SRC-IP-CIDR,192.168.1.201/32
- IP-CIDR,127.0.0.0/8
- GEOIP,CN
- DST-PORT,80
- SRC-PORT,7777domain
纯域名模式, 内容要遵循 Clash wildcard 语法
payload:
- '.blogger.com'
- '*.*.microsoft.com'
- 'books.itunes.apple.com'ipcidr
纯 IP 网段列表
payload:
- '192.168.1.0/24'
- '10.0.0.0.1/32'