Linux代理加速：apt 和 Docker 的解决方案

在 Windows 和手机端，实现代理的方式很直观，某个软件，开启运行，就能发挥一些作用。但 Linux 代理 ，没有用户界面，没有运行按钮，无从下手。

受够了国内机器拉镜像龟速，经常断联；apt 更新一次半小时过去了，AhFei 曾经也深受折磨。

本文的内容应该能解决 99% 的代理加速需求。怎么在国内机器上下载 GitHub 项目？又怎么在国内机器上使用 apt 快速更新软件和使用 Docker 拉取镜像？

适用系统：Debian 系发行版，包括 Ubuntu 和 Armbian

I might have made some mistakes, please let me know if I’ve gotten anything wrong!

为什么不用镜像加速？

AhFei 在初接触 Linux 时，看到网络上都是配置镜像的方法，但奇怪的是，这些镜像源对我的机器加速效果不能说完全没有，只能说肉眼分辨不出来。所以给我的印象，镜像加速就是垃圾。

釜底抽薪的手段。清风山冈、明月大江。代理加速，一招鲜，吃遍天，就是好用就是适用广。

接着，怎么安装魔法软件、编辑配置、得到 SOCKS5 和 HTTP 代理地址，请查看各大项目官方教程中，在 Linux 上怎么安装客户端来解决。本文只为如何用于加速而写，技术交流，不涉及任何魔法方法。

假设 SOCKS 代理地址为 127.0.0.1:1080 ，HTTP 代理地址为 127.0.0.1:8118 。

熟悉一下如何验证代理是否正常运行：（cip.cc 这个网站会返回你机器的 IP）

Copy
# SOCKS 代理
curl -x socks5://127.0.0.1:1080 cip.cc

Copy
# HTTP 代理
curl -x 127.0.0.1:10809 cip.cc

加密码的：

Copy
curl -x socks5://Username:Password@127.0.0.1:10808 cip.cc

SOCKS 转换 HTTP 代理

有此节的原因，是有的魔法方法不提供 HTTP 代理，必须要把 SOCKS 转成 HTTP 才能给 apt、Docker 等使用。

如果已经有 HTTP 代理了，可跳过。

privoxy

官网： Privoxy - Home Page

安装：

Copy
sudo apt install -y privoxy

配置：

Copy
sudo vim /etc/privoxy/config

更改 listen-address 和 forward-socks5t ，具体说明：

listen-address 是稍后本机 HTTP 代理监听端口，默认是监听 127.0.0.1 的 8118 端口

Copy
# 如果是国内机子，应该设置只允许本机访问
listen-address 127.0.0.1:8118
# 如果是家里的服务器，可以放开，方便局域网其他机器使用
listen-address 0.0.0.0:8118

8118 端口当然可以随意修改，不被其他程序占用就行

forward-socks5t 是 privoxy 要监听的 SOCKS 代理，作为桥梁，把上面的 HTTP 端口监听的转发给这个 SOCKS 代理。不要忽略最后的 .

Copy
forward-socks5t / 127.0.0.1:1080 .
# 带密码的
forward-socks5 / Username:Password@127.0.0.1:1080 .

重启生效：

Copy
sudo systemctl restart privoxy.service
sleep 3
sudo systemctl status privoxy.service

forward-socks5t 和 forward-socks5 是两种不同的代理协议。

forward-socks5t：这是一种支持透明传输的 SOCKS5 代理协议。使用该协议时，代理服务器将客户端发出的 TCP 数据包原样转发到目标服务器，而目标服务器返回的响应也会直接传送回客户端。这种方式实现了透明代理，使得客户端和目标服务器之间的连接对于双方来说都是完全透明的，彼此无感知。

forward-socks5：这是一种普通的 SOCKS5 代理协议。在使用该协议时，客户端与代理服务器之间建立连接后，客户端需要发送特定的命令请求代理服务器与目标服务器建立连接。代理服务器将客户端请求的数据中继给目标服务器，并将目标服务器返回的响应发送回客户端。这种方式下，客户端意识到自己正在通过代理进行通信，而目标服务器也知道请求来自代理服务器。

因此，区别主要在于透明传输和普通代理之间的差异。当需要隐藏客户端和目标服务器之间的代理存在，使其对双方透明时，可以选择使用 forward-socks5t。而如果客户端和目标服务器意识到代理的存在，并且有特定的交互协议进行通信，那么可以选择使用 forward-socks5。

设置环境变量

先说原理，这个方法之所以能让某些软件走代理，而对另一些不生效，是因为，生效的那些软件，会在运行时检查环境变量里有没有设置代理，有的话自然就走了。

也就是说，这种方式，本身并不会改变机器的网络结构，能否起作用，全在于软件支持不支持。

支持的软件，一般应该会提供选项，手动指明代理，这样其实更可控一些。比如：

pip3（若有环境变量 http_proxy，不需要用这个）

Copy
pip3 install --proxy="http://127.0.0.1:8118" packageName

只设置两个环境变量：HTTP_PROXY 和 HTTPS_PROXY：

Copy
export http_proxy="http://127.0.0.1:8118" # http 流量走的代理
export https_proxy="http://127.0.0.1:8118"
export no_proxy=127.0.0.1,localhost,192.168.* # 不进行代理的网段

取消代理

Copy
unset http_proxy https_proxy no_proxy

测试是否代理了

Copy
curl cip.cc

有验证的代理：

Copy
export http_proxy="Username:Password@proxy-server-ip:8118"
export https_proxy="Username:Password@proxy-server-ip:8118"

上面的命令使用不便，可以使用 alias 简化命令

Copy
vim ~/.bashrc

添加（注意修改代理的地址）

Copy
alias ftz='export http_proxy="127.0.0.1:8118" https_proxy="127.0.0.1:8118" no_proxy=127.0.0.1,localhost,192.168.*'
alias ctz='unset http_proxy https_proxy no_proxy'

立刻让配置生效：

Copy
source ~/.bashrc

这样以后连接上服务器，终端

输入 ftz（放梯子）即可为终端设置代理

输入 ctz（撤梯子）即可为终端取消代理

另外，ftz 后，这个代理只在当前终端生效，如果退出，再登录，就没有代理了。这样可控性更好。

apt 代理

Apt 不会用 HTTP Proxy 环境变量。它使用独立的配置文件。

在 /etc/apt/apt.conf.d/ 创建新的配置文件：

Copy
sudo vim /etc/apt/apt.conf.d/proxy.conf

Copy
Acquire {
HTTP::proxy "http://127.0.0.1:8118";
HTTPS::proxy "http://127.0.0.1:8118";
}

验证：

Copy
sudo apt update

Docker 镜像代理

因为镜像的拉取和管理都是 docker daemon 负责的，而 docker daemon 是由 systemd 管理的，所以要从 systemd 配置入手，给 docker daemon 配置代理。

官方文档： Configure the daemon with systemd | Docker Docs

创建 dockerd 相关的 systemd 目录，这种 .d 目录下的配置将覆盖默认配置

Copy
sudo mkdir -p /etc/systemd/system/docker.service.d

新建配置文件 http-proxy.conf

Copy
sudo vim /etc/systemd/system/docker.service.d/proxy.conf

添加配置，类似前面的

Copy
[Service]
Environment="HTTP_PROXY=http://127.0.0.1:8118/"
Environment="HTTPS_PROXY=http://127.0.0.1:8118/"
Environment="NO_PROXY=127.0.0.1,localhost,192.168.*,*.example.com"
# 如果 `NO_PROXY=*`，那么所有请求都将不通过代理服务器

重新加载配置文件，重启 Dockerd 才能生效

Copy
sudo systemctl daemon-reload
sudo systemctl restart docker

检查确认环境变量已经正确配置：

Copy
sudo systemctl show --property=Environment docker

可以拉取镜像试试加速效果了

Docker 容器代理

在容器运行阶段，如果需要代理上网，只需要加上环境变量，比如使用 docker-compose 的话，其配置文件里的环境变量，增加下面三部分即可。

Copy
environment:
- http_proxy="192.168.1.11:10809"
- https_proxy="192.168.1.11:10809"
- no_proxy="localhost,127.0.0.1,.example.com"

它的原理，就是上面所谓的 “设置环境变量”，因此能不能生效，还得看里面运行的服务，会不会主动撷取环境变量了。

这个感觉没什么用，国内 emby 不能刮削可以拿它来解决，但是，这种全局变量，可能会影响其他功能。

如果容器默认就使用代理，也可以配置 ~/.docker/config.json。

Copy
{
"proxies":
{
"default":
{
"httpProxy": "http://proxy.example.com:8080",
"httpsProxy": "http://proxy.example.com:8080",
"noProxy": "localhost,127.0.0.1,.example.com"
}
}
}

这个是用户级的配置，除了 proxies，docker login 等相关信息也会在其中。而且还可以配置信息展示的格式、插件参数等。

注意：无论是 docker run 还是 docker build，默认是网络隔绝的。如果代理使用的是 localhost:3128 这类，则会无效。这类仅限本地的代理，必须加上 --network host 才能正常使用。

Docker Build 代理

虽然 docker build 的本质，也是启动一个容器，但是环境会略有不同，用户级配置无效。在构建时，需要注入 http_proxy 等参数。

Copy
docker build . \
--build-arg "HTTP_PROXY=http://proxy.example.com:8080/" \
--build-arg "HTTPS_PROXY=http://proxy.example.com:8080/" \
--build-arg "NO_PROXY=localhost,127.0.0.1,.example.com" \
-t your/image:tag

原文链接： https://technique.vfly2.com/2023/11/linux-proxy-acceleration-for-apt-docker/

版权声明：本博客所有文章除特別声明外，均为 AhFei 原创，采用 CC BY-NC-SA 4.0 许可协议。转载请注明来源 技焉洲 (technique.vfly2.com) 。

保持更新 ٩(・̤̀ᵕ・̤́๑)ᵒᵏᵎᵎᵎᵎ 清晰恒益的实用技能，欢迎使用 RSS 订阅，或在支持 ActivityPub 的平台关注 @vfly2tech@technique.vfly2.com 接收新文章的推送，如果能留言互动就更好了。