Docker-registry v2 带有 tls 和 nginx 身份验证错误背后的基本身份验证

SWi*_*els 7 nginx bcrypt ubuntu-14.04 docker-registry docker-compose

简短:我无法使用 my.domain.ch 名称从外部(运行 MAC 的本地计算机)登录我的 docker-registry(托管在服务器中心的 ubuntu-vm (14.04LTS) 上)。

可以使用“docker login http://localhost:5000 ”从运行注册表的ubuntu-machine(vm-2)成功登录

这是我的设置:

vm-1:Ubuntu 14.04 上的 nginx/1.10.1 充当反向代理(此处未安装 docker):

upstream registry {
    server vm-2:5000 fail_timeout=5s;
}

server {
 listen 80;
 server_name my.domain.ch; # server_name ;
 return 301 https://$host$request_uri;
}

server {
 listen 443 ssl;
 server_name my.domain.ch; # server_name ;

 charset utf-8;
 keepalive_timeout 5;
 add_header Docker-Distribution-Api-Version registry/2.0 always;
 ssl_certificate         /etc/nginx/ssl/cert.pem;
 ssl_certificate_key     /etc/nginx/ssl/key.pem;

 ssl_ecdh_curve          secp521r1;

 ssl_protocols           TLSv1.1 TLSv1.2;
 ssl_prefer_server_ciphers       on;
 ssl_ciphers ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCMSHA384:ECDHE-ECDSA-AES256-SHA384:EC$

 proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
 proxy_set_header X-Forwarded-Proto $scheme;
 proxy_set_header Host $http_host;
 proxy_set_header X-Original-URI $request_uri;
 proxy_set_header Docker-Distribution-Api-Version registry/2.0;
 proxy_set_header X-Real-IP $remote_addr;
 proxy_read_timeout 900;

 location / {
    auth_basic "Restricted";
    auth_basic_user_file /etc/nginx/htpasswd;
    proxy_pass https://registry;
 }
}
Run Code Online (Sandbox Code Playgroud)

vm-2 docker-registry 在 Ubuntu 14.04 上充当注册表主机。

Docker version 1.12.1, build 23cf638

docker-compose version 1.7.0, build 0d7bf73

docker-registry version 2.5.1

这些是

  • /opt/docker-registry/auth (htaccess)
  • /opt/docker-registry/certs(密钥和证书)
  • /opt/docker-registry/data(空)
  • /opt/docker-registry/docker-compose.yml

docker-compose.yml 看起来像这样:

registry:
  restart: always
  image: registry:2
  ports:
   - 5000:5000
 environment:
    REGISTRY_HTTP_TLS_CERTIFICATE: /certs/cert.pem
    REGISTRY_HTTP_TLS_KEY: /certs/key.pem
    REGISTRY_AUTH: "htpasswd"
    REGISTRY_AUTH_HTPASSWD_REALM: basic-realm
    REGISTRY_AUTH_HTPASSWD_PATH: /auth/htpasswd
    REGISTRY_LOG_LEVEL: "debug"
 volumes:
   - /opt/docker_registry/data:/var/lib/registry
   - /opt/docker_registry/certs:/certs
   - /opt/docker_registry/auth:/auth
Run Code Online (Sandbox Code Playgroud)

从我的 MAC 我尝试

docker login https://my.domain.ch
Username: MyUserName
Password:
Error response from daemon: login attempt to https://my.domain.ch/v2/ failed with status: 401 Unauthorized
Run Code Online (Sandbox Code Playgroud)

我的研究表明:

David Daeschler写道,docker只支持 bcrypt 的基本身份验证。(我尝试使用 apache-md5、md5 和 crypt 都不起作用)。所以我按照建议使用 bcrypt 作为我的 htacces。

我的 docker-registry 日志:

registry_1  | time="2016-09-22T10:01:00.809076941Z" level=debug msg="authorizing request" go.version=go1.6.3 http.request.host=mydomain.ch http.request.id=f1b0ccda-2d03-4480-aaf8-b7248acaed5f http.request.method=GET http.request.remoteaddr=xxx.xxx.xxx.127 http.request.uri="/v2/" http.request.useragent="docker/1.12.1 go/go1.6.3 git-commit/23cf638 kernel/4.4.20-moby os/linux arch/amd64 UpstreamClient(Docker-Client/1.12.1 \\(darwin\\))" instance.id=59b4a38a-307e-446d-9f8a-3618c35bb6bb service=registry version=v2.5.1

registry_1  | time="2016-09-22T10:01:00.811894104Z" level=error msg="error authenticating user \"MyUserName\": authentication failure" go.version=go1.6.3 http.request.host=my.domain.ch http.request.id=f1b0ccda-2d03-4480-aaf8-b7248acaed5f http.request.method=GET http.request.remoteaddr=xxx.xxx.xxx.127 http.request.uri="/v2/" http.request.useragent="docker/1.12.1 go/go1.6.3 git-commit/23cf638 kernel/4.4.20-moby os/linux arch/amd64 UpstreamClient(Docker-Client/1.12.1 \\(darwin\\))" instance.id=59b4a38a-307e-446d-9f8a-3618c35bb6bb service=registry version=v2.5.1

registry_1  | time="2016-09-22T10:01:00.812631504Z" level=warning msg="error authorizing context: basic authentication challenge for realm \"basic-realm\": authentication failure" go.version=go1.6.3 http.request.host=my.domain.ch http.request.id=f1b0ccda-2d03-4480-aaf8-b7248acaed5f http.request.method=GET http.request.remoteaddr=83.xxx.xxx.127 http.request.uri="/v2/" http.request.useragent="docker/1.12.1 go/go1.6.3 git-commit/23cf638 kernel/4.4.20-moby os/linux arch/amd64 UpstreamClient(Docker-Client/1.12.1 \\(darwin\\))" instance.id=59b4a38a-307e-446d-9f8a-3618c35bb6bb service=registry version=v2.5.1

registry_1  | xxx.xxx.xxx.11 - - [22/Sep/2016:10:01:00 +0000] "GET /v2/ HTTP/1.0" 401 87 "" "docker/1.12.1 go/go1.6.3 git-commit/23cf638 kernel/4.4.20-moby os/linux arch/amd64 UpstreamClient(Docker-Client/1.12.1 \\(darwin\\))"
Run Code Online (Sandbox Code Playgroud)

nginx 日志:

2016/09/22 09:14:34 [crit] 13318#0: *8 crypt_r() failed (22: Invalid argument), client: xxx.xxx.xxx.127, server: my.domain.ch, request: "GET /v2/ HTTP/1.1", host: "my.domain.ch"
Run Code Online (Sandbox Code Playgroud)

这个错误原因包含在 Docker.com的这个回答中。(简而言之:搜索这表明这取决于 debian 附带的 gcc 版本。)

我从日志和错误中知道的是:

  • 它已正确转发请求
  • 端口已打开并接受请求
  • TLS 有效且证书正确 - 它使用 api 的 v2
  • 必须与 htaccess 有关
  • 肯定是nginx的问题。因此在本地它有效

如何让 nginx 理解 bcrypt? 还是其他地方的错误?

感谢您的帮助

编辑:

从 docker.com 的家伙那里找到了这个

I'm not sure if this will help, but we've become tired of dealing with nginx's edge cases for new users, so registry 2.1 will come with htpasswd based basic auth support.
Run Code Online (Sandbox Code Playgroud)

从使用 docker-registry v2.5.1 开始,基本身份验证应该可以工作。

我安装sudo apt-get install apache2-utilsvm-1 上。我认为它可能会带来 bcrypt。它没有用。

当显式安装 bcrypt ( sudo apt-get install bcrypt) 我得到bcrypt is already the newest version.

sudo apt-get install libgmp3-dev按照此处的建议添加也不起作用。

如上所述这里(一般nginx的?或基本身份验证的?)auth_basic不支持bcrypt。但是 docker-registry 允许的唯一加密是 bcrypt 用于 htaccess 密码。

此处阅读nginx 无法处理 bcrypt 密码哈希。

在 nginx 1.10.1 后面不可能有 docker-registry v2.5.1 吗?

SWi*_*els 0

我仍然没有得到如何解决我的问题的提示。因此,我得到了一个解决方法:我将防火墙配置为将端口直接转发到运行注册表的计算机。所以我可以使用域名从外部连接到我的注册表。

如果有人知道如何使用 nginx 运行它,我将不胜感激。