github.com/circular-dark/docker@v1.7.0/docs/articles/certificates.md (about) 1 <!--[metadata]> 2 +++ 3 title = "Using certificates for repository client verification" 4 description = "How to set up and use certificates with a registry to verify access" 5 keywords = ["Usage, registry, repository, client, root, certificate, docker, apache, ssl, tls, documentation, examples, articles, tutorials"] 6 [menu.main] 7 parent = "mn_docker_hub" 8 weight = 7 9 +++ 10 <![end-metadata]--> 11 12 # Using certificates for repository client verification 13 14 In [Running Docker with HTTPS](/articles/https), you learned that, by default, 15 Docker runs via a non-networked Unix socket and TLS must be enabled in order 16 to have the Docker client and the daemon communicate securely over HTTPS. 17 18 Now, you will see how to allow the Docker registry (i.e., *a server*) to 19 verify that the Docker daemon (i.e., *a client*) has the right to access the 20 images being hosted with *certificate-based client-server authentication*. 21 22 We will show you how to install a Certificate Authority (CA) root certificate 23 for the registry and how to set the client TLS certificate for verification. 24 25 ## Understanding the configuration 26 27 A custom certificate is configured by creating a directory under 28 `/etc/docker/certs.d` using the same name as the registry's hostname (e.g., 29 `localhost`). All `*.crt` files are added to this directory as CA roots. 30 31 > **Note:** 32 > In the absence of any root certificate authorities, Docker 33 > will use the system default (i.e., host's root CA set). 34 35 The presence of one or more `<filename>.key/cert` pairs indicates to Docker 36 that there are custom certificates required for access to the desired 37 repository. 38 39 > **Note:** 40 > If there are multiple certificates, each will be tried in alphabetical 41 > order. If there is an authentication error (e.g., 403, 404, 5xx, etc.), Docker 42 > will continue to try with the next certificate. 43 44 Our example is set up like this: 45 46 /etc/docker/certs.d/ <-- Certificate directory 47 └── localhost <-- Hostname 48 ├── client.cert <-- Client certificate 49 ├── client.key <-- Client key 50 └── localhost.crt <-- Registry certificate 51 52 ## Creating the client certificates 53 54 You will use OpenSSL's `genrsa` and `req` commands to first generate an RSA 55 key and then use the key to create the certificate. 56 57 $ openssl genrsa -out client.key 1024 58 $ openssl req -new -x509 -text -key client.key -out client.cert 59 60 > **Warning:**: 61 > Using TLS and managing a CA is an advanced topic. 62 > You should be familiar with OpenSSL, x509, and TLS before 63 > attempting to use them in production. 64 65 > **Warning:** 66 > These TLS commands will only generate a working set of certificates on Linux. 67 > The version of OpenSSL in Mac OS X is incompatible with the type of 68 > certificate Docker requires. 69 70 ## Testing the verification setup 71 72 You can test this setup by using Apache to host a Docker registry. 73 For this purpose, you can copy a registry tree (containing images) inside 74 the Apache root. 75 76 > **Note:** 77 > You can find such an example [here]( 78 > http://people.gnome.org/~alexl/v1.tar.gz) - which contains the busybox image. 79 80 Once you set up the registry, you can use the following Apache configuration 81 to implement certificate-based protection. 82 83 # This must be in the root context, otherwise it causes a re-negotiation 84 # which is not supported by the TLS implementation in go 85 SSLVerifyClient optional_no_ca 86 87 <Location /v1> 88 Action cert-protected /cgi-bin/cert.cgi 89 SetHandler cert-protected 90 91 Header set x-docker-registry-version "0.6.2" 92 SetEnvIf Host (.*) custom_host=$1 93 Header set X-Docker-Endpoints "%{custom_host}e" 94 </Location> 95 96 Save the above content as `/etc/httpd/conf.d/registry.conf`, and 97 continue with creating a `cert.cgi` file under `/var/www/cgi-bin/`. 98 99 #!/bin/bash 100 if [ "$HTTPS" != "on" ]; then 101 echo "Status: 403 Not using SSL" 102 echo "x-docker-registry-version: 0.6.2" 103 echo 104 exit 0 105 fi 106 if [ "$SSL_CLIENT_VERIFY" == "NONE" ]; then 107 echo "Status: 403 Client certificate invalid" 108 echo "x-docker-registry-version: 0.6.2" 109 echo 110 exit 0 111 fi 112 echo "Content-length: $(stat --printf='%s' $PATH_TRANSLATED)" 113 echo "x-docker-registry-version: 0.6.2" 114 echo "X-Docker-Endpoints: $SERVER_NAME" 115 echo "X-Docker-Size: 0" 116 echo 117 118 cat $PATH_TRANSLATED 119 120 This CGI script will ensure that all requests to `/v1` *without* a valid 121 certificate will be returned with a `403` (i.e., HTTP forbidden) error.