使用nginx搭建docker加速源与auth.docker.io鉴权401问题解决
6月份dockerhub被墙,各大加速源关停,考虑自用docker较多,可以搭建一个自用加速源。
问题
9月份,auth.docker.io被墙,导致原来使用nginx代理的docker加速源失效,百般周折后,终于在Ling大佬博客发现解决方案。
2024 年 09 月 12 日 auth.docker.io 被墙,增加反代 auth.docker.io 的配置 官方的镜像仓库无论是否登录,都会要求认证,而当我们使用反代了官方仓库的镜像源拉取镜像时,官方仓库会首先返回一个 401 Unauthorized 响应,并附带一个 WWW-Authenticate 头,其中包含了获取认证所需的服务地址和授权范围(scope)。而这个“获取认证所需的服务地址”默认是 auth.docker.io。但是这个域名今天已经被封禁了,进而影响了我们拉取镜像。 在经过测试后发现可以通过重写这一 WWW-Authenticate 头,将认证请求导向我们自己的反代,交由反代服务器去访问 auth.docker.io,这样就规避了对 auth.docker.io 的封禁。
更新后的配置
nginx
#反代docker hub镜像源
server {
listen 443 ssl;
server_name 域名;
ssl_certificate 证书地址;
ssl_certificate_key 密钥地址;
ssl_session_timeout 24h;
ssl_ciphers 'ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256';
ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3;
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;
add_header www-authenticate 'Bearer realm="https://域名/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;
}
# 处理 Docker OAuth2 Token 认证请求
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;
}
}