前面我介绍了如何使用Cloudflare Workpage构建docker hub代理,那么CF是有请求限制的,如果是个人使用应该还够,如果是公司使用(应该也够)…那么今天的话我就使用Nginx对docker hub进行反代

部署准备

  • 国外服务器一台,静态公网IPV4或者NAT都行
  • 域名可有可无

部署步骤

安装nginx和docker这边就省流了

1
2
3
4
5
#debian系
sudo apt update && sudo apt install nginx docker.io -y
#红帽系
sudo yum install docker-ce nginx -y
#或者podman,跟docker一样

制作证书(可有可无)

1
2
3
4
5
6
7
8
9
10
11
12
13
mkdir /certs && cd /certs
openssl genrsa -out you.key 2048
openssl req -new -key you.key -out you.csr -subj "/C=CN/ST=State/L=City/O=Organization/OU=Department/CN=*.alybaba.top"
#注 /CN填写域名或者IP,如"docker.xxx.xxx",其他随意
# C:国家代码(如 CN 表示中国)
# ST:省份
# L:城市
# O:公司名称
# OU:部门名称
# CN:通用名称(这里为 *.xxx.xxx 泛域名)
openssl x509 -req -in you.csr -signkey you.key -out you.crt -days 3650
# 这里注意天数随意,我给自己签了10年
# 可使用安装certbot或者其他的SSL证书,自签也不是不能用...

完事后你的当前目录下就会有证书和key了,下面是Nginx的配置,可以根据自己实际情况进行修改

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
server {
listen 443 ssl;
#server_name _; 如果你没域名的话
server_name registry.alybaba.top;
ssl_certificate /you/path/you.crt;
ssl_certificate_key /you/path/you.key;
root /var/www/html;
index index.html;

location /v2/ {
proxy_pass https://registry-1.docker.io; # Docker Hub 的官方镜像仓库
proxy_set_header Host registry-1.docker.io;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;

# 关闭缓存
proxy_buffering off;

# 转发认证相关的头部
proxy_set_header Authorization $http_authorization;
proxy_pass_header Authorization;

# 重写 www-authenticate 头为你的反代地址
proxy_hide_header www-authenticate;

#同理,如果你没域名的话,这里请填写IP地址
#add_header www-authenticate 'Bearer realm="https://x.x.x.x/token",service="registry.docker.io"' always;
add_header www-authenticate 'Bearer realm="https://registry.alybaba.top/token",service="registry.docker.io"' always;
# always 参数确保该头部在返回 401 错误时无论什么情况下都会被添加。

# 对 upstream 状态码检查,实现 error_page 错误重定向
proxy_intercept_errors on;
# error_page 指令默认只检查了第一次后端返回的状态码,开启后可以跟随多次重定向。
recursive_error_pages on;
# 根据状态码执行对应操作,以下为301、302、307状态码都会触发
error_page 301 302 307 = @handle_redirect;
}
location /token {
resolver 1.1.1.1 valid=600s;
proxy_pass https://auth.docker.io; # Docker 认证服务器

# 设置请求头,确保转发正确
proxy_set_header Host auth.docker.io;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;

# 传递 Authorization 头信息,获取 Token
proxy_set_header Authorization $http_authorization;
proxy_pass_header Authorization;
# 禁用缓存
proxy_buffering off;
}
location @handle_redirect {
resolver 1.1.1.1;
set $saved_redirect_location '$upstream_http_location';
proxy_pass $saved_redirect_location;
}
}

同时由于是自签证书需要添加受信任

1
2
3
4
5
6
sudo tee /etc/docker/daemon.json << EOF
{
"registry-mirrors": ["https://registry.alybaba.top"]
"insecure-registries": ["registry.alybaba.top"]
}
EOF

ok,那么到这里,就已经部署完毕了,需要注意的是,如果你不打算加证书,请把相关配置中的https修改成http,IP同理,之后开启对应防火墙的端口即可愉快的进行拉取镜像了,
1
2
3
4
5
6
7
8
9
10
11
#如果是iptables
sudo iptables -IINPUT -p tcp --dport YOU_PORT -j ACCEPT
#如果是ufw
sudo ufw allow YOU_PORT && ufw reload
#如果是nftbles
sudo nft add table inet filter
sudo nft add chain inet filter input { type filter hook input priority 0 \; }
sudo nft add rule inet filter input tcp dport YOU_PORT accept
#如果是firewall
sudo firewall-cmd --zone=public --add-port=YOU_PORT/tcp --permanent
sudo firewall-cmd --reload

那么经测试,这台圣保罗的机器速度大概10-20m左右…相比于4G的带宽确实有点慢了,不过考虑到圣保罗都在南美了,可以用就ok了,后续我有空再换美国,或者欧洲机器试试

  • 扩展,可以使用nginx模块或者防火墙对访问IP进行限制,这里我流量比较多,就不说了
  • 相关github项目 https://github.com/dqzboy/Docker-Proxy 那么这个项目部署起来也是非常简单,作者还特意写了一键脚本,我也是花了10来分钟就部署好了,有兴趣的可以关注关注
  • 加速站点:registry.alybaba.top