Clash 学习笔记
下面的内容完全是 AI 大模型生成的,与本人毫无关系,本人不对内容负任何责任。
理解篇
Clash 代理逻辑可以分为三部分:
- 如何获取流量:接管系统代理,其他应用的网络请求可以会被 Clash 接管,或者 TUN 模式直接彻底接管流量
- 如何分类流量:按照域名或 IP 地址等进行分类处理
- 如何转发流量:按照代理组的各种策略进行转发,最终流量走向一个具体的物理节点
如何获取流量
首先关注如何获取流量:存在主动和被动两类方式。
先关注被动方式:只要 clash 本身在运行,就一直在监听对应端口,如果使用环境变量或者程序提供的代理选项指向了这个端口,就可以使用 clash 提供的代理。
对于命令行工具,建议通过环境变量设置代理。
然后关注主动方式:在 Windows 上存在 System Proxy 和 Tun mode 两种主动接管流量的方式,对应不同层次的接管逻辑:
- System Proxy:设置系统 http 代理(指向 clash 目前监听的端口),由应用自愿决定是否使用代理,应用可以选择绕过,对于大部分命令行工具和网络游戏可能不会生效。
- TUN Mode(虚拟网卡):Clash 创建一个虚拟网卡(TUN),修改系统路由表,强制接管 IP 层流量。(某些游戏加速器也会这么做,因此两者可能会冲突)
这两个模式不是相互冲突的,但是建议只开启其中一个即可,某些 GUI 会让用户只选择其中一个,另一个会被自动关闭。
对于 Linux,通常没有提供与 System Proxy 等效的方式,但是还有一些其他方式(例如 redir-port)。
如何分类和转发流量
然后关注如何分类和转发流量,首先需要理解从机场的订阅链接获得的配置文件:
一个机场必须提供一组分散在各个地区的实际节点,它提供的配置文件包括这些节点的实际信息以及连接方式(密码),还有代理组和规则。
下面依次解释这三个核心概念:
- 节点(Proxy / Node):节点是最终网络出口
- 对应一台真实服务器,包含协议、地址、端口、密钥等,不包含任何策略
- 某个连接的流量最终一定落到某个具体节点(DIRECT 直接连接也会被视作一个 Proxy)
- 代理组(Proxy Group):策略控制单元,决定流量下一跳的选择
- 它包括一组候选目标作为流量的下一跳,候选目标可以是某个具体的 Proxy,也可以是其他的 Proxy Group,从而形成一个多层策略树结构
- 它对于下一跳目标的选择策略通常是固定在配置文件中的,包括如下几种:
- select:手动选择(运行时由用户在 UI 层面选择,不会写入到配置文件中)
- load-balance:负载均衡
- url-test:自动测速选最优
- fallback:故障转移(按顺序尝试,直到找到可用的)
- 规则(Rule):流量分类的匹配入口,实质是一个 swich 语句,将特定类型的流量导向一个 Proxy 或者 Proxy Group,或者直接连接,例如
- 根据目标域名或者 IP 地址进行匹配
DOMAIN-SUFFIX,google.com,节点组:如果目标域名是 google.com 的,则使用 节点组 这个 Proxy GroupGEOIP,CN,DIRECT:如果目标地址是 CN 的 IP 地址,则使用 DIRECT 也就是直接连接
- 匹配规则的兜底语句例如
MATCH,其他流量:如果没有匹配的规则,选择 其他流量 这个 Proxy Group
- 根据目标域名或者 IP 地址进行匹配
配置文件中的 select 部分提供给用户进行手动选择,通常会在 Clash 的 UI 中体现:
- 对于策略为 select 的 Proxy Group,可以手动选择一个测试延迟较低的下一跳目标,这种 UI 层面的选择是持续性的,如果不选择,则会使用第一个;
- 在其他策略的 Proxy Group 中,没有选中其中一个目标的概念,也没有对应的 UI 操作。
整体控制
在配置文件之上,Clash 还有更高层次的整体控制逻辑:
- 可以在多个订阅之间切换,此时使用对应的配置文件进行处理;(DIRECT 也可能作为一个默认的订阅方案被提供)
- 可以设置运行模式:
- 直连(DIRECT):对所有流量不经过任何代理,直接连接
- 规则(策略模式)(RULE):基于当前选择的订阅所对应的配置文件,使用其中设置的规则和代理组对流量进行分类处理;
- 全局(GLOBAL):基于当前选择的订阅所对应的配置文件,绕过规则匹配(即不区分流量特征),所有流量都送入当前在 UI 层面选择的一个 Proxy Group 或 Proxy。
Clash 还有一个值得关注的点是 DNS 覆写,如果使用规则模式,建议开启,这会让 Clash 也接管 DNS 查询环节,使得代理操作更安全一点。
网络连接视角
下面从本地应用发起一个网络连接的视角,来理解 Clash 在规则模式下的处理:
第一步,流量是否进入 Clash(接管阶段),包括两种情况:
- System Proxy:应用愿意用系统代理,则进入 Clash,不愿意则可以绕过
- TUN 模式:不管应用愿不愿意,流量都进 Clash
第二步,流量怎么分类(规则阶段)
- Clash 查看 域名 / IP / 端口信息,按配置文件里的 Rule 从上到下匹配,根据匹配结果交给某个 Proxy Group 或者 Proxy。
第三步,流量具体怎么走(代理组阶段)
- 由 Proxy Group 根据自己的策略决定下一跳:
- select:用 UI 中用户选的那个,没选过就用第一个
- url-test / load-balance / fallback:顾名思义,用内置规则来选择下一跳
- 如果代理组里还是代理组,就一层层往下找,直到找到一个具体的 Proxy,直接连接也视作一个 Proxy。
- 如果规则阶段直接指定了一个具体的 Proxy,那么代理组阶段就跳过了。
- 由 Proxy Group 根据自己的策略决定下一跳:
第四步,建立连接并转发
- Clash 用该节点的信息建立真实连接,数据开始来回转发,这条连接期间一般不会再重新选路。
全局模式相对于规则模式的不同是,忽略规则阶段,全部流量都使用 UI 当前选的一个 Proxy / Proxy Group,如果是 Proxy Group,则继续往下,直到找到一个具体的 Proxy。
在直连模式下,进入 Clash 的流量通常会被统一按 DIRECT 处理,即不经过远端代理节点;规则和代理组选择基本被绕过,但 Clash 仍可能参与接管、DNS 和连接转发过程。
补充:分流代理的危险性
目前绝大多数的代理都采用了国内国外分流代理的策略,但是这种做法存在显而易见的危险。
使用分流代理的方式容易泄露自身的隐私信息,包括但不限于 IP 地址,浏览器以及硬件指纹等等一系列信息,并且可以将代理 IP 与真实 IP 进行身份关联。
一个最常见的例子就是如果某个国外的网站使用了百度统计脚本,此时代理 IP 与真实 IP 的对应关系就可以轻松被这个网站获取。另一个例子就是一些恶意的邮件,比如使用国外的邮箱服务时,接收到了一个恶意邮件,这个邮件中嵌入了一些国内的资源如图片,那么真实 IP 等信息也可以被轻松获取。—— Arch Linux 安装使用教程之魔法学院
可以在 https://www.ip111.cn 测试访问不同网站所使用的 IP。
使用篇
原版 Clash 内核的作者已经删库跑路了,早期的一些基于内核封装的 GUI 软件例如 Clash for Windows,Clash For Android 也已经删库或停止更新。
目前还有一些 fork 或重写的延续性项目仍然在更新,例如 MetaCubeX/mihomo 内核以及基于这个内核封装的 GUI 软件。这里的选择方案是:
- 在 Linux 上直接使用 MetaCubeX/mihomo 内核
- 在 Windows 上使用 Clash Verge
- 在 Android 上使用 Clash Meta for Android
在 Windows 和 Android 使用的是可视化软件,因此非常容易,下面只记录一下在 Linux 上直接使用 mihomo 内核的方法。
参考资料:
Linux 使用 mihomo
从 MetaCubeX/mihomo 下载 Mihomo 内核的预编译包(区分v1/v2/v3,取决于CPU是否支持部分指令以加速优化,通常可以直接选v3),然后放在 ~/.local/bin 中即可
1 | wget https://github.com/MetaCubeX/mihomo/releases/download/v1.19.24/mihomo-linux-amd64-v3-v1.19.24.gz |
然后测试一下
1 | mihomo -v |
Mihomo 的正常运行需要两个文件:
- 配置文件
config.yaml Country.mmdb文件,这是一个 IP 地址定位数据库,利用 GeoIP2 服务识别互联网用户的地点位置,以供规则分流时使用,如果在启动时没有找到会尝试自动下载。
将这两个文件准备好,存放在 ~/.config/miholo 目录下。
除了复制已有的配置文件,也可以直接从订阅链接获取,例如使用 wget 命令(注意链接必须用引号包起来)
1 | wget -O config.yaml 'http://example.com/shortURL' |
使用 curl 命令则必须要加上 -L 选项,否则不会自动跟随重定向
1 | curl -L -o config.yaml 'http://example.com/shortURL' |
有的订阅链接可能需要在最后加上 &clash 的版本,否则无法正常识别。
在一个会话中手动启动 mihomo
1 | miholo |
代理并不会被其他程序主动使用,使用代理的方法通常包括:
- 配置程序支持的相关环境变量,例如
https_proxy、http_proxy、all_proxy、no_proxy; - 使用程序自身提供的代理选项,例如
curl -x socks5h://localhost:7891 www.baidu.com
注意:需要保持 miholo 持续运行,其他程序才能使用代理。
默认情况下,miholo 通常会监听 127.0.0.1 的 7890,7891 端口或合并的 7890 端口(取决于配置文件),可以使用下面的命令检查当前相关端口(789*)的监听情况
1 | ss -lntp | grep 789 |
输出形如
1 | LISTEN 0 4096 127.0.0.1:7890 0.0.0.0:* users:(("mihomo",pid=1196035,fd=3)) |
这对应配置文件中指定的混合端口
1 | # HTTP 和 SOCKS5 混合代理端口 |
配置文件中还有一种常见的做法是把 HTTP 和 SOCKS5 代理端口分开:
1 | port: 7890 |
我们需要在后台持续开启 clash,对于 Linux 远程服务器来说,一种简单的做法是 Linux 后台命令,另一种做法是使用 tmux 专门开启一个 session 来运行 clash。
更专业的做法是使用 systemd,下面简单记录一下用户级的 systemd 使用方法。
新建 service 文件 ~/.config/systemd/user/miholo.service,向其中添加内容
1 | [Unit] |
重新加载系统服务,启动并配置自动启动
1 | systemctl --user daemon-reload |
检查状态
1 | systemctl --user status mihomo |
注意:Ubuntu 默认用户级 systemd 服务在用户登出后会自动终止,如果需要让服务持续运行,还需要 root 用户或 sudo 权限进行手动配置
1 | sudo loginctl enable-linger SOME_USER |
验证
1 | loginctl show-user $USER | grep Linger |
输出 Linger=yes 表示已启用。
控制 API
Clash 除了支持几个代理端口,还有一个 external-controller,这是 Clash 的控制 API 服务器端口,通常默认为 9090 端口,可以通过这个端口对 Clash 进行操作,包括切换配置,测试节点延迟等(GUI 功能都是对此的封装)。
例如使用如下命令测试节点的延迟
1 | curl -s -X GET -H "Authorization: Bearer mypassword" http://127.0.0.1:9090/proxies?test=true > delay.json |
对接 clash 的 external-controller,可以使用 yacd 在 web 端进行简单的管理,但是不包括更新链接的功能。
这个功能对 Linux 服务器很有用,使用 ssh 转发 9090 端口到本地,就可以使用 web 端进行管理。但是对 Windows 没什么用,因为 clash verge 等都是更好的 GUI 封装,而且 clash verge 默认把这个功能关闭了。
自定义规则
由于每次更新订阅时都会自动应用所有规则,但是我们有时需要对规则进行自定义的修改,此时就非常不便。Clash Verge 允许用户配置针对 Profile 进行修改的额外脚本,不会被更新覆盖。
例如对一些学术期刊网站不走代理
1 | // Define main function (script entry) |
