macOS 上的移动代理配置
macOS 会为每个网络服务分别保存代理设置,而“终端”则完全不会读取这些设置。本指南将介绍“代理”面板、哪些浏览器会遵循这些设置、如何使用 networksetup 编写脚本进行配置,以及针对那些忽略这些设置的情况该如何处理。
- 代理服务器属于网络服务——相关设置分别与 Wi-Fi 或以太网关联,而非与 Mac 关联。
- Safari 本身没有代理设置 ——它完全遵循系统设置面板,因此是进行测试的理想选择。
- Terminal 会忽略该面板 —— curl、git、npm 和 wget 会读取环境变量。
- 使用 networksetup 脚本完成整个操作 ——当你经常在代理连接和直接连接之间切换时,这非常有用。
macOS 无需任何额外软件即可支持 HTTP(S) 和 SOCKS5。
networksetup 将整个配置浓缩为两行。
“代理”窗格及其所属的接口
macOS 将代理设置集中在一个显眼的位置,这让人感觉比 Windows 更简单。实际上确实如此——但有一个结构上的陷阱,会在初始设置成功很久之后仍会让用户感到困惑:这些设置属于一个网络服务,而不是 Mac 本身。
打开“系统设置”,进入“网络”,然后选择您当前使用的连接。点击“详细信息”,再点击“代理”。您将看到一个带有复选框的代理类型列表。勾选您需要的代理类型,填写服务器和端口地址,如果您的代理需要凭据,请勾选“身份验证”复选框,然后依次点击“确定”和“应用”。
| 窗格中的条目 | 它实际上配置了什么 | 在以下情况下使用它: |
|---|---|---|
| Web 代理(HTTP) | 普通 HTTP 请求 | 始终伴随安全连接——大部分流量采用HTTPS,但也有部分不采用HTTPS |
| 安全 Web 代理(HTTPS) | 用于 HTTPS 请求的隧道 | 总是如此。正是因为漏掉了这一项,才导致有些网站能加载,而有些却不能。 |
| SOCKS 代理 | 原始 TCP 数据,而不仅仅是 Web 流量 | 对于非 Web 协议,或者当您的服务商提供了 SOCKS5 端口时 |
| 绕过列表 | 应直接连接的主机 | 代理无法访问的本地地址和内部主机名 |
这些设置会应用到您所选的网络服务上——比如 Wi-Fi。 插入以太网线、通过手机共享网络,或连接 USB 适配器时,macOS 会使用该服务自身的代理设置,而这些设置是空的。代理功能并未停止工作;您只是切换到了一个从未配置过的不同网络接口。请为实际使用的每项服务分别进行配置。
正是这种结构使得 macOS 非常适合编写脚本。由于每个服务都是通过名称来调用的,因此只需两条命令即可开启代理,再用两条命令关闭,这比每次切换时都要在面板中反复点击要方便得多。
networksetup -listallnetworkservices networksetup -setwebproxy "Wi-Fi" proxy.example.net 8000 on user123 s3cret networksetup -setsecurewebproxy "Wi-Fi" proxy.example.net 8000 on user123 s3cret networksetup -setsocksfirewallproxy "Wi-Fi" proxy.example.net 1080 on user123 s3cret networksetup -getwebproxy "Wi-Fi" networksetup -setwebproxystate "Wi-Fi" off
系统命令可在不清除您已输入内容的情况下关闭代理,因此,在代理模式和直接连接模式之间切换只需一条命令,而无需重新输入四个值。
Safari、Chrome 以及遵循系统设置的浏览器
Safari 本身没有代理配置。完全没有——既找不到相关对话框,也不存在配置出错的可能。 Safari 发出的每个请求都遵循“代理”面板的设置。这一点足够特别,值得加以利用:Safari 是检验系统级配置是否正确的最纯粹的测试方式,因为它不会被你遗忘的某个应用程序设置所覆盖。
Chrome 默认也会遵循系统设置面板,其代理设置按钮仅会打开 macOS 的网络设置,而非提供自己的代理设置选项。可以通过在启动时添加命令行参数来覆盖此行为,这在需要让某个浏览器通过代理连接,而系统其他部分直接连接时,偶尔会派上用场。
/Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome \ --proxy-server="http://proxy.example.net:8000" \ --user-data-dir="/tmp/chrome-proxied"
Firefox 是个例外,这一点在任何地方都一样:它会保留自己的连接设置,并优先使用这些设置而非系统设置。如果 Safari 通过代理退出,而 Firefox 没有,那么就该查看那个对话框。
若要同时通过不同的代理运行多个配置文件,仅靠浏览器标志已不够用——这就是 反检测浏览器 存在的意义。
终端无法读取“代理”面板
这一点往往让所有人都措手不及。curl、wget、git、npm、pip 以及 macOS 上几乎所有的命令行工具都会完全忽略“代理”面板。它们读取环境变量,这与在 Linux 上的行为完全一致,而 macOS 并未在两者之间提供任何桥梁。
这并非一个错误,也没有任何设置可以改变其行为。该面板用于配置 Cocoa 应用程序所使用的系统网络层;而命令行工具则沿用了早于该层的 Unix 惯例。
export http_proxy="http://user123:[email protected]:8000" export https_proxy="$http_proxy" export no_proxy="localhost,127.0.0.1,::1" # Verify without touching the shell environment curl -x "$http_proxy" https://api.ipify.org ; echo curl https://api.ipify.org ; echo
在 macOS 上,使用小写是更稳妥的选择。有些工具只识别小写名称,少数工具只识别大写名称,同时设置两者是常见的做法——但请注意,出于设计考虑,curl 会忽略大写的 HTTPS_PROXY,以避免发生标头注入问题。 导出小写名称对可以兼容最广泛的软件。
与任何系统一样,将密码写入shell配置文件意味着您运行的每个进程都能读取该密码。如果该Mac拥有一个固定的IP地址,请联系您的服务提供商将其加入白名单,并完全删除这些凭据。
诊断 macOS 提示已配置的代理
“代理”窗格中显示的勾选框并不能证明你关注的应用程序正在使用它。应从该层向外推导,而不是从凭据入手。
| 症状 | 最可能的原因 |
|---|---|
| 昨天工作了,今天没工作 | 您当前连接的是另一个网络服务。请检查哪个网络接口处于活动状态。 |
| Safari 启用了代理,而 Terminal 则未启用 | 运行正常。导出环境变量。 |
| 有些网站能正常加载,有些则卡住了 | Web 代理已启用,但安全 Web 代理已禁用,因此 HTTPS 没有路由。 |
| 只有 Firefox 能绕过代理 | 其自身的连接设置将覆盖系统设置。 |
| 凭证多次被拒绝 | 在Web代理字段中输入SOCKS凭据。这两个端口需要分别登录。 |
最快捷的单一测试方法是打开 Safari,并加载一个显示您公共地址的网页。由于 Safari 无法单独配置,因此它显示的结果就是系统级代理的真实情况——如果该页面通过代理访问,而其他内容则未通过代理,说明系统本身没有问题,只是其他应用程序读取的是不同的层级。
您还可以使用以下方法确认端点本身: 免费的 PXM2 代理检测工具,该报告会显示检测到的代理类型和出口国家。
为 macOS 获取移动代理
PXM2 实时节点位置——选择您需要出口 IP 的国家/地区,并按照本页的步骤进行配置:
法国
印度
新加坡
常见问题解答
如何在 macOS 上设置代理?
打开“系统设置”,进入“网络”,选择您正在使用的网络连接,点击“详细信息”,然后选择“代理”。启用 HTTP 的“Web 代理”、HTTPS 的“安全 Web 代理”或“SOCKS 代理”,输入主机名和端口号,如果代理需要凭据,请添加凭据,然后点击“确定”。Safari 和 Chrome 会立即识别这些设置。
为什么当我从 Wi-Fi 切换到有线网络时,代理就无法正常工作了?
这是因为 macOS 是按网络服务分别存储代理设置,而非全局存储。在连接 Wi-Fi 时配置“代理”面板仅会配置 Wi-Fi 的设置;而通过以太网或其他适配器连接时,系统会使用该适配器自身的设置,但这些设置为空。请为实际使用的每个网络服务分别进行配置,或者使用 networksetup 脚本进行自动化配置。
Safari 有自己的代理设置吗?
不。Safari 完全没有独立的代理配置——它发出的每个请求都遵循“网络”设置中的“代理”面板。这使其在故障诊断中真正派上用场:如果 Safari 能通过代理连接,而另一款应用却无法通过,说明系统配置没有问题,而是另一款应用正在读取其他内容。
为什么 curl 会忽略我的 macOS 代理设置?
因为 curl 从来不会读取“代理”面板。它会读取 http_proxy 和 https_proxy 环境变量,wget、git 和 npm 也是如此。请在您的 shell 配置文件中导出这些变量,或者显式地将代理信息传递给 curl。这是一种设计上的差异,而非缺陷,几乎每个人都会因此遇到一次问题。
如何在 macOS 上通过命令行设置代理?
使用 `networksetup` 命令,并将网络服务的名称完全按“网络设置”中显示的名称输入——例如 `networksetup -setwebproxy "Wi-Fi" host port`。针对安全 Web 代理和 SOCKS 代理,分别有对应的命令,此外还有状态命令,可用于关闭各自的代理,而无需清除已输入的内容。
相关移动代理指南
Windows 和 Linux 对同一个问题采取了不同的处理方式——如果你需要在不同机器之间切换工作,这两种系统都值得了解。