Mac 端爱国上网最佳实践

背景

最优秀的配置就是在使用时感觉不到配置的存在,然而复杂的应用场景决定了我们需要多种代理配置。虽然最终的目的是摆脱繁琐的配置切换,但在此之前,我们有必要梳理一下日常使用中常见的痛点。

  1. 模拟器需要连代理,因此电脑必须设置 HTTP/HTTPS 代理
  2. 终端无法使用 Shadowsocks 代理,即使设置了全局代理也不行
  3. 某些应用,比如 Telegram,需要科学上网
  4. 访问墙外网站需要连 VPS,墙内网站不需要连接,代理会让国内网站访问速度降低

本质

复杂的需求导致了代理场景的多样化,一般来说有三种:

  1. Charles 的 HTTP(s) 代理
  2. VPS 的 socks5 代理或 PAC
  3. 直接连接

上述问题的本质都来源于这三种代理是互斥的,而且切换起来比较麻烦。在 Mac 上有脚本可以切换,但有时依然无法人工区分改用哪种代理,在 iOS 上,就连设置代理都会非常耗时。

目标与解决思路

明确了问题与问题背后的复杂度以后,我们需要确定一个目标,以目标为导向,来指导自己的行动。

目标其实非常简单:

经过有限次的配置,彻底避免切换代理

换句话说,就是希望代理的切换是自动进行的,全程不再需要人工干预。

这似乎有悖于目前的工作模式,不过没关系,既然系统代理不方便,我们就需要一个全局代理,起到 路由 作用,根据一定的规则把请求转发到合适的代理上去。这样就把代理的切换简化成了规则的配置,规则永远存在,只要不断维护完善就行。

Mac 配置

Mac 上用到四个工具:

  1. Proxifier: 全局控制工具,负责应用层面的请求转发
  2. Charles:一种代理,负责处理那些需要被抓包的请求
  3. sslocal: ss 代理的客户端,负责处理那些需要走 Shadowsocks 协议的请求
  4. SwitchyOmega:Chrome 拓展工具,负责对 Chrome 中的网页进行智能代理选择

sslocal

首先我们要租一台境外的服务器,用来运行 shadowsocks 的服务端。如果还没有租用服务器,可以购买搬瓦工的服务,便宜且稳定,这个链接 年费 20 美元,每月 500G 流量,这个链接 年费 50 美元,每月 1000G 流量,

首先运行:

pip install shadowsocks

然后运行:

ssserver -p port -k password -m method
# port 指定 ssserver 运行在服务端的哪个端口
# password 是客户端用来连接的密码
# method 是加密方式,比如 rc-md5 或 aes-256-cfb 等

注意:如果你通过 ssh 连接到服务器, 在 ssh 断开后,你执行的进程也会随之被杀死。要想让 ssserver 长久运行,需要下面这个命令:

nohup ssserver -p port -k password -m method &

简单两行代码,一个 shadowsocks 的服务就搭建完成了。

在 Mac 上运行 Shadowsocks 客户端一样容易,根本不需要那些乱七八糟的 GUI 工具,同样先安装 shadowsocks 工具:

pip install shadowsocks

如果你还没有安装 pip3,则先输入:

brew install python3

接下来填写一下 sslocal 的配置,按照 JSON 格式填写即可:

{
    "server":"ip",
    "server_port":443,
    "local_port":14179,
    "password":"password",
    "timeout":600,
    "method":"aes-256-cfb"
}

然后就可以运行 sslocal 了:

nohup sslocal -q -c shadowsocks.json &

这样就在后台运行了 sslocal 进程,任何应用都可以使用 socks 协议代理到本机的 14179 端口,从而实现科学上网。

Proxifier

Proxifer 是一个控制 app 代理方式的软件,有了它,我们就可以控制某个 app,比如 Telegram 使用哪种代理。首先在 Proxifier 中建立一个 Shadowsocks 代理:

依次选择 Proxies、Add 并填写本机的端口。接下来就可以把某些特定应用的流量转到代理上了:

终端科学上网

有些时候,安装一些软件包会非常慢,这是因为数据源存在国外的服务器上,但终端默认不会走代理,即使设置了全局代理也无效。

最简单的方式是使用如下命令:

export ALL_PROXY=socks5://127.0.0.1:1080
# 取消代理可以用下面命令
# unset ALL_PROXY

不过根据个人实践,偶尔这个命令会有抽风的时候,更复杂,也更靠谱的做法是安装 polipo。完整教程可以参考这篇文章:为终端设置 Shadowsocks 代理

当然,如果你能用路由器翻墙,那么就不存在终端翻墙的问题了。

Charles

Charles 作为一个大名鼎鼎的抓包工具,具体使用方法就不用我细说了,可以参考巧哥的这篇文章:iOS 开发工具-网络封包分析工具 Charles

虽然 Charles 的抓包功能足够强大,但美中不足的是,它的数据处理能力极为孱弱。虽然有 Map Local/Remote 和 Rewrite 功能,但终究不是图灵完备的语言, 灵活性和可拓展性还不够强大,比如如果数据是使用 protobuf 的形式传输,Charles 就无能为力了。

通常情况下,为了搭建一个多端统一、长期可维护的测试环境,我们需要一个中间人服务器,经过一段时间的尝试和技术选型,最终我们选择了 MITM,详细内容可以参考我的这篇博客:HTTP 代理服务器技术选型之旅

有了 MITM 工具以后,iOS 模拟器的调试问题就迎刃而解了。注意,此时不要直接修改系统的代理,因为来回切换代理比较麻烦,Charles 提供了一个非常好用的功能,叫 External Proxy。顾名思义,Charles 可以把自己视为一个中转站,把经过自己的数据发送到下一个代理服务器上去。

因此,日常工作中,我采用的方案是系统代理长期设置为 Charles,且 Charles 长期将外部代理设置为 MITM,两者要么同时生效,要么同时失效,经过 Charles 数据一定会经过 MITM 。

快速切换系统代理

上述配置虽然大部分时候都能 work,但万一出现 Proxifier 不能指定代理,而且这个网络流量又不能走代理服务器时,我们还需要一个终极方案——快速把系统代理还原为默认。虽然我至今只在某次更新 App Store 时遇到过上述问题,但做好技术储备还是没有坏处的。

使用 networksetup 配合各种参数即可实现上述需求,我写了一个可以自动切换 Charles 和 GoAgentX 代理的脚本,在这里 可以下载并根据自己的需求自行修改。

效果如图所示:

SwitchyOmega

最后一个要用到的工具是 Chrome 的一个插件:SwitchyOmega,它可以给不同的 URL 配置不同的访问策略。

首先我们新建一个情景,用来处理需要科学上网的网站。

图片

如果是前端开发,那些需要抓包调试的网站可以代理到 Charles 上,过程类似就不赘述了。

然后需要配置下 auto switch 场景,在绝大多数时候,我们都将使用这个场景:

图片

第一个区域内是一些自己制定的规则,如果自动配置中某些网站的访问方式不符合我们的要求,可以单独列在这里。第二个区域表示如果命中规则列表,则使用 socks 代理,否则就直接连接。第三个区域则使用了一个开源的网址列表,列出了那些需要科学上网的网站。

有了这样的配置,我们就可以实现 百度、淘宝、京东等网站直接连接,YouTube、Google、草榴等网站科学上网了。

Mac 配置小结

Mac 上需要用到的软件较多,但每个软件的使用都不太复杂,回忆一下之前的几个痛点:

  1. 模拟器需要连接代理,因此电脑需要设置 HTTP/HTTPS 代理。
  2. 这一点我们其实是通过长期设置代理为 Charles -> MITM 实现的,并且利用脚本来快速切换代理。
  3. 终端无法使用 SS 代理,即使是全局代理也不行。这个问题通过 polipo 工具解决,并且编写了脚本。
  4. 某些应用,比如 Telegram,需要科学上网。这个问题通过 Proxifier 来设置某个 app 使用的代理方式。
  5. 按需代理,只有需要科学上网的网站才用代理。这个需求通过 Chrome 的插件 SwitchyOmega 完成。

results matching ""

    No results matching ""