在Linux终端和CI中配置代理:HTTP_PROXY、HTTPS_PROXY、NO_PROXY逐步指南
想象一下:你打开终端,输入安装包的命令,却只得到一片寂静或连接错误。原因往往是网络访问只能通过代理服务器,而系统对此一无所知。本指南将教你如何在Linux和CI环境中配置代理,让所有需要的地方都能正常工作。
引言:你将获得什么,以及本指南适合谁
学完本教程,你将能够自信地在Linux终端和持续集成系统中配置代理。你会理解环境变量的工作原理,掌握如何正确构建代理URL,并让所有关键开发工具都能通过代理运行。
具体收获:
- 在当前终端会话中配置代理并生效。
- 永久配置,重启后依然有效。
- 为apt、dnf、git、npm、pip、curl、wget、Docker正确配置。
- 在GitHub Actions和GitLab Runner中构建可用的CI流水线。
- 理解如何验证流量确实通过代理。
- 安全存储代理密码的技巧。
适用人群: 初级系统管理员、开发者和DevOps工程师,他们工作在拥有公司代理的环境中。也包含进阶内容:systemd细节、SSH的ProxyCommand以及CI中的秘密遮蔽。
前提知识: 你需要能够打开终端、输入命令,并理解文件和文件夹的概念。其余内容将在讲解中逐步解释。
所需时间: 基础配置大约15分钟。完整阅读本指南并配置所有工具和CI大约需要60-90分钟。不要着急,最好一步步认真完成。
建议: 在另一个窗口中打开本指南,按顺序执行命令。这样你绝不会错过重要步骤。
准备阶段:地址、端口、用户名和正确的代理URL
在开始配置之前,需要收集代理服务器的信息。没有这些信息就无法继续。
从何处获取代理信息
通常代理由以下一方提供:
- 公司系统管理员 —— 如果你在公司网络内工作。向他索要地址、端口和认证信息。
- 代理租赁服务商 —— 在个人账户中通常有访问配置区域。
- 你自己的服务器 —— 如果你自己搭建了代理,那么信息你已知晓。
你需要四个要素:地址(host)、端口(port)、用户名(username) 和 密码(password)。有时无需用户名和密码 —— 即无需认证的代理。
如何构建代理URL
代理以单一字符串形式指定 —— URL。通用格式如下:
协议://用户名:密码@地址:端口
举例说明。假设代理地址为 proxy.example.com,端口 3128,用户名 ivan,密码 secret123。那么URL将如下所示:
http://ivan:secret123@proxy.example.com:3128
如果无需认证,URL更简单:
http://proxy.example.com:3128
关于协议: 最常用的是 http 协议,即使访问的是HTTPS网站也可以。这很正常 —— 这里的协议指的是与代理服务器通信的协议,而非目标网站。有时会遇到使用 https 或 socks5 协议的代理。
为什么密码中的特殊字符需要编码
这是导致神秘错误最常见的原因之一。如果密码中包含像 @、:、/、#、? 这样的特殊字符,它们会破坏URL的解析。例如,字符 @ 用于分隔认证信息与地址。如果它出现在密码中,系统会混淆,无法区分密码结束和地址开始的位置。
解决方案是 百分比编码(percent-encoding)。每个有问题的字符都会被替换为百分号加上其十六进制代码。
常见替换:
- 字符 @ 变成 %40
- 字符 : 变成 %3A
- 字符 / 变成 %2F
- 字符 # 变成 %23
- 字符 ? 变成 %3F
- 空格字符变成 %20
- 字符 % 变成 %25
示例:如果密码是 p@ss:word,那么在URL中应表示为 p%40ss%3Aword。完整的URL将是:
http://ivan:p%40ss%3Aword@proxy.example.com:3128
提示: 要快速对密码进行编码,可以使用命令 python3 -c "import urllib.parse, sys; print(urllib.parse.quote(sys.argv[1], safe=''))" '你的密码'。它会输出一个可直接插入URL的字符串。
⚠️ 注意: 切勿在公共计算机的终端中直接输入真实密码——它会进入历史记录。关于安全输入,我们将在指南末尾单独讨论。
✅ 检查: 你应该已经拥有一个或多个构建好的代理URL,密码中的所有特殊字符都已编码。请将它们保存在安全的地方,最好是密码管理器。
基础概念:环境变量、大小写和NO_PROXY格式
为了让配置不再神秘,我们来解析三个基本概念。这需要五分钟,但能为你节省数小时的调试时间。
什么是环境变量
环境变量 是操作系统保存在内存中并传递给运行程序的一个命名值。可以把它想象成一张便条,系统向每个新程序展示:这是代理地址,请使用它。
Linux中的许多网络工具在启动时会读取特定的变量,如果找到它们,就会自动将流量通过代理发送。最重要的变量包括:
- HTTP_PROXY —— 用于未加密的HTTP请求的代理。
- HTTPS_PROXY —— 用于加密的HTTPS请求的代理。
- NO_PROXY —— 需要直连(绕过代理)的地址列表。
- FTP_PROXY —— 用于FTP协议的代理,现在很少使用。
- ALL_PROXY —— 适用于所有协议的代理,通常用于socks。
http_proxy与HTTP_PROXY的大小写区别
这是一个微妙但重要的点。Linux区分大小写,因此 http_proxy 和 HTTP_PROXY 实际上是两个不同的变量。不同的程序会读取不同的版本。
历史上形成了这样的惯例:
- curl工具同时读取小写和大写版本,但小写的 http_proxy 有一个安全特性——在CGI环境中curl会忽略大写的HTTP_PROXY,以防止攻击。
- wget工具传统上偏好小写名称。
- 许多使用不同语言编写的程序会读取大写版本。
实际结论: 为了保险起见,同时设置小写和大写版本。这是最可靠的策略,我们将采用它。
NO_PROXY的格式以及为什么它不支持CIDR
NO_PROXY 变量包含一个以逗号分隔的地址列表,这些地址应该被直连访问。这对于内部资源至关重要:数据库、本地服务、云元数据。
正确值的示例:
localhost,127.0.0.1,.example.com,.internal,169.254.169.254
注意 example.com 前面的点。点表示该规则适用于所有子域名:api.example.com、git.example.com 等等。
⚠️ 注意: NO_PROXY 通常不支持CIDR表示法和子网掩码。像 10.0.0.0/8 这样的写法在大多数工具中不会生效。某些现代库版本可能支持,但不可依赖。请明确列出具体的地址和域名后缀。
此外,NO_PROXY 通常不支持星号作为通配符。不要写 *.example.com —— 使用前面的点:.example.com。
提示: 始终在 NO_PROXY 中添加 localhost 和 127.0.0.1。否则本地请求会通过代理,很可能出错。
✅ 检查: 你理解 HTTP_PROXY、HTTPS_PROXY 和 NO_PROXY 的作用,了解大小写差异,并记住 NO_PROXY 不支持CIDR。现在可以进入实践了。
步骤1:在当前会话中启用代理并用curl测试
本阶段目标: 学会在打开的终端中快速启用代理,并确认其工作正常。这些设置仅在关闭终端窗口前有效——非常适合测试。
通过export设置变量
export命令在当前会话中创建环境变量。执行以下命令,替换成你自己的代理URL。
- 打开终端。
- 输入HTTP命令:export http_proxy="http://ivan:secret123@proxy.example.com:3128"
- 输入HTTPS命令:export https_proxy="http://ivan:secret123@proxy.example.com:3128"
- 复制为大写版本:export HTTP_PROXY="$http_proxy"
- 再次复制:export HTTPS_PROXY="$https_proxy"
- 设置例外:export no_proxy="localhost,127.0.0.1,.example.com"
- 复制:export NO_PROXY="$no_proxy"
构造 "$http_proxy" 会代入已设置的小写变量的值,避免重复输入URL。
提示: 注意整个URL都用双引号括起来。这可以防止bash shell错误解释特殊字符。
通过curl验证
现在验证变量是否被读取。curl工具非常适合此用途。
- 检查变量是否已设置:echo $http_proxy —— 你应该看到你的URL。
- 执行详细请求:curl -v http://example.com
- 在输出中查找包含 "Connected to proxy.example.com" 的行 —— 这表示curl已通过代理。
如果认证信息正确且代理可访问,你将收到HTML页面作为响应。如果看到错误407,则问题出在用户名或密码上——返回前面的编码部分检查。
提示: 标志 -v(verbose)显示连接的详细信息。这是调试代理的主要工具。没有它,你无法看到请求实际发往何处。
要禁用当前会话的代理,使用unset命令:unset http_proxy https_proxy HTTP_PROXY HTTPS_PROXY no_proxy NO_PROXY。所有变量都将消失。
✅ 检查: curl -v http://example.com 显示通过你的代理服务器连接并返回页面内容。如果是这样,第一步就成功了。
步骤2:使配置永久生效
本阶段目标: 让代理在每次登录系统时自动启用,并在重启后保持不变。这里有几种层级,选择适合你的即可。
选项A:仅限当前用户,通过 ~/.bashrc
文件 ~/.bashrc 在你以当前用户身份打开交互式终端时执行。这是最安全的方式——你不影响系统其他用户。
- 使用编辑器打开文件:nano ~/.bashrc
- 滚动到文件末尾。
- 添加与步骤1中相同的export行。
- 保存文件:按Ctrl+O,然后Enter,再按Ctrl+X退出。
- 应用更改而不重启:source ~/.bashrc
提示: 编辑前先备份:cp ~/.bashrc ~/.bashrc.backup。如果出现问题,你可以轻松恢复原始文件。
选项B:全系统设置,通过 /etc/environment
/etc/environment 文件为所有用户设置变量,甚至在bash之外也生效。这里的格式特殊:不使用export,直接写 变量名=值。
- 以管理员权限打开文件:sudo nano /etc/environment
- 添加不带export的行,例如:http_proxy="http://ivan:secret123@proxy.example.com:3128"
- 类似地添加 https_proxy、HTTP_PROXY、HTTPS_PROXY、no_proxy、NO_PROXY。
- 保存并退出。
- 要生效,请注销并重新登录,或重启计算机。
选项C:通过 /etc/profile.d
更灵活的系统级方式是创建一个单独的脚本放在 /etc/profile.d 目录下。该目录中的所有 .sh 文件都会在登录时执行。
- 创建文件:sudo nano /etc/profile.d/proxy.sh
- 内部使用普通的export命令,如步骤1所示。
- 保存文件。
- 使其可执行:sudo chmod +x /etc/profile.d/proxy.sh
这种方式比 /etc/environment 更方便,因为它支持完整的shell语法。
选项D:为系统服务通过systemd drop-in配置
注意,这是一个重要的细节。由systemd管理的后台服务不会读取你的 ~/.bashrc,并且通常忽略 /etc/environment。它们需要单独的方法——drop-in文件。
假设你需要为某个特定服务(例如 some-service)配置代理。
- 创建drop-in目录和文件:sudo systemctl edit some-service
- 编辑器打开。输入配置块。
- 在 [Service] 部分添加类似 Environment="HTTP_PROXY=http://ivan:secret123@proxy.example.com:3128" 的行。
- 类似地添加 Environment 行用于 HTTPS_PROXY 和 NO_PROXY。
- 保存文件。
- 重新加载配置:sudo systemctl daemon-reload
- 重启服务:sudo systemctl restart some-service
Environment 指令仅为该服务设置变量。这是systemd服务的唯一正确方式。
⚠️ 注意: 在RHEL、CentOS、Fedora和AlmaLinux上,路径和工具是相同的——systemd的工作方式一致。区别稍后会在包管理器部分出现。
✅ 检查: 打开一个新终端(不是手动执行export的那个)并执行 echo $http_proxy。如果你看到你的URL,则永久配置已生效。
步骤3:分别配置包管理器和实用工具
本阶段目标: 许多工具不会读取环境变量,或者有自己的配置文件。我们将逐一配置,确保一切正常。
Ubuntu和Debian上的apt
apt包管理器通常通过sudo运行,可能看不到你的变量。更可靠的方式是在它自己的配置文件中设置代理。
- 创建文件:sudo nano /etc/apt/apt.conf.d/95proxies
- 添加行:Acquire::http::Proxy "http://ivan:secret123@proxy.example.com:3128";
- 添加HTTPS行:Acquire::https::Proxy "http://ivan:secret123@proxy.example.com:3128";
- 保存文件。
- 测试:sudo apt update
注意每行末尾的分号——这是apt语法的必需部分。
RHEL、Fedora、AlmaLinux上的dnf和yum
在RHEL系列系统上,代替apt的是dnf和yum。代理在主配置文件中设置。
- 打开文件:sudo nano /etc/dnf/dnf.conf (对于旧系统 /etc/yum.conf)
- 在 [main] 部分添加行:proxy=http://proxy.example.com:3128
- 如果需要认证,额外添加:proxy_username=ivan 和 proxy_password=secret123
- 保存文件。
- 测试:sudo dnf makecache
在dnf中,用户名和密码更适合用单独的指令指定,而不是放在URL中。
通过 .npmrc 配置npm
- 设置代理命令:npm config set proxy "http://ivan:secret123@proxy.example.com:3128"
- 设置HTTPS:npm config set https-proxy "http://ivan:secret123@proxy.example.com:3128"
- 设置会自动写入 ~/.npmrc 文件。
- 验证:npm config get proxy
通过 pip.conf 配置pip
- 创建目录:mkdir -p ~/.config/pip
- 打开文件:nano ~/.config/pip/pip.conf
- 添加 [global] 部分和行:proxy = http://ivan:secret123@proxy.example.com:3128
- 保存文件。
- 通过安装任意包测试:pip install requests
或者,你可以在命令中直接指定代理:pip install requests --proxy http://proxy.example.com:3128
通过 http.proxy 配置git
- 全局设置:git config --global http.proxy "http://ivan:secret123@proxy.example.com:3128"
- 如果需要,单独为HTTPS设置:git config --global https.proxy "http://ivan:secret123@proxy.example.com:3128"
- 验证:git config --global --get http.proxy
要删除设置:git config --global --unset http.proxy
通过ProxyCommand配置git over SSH
如果你使用SSH克隆仓库(地址样式为 git@github.com),http.proxy 设置无效——SSH是另一种协议。这里需要 ProxyCommand。
- 打开文件:nano ~/.ssh/config
- 为所需主机添加块:Host github.com 行,然后缩进添加 ProxyCommand nc -X connect -x proxy.example.com:3128 %h %p
- 保存文件。
- 如果尚未安装netcat,安装它:Ubuntu上 sudo apt install netcat-openbsd,RHEL上 sudo dnf install nmap-ncat。
这里 %h 和 %p 会被自动替换为目标主机和端口。标志 -X connect 指示netcat使用HTTP代理。
通过 .curlrc 配置curl
- 打开文件:nano ~/.curlrc
- 添加行:proxy = "http://ivan:secret123@proxy.example.com:3128"
- 保存文件。
现在,即使没有环境变量,curl也将始终使用代理。
通过 .wgetrc 配置wget
- 打开文件:nano ~/.wgetrc
- 添加行:http_proxy = http://proxy.example.com:3128 和 https_proxy = http://proxy.example.com:3128
- 添加 use_proxy = on
- 保存文件。
PHP的composer
Composer读取环境变量HTTP_PROXY,所以通常不需要单独配置。如果你想显式设置,使用启动时的变量:HTTP_PROXY=http://proxy.example.com:3128 composer install
Go和GOPROXY:重要警告
⚠️ 注意: GOPROXY 变量不是我们意义上的代理服务器。不要混淆。GOPROXY 指向Go模块镜像——一个下载库的服务。它是仓库地址,而非网络代理。
要让Go通过你的常规代理访问互联网,请使用标准的HTTP_PROXY和HTTPS_PROXY。并且保留GOPROXY为默认值,除非你有更改模块镜像的特定需求。
提示: 记住一条规则——如果变量名中含有PROXY,并不一定意味着它是关于网络代理的。GOPROXY、npm registry等——它们是关于包来源的。
✅ 检查: 为每个配置好的工具执行测试操作:sudo apt update、npm install、git ls-remote 等。所有操作都应成功连接到网络。
步骤4:配置Docker和Kubernetes
本阶段目标: Docker是一个特例。它有三个不同的代理配置位置,混淆它们是一个典型错误。我们将逐一分析。
位置1:通过systemd drop-in配置Docker守护进程
此配置用于让Docker自身能够从注册表拉取镜像。Docker守护进程由systemd管理,因此我们使用熟悉的drop-in机制。
- 创建目录:sudo mkdir -p /etc/systemd/system/docker.service.d
- 创建文件:sudo nano /etc/systemd/system/docker.service.d/proxy.conf
- 添加 [Service] 部分。
- 添加行 Environment="HTTP_PROXY=http://proxy.example.com:3128"
- 类似地为HTTPS_PROXY和NO_PROXY添加行。
- 重新加载配置:sudo systemctl daemon-reload
- 重启Docker:sudo systemctl restart docker
可以通过命令检查:sudo systemctl show --property=Environment docker
位置2:通过build-arg构建镜像
构建镜像时,Dockerfile中的命令(例如 apt install)在隔离环境中执行,看不到主机的代理。需要显式传递代理。
- 在Dockerfile中,在RUN命令之前添加指令 ARG http_proxy 和 ARG https_proxy。
- 构建镜像并传递参数:docker build --build-arg http_proxy=http://proxy.example.com:3128 --build-arg https_proxy=http://proxy.example.com:3128 -t myimage .
⚠️ 注意: 不要在Dockerfile中使用ENV指令直接写入代理密码。它会保留在镜像层中,任何获取镜像的人都能看到密码。请使用build-arg,更好的做法是使用无需密码的代理来进行构建。
位置3:通过 ~/.docker/config.json 为启动的容器配置
为了让启动的容器自动获得代理变量,请配置Docker客户端配置。
- 打开文件:nano ~/.docker/config.json
- 添加 proxies 块,包含 default 部分。
- 在其中指定 httpProxy、httpsProxy 和 noProxy 的值。
- 保存文件。
现在,每次执行 docker run 时,变量都会自动传递给容器内部。
在Kubernetes清单中设置变量
在Kubernetes中,代理通过容器规范中的环境变量设置。在Pod或Deployment清单的 env 部分,添加 name 为 HTTP_PROXY、HTTPS_PROXY、NO_PROXY 的条目,并设置相应的 value。
提示: 敏感值应存储在Secret对象中,并通过 valueFrom 引用,而不是直接写入清单。这样密码不会出现在版本控制系统中。
✅ 检查: 执行 docker pull hello-world —— 镜像应成功下载。然后执行 docker run --rm alpine env | grep -i proxy —— 你会看到容器内部传递的变量。
步骤5:在CI中配置代理——GitHub Actions和GitLab Runner
本阶段目标: 让CI流水线通过代理工作,同时安全存储访问信息,避免密码泄露到日志中。
在Secrets中存储访问信息
CI的首要规则:永远不要将代理密码直接写在YAML流水线文件中。该文件存储在仓库中,所有人都能看到密码。请使用secrets机制。
在GitHub Actions中,secrets在仓库设置中添加:Settings -> Secrets and variables -> Actions。创建一个名为 PROXY_URL 的secret,粘贴完整的代理URL。
在GitLab中,secrets称为CI/CD变量。在Settings -> CI/CD -> Variables中添加。务必为敏感值勾选 Masked 和 Protected 选项。
配置GitHub Actions
- 在流水线文件 .github/workflows 中,在job级别添加 env 块。
- 设置 HTTP_PROXY,其值通过 secrets.PROXY_URL 的双花括号语法引用。
- 类似地设置 HTTPS_PROXY 和 NO_PROXY。
- 这些变量将对该job中的所有步骤可用。
配置GitLab Runner
在GitLab中有两个层级。可以在 .gitlab-ci.yml 文件中通过 variables 块设置变量,也可以在Runner的config.toml配置文件中通过 environment 部分设置。
- 对于项目:在 .gitlab-ci.yml 中添加 variables 块,引用受保护的变量。
- 对于Runner的所有项目:打开Runner的 config.toml,在 [[runners]] 部分添加 environment 参数,列出所需的变量。
在日志中遮蔽密码
即使使用secrets,密码也可能意外出现在日志中,如果某条命令输出了它。GitHub Actions会自动用星号遮蔽secrets的值。在GitLab中,勾选 Masked 选项可以实现此功能——但只有当值满足要求(不包含某些特殊字符且长度足够)时才有效。
⚠️ 注意: 避免使用 -v 标志或 echo 命令打印完整的代理URL到日志。即使有遮蔽机制,也最好不要冒险。调试时只打印地址和端口,不包含用户名和密码。
提示: 将代理URL存储为不嵌入密码的形式,而将用户名和密码作为单独的secrets。这样更容易遮蔽和轮换。
✅ 检查: 手动运行流水线。执行网络请求的步骤(例如安装依赖)应成功完成。日志中不应看到密码。
结果验证:确认流量确实通过代理
仅仅配置是不够的——需要证明流量确实经过代理,而不是直连。以下是检查清单。
检查清单:应该正常工作的项目
- 在新终端中执行 echo $http_proxy 显示你的URL。
- curl -v http://example.com 显示 Connected to 代理 的行。
- sudo apt update 成功更新包列表。
- git ls-remote 到远程仓库成功。
- docker pull 拉取镜像成功。
- CI流水线显示绿色成功。
如何可靠测试
最可靠的方法是查看目标服务器看到的外部IP地址。向显示你IP的服务发送请求。如果通过代理,你将看到代理服务器的IP地址,而不是你自己的。
- 执行不带代理的请求:env -u http_proxy -u https_proxy curl -s http://ifconfig.me —— 你将看到自己的真实IP。
- 执行带代理的请求:curl -s http://ifconfig.me —— 你将看到代理的IP。
- 如果两个地址不同——代理正在工作。
另一种方法是查看代理服务器本身的日志(如果你有访问权限)。你的请求应该出现在那里。
提示: env -u 命令会临时移除某个变量,仅影响一个命令,不改变当前会话。便于比较有代理和无代理时的行为。
✅ 检查: 通过代理时的IP地址与直连时的不同。这是流量经过代理的百分之百证据。
常见错误及解决方法
我们分析一些常见问题。格式简单:问题、原因、解决方案。
问题1:sudo不继承变量
原因: sudo出于安全考虑默认会清理环境。你的export设置不会传递到sudo下的命令。
解决方案: 使用 -E 标志保留环境:sudo -E apt update。或者通过sudoers文件配置持久保留。执行 sudo visudo 并添加行 Defaults env_keep += "http_proxy https_proxy HTTP_PROXY HTTPS_PROXY no_proxy NO_PROXY"。之后sudo将始终传递这些变量。
问题2:证书错误
原因: 某些公司代理会拦截HTTPS,并使用自己的根证书替换证书。系统不信任该证书,因此报错。
解决方案: 向管理员获取代理的根证书。在Ubuntu和Debian上,将其复制到 /usr/local/share/ca-certificates,扩展名为 .crt,然后执行 sudo update-ca-certificates。在RHEL上,放入 /etc/pki/ca-trust/source/anchors,然后执行 sudo update-ca-trust。之后所有工具都会信任该代理。
问题3:curl工作,但apt不工作
原因: curl读取环境变量,而apt在sudo下看不到这些变量,并且没有自己的代理配置。
解决方案: 按照步骤3中的描述,在 /etc/apt/apt.conf.d 中配置apt的代理。这是与环境变量独立的配置,apt需要它。
问题4:密码包含特殊字符
原因: 未编码的密码中的 @、:、/ 等符号会破坏URL解析。
解决方案: 应用准备阶段描述的百分比编码。将 @ 替换为 %40,: 替换为 %3A,依此类推。
问题5:错误407 Proxy Authentication Required
原因: 用户名或密码错误,或者代理要求认证但你未提供。
解决方案: 重新检查用户名和密码。确保URL中包含认证信息。检查特殊字符的编码。
问题6:内部资源无法访问
原因: 对本地和内部地址的请求也通过代理发送,但代理不认识这些地址。
解决方案: 将这些地址添加到 NO_PROXY 中。不要忘记 localhost、127.0.0.1 以及以点开头的内部域名。
问题7:Docker守护进程看不到代理
原因: 你在bashrc中设置了变量,但Docker守护进程由systemd管理,不读取这些变量。
解决方案: 使用步骤4中的systemd drop-in,不要忘记 daemon-reload 和 restart docker。
问题8:设置未生效
原因: 你编辑了bashrc,但未重启终端。
解决方案: 执行 source ~/.bashrc 或打开新的终端窗口。
附加功能与高级配置
当基本配置正常工作后,可以提升便利性和灵活性。
代理开关函数
在 ~/.bashrc 中创建两个函数:proxy_on 用于启用,proxy_off 用于禁用。在 proxy_on 中放置 export 命令,在 proxy_off 中放置 unset 命令。这样切换只需一个命令。
为不同任务使用不同代理
你可以仅为单个命令设置代理,而不改变整个环境。示例:https_proxy=http://other:3128 curl https://example.com。该变量仅对该命令有效。
SOCKS代理
如果你有SOCKS5类型的代理,在URL中使用 socks5 协议,并使用 ALL_PROXY 变量。curl有 --socks5 标志。注意,并非所有工具都支持SOCKS。
提示: 对于完全不支持代理的工具,存在像 proxychains 这样的包装器。但请有意识地使用,它们会改变程序的网络调用行为。
配置汇总表
保留此汇总以备快速参考。格式:工具 —— 配置文件 —— 变量或指令。
- Shell会话 —— 临时内存 —— export http_proxy 和 HTTP_PROXY
- 用户级别 —— ~/.bashrc —— export 变量
- 全系统 —— /etc/environment —— http_proxy 不带export
- 全系统 —— /etc/profile.d/proxy.sh —— export 变量
- systemd服务 —— 通过 systemctl edit 的drop-in —— Environment 指令
- apt (Ubuntu, Debian) —— /etc/apt/apt.conf.d/95proxies —— Acquire::http::Proxy
- dnf, yum (RHEL) —— /etc/dnf/dnf.conf —— proxy, proxy_username, proxy_password
- npm —— ~/.npmrc —— proxy 和 https-proxy
- pip —— ~/.config/pip/pip.conf —— global 部分的 proxy
- git (HTTPS) —— git全局配置 —— http.proxy
- git (SSH) —— ~/.ssh/config —— ProxyCommand
- curl —— ~/.curlrc —— proxy
- wget —— ~/.wgetrc —— http_proxy, https_proxy, use_proxy
- composer —— 环境 —— HTTP_PROXY
- Docker守护进程 —— /etc/systemd/system/docker.service.d/proxy.conf —— Environment
- Docker构建 —— build命令 —— build-arg http_proxy
- Docker容器 —— ~/.docker/config.json —— proxies 块
- Kubernetes —— Pod清单 —— env 中的 HTTP_PROXY
- GitHub Actions —— workflow文件 —— env 块,使用secrets
- GitLab —— .gitlab-ci.yml 或 config.toml —— variables 或 environment
常见问题FAQ
是否需要同时设置小写和大写变量?
是的,这是最可靠的策略。不同程序读取不同的大小写版本,设置两种版本可以消除意外。
为什么curl能看到代理,而apt不行?
因为apt在sudo下不继承环境变量,并且有自己的配置文件。请通过 /etc/apt/apt.conf.d 中的文件单独配置apt。
如何临时为一条命令禁用代理?
在命令前使用 env -u http_proxy -u https_proxy。这仅对该次调用移除变量。
可以在NO_PROXY中指定子网吗?
通常不行。NO_PROXY 不可靠地支持CIDR表示法。请明确列出具体的地址和以点开头的域名后缀。
GOPROXY 是我的代理服务器吗?
不是。GOPROXY 指向Go模块镜像,而非网络代理。对于网络代理,Go使用 HTTP_PROXY 和 HTTPS_PROXY。
如何安全存储代理密码?
在CI中使用secrets。本地使用权限为600的 .netrc 文件或密码管理器。避免密码出现在命令历史中。
为什么git over SSH不通过 http.proxy?
因为SSH是独立协议。请通过 ~/.ssh/config 文件为所需主机设置 ProxyCommand。
通过代理时出现证书错误怎么办?
将代理的根证书安装到系统存储中,并使用 update-ca-certificates(Debian)或 update-ca-trust(RHEL)更新信任。
bashrc中的设置在新会话中不工作,为什么?
可能你编辑了错误的文件,或者未保存更改,或者未打开新终端。通过 echo 和 source 检查。
如何验证流量确实通过代理?
比较使用代理和不使用代理时的外部IP(通过向IP检测服务发送curl命令)。不同的地址证实代理正在工作。
结论:你掌握了什么,以及下一步方向
恭喜你,你已经走过了很长的路。我们来总结一下你现在的能力。
你学会了构建正确的代理URL并对密码中的特殊字符进行编码。你理解了HTTP_PROXY、HTTPS_PROXY和NO_PROXY变量,包括大小写细节和例外格式。你可以在会话中启用代理,并通过多种方式使其永久生效,包括为服务配置systemd drop-in。
你为所有关键工具配置了代理:apt和dnf、npm和pip、HTTPS和SSH的git、curl和wget、composer,并理解了GOPROXY的重要区别。你掌握了Docker的三个配置位置以及Kubernetes中的变量。最后,你在GitHub Actions和GitLab中配置了代理,实现了安全存储和密码遮蔽。
下一步做什么: 通过实践巩固知识。按照本指南在一台测试机器上从头配置代理。创建开关函数方便切换。查看你的代理服务器日志,亲眼看到流量。
发展方向: 下一步是使用像Ansible这样的配置管理工具自动化设置,以便一键在多台机器上部署代理。此外,深入了解证书处理以及不同类型的代理也很有用。
提示: 保存本指南中的汇总表作为速查表。当需要快速回忆某个工具的代理配置位置时,它会为你节省大量时间。
你做得非常出色。现在,Linux终端和CI中的代理对你来说已不再神秘。祝配置顺利,连接稳定。