Linux 上的移动代理配置
在 Linux 系统中,每个工具都管理自己的代理配置,因此没有一个统一的设置位置。本指南将介绍环境变量及其作用范围、桌面设置及其局限性,以及那些坚持使用自身配置文件的工具。
- 环境变量可作用于大多数工具 — curl、wget、git、pip 和 npm 都会读取 http_proxy 和 https_proxy。
- sudo 会将其丢弃 —— 除非你刻意将其传递过去,否则具有提升权限的命令会绕过你的代理。
- apt 设计上会忽略这些设置 —— 该软件包管理器希望使用自己的配置文件,而不是你的 shell 环境变量。
- 该桌面设置并非全局生效 —— 它仅适用于 GNOME 应用程序,而您的终端并不属于此类。
将静态服务器地址加入白名单,并完全跳过凭据验证。
一个配置文件中的四个导出项配置了用户空间的大部分内容。
环境变量及其作用范围
Linux 没有其他操作系统所指的那种系统级代理设置。取而代之的是一种约定:大多数软件会读取 http_proxy 和 https_proxy 环境变量,并尊重 no_proxy 设置,以绕过对这些主机的代理。 这一惯例覆盖了相当广泛的范围——包括 curl、wget、git、pip、npm 以及大多数编程语言的运行时环境——但这终究只是一种惯例而非硬性规则,而本指南真正要探讨的正是那些例外情况。
export http_proxy="http://user123:[email protected]:8000" export https_proxy="$http_proxy" export no_proxy="localhost,127.0.0.1,::1,.internal.example.com,10.0.0.0/8" # Some tools read only the upper-case names export HTTP_PROXY="$http_proxy" export NO_PROXY="$no_proxy"
请务必将 no_proxy 设置为特定值,切勿留空。 如果不设置该参数,发往 localhost 和内部主机名的请求会被发送到代理服务器,而代理服务器无法访问这些地址——因此,五分钟前还能正常运行的数据库连接或健康检查,此刻却会因看似与代理无关的原因开始超时。参数以逗号分隔、不包含空格,且开头带点可匹配子域名。
请注意,https_proxy 接受 http:// 这种方案。该方案指定了如何连接到代理,而非目标服务器使用的协议;客户端会建立一条隧道,而 TLS 协议则在隧道内端到端运行。 对于 SOCKS5,建议使用 socks5h 格式,其末尾的 h 表示 DNS 解析也将通过代理进行——如果没有这个 h,您的机器会本地解析每个主机名,并将您访问的全部域名列表泄露到您所在的网络中。
| 图层 | 谁在阅读它 | 它遗漏了什么 |
|---|---|---|
| 环境变量 | curl、wget、git、pip、npm、大多数运行时环境 | 通过 sudo、apt 执行的任何操作,以及由 systemd 启动的服务 |
| 桌面端代理设置 | GNOME Web 以及读取桌面配置的应用程序 | 您的终端,以及从该终端启动的所有程序 |
| 按工具配置 | apt、Docker、snap、git——每个都有自己的文件 | 没什么,但每个工具必须写一个 |
| proxychains | 任何程序,通过拦截其网络调用 | 静态链接的二进制文件,以及任何不依赖 libc 网络功能的程序 |
桌面代理设置及其涵盖的内容
GNOME、KDE 及其他桌面环境都提供了网络代理设置,这看起来像是 Linux 原本所缺乏的全局控制功能。但事实并非如此。该设置只是写入了一个桌面配置键,只有刻意读取该键的应用程序才会受到影响——实际上,只有 GNOME Web 以及少数几个 GNOME 应用程序会受到影响。
你的终端无法读取它,从终端启动的任何程序也无法读取。设置桌面代理后却疑惑为什么 curl 会返回你的真实地址,这大概是 Linux 代理设置中最常见的错误,而犯下这个错误也是完全可以理解的:界面中没有任何提示说明其作用范围如此狭窄。
将桌面设置视为一种应用程序级设置,只不过它恰好位于系统菜单中。如果你希望整个用户空间都经过代理处理,那么在shell配置文件中设置环境变量就是实现这一目标的机制——但即便是这些设置,在sudo的边界处也会失效。
apt、sudo 以及需要单独配置文件的工具
有两件事肯定会导致原本正常运行的 Linux 代理配置失效,这两者都与环境无法跨越边界有关。
首先是 sudo。出于安全考虑,sudo 在运行命令前会清除大多数环境变量,因此您精心导出的代理设置便不复存在了。 临时解决方法是要求 sudo 保留环境变量;要永久解决,则需将代理变量添加到 sudoers 文件中的 env_keep 列表中,该文件应使用 visudo 进行编辑,而非直接编辑。
第二种方法很合适,它设计上就忽略了环境变量,而是希望使用自己的配置。虽然每次通过 sudo 传递变量也能行得通,但配置文件更可靠,因为无论谁以何种方式运行该命令,它都会生效。
# apt -- write /etc/apt/apt.conf.d/95proxies Acquire::http::Proxy "http://user123:[email protected]:8000"; Acquire::https::Proxy "http://user123:[email protected]:8000"; # sudo -- preserve the environment for one command sudo -E some-command # sudo -- permanently, via `sudo visudo` Defaults env_keep += "http_proxy https_proxy no_proxy HTTP_PROXY HTTPS_PROXY NO_PROXY" # git, which keeps its own config git config --global http.proxy "http://user123:[email protected]:8000"
Docker 值得单独提一下,因为它存在两个名称相同的独立问题。 守护进程需要一个代理来拉取镜像,该配置通过 systemd 即插即用文件进行设置;而容器则需要通过构建参数或环境变量传递代理。对其中一方的配置对另一方毫无作用,这便导致了大家熟悉的情况:镜像可以正常拉取,但其中的应用程序却无法访问任何资源。
对于完全不支持代理的软件——例如某些较旧的网络实用程序和少数闭源工具——proxychains 是标准解决方案。 它会预加载一个库,该库会拦截程序的网络调用,并将其通过其配置文件中定义的代理进行路由,同时支持 SOCKS5 和 HTTP 协议。但对于静态链接的二进制文件,它无法提供帮助,因为此时没有任何内容可被拦截。
查明某个命令实际使用的代理服务器
由于每个工具都是独立配置的,因此真正有意义的问题从来不是“代理是否正常工作”,而是“该命令正在读取哪套配置”。应直接询问该命令本身,而非检查设置。
env | grep -i proxy curl -v https://api.ipify.org 2>&1 | head -20 curl https://api.ipify.org ; echo # through whatever env says curl --noproxy '*' https://api.ipify.org ; echo # deliberately direct sudo -E env | grep -i proxy # does sudo keep them?
| 症状 | 最可能的原因 |
|---|---|
| 在 shell 中可以运行,但在 sudo 环境下会失败 | sudo 清除了环境变量。请使用 preserve 标志或 env_keep。 |
| curl 通过代理,而 apt 则不是 | apt 会忽略环境变量。请在 apt.conf.d 目录下提供一个配置文件。 |
| 桌面设置已开启,终端不受影响 | 运行正常。桌面键无法触发shell。 |
| 本地服务突然超时 | no_proxy 未设置,因此 localhost 的流量正被发送到代理服务器。 |
| 镜像无法下载,容器无法连接网络 | Docker 守护进程经过代理,但容器并未经过代理。 |
| 设置正确,没有任何更改 | 该个人资料虽经编辑,但从未注明来源。请打开一个新的终端窗口。 |
如果你想确认的是端点本身,而不是你的配置,那么 免费的 PXM2 代理检测工具 通过浏览器进行测试,并报告检测到的代理类型和出口国家。
为 Linux 获取移动代理
PXM2 实时节点位置——选择您需要出口 IP 的国家/地区,并按照本页的步骤进行配置:
法国
印度
新加坡
常见问题解答
如何在 Linux 上设置代理?
在您的 shell 中导出 http_proxy 和 https_proxy,并为需要绕过代理的主机设置 no_proxy。将这些设置添加到您的 shell 配置文件中,以确保其持久生效。这样可以覆盖 curl、wget、git、pip、npm 以及大多数命令行软件,不过 apt 以及其他少数工具还需要额外的配置。
为什么 apt 会忽略我的代理环境变量?
这是设计使然——当 apt 在 sudo 环境下运行时,它不会继承您的 shell 环境,而是优先使用自身的配置。请在 /etc/apt/apt.conf.d/ 目录下的某个文件中添加一条 Acquire proxy 指令,这样无论由谁以何种方式运行该命令,该设置都能保留下来。这比每次都通过 sudo 传递变量要可靠得多。
为什么我的代理在 sudo 环境下无法正常工作?
sudo 在执行命令前会清除大部分环境变量,因此您导出的代理设置无法生效。若仅需临时使用,请使用保留环境的 sudo 选项;若需长期生效,请通过 visudo 将代理变量添加到 sudoers 文件中的 env_keep 中。
GNOME 的网络代理设置是否适用于终端?
不。桌面代理设置仅适用于读取桌面配置的应用程序——例如 GNOME Web 以及少数几款 GNOME 应用程序。终端工具读取的是环境变量,因此完全不受此设置影响。设置代理后却期望 curl 也能遵循该设置,这是 Linux 代理配置中最常见的错误之一。
如何为不支持代理的应用程序设置代理?
使用 proxychains,它会拦截程序的网络请求,并将其通过你在其配置文件中设置的代理进行转发。对于既不读取环境变量也不支持自身代理设置的软件而言,这是标准解决方案,且它既支持 SOCKS5,也支持 HTTP。
相关移动代理指南
如果您的 Linux 机器是服务器而非桌面电脑,IP 白名单通常是更好的身份验证选择——设置概述中介绍了何时应优先采用该方法。
设置指南
核心移动代理指南
让您的 Linux 服务器通过真实运营商 IP 进行路由
专用的 4G/5G 调制解调器,提供无限带宽和无限轮询次数——支持 HTTP(S) 和 SOCKS5 端点,并为拥有稳定 IP 地址的服务器提供 IP 白名单功能。
获取移动代理