docker-archive / docker-registry

This is **DEPRECATED**! Please go to https://github.com/docker/distribution
Apache License 2.0
2.89k stars 877 forks source link

Can't make work .htpasswd authentication with signed certs #1031

Closed kopax closed 8 years ago

kopax commented 8 years ago

HI everyone. I am trying hard to enable .htpasswd TLS authentication in my docker registry. After a few hours of deprecreted documentation and tutorials, I think I might need some of your help.

I have the feeling that the environment var aren't working so I choosed to try the config.yml way :

version: 0.1
log:
  fields:
    service: registry
storage:
  cache:
    blobdescriptor: inmemory
  filesystem:
    rootdirectory: /docker-data/registry
  maintenance:
    uploadpurging:
      enabled: true
      age: 168h
      interval: 24h
      dryrun: false
http:
  addr: :5000
  secret: s3cR4tReGisTRy
  headers:
    X-Content-Type-Options: [nosniff]
  tls:
    certificate: /etc/ssl/certs/wildcard.domain.com.chained.crt
    key: /etc/ssl/private/wildcard.domain.com.key
health:
  sotragedriver:
    enabled: true
    interval: 10s
    threshold: 3
auth:
  htpasswd:
    realm: registry.localhost
    path: /auth/.htpasswd

My nginx looks like this :

upstream docker-registry {
  server registry:5000;
}

server {
  listen 80;
  server_name docker.domain.com;
  server_tokens off;
  root /dev/null;
  return 301 https://$server_name$request_uri;
}

server {
  listen 443 ssl http2;

  server_name docker.domain.com;
  server_tokens off;
  root /dev/null;

  client_max_body_size 0; # disable any limits to avoid HTTP 413 for large image uploads

    ssl on;

    # certs sent to the client in SERVER HELLO are concatenated in ssl_certificate
    ssl_certificate /etc/ssl/certs/wildcard.domain.com.chained.crt;
    ssl_certificate_key /etc/ssl/private/wildcard.domain.com.key;
    ssl_session_timeout 24h;
    ssl_session_cache shared:SSL:10m;

    # Diffie-Hellman parameter for DHE ciphersuites, recommended 2048 bits or better
    ssl_dhparam /etc/ssl/dhparam-2048.pem;

    ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
    ssl_ciphers 'ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:CAMELLIA:DES-CBC3-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA';
    ssl_prefer_server_ciphers on;

    ## OCSP Stapling ---
    ## fetch OCSP records from URL in ssl_certificate and cache them
    ssl_stapling on;
    ssl_stapling_verify on;

    ## verify chain of trust of OCSP response using Root CA and Intermediate certs
    ssl_trusted_certificate /etc/ssl/certs/GandiStandardSSLCA2.pem;

    resolver 127.0.0.1;

  # required to avoid HTTP 411: see Issue #1486 (https://github.com/docker/docker/issues/1486)
  chunked_transfer_encoding on;

  location /v2/ {
    # Do not allow connections from docker 1.5 and earlier
    # docker pre-1.6.0 did not properly set the user agent on ping, catch "Go *" user agents
    if ($http_user_agent ~ "^(docker\/1\.(3|4|5(?!\.[0-9]-dev))|Go ).*$" ) {
      return 404;
    }

    proxy_headers_hash_max_size     51200;
    proxy_headers_hash_bucket_size  6400;
    auth_basic                      "registry.localhost";
    auth_basic_user_file             /etc/nginx/htpasswd/docker/.htpasswd;
    add_header                       Docker-Distribution-Api-Version registry/2.0 always;

    proxy_set_header                 Host $http_host;
    proxy_set_header                 X-Forwarded-For $proxy_add_x_forwarded_for;
    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_set_header                 X-Original-URI $request_uri;
    proxy_set_header                 Docker-Distribution-Api-Version registry/2.0;

    proxy_read_timeout               900;
    proxy_pass                       http://docker-registry;
  }

  location /v1/_ping {
    auth_basic off;
    return 200 'V2 registry';
  }

  access_log  /var/log/nginx/docker_access.log;
  error_log   /var/log/nginx/docker_error.log;

}

By accessing the url https://docker.domain.com I got the following error

$ 2015/09/30 01:36:39 http: TLS handshake error from 172.17.1.62:60053: tls: first record does not look like a TLS handshak
dmp42 commented 8 years ago

All the documentation you need is here:

https://github.com/docker/distribution/tree/master/docs

Specifically:

https://github.com/docker/distribution/tree/master/docs/deploying.md

You don't need nginx - if you insist on using it, there is a recipe for it specifically: https://github.com/docker/distribution/blob/master/docs/nginx.md

Also, you are in the wrong place - docker-registry is the deprecated, python implementation.

From your logs, it seems you try to connect to port 60053 - which doesn't seem to match neither your nginx nor your backend registry.

kopax commented 8 years ago

@dmp42 , thanks for guiding me along this.

Unfortunately, I have already checked the first link, and I have also already read more than once the second link and third link.

Regarding my logs, it was the only config where registry process was logging something, I have no clue why nginx forward it to a port 60053 which got logged in the correct registry container.

Using the config you gave me from the second and third link, I was landing on a http code 502 page with nginx logging the following error :

[error] 9#9: send() failed (111: Connection refused) while resolving, resolver: 127.0.0.1:53