Featured image of post 仅使用小猫配置透明代理

仅使用小猫配置透明代理

All in one之透明代理

前言

在24年的时候,我写过《基于DNS的分流方案》,采用了Mosdns和小猫组合的方式来实现透明代理。这套方案确实很不错,直到现在依然能稳定工作。既然如此,那我为什么要考虑更换它呢?主要原因是如果想修改某个域名的规则是否走代理,不但要在小猫里设置规则,还要同步在Mosdns中配置,一个域名要在两个地方进行配置,实在是不太好维护。此外,2年过去了mihomo本身的dns模块已经更新了很多功能了,现在再使用mosdns进行套娃也没有场景了。

最近看到Aethersailor的设置方案1,里面的思路比较符合我的需求:只使用一个插件完成代理、DNS和分流配置。这个教程已经写的非常详细了,我这里就不重复引用,只记录我在此基础上的修改吧。

实现效果

按照这个方案配置完成后,大致可以实现下面这些效果:

  • 使用Fake-IP模式获得较好的性能;
  • 国内直连流量尽量不进入内核,减少路由器性能消耗;
  • 非直连域名的 DNS 解析交给远端处理,降低解析结果不一致和 DNS 泄漏的概率;
  • 后续日常使用基本只需要在控制面板里切换策略组。

配置过程

先按教程完成最基本的配置,现在已经有一个可以正常使用的透明代理环境了。与教程不一样的地方,我这里没有选择进行UDP代理,毕竟目前浏览网页还主要是TCP流量。但是我在使用的时候遇到了下面的问题,在此就做个记录吧。

精简规则

原版的规则实在是太多了,实际使用的时候并不需要这么多的规则。同时,我也需要对自动选择的节点进行分类。虽然插件提供了覆写设置,但是不如直接修改配置文件来的快了,于是就有了下面的这个版本。

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
# Powered by luoboQAQ

# url 里填写自己的订阅,名称不能重复
proxy-providers:
  provider1:
    url: "https://example.com"
    path: ./config/provider1.yaml
    proxy: DIRECT
    type: http
    interval: 86400
    health-check:
      enable: true
      url: https://cp.cloudflare.com/generate_204
      interval: 300

mixed-port: 7890
ipv6: true
allow-lan: true
unified-delay: false
tcp-concurrent: true
external-controller: 127.0.0.1:9090
external-ui: ui
external-ui-url: "https://github.com/Zephyruso/zashboard/releases/latest/download/dist.zip"

find-process-mode: strict

profile:
  store-selected: true
  store-fake-ip: true

proxy-groups:

  - name: 🚀 手动选择
    type: select
    use:
      - provider1
    proxies:
      - ♻️ 自动选择
      - 🇭🇰 香港节点
      - 🇺🇸 美国节点
      - 🇯🇵 日本节点
      - 🇼🇸 台湾节点
  - name: ♻️ 自动选择
    type: url-test
    url: https://cp.cloudflare.com/generate_204
    interval: 300
    tolerance: 50
    use:
      - provider1
    # 只考虑低倍率节点
    filter: ":0"
  - name: 📺 Bahamut
    type: select
    use:
      - provider1
    proxies:
      - 🇼🇸 台湾节点
      - 🚀 手动选择
      - 🎯 全球直连
  - name: 🤖 AI服务
    type: select
    use:
      - provider1
    proxies:
      - 🚀 手动选择
      - ♻️ 自动选择
      - 🇭🇰 香港节点
      - 🇺🇸 美国节点
      - 🇯🇵 日本节点
      - 🇼🇸 台湾节点
  - name: 🤖 claude大人
    type: select
    use:
      - provider1
    proxies:
      - 🚀 手动选择
      - ♻️ 自动选择
      - 🇭🇰 香港节点
      - 🇺🇸 美国节点
      - 🇯🇵 日本节点
      - 🇼🇸 台湾节点
  - name: 🍎 苹果服务
    type: select
    use:
      - provider1
    proxies:
      - 🎯 全球直连
      - 🚀 手动选择
      - ♻️ 自动选择
      - 🇭🇰 香港节点
      - 🇺🇸 美国节点
      - 🇯🇵 日本节点
      - 🇼🇸 台湾节点
  - name: Ⓜ️ 微软服务
    type: select
    use:
      - provider1
    proxies:
      - 🎯 全球直连
      - 🚀 手动选择
      - ♻️ 自动选择
      - 🇭🇰 香港节点
      - 🇺🇸 美国节点
      - 🇯🇵 日本节点
      - 🇼🇸 台湾节点
  - name: 🎮 游戏平台
    type: select
    use:
      - provider1
    proxies:
      - 🎯 全球直连
      - 🚀 手动选择
      - ♻️ 自动选择
      - 🇭🇰 香港节点
      - 🇺🇸 美国节点
      - 🇯🇵 日本节点
      - 🇼🇸 台湾节点
  - name: 🎮 Steam
    type: select
    use:
      - provider1
    proxies:
      - 🎯 全球直连
      - 🚀 手动选择
      - ♻️ 自动选择
      - 🇭🇰 香港节点
      - 🇺🇸 美国节点
      - 🇯🇵 日本节点
      - 🇼🇸 台湾节点
  - name: 🚀 测速工具
    type: select
    use:
      - provider1
    proxies:
      - 🎯 全球直连
      - 🚀 手动选择
      - ♻️ 自动选择
      - 🇭🇰 香港节点
      - 🇺🇸 美国节点
      - 🇯🇵 日本节点
      - 🇼🇸 台湾节点
  - name: 🎓 谷歌学术
    type: select
    use:
      - provider1
    proxies:
      - 🚀 手动选择
      - ♻️ 自动选择
      - 🇭🇰 香港节点
      - 🇺🇸 美国节点
      - 🇯🇵 日本节点
      - 🇼🇸 台湾节点
  - name: 🐟 漏网之鱼
    type: select
    use:
      - provider1
    proxies:
      - 🚀 手动选择
      - ♻️ 自动选择
      - 🎯 全球直连
      - 🇭🇰 香港节点
      - 🇺🇸 美国节点
      - 🇯🇵 日本节点
      - 🇼🇸 台湾节点
  - name: 🔀 非标端口
    type: select
    proxies:
      - 🎯 全球直连
      - 🐟 漏网之鱼
  #分隔,下面是地区分组
  - name: 🇭🇰 香港节点
    type: url-test
    url: https://cp.cloudflare.com/generate_204
    interval: 300
    tolerance: 50
    include-all: true
    exclude-type: direct
    filter: "(?i)港|hk|hongkong|hong kong"
  - name: 🇯🇵 日本节点
    type: url-test
    url: https://cp.cloudflare.com/generate_204
    interval: 300
    tolerance: 50
    include-all: true
    exclude-type: direct
    filter: "(?i)日|jp|japan"
  - name: 🇺🇸 美国节点
    type: url-test
    url: https://cp.cloudflare.com/generate_204
    interval: 300
    tolerance: 50
    include-all: true
    exclude-type: direct
    filter: "(?i)美|us|unitedstates|united states"
  - name: 🇼🇸 台湾节点
    type: url-test
    url: https://cp.cloudflare.com/generate_204
    interval: 300
    tolerance: 50
    include-all: true
    exclude-type: direct
    filter: (🇹🇼|🇼🇸|台|新北|彰化|\bTW(?:[-_ ]?\d+(?:[-_ ]?[A-Za-z]{2,})?)?\b|Taiwan|TAIWAN|TWN|TPE|ROC)
  - name: 🎯 全球直连
    type: select
    proxies:
      - DIRECT

rules:
  # 本地地址和域名直连
  - GEOSITE,private,🎯 全球直连
  - GEOIP,private,🎯 全球直连,no-resolve
  # Custom项目收录的直连规则
  - RULE-SET,Custom_Direct_Domain,🎯 全球直连
  - RULE-SET,Custom_Direct_Classical_IP,🎯 全球直连
  # Custom项目收录的代理规则
  - RULE-SET,Custom_Proxy_Domain,🚀 手动选择
  - RULE-SET,Custom_Proxy_Classical_IP,🚀 手动选择
  - GEOSITE,google-cn,🎯 全球直连
  - GEOSITE,category-games@cn,🎯 全球直连
  - RULE-SET,Steam_CDN_Classical,🎯 全球直连
  - GEOSITE,category-game-platforms-download,🎯 全球直连
  - GEOSITE,category-public-tracker,🎯 全球直连
  # 分流规则
  - GEOSITE,anthropic,🤖 claude大人
  - GEOSITE,category-ai-!cn,🤖 AI服务
  - GEOSITE,google-scholar,🎓 谷歌学术
  - GEOSITE,category-speedtest,🚀 测速工具
  - GEOSITE,imgur,🇯🇵 日本节点
  - GEOSITE,bahamut,📺 Bahamut
  - GEOSITE,steam,🎮 Steam
  - GEOSITE,category-games,🎮 游戏平台
  - GEOSITE,gfw,🚀 手动选择
  - GEOIP,telegram,🚀 手动选择,no-resolve
  - GEOIP,twitter,🚀 手动选择,no-resolve
  - GEOIP,facebook,🚀 手动选择,no-resolve
  - GEOIP,google,🚀 手动选择,no-resolve
  - GEOIP,netflix,🚀 手动选择,no-resolve
  - GEOSITE,cn,🎯 全球直连
  - GEOIP,cn,🎯 全球直连,no-resolve
  - RULE-SET,Custom_Port_Direct,🔀 非标端口
  - MATCH,🐟 漏网之鱼


rule-anchor:
  ip: &ip {type: http, interval: 86400, behavior: ipcidr, format: mrs}
  domain: &domain {type: http, interval: 86400, behavior: domain, format: mrs}
  classical_list: &classical_list {type: http, interval: 86400, behavior: classical, format: text}
# 规则可在https://github.com/MetaCubeX/meta-rules-dat/tree/meta 查看
rule-providers:
  Custom_Direct_Domain:
    type: http
    behavior: domain
    url: https://testingcf.jsdelivr.net/gh/Aethersailor/Custom_OpenClash_Rules@main/rule/Custom_Direct_Domain.yaml
    path: ./providers/Custom_Direct_Domain.yaml
    interval: 28800
  Custom_Direct_Classical_IP:
    type: http
    behavior: classical
    url: https://testingcf.jsdelivr.net/gh/Aethersailor/Custom_OpenClash_Rules@main/rule/Custom_Direct_Classical_IP.yaml
    path: ./providers/Custom_Direct_Classical_IP.yaml
    interval: 28800
  Custom_Proxy_Domain:
    type: http
    behavior: domain
    url: https://testingcf.jsdelivr.net/gh/Aethersailor/Custom_OpenClash_Rules@main/rule/Custom_Proxy_Domain.yaml
    path: ./providers/Custom_Proxy_Domain.yaml
    interval: 28800
  Custom_Proxy_Classical_IP:
    type: http
    behavior: classical
    url: https://testingcf.jsdelivr.net/gh/Aethersailor/Custom_OpenClash_Rules@main/rule/Custom_Proxy_Classical_IP.yaml
    path: ./providers/Custom_Proxy_Classical_IP.yaml
    interval: 28800
  Steam_CDN_Classical:
    type: http
    behavior: classical
    url: https://testingcf.jsdelivr.net/gh/Aethersailor/Custom_OpenClash_Rules@main/rule/Steam_CDN_Classical.yaml
    path: ./providers/Steam_CDN_Classical.yaml
    interval: 28800
  Custom_Port_Direct:
    type: http
    behavior: classical
    url: https://testingcf.jsdelivr.net/gh/Aethersailor/Custom_OpenClash_Rules@main/rule/Custom_Port_Direct.yaml
    path: ./providers/Custom_Port_Direct.yaml
    interval: 28800

分流BT/PT流量

在我的网络拓扑中有一台NAS,上面运行了qBittorrent进行下载任务。虽然按照项目原始的配置,这些下载的流量进入到核心当中也还是直连,不会消耗流量。但这样不但增加小猫的压力,还导致控制面板项目很多,不方便查看。于是就需要编写防火墙规则将这些流量不要进入核心。由于NAS的ip地址是静态的,于是我便指定将此机子的非80/443端口的流量不要进入核心。

插件设置-开发者选项中添加下面的两条命令:

1
2
3
LOG_TIP "配置NAS非标端口流量不进入核心"
nft insert rule inet fw4 openclash ip saddr 192.168.6.20 tcp dport != { 80, 443 } return
nft insert rule inet fw4 openclash_mangle_v6 ip6 saddr fd11:4514:6::20 tcp dport != { 80, 443 } return
💡 提示

这里我只配置了TCP流量,如果启用了UDP代理还需要加上对应的规则

解决浏览器本地网络访问权限提示

自从Chrome 142版本开始,Google正式引入了Local Network Access(LNA,本地网络访问)相关限制2。简单来说,如果一个公网网站尝试访问用户本地网络中的地址,例如192.168.x.x127.0.0.1,或者其他被浏览器认为属于本地/私有网络的地址,Chrome就会先拦截请求,并要求用户授予本地网络访问权限。这个功能的出发点是好的,主要是为了防止网页在用户不知情的情况下访问路由器、NAS、打印机等局域网设备,从而降低CSRF攻击和局域网指纹识别的风险。

但是在Fake-IP模式下,这个机制就容易被误伤。Fake-IP的原理并不是直接返回域名真实IP,而是先返回一个保留地址段中的“假IP”,再由内核根据这个假IP找回原始域名并进行分流。问题就出在这里:浏览器看到网页连接的不是一个普通公网IP,而是一个比较特殊的Fake-IP地址时,可能会把它当成对本地网络或非公网地址的访问。于是原本应该由内核接管并转发的请求,还没走到代理链路,就先被Chrome的LNA检查拦了下来。表现出来的现象就是:Chrome一直弹出本地网络访问权限提示。

最简单粗暴的方法有两种:「所有域名都返回fake-ip」与「禁用该权限控制」。对于第一种,所有流量都会进入核心这肯定是不行,而第二种明显是饮鸩止渴,让浏览器变得更不安全,而且还要对所有的设备进行设置太过麻烦。

所以我们可以使用一些未被使用的公网ip来作为我们的fake-ip范围3。我选择了25.0.0.0/8(英国国防部所属,没有路由)和2001:2::/48(IANA保留的测试用网段)这两个网段来实现。配置如下:

  • 覆写设置-DNS设置-Fake-IP 地址范围 (IPv4 Cidr),修改为25.0.0.0/8
  • 插件设置-IPv6设置-Fake-IP 地址范围 (IPv6 Cidr),修改为2001:2::/48

Cloudflare CDN优选

在我的网络环境(校园网)中,通过IPv6访问Cloudflare CDN的落点为HKG,速度很快且延迟很低。于是对于一些套用CF CDN的网站,我可以通过修改域名解析结果,通过只返回ipv6地址来实现优选的效果。

一开始,我是在Dnsmasq中设置,但是如果仅手动设置AAAA地址,它还是会返回A地址,从而导致优选失效。如果想要让Dnsmasq仅返回AAAA地址,还需要在配置文件中设置为local很麻烦。好在现在mihomo核心已经支持Hosts配置,只需要在其中填入即可。

覆写设置-DNS设置中,勾选Hosts,并填入下面的内容即可:

1
2
3
4
5
6
7
8
# Static hosts for DNS server and connection establishment (like /etc/hosts)
#
# Wildcard hostnames are supported (e.g. *.clash.dev, *.foo.*.example.com)
# Non-wildcard domain names have a higher priority than wildcard domain names
# e.g. foo.example.com > *.example.com > .example.com
# P.S. +.foo.com equals to .foo.com and foo.com

'+.vcb-s.com': '2606:4700:0:ce6b:dede:5ae2:2485:3061'

但是这样配置完后,却发现网站无法访问,提示SSL证书错误。经过排查发现,这样设置流量依旧进入了核心而不是直连,从而导致了错误。(IPv4却不会出现这样的问题,很奇怪,可能是TPoxy的问题导致的吧)于是我便将Cloudflare CDN的ipv6域名段全部设置在了排除列表,终于让网站能访问了。

插件设置-IPv6设置-本地 IPv6 绕过地址中,添加下面的地址:

1
2
3
4
5
6
7
8
#cf
2400:cb00::/32
2606:4700::/32
2803:f800::/32
2405:b500::/32
2405:8100::/32
2a06:98c0::/29
2c0f:f248::/32

小结

这样配置下来,最大的好处就是省心。现在把这些逻辑都收回到小猫里面,只需要配置一次,后续订阅、规则、DNS和绕过设置也都在同一个界面里维护。

对我来说,这套方案的目标并不是追求功能堆满,而是尽量简化配置链路。这样在我毕业之后,后续的同学也能将这套配置好好的维护下去吧。

参考链接