只有跳板代理能联网时访问国际互联网(Mihomo、Clash)

这篇文章的操作没那么合规, 但是大家都是睁一只眼闭一只眼的

有些公司手边机器不能联网, 但会给一个代理跳板, 那如何在本地置Mihomo/Clash来访问国际互联网呢? 访问国际互联网分两个方面:

  1. 域名解析
  2. IP跳板

域名问题

如果本地无法联网, 那么你的域名大概率全都会解析失败, 如果不考虑国际互联网, 那么有两种常见代理协议:

  1. socks5, 可代理任何基于 TCP/UDP 的网络请求
  2. http, 只允许基于 HTTP(s) 的网络请求, 并且通常只支持版本 $\leq$ http/1.1 的, 这也是配置非 TUN 代理后 cursor 通常要下降到 http/1.1 才能正常工作的原因

socks5 默认不将域名解析交给代理, 假如你设置代理为socks5://10.10.10.13:1234, 其访问流程是:

  1. 访问 msys2.org
  2. 将域名交给本地配置的 DNS 解析
  3. 获取 ip
  4. 将对 ip 的网络请求交给 10.10.10.13:1234

所以在软件里设置 socks5 代理后, 有可能卡死在第二步还是访问不了.

有些软件支持 socks5h 协议, 如果你配置为socks5h://10.10.10.13:1234, 则可以

  1. 访问 msys2.org
  2. 将对 域名 的网络请求交给 10.10.10.13:1234

有些工具不允许设置 socks5h, 但是通常会有类似使用 SOCKS v5 时代理 DNS 查询的选项, 勾上也相当于 socks5h.

如下是三种情况的细节, 你可以在本机同样执行试试看:

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
# socks5, 先本地解析域名, 再连接代理
C:\>curl -v -x socks5://127.0.0.1:21882 google.com
* Trying 127.0.0.1:21882...
* Host google.com:80 was resolved.
* IPv6: (none)
* IPv4: 198.18.0.43
* SOCKS5 connect to 198.18.0.43:80 (locally resolved)
* SOCKS5 request granted.
* Connected to 127.0.0.1 () port 21882
* using HTTP/1.x
* Connected to 127.0.0.1 (127.0.0.1) port 21882
* using HTTP/1.x

# socks5h, 代理负责解析
C:\>curl -v -x socks5h://127.0.0.1:21882 google.com
* Trying 127.0.0.1:21882...
* SOCKS5 connect to google.com:80 (remotely resolved)
* SOCKS5 request granted.
* Connected to 127.0.0.1 () port 21882
* using HTTP/1.x
* Connected to 127.0.0.1 (127.0.0.1) port 21882
* using HTTP/1.x

# http, 一并发给代理
C:\>curl -v -x http://127.0.0.1:21882 google.com
* Trying 127.0.0.1:21882...
* Connected to 127.0.0.1 (127.0.0.1) port 21882
* using HTTP/1.x
> GET http://google.com/ HTTP/1.1
> Host: google.com
> User-Agent: curl/8.14.1
> Accept: */*
> Proxy-Connection: Keep-Alive
>
* Request completely sent off

curl 目前广泛存在于各种操作系统, 如上命令在 Linux/Windows 下直接使用, 不过在 PowerShell 下, curl 是Invoke-WebRequest的别名, 你应当使用 curl.exe 或者换到 cmd 里.

机场问题

访问国际互联网时, 通常你有一个机场和一些自定义的配置, 那么通常的格式是:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
proxy-providers:
机场提供器:
type: http
path: ./ruleset/uuds.yaml
url: <订阅url>

proxy-groups:
- name: 自动机场
type: url-test
use:
- 机场提供器
# 更多组...
rules:
- DOMAIN-SUFFIX,cursor.sh,自动机场
# 更多规则...

机场节点走跳板

若要让机场走内部跳板转一道, 可以

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
proxy-providers:
机场提供器:
type: http
path: ./ruleset/uuds.yaml
url: <订阅url>

+ proxies:
+ - name: first-hop
+ type: <公司内部代理类型 socks5 或 http>
+ server: <公司内部代理 IP>
+ port: <公司内部代理 Port>

proxy-groups:
- name: 自动机场
type: url-test
use:
- 机场提供器
+ - name: 自动机场-relay
+ type: relay
+ proxies:
+ - first-hop
+ - 自动机场
# 更多组...
rules:
- - DOMAIN-SUFFIX,cursor.sh,自动机场
+ - DOMAIN-SUFFIX,cursor.sh,自动机场-relay
# 更多规则...

图中绿色部分是要新增的, 红色部分是要减少的

机场订阅走跳板

很快你会发现订阅压根更新不出来, 那么你需要:

1
2
3
4
5
6
proxy-providers:
机场提供器:
type: http
path: ./ruleset/uuds.yaml
url: <订阅url>
+ proxy: first-hop

这样机场订阅更新就走跳板了, 一定要注意使用 https 的订阅链接.

另外, 这个方案也可以用在普通情况, 比如你有自己的一个服务器, 并且机场订阅链接无法直接访问, 就可以通过指定订阅更新代理到自己服务器来避开.

mihomo内域名解析走跳板

但是到这一步还是不行, 因为域名解析完全失败, 只要把这个加到配置里:

1
2
3
4
5
6
7
8
9
dns:
enable: true
enhanced-mode: fake-ip
proxy-server-nameserver:
- 'https://1.12.12.12/dns-query#first-hop'
- 'https://1.1.1.1/dns-query#first-hop'
proxy-server-nameserver:
- 'https://1.12.12.12/dns-query#first-hop'
- 'https://1.1.1.1/dns-query#first-hop'

这样 mihomo 内部的域名解析请求就会通过跳板转发到 https://1.12.12.12/dns-query 走 DoH.