nginx - 如何在docker Registry v2中公开发布和推送要求登录的信息?

标签 nginx docker privileges basic-authentication docker-registry

我使用以下指令将注册表作为组合容器启动:
https://www.digitalocean.com/community/tutorials/how-to-set-up-a-private-docker-registry-on-ubuntu-14-04

但是,我想区分访问权限,因此任何未登录的用户都可以从存储库中提取图像,但不能推送。

在第一种方法中,我尝试通过在nginx中进行设置来实现这一点(因为我像在本教程中那样将其用于前端)limit_except

limit_except GET HEAD {
    auth_basic "Docker Registry";
    auth_basic_user_file /etc/nginx/conf.d/registry.password;
}

不幸的是,这样拉动就可以顺利进行,但是docker login命令不起作用。
$ docker login myhost.example.net
Username: myuser
Password: 
Email: 
Error response from daemon: no successful auth challenge for https://myhost.example.net/v2/ - errors: []

看起来,docker pull和docker login都发送相同的HTTP GET请求,很难区分它们。
GET /v2/ HTTP/1.1
Host: myhost.example.net
User-Agent: docker/1.9.1 go/go1.4.2 git-commit/a34a1d5 kernel/4.2.0-19-generic os/linux arch/amd64
Accept-Encoding: gzip

现在,让我们看一下不同的请求并进行分析。

Docker 登录(上的http basic变为):
GET /v2/ HTTP/1.1
Host: myhost.example.net
User-Agent: docker/1.9.1 go/go1.4.2 git-commit/a34a1d5 kernel/4.2.0-19-generic os/linux arch/amd64
Accept-Encoding: gzip

HTTP/1.1 401 Unauthorized
Server: nginx/1.9.9
Date: Tue, 05 Jan 2016 09:40:40 GMT
Content-Type: text/html
Content-Length: 194
Connection: keep-alive
WWW-Authenticate: Basic realm="Docker Registry"
Docker-Distribution-Api-Version: registry/2.0

<html>
<head><title>401 Authorization Required</title></head>
<body bgcolor="white">
<center><h1>401 Authorization Required</h1></center>
<hr><center>nginx/1.9.9</center>
</body>
</html>
GET /v2/ HTTP/1.1
Host: myhost.example.net
User-Agent: docker/1.9.1 go/go1.4.2 git-commit/a34a1d5 kernel/4.2.0-19-generic os/linux arch/amd64
Authorization: Basic eHh4Onh4eAo=
Accept-Encoding: gzip

HTTP/1.1 200 OK
Server: nginx/1.9.9
Date: Tue, 05 Jan 2016 09:40:40 GMT
Content-Type: application/json; charset=utf-8
Content-Length: 2
Connection: keep-alive
Docker-Distribution-Api-Version: registry/2.0
X-Content-Type-Options: nosniff
Docker-Distribution-Api-Version: registry/2.0

Docker 登录(将http basic的禁用)
GET /v2/ HTTP/1.1
Host: myhost.example.net
User-Agent: docker/1.9.1 go/go1.4.2 git-commit/a34a1d5 kernel/4.2.0-19-generic os/linux arch/amd64
Accept-Encoding: gzip

HTTP/1.1 200 OK
Server: nginx/1.9.9
Date: Tue, 05 Jan 2016 10:09:26 GMT
Content-Type: application/json; charset=utf-8
Content-Length: 2
Connection: keep-alive
Docker-Distribution-Api-Version: registry/2.0
X-Content-Type-Options: nosniff
Docker-Distribution-Api-Version: registry/2.0

收到200 OK后,命令如上所述失败。

Docker (http基本已将禁用):
GET /v2/ HTTP/1.1
Host: myhost.example.net
User-Agent: docker/1.9.1 go/go1.4.2 git-commit/a34a1d5 kernel/4.2.0-19-generic os/linux arch/amd64
Accept-Encoding: gzip

HTTP/1.1 200 OK
Server: nginx/1.9.9
Date: Tue, 05 Jan 2016 09:53:54 GMT
Content-Type: application/json; charset=utf-8
Content-Length: 2
Connection: keep-alive
Docker-Distribution-Api-Version: registry/2.0
X-Content-Type-Options: nosniff
Docker-Distribution-Api-Version: registry/2.0

{}GET /v2/my-ubuntu-image/manifests/latest HTTP/1.1
Host: myhost.example.net
User-Agent: docker/1.9.1 go/go1.4.2 git-commit/a34a1d5 kernel/4.2.0-19-generic os/linux arch/amd64
Accept-Encoding: gzip

HTTP/1.1 200 OK
Server: nginx/1.9.9
Date: Tue, 05 Jan 2016 09:53:54 GMT
Content-Type: application/json; charset=utf-8
Content-Length: 39196
Connection: keep-alive
Docker-Content-Digest: sha256:8b6bef1314e51d06ab2f89af1f1d2c486245d4c2b1b3c169812b479c12f5410e
Docker-Distribution-Api-Version: registry/2.0
Etag: "sha256:8b6bef1314e51d06ab2f89af1f1d2c486245d4c2b1b3c169812b479c12f5410e"
X-Content-Type-Options: nosniff
Docker-Distribution-Api-Version: registry/2.0

{
 ... (truncated) ...

Docker (在
上将http basic设置为,将设置为凭据):
GET /v2/ HTTP/1.1
Host: myhost.example.net
User-Agent: docker/1.9.1 go/go1.4.2 git-commit/a34a1d5 kernel/4.2.0-19-generic os/linux arch/amd64
Accept-Encoding: gzip

HTTP/1.1 401 Unauthorized
Server: nginx/1.9.9
Date: Tue, 05 Jan 2016 09:52:00 GMT
Content-Type: text/html
Content-Length: 194
Connection: keep-alive
WWW-Authenticate: Basic realm="Docker Registry"
Docker-Distribution-Api-Version: registry/2.0

<html>
<head><title>401 Authorization Required</title></head>
<body bgcolor="white">
<center><h1>401 Authorization Required</h1></center>
<hr><center>nginx/1.9.9</center>
</body>
</html>
GET /v2/my-ubuntu-image/manifests/latest HTTP/1.1
Host: myhost.example.net
User-Agent: docker/1.9.1 go/go1.4.2 git-commit/a34a1d5 kernel/4.2.0-19-generic os/linux arch/amd64
Authorization: Basic cmZzY206d2llbGJyZnNjbXBvd3N6ZWN6YXN5
Accept-Encoding: gzip

HTTP/1.1 200 OK
Server: nginx/1.9.9
Date: Tue, 05 Jan 2016 09:52:00 GMT
Content-Type: application/json; charset=utf-8
Content-Length: 39196
Connection: keep-alive
Docker-Content-Digest: sha256:8b6bef1314e51d06ab2f89af1f1d2c486245d4c2b1b3c169812b479c12f5410e
Docker-Distribution-Api-Version: registry/2.0
Etag: "sha256:8b6bef1314e51d06ab2f89af1f1d2c486245d4c2b1b3c169812b479c12f5410e"
X-Content-Type-Options: nosniff
Docker-Distribution-Api-Version: registry/2.0
... (truncated) ...

Docker (在
上将http basic设置为,在没有凭据的情况下设置):
GET /v2/ HTTP/1.1
Host: myhost.example.net
User-Agent: docker/1.9.1 go/go1.4.2 git-commit/a34a1d5 kernel/4.2.0-19-generic os/linux arch/amd64
Accept-Encoding: gzip

HTTP/1.1 401 Unauthorized
Server: nginx/1.9.9
Date: Tue, 05 Jan 2016 09:39:54 GMT
Content-Type: text/html
Content-Length: 194
Connection: keep-alive
WWW-Authenticate: Basic realm="Docker Registry"
Docker-Distribution-Api-Version: registry/2.0

<html>
<head><title>401 Authorization Required</title></head>
<body bgcolor="white">
<center><h1>401 Authorization Required</h1></center>
<hr><center>nginx/1.9.9</center>
</body>
</html>
GET /v2/ HTTP/1.1
Host: myhost.example.net
User-Agent: docker/1.9.1 go/go1.4.2 git-commit/a34a1d5 kernel/4.2.0-19-generic os/linux arch/amd64
Accept-Encoding: gzip

HTTP/1.1 401 Unauthorized
Server: nginx/1.9.9
Date: Tue, 05 Jan 2016 09:39:54 GMT
Content-Type: text/html
Content-Length: 194
Connection: keep-alive
WWW-Authenticate: Basic realm="Docker Registry"
Docker-Distribution-Api-Version: registry/2.0

<html>
<head><title>401 Authorization Required</title></head>
<body bgcolor="white">
<center><h1>401 Authorization Required</h1></center>
<hr><center>nginx/1.9.9</center>
</body>
</html>
GET /v1/repositories/my-ubuntu-image/images HTTP/1.1
Host: myhost.example.net
User-Agent: docker/1.9.1 go/go1.4.2 git-commit/a34a1d5 kernel/4.2.0-19-generic os/linux arch/amd64
X-Docker-Token: true
Accept-Encoding: gzip

HTTP/1.1 404 Not Found
Server: nginx/1.9.9
Date: Tue, 05 Jan 2016 09:39:54 GMT
Content-Type: text/html
Content-Length: 168
Connection: keep-alive

<html>
<head><title>404 Not Found</title></head>
<body bgcolor="white">
<center><h1>404 Not Found</h1></center>
<hr><center>nginx/1.9.9</center>
</body>
</html>

通过查看最后一个示例,我们可以清楚地看到何时pull没有凭据尝试两次访问url / v2 /,所以当客户端在行中两次请求/ v2 / url时,也许我们可以以某种方式区分请求?

我还听说最新的注册表(我认为版本> = 2.1)具有对HTTP基本身份验证的内置支持,但是我在文档中找不到。

我希望我能对此事进行彻底的解释。

最佳答案

我在回答问题,因为我在Docker的github上发现了问题线程。的
情况似乎很复杂。由于注册表规范是开放的,很难说是谁应该归咎于谁,因此 docker 工具还是注册表。

请在这里查看问题以及其他相关问题:
https://github.com/docker/distribution/issues/1230

Portus似乎很有趣。谢谢@ {Jonathon Reinhart}!稍后我会尝试。

现在,我只将POST请求和PUT请求限制为来自本地地址或本地主机的请求(您可以忽略nginx)。

POST /v2/superpartia/blobs/uploads/ HTTP/1.1
Host: myhost.example.net
User-Agent: docker/1.9.1 go/go1.4.2 git-commit/a34a1d5 kernel/4.2.0-19-generic os/linux arch/amd64
Content-Length: 0
Authorization: Basic eHh4Onh4eA==
Content-Type: 
Accept-Encoding: gzip
ked from local address

因此,我仅限制了除GET和HEAD以外的所有内容(GET隐含了HEAD,请参阅nginx手册)
location /v2/ {
...
    limit_except GET {
        allow 172.x.x.x;
        deny all;
    }
...

这种方式阻止了推送:
Error parsing HTTP response: invalid character '<' looking for beginning of value: "<html>\r\n<head><title>403 Forbidden</title></head>\r\n<body bgcolor=\"white\">\r\n<center><h1>403 Forbidden</h1></center>\r\n<hr><center>nginx/1.9.9</center>\r\n</body>\r\n</html>\r\n"

关于nginx - 如何在docker Registry v2中公开发布和推送要求登录的信息?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34610539/

相关文章:

ruby-on-rails - ECS 上的 Rails 迁移

docker - 从私有(private)注册表中提取失败 - 不支持的 docker v1 存储库请求

根据安装程序的 NSIS 卸载程序权限

django - build_absolute_uri 在反向代理后面使用 HTTPS

ruby-on-rails - 未触发 Actioncable 超时断开连接

apache - 删除 Nginx 或 Apache 中的基本授权 header

java - ORA-01031 : insufficient privileges creating JMS connection to Oracle topic

nginx - 使用 Spring Cloud OAuth2 的 SSL/代理问题

docker - 如何备份/恢复 docker 镜像以进行部署?

oracle - Oracle 过程是否继承其创建者的特权?