linux 通过 shadowsocks 代理 下载 docker 镜像

Shadowsocks-libev 是一个轻量级安全 SOCKS5 代理,适用于嵌入式设备和低端设备。
https://github.com/shadowsocks/shadowsocks-libev

为什么要写这篇文章

我有一个香橙派,在下载 docker 镜像时,国内镜像源不稳定,用阿里云的容器加速器,个人免费版下载的镜像又很旧,跟不上官方的更新速度。

所以,就想着用个代理,直接从官网 http://hub.docker.com 下载镜像。

一、linux 服务端(debian amd64)

安装 shadowsocks-libev

1
apt install -y shadowsocks-libev

安装后会默认启动 ss-server 服务

1
2
# 查看 ss-server 是否运行
ps aux | grep -i ss-server

修改配置文件

注意 server 可以用 ipv4 0.0.0.0 、ipv6 [::0] 来表示本机公网ip
也可以是真实的服务器公网ip,可以使用 curl -s ipinfo.io/ip 获取本机公网ip
但不能是 127.0.0.1[::1]

1
2
3
4
5
6
7
8
9
10
11
12
cat > /etc/shadowsocks-libev/config.json << EOF
{
"server":["[::0]", "0.0.0.0"],
"mode":"tcp_and_udp",
"server_port":8388,
"local_port":1080,
"password":"password",
"timeout":86400,
"method":"aes-256-gcm",
"fast_open": true
}
EOF

重启 shadowsocks-libev 使配置文件生效

1
2
# 重启
systemctl restart shadowsocks-libev.service

放行 8388 服务端口

1
2
3
4
5
6
iptables -I INPUT -p tcp --dport 8388 -j ACCEPT
iptables -I INPUT -p udp --dport 8388 -j ACCEPT
# 保存规则,不然重启后开放的端口会失效
iptables-save > /etc/iptables.up.rules
# 查看 8388 端口
iptables -L | grep 8388

二、linux 客户端代理(香橙派 debian arm64)

1、安装 shadowsocks-libev

1
apt install -y shadowsocks-libev

停止 shadowsocks-libev 默认运行的 ss-server,并禁用开机自启

1
2
3
4
# 停止掉默认运行的 ss-server
systemctl stop shadowsocks-libev.service
# 禁用开机自启
systemctl disable shadowsocks-libev.service

2、启动 ss-local 客户端(命令行运行)

也可以使用配置文件启动(与服务端的参数和启动方式一样)

参数说明
-s "189.28.18.198" 远程服务器ip(服务端的公网ip)
-p 8388 服务器端口
-l 1080 本地端口
-m "aes-256-gcm" 加密
-k "password" 密码
--fast-open 使用TCP Fast Open扩展

1
2
3
4
5
6
7
/usr/bin/ss-local \
-s "189.28.18.198" \
-p 8388 \
-l 1080 \
-m "aes-256-gcm" \
-k "password" \
--fast-open

3、启动 ss-local 客户端(配置文件运行)

/usr/bin/ss-local -c /etc/shadowsocks-libev/config.json

1
2
3
4
5
6
7
8
9
10
11
12
cat > /etc/shadowsocks-libev/config.json << EOF
{
"server":["189.28.18.198"],
"mode":"tcp_and_udp",
"server_port":8388,
"local_port":1080,
"password":"password",
"timeout":86400,
"method":"aes-256-gcm",
"fast_open": true
}
EOF

3、安装 privoxy

shadowsockssocks5 代理。
docker 原生不支持 socks5 ,仅支持 http
所以需要使用 privoxy 转发 http

1
apt install -y privoxy

3.1、修改 privoxy 配置文件

1
2
3
4
5
6
7
8
9
# 先备份配置文件
cp /etc/privoxy/config /etc/privoxy/config.bak

#查看配置文件(过滤掉配置文件中的注释项)并写入另一文件
grep -v "#" /etc/privoxy/config.bak > /etc/privoxy/config

# 查看是否含有以下配置,没有则编辑配置文件,如下:
# 0.0.0.0 表示允许其它机器引用此代理
listen-address 0.0.0.0:8118

关于配置文件,多说一句(为了保持文章的连贯性,暂时可跳过此说明)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# ipv4 和 ipv6 不能同时监听在同一个端口
# ipv4(0.0.0.0 表示允许其它机器引用此代理)
listen-address 0.0.0.0:8118
# 或者 ipv6(::0 表示允许其它机器引用此代理)
listen-address [::0]:8118

# 如果是本地使用,可以试试这个
listen-address 127.0.0.1:8118
# 或者
listen-address [::1]:8118

##### 以下是代理转发设置,首先级大于 namelist.action 文件 #####

# 表示所有网页都走本地的 ipv4 1080 端口(此时监听的是ipv4地址)
#forward-socks5 / 127.0.0.1:1080 .

# 表示所有网页都走本地的 ipv6 1080 端口(此时监听的是ipv6地址)
#forward-socks5 / [::1]:1080 .

# 表示 *.docker.com 走本地的 1080 端口
#forward-socks5 .docker.com 127.0.0.1:1080 .

# 如果你想全部放行(但这样会使所有网址都走代理,访问 baidu.com 会变慢)
#forward-socks5 / 127.0.0.1:1080 .

3.2、创建网站放行列表文件 namelist.action

1
2
3
4
5
cat > /etc/privoxy/namelist.action << EOF
{+forward-override{forward-socks5 127.0.0.1:1080 .}}
# 表示以下网站都走本地的 1080 端口,一个域名一行
.docker.com
EOF

在配置文件末尾处追加 actionsfile namelist.action 引入新建的网站放行列表文件

1
echo -e "\nactionsfile namelist.action" >> /etc/privoxy/config

3.3、重启 privoxy

1
systemctl restart privoxy

4、加速下载镜像 docker 代理配置

适用于直接下载docker pull和创建容器时的自动下载docker run

1
2
3
4
5
6
7
8
9
10
sudo mkdir -p /etc/systemd/system/docker.service.d
sudo tee /etc/systemd/system/docker.service.d/http-proxy.conf << EOF
[Service]
Environment="HTTP_PROXY=http://127.0.0.1:8118"
Environment="HTTPS_PROXY=http://127.0.0.1:8118"
# 不使用代理的地址
Environment="NO_PROXY=localhost,127.0.0.1"
EOF
systemctl daemon-reload
systemctl restart docker

5、使用方法

5.1、使用 curl 测试代理是否生效

注意:代理名是小写的 http_proxy,https_proxy

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 如果未设置代理直接访问,显示你家里的宽带ip(电信、移动、联通)
curl myip.ipip.net

# 香橙派自身使用代理
export http_proxy="http://127.0.0.1:8118" https_proxy="http://127.0.0.1:8118"
# 局域网中其它设备使用代理,香橙派在局域网中的ip `192.168.1.121`(此时香橙派相当于一个代理服务器)
export http_proxy="http://192.168.1.121:8118" https_proxy="http://192.168.1.121:8118"

# 关键一步别忘了在 namelist.action 中放行 myip.ipip.net 未放行返回的还是家里的宽带ip
cat >> /etc/privoxy/namelist.action << EOF
myip.ipip.net
EOF

# 如果代理成功,会返回服务端的公网ip
curl myip.ipip.net
# 如果代理成功,wget 会下载 html 文件
wget http://hub.docker.com

5.2、加速创建镜像

(这里的 ip 地址是默认虚拟网卡 docker0 的地址 172.17.0.1
因为容器要与宿主机通信,要访问到宿主机的代理
如果局域网中其他设备,也需要代理,可以使用香橙派的ip 192.168.1.121(此时香橙派相当于一个代理服务器)

1
2
3
4
5
6
7
8
9
docker build \
--build-arg HTTPS_PROXY="http://172.17.0.1:8118" \
--build-arg HTTP_PROXY="http://172.17.0.1:8118" \
-t my_image:tag .

docker build \
--build-arg HTTPS_PROXY="http://192.168.1.121:8118" \
--build-arg HTTP_PROXY="http://192.168.1.121:8118" \
-t my_image:tag .

5.3、容器中加速安装软件

1
2
3
4
export HTTP_PROXY="http://172.17.0.1:8118" HTTPS_PROXY="http://172.17.0.1:8118"
# 或者局域网中其他设备,也需要代理,可以使用香橙派的ip `192.168.1.121`(此时香橙派相当于一个代理服务器)
export HTTP_PROXY="http://192.168.1.121:8118" HTTPS_PROXY="http://192.168.1.121:8118"
apt install -y htop

或者在创建容器时定义环境变量

1
2
3
4
5
docker run -itd \
--env HTTPS_PROXY="http://192.168.1.121:8118" \
--env HTTP_PROXY="http://192.168.1.121:8118" \
--name test \
my_image:tag

三、windows 客户端代理(PC win10 x64)

让 windows 作为代理服务器,实现香橙派加速下载 docker 镜像
香橙派不需要运行 ss-localprivoxy

1、首先要让 windows 可以访问 http://hub.docker.com

下载 windows 客户端 https://github.com/shadowsocks/shadowsocks-windows

操作说明
双击 Shadowsocks.exe 进行如下配置
服务器地址: 189.28.18.198
服务器端口: 8388
密码: password
加密: aes-256-gcm
代理端口: 1080
点击确定,在任务栏右下角找到纸飞机图标,右键 – 系统代理 – PAC模式/全局模式

以上完成,windows 就可以成功访问 http://hub.docker.com

2、允许其他设备连入 windows 客户端

在 windows 任务栏右下角找到纸飞机图标,右键 – 允许其他设备连入。
查看 windows 的本地局域网 ip 192.168.1.3

3、香橙派中 docker 代理的配置

3.1、加速下载镜像

适用于 docker pull 直接下载 和 docker run 安装时的自动下载

1
2
3
4
5
6
7
8
9
10
mkdir -p /etc/systemd/system/docker.service.d
tee /etc/systemd/system/docker.service.d/http-proxy.conf << EOF
[Service]
Environment="HTTP_PROXY=http://192.168.1.3:1080"
Environment="HTTPS_PROXY=http://192.168.1.3:1080"
# 不使用代理的地址
Environment="NO_PROXY=localhost,127.0.0.1"
EOF
systemctl daemon-reload
systemctl restart docker

3.2、加速创建镜像(方式一)

docker build -t my_image:tag .

(此配置文件修改保存后即生效,不需要重新启动 Docker)
注意: ~/.docker/config.json 的代理信息,会在随后创建的容器中出现,之前创建的容器不受影响
在容器输入 envexport 就可以查看到(代理名称大写和小写都存在 HTTP_PROXY, http_proxy 等等)
(创建的镜像中并不会存在代理信息,只对本机创建的容器有影响)

1
2
3
4
5
6
7
8
9
10
11
12
13
# 请确认文件是否存在,如果存在,则需要在原配置中增加 "proxies" 对象
# 以下命令是默认文件不存在,直接创建
cat > ~/.docker/config.json << EOF
{
"proxies": {
"default": {
"httpProxy": "http://192.168.1.3:1080",
"httpsProxy": "http://192.168.1.3:1080",
"noProxy": "*.test.example.com, .example2.com"
}
}
}
EOF

3.3、加速创建镜像(方式二)

如果不想修改 ~/.docker/config.json 文件
可以在 docker build --build-arg 后跟上代理设置,创建的容器中不会出现代理信息

1
2
3
4
docker build \
--build-arg HTTPS_PROXY="http://192.168.1.3:1080" \
--build-arg HTTP_PROXY="http://192.168.1.3:1080" \
-t my_image:tag .

3.4、在容器中加速安装软件

如果你想在容器中加速安装软件,在创建容器时通过 --env指定代理

1
2
3
4
5
docker run -itd \
--env HTTPS_PROXY="http://192.168.1.3:1080" \
--env HTTP_PROXY="http://192.168.1.3:1080" \
--name test \
my_image:tag

或者在进入容器后,通过 export指定代理

1
export HTTP_PROXY="http://192.168.1.3:1080" HTTPS_PROXY="http://192.168.1.3:1080"

设置代理,需要注意的知识点(为了保持文章的连贯性,暂时可跳过此说明)

如果变量名只有大写的 HTTP_PROXY HTTPS_PROXY
可以加速安装软件,此时正常使用代理
执行 curl myip.ipip.net
返回的是家中宽带的ip(移动/联通/电信)
当前 IP:x.x.x.x 来自于:中国 移动

如果变量名只有小写的 http_proxy https_proxy
无法加速安装软件,此时无法使用代理
执行 curl myip.ipip.net
返回的是服务端的公网ip
当前 IP:189.28.18.198 来自于:美国 加利福尼亚州 洛杉矶

所以,设置代理时,最好把大小写代理名全都设置上

4. 让 docker 代理配置生效

1
2
# 只修改 `~/.docker/config.json` 文件,不需要此操作
systemctl daemon-reload && systemctl restart docker

查看代理信息是否修改成功
针对 /etc/systemd/system/docker.service.d/http-proxy.conf 文件的配置项

1
2
3
4
# 方式一
docker info
# 方式二
systemctl show --property=Environment docker

5. 应用

5.1、加速下载镜像、创建镜像

1
2
3
4
5
6
7
8
9
10
# 加速下载镜像(针对增加 `/etc/systemd/system/docker.service.d/http-proxy.conf` 文件)
docker pull debian:latest
docker run -itd --name test debian:latest
# 加速创建镜像(针对修改 `~/.docker/config.json` 文件)
docker build -t my_image:tag .
# 加速创建镜像(针对添加 `--build-arg` 变量)
docker build \
--build-arg HTTPS_PROXY="http://192.168.1.3:1080" \
--build-arg HTTP_PROXY="http://192.168.1.3:1080" \
-t my_image:tag .

5.2、windows 使用 xshell 连接 ipv6 服务器

如果你用 xshell 可以正常访问 ipv4 服务器,在此基础上添加代理即可。

1、在代理中设置 socks5 代理 127.0.0.1:1080
2、把主机由 ipv4 地址换成 ipv6 地址
修改这两项,你就可以正常的连接 ipv6 服务器了。

四、docker 容器

https://github.com/shadowsocks/shadowsocks-rust

1
2
3
4
5
6
7
8
9
10
11
12
docker run --name sslocal-rust \
--restart always \
-p 1080:1080/tcp \
-v /path/to/config.json:/etc/shadowsocks-rust/config.json \
-dit ghcr.io/shadowsocks/sslocal-rust:latest

docker run --name ssserver-rust \
--restart always \
-p 8388:8388/tcp \
-p 8388:8388/udp \
-v /path/to/config.json:/etc/shadowsocks-rust/config.json \
-dit ghcr.io/shadowsocks/ssserver-rust:latest