Introduction
In my previous article, I explained how to set up your private Docker registry in your local machine with the Docker Registry tool. All features work fine when you are consuming the private registry from the host machine but the problem will start when you try to access from the remote machine, the docker will throw an error about https connection. Also, it is mandatory to secure your private registry when it accessible through public networks. In this article, we are going to see what are all the possible options we have and how to use them.
This is the second part of my private Docker Registry series and the following list shows the outline of the series:
Securing the Private Registry
We have three security options to secure your private registry and we are going to cover all three options in this article. The available options are:
- Enabling the SSL with CA Certificate
- Enabling the SSL with Self-Signed Certificate
- Basic Authentication
CA Certificate
To enable the https in a web server, we need an SSL certificate against our domain name (for our example hub.docker.local
). There are lots of CAs out there in the market to provide these certificates. For a production environment, it is recommended to use the SSL certificate from CAs instead of creating your own. Docker registry supports using Let's Encrypt (open source CA) so you can think of using this as well. Assume you have received the required SSL certificates (hub.docker.local.crt, hub.docker.local.key) from your CA vendor for the hub.docker.local domain and now you're ready to configure SSL for your private registry.
Do the following steps to configure SSL to your private registry:
- Open a PowerShell console (terminal in Linux)
- Navigate to C:\localhub folder (remember we created this folder in the previous article). For Linux, go to /home/localhub.
- Create certs folder
- Copy your certificate files hub.docker.local.crt, hub.docker.local.key into certs folder
- Spin up a container for registry with your SSL certificates
Windows:
docker run -d -p 443:443 --name local.hub -v C:/localhub/certs:/certs
-v C:/localhub/registry:/var/lib/registry -e REGISTRY_HTTP_ADDR=0.0.0.0:443
-e REGISTRY_HTTP_TLS_CERTIFICATE=/certs/hub.docker.local.crt
-e REGISTRY_HTTP_TLS_KEY=/certs/hub.docker.local.key registry
Linux:
docker run -d -p 443:443 --name local.hub -v /home/localhub/certs:/certs
-v /home/localhub/registry:/var/lib/registry -e REGISTRY_HTTP_ADDR=0.0.0.0:443
-e REGISTRY_HTTP_TLS_CERTIFICATE=/certs/hub.docker.local.crt
-e REGISTRY_HTTP_TLS_KEY=/certs/hub.docker.local.key registry
- Ensure your registry container is up and running:
Windows/Linux:
docker container ls
- Repeat the same steps from the previous article to push & pull an image from your private registry:
Windows/Linux:
docker pull alpine
docker tag alpine hub.docker.local/alpine
docker push hub.docker.local/alpine
docker rmi hub.docker.local/alpine
docker images
docker pull hub.docker.local/alpine
docker images
- Also, check the catalog URL https://hub.docker.local/v2/_catalog with a browser to ensure your registry returning the metadata
Self-Signed Certificate
It is strongly not recommended to use a self-signed certificate for production however, we can use this for testing purposes and understanding the capability of SSL. To use the self-signed certificate, we need to do the following things:
- Configure a local DNS entry
- Generate self-signed certificate
- Apply the self-signed certificate to the registry
Configure a Local DNS Entry
At the beginning of the previous article, we have seen how to configure the local DNS entry for hub.docker.local
. Please refer to it and we are going to use the same.
Generate Self-Signed Certificate
We are going to use OpenSSL to generate the self-signed certificates. For Linux, OpenSSL comes with part of application repository so you can easily pull it through apk if it is not installed already. For Windows, you need to download and install manually from this links 64 bit/32 bit.
Windows Installation
Download the appropriate OpenSSL installer for your CPU architecture and it is recommend to choose the bin folder to extract binary files instead of System 32 folder. Once installation is done, add the openssl installed bin folder to PATH environment variables.
Do the following steps to generate the self-signed certificate:
Apply the Self-Signed Certificate to the Registry
Just repeat the same steps that you followed in applying CA certificate with newly created certificate files.
- Spin up a container for registry with your self-signed SSL certificates:
Windows:
docker run -d -p 443:443 --name local.hub -v C:/localhub/certs:/certs
-v C:/localhub/registry:/var/lib/registry -e REGISTRY_HTTP_ADDR=0.0.0.0:443
-e REGISTRY_HTTP_TLS_CERTIFICATE=/certs/localhub.crt
-e REGISTRY_HTTP_TLS_KEY=/certs/localhub.key registry
Linux:
docker run -d -p 443:443 --name local.hub -v /home/localhub/certs:/certs
-v /home/localhub/registry:/var/lib/registry -e REGISTRY_HTTP_ADDR=0.0.0.0:443
-e REGISTRY_HTTP_TLS_CERTIFICATE=/certs/localhub.local.crt
-e REGISTRY_HTTP_TLS_KEY=/certs/localhub.key registry
- Ensure your registry container is up and running:
Windows/Linux:
docker container ls
- Do the image push & pull from your private registry with following commands:
Windows/Linux:
docker pull alpine
docker tag alpine hub.docker.local/alpine
docker push hub.docker.local/alpine
docker rmi hub.docker.local/alpine
docker images
docker pull hub.docker.local/alpine
docker images
- Check the catalog URL https://hub.docker.local/v2/_catalog with a browser to ensure your registry returning the metadata. This time, you receive a warning about an invalid certificate.
Basic Authentication
So far, we have seen how to share your private registry images securely across the networks and it is also important to consider how to restrict the access to the content. In this section, we are going to how to set up the user authentication to your private registry. Do the following steps to enable the user authentication to your private registry,
- Open a PowerShell console (terminal in Linux)
- Navigate to C:\localhub folder (remember we created this folder in the previous article). For Linux, go to /home/localhub
- Create auth folder
- Type the following command to generate the user profile file:
Windows/Linux:
docker run --entrypoint htpasswd registry -Bbn iniyan pass123
It seems windows docker having issue when directly write the output into a file,
to avoid the issue copy the console output of above command without any space
and paste to a notepad, save to htpasswd(without any extension) file under C:\localhub\auth.
Linux:
docker run --entrypoint htpasswd registry -Bbn iniyan pass123 > auth/htpasswd
- Stop the registry container that is already running:
Windows/Linux:
docker container stop local.hub
docker container rm local.hub
- Spin a new container for registry with the following parameters:
Windows:
docker run -d -p 443:443 --name local.hub -v C:/localhub/certs:/certs
-v C:/localhub/registry:/var/lib/registry -v C:/localhub/auth:/auth
-e "REGISTRY_AUTH=htpasswd" -e "REGISTRY_AUTH_HTPASSWD_REALM=Registry Realm"
-e REGISTRY_AUTH_HTPASSWD_PATH=/auth/htpasswd -e REGISTRY_HTTP_ADDR=0.0.0.0:443
-e REGISTRY_HTTP_TLS_CERTIFICATE=/certs/localhub.crt
-e REGISTRY_HTTP_TLS_KEY=/certs/localhub.key registry
Linux:
docker run -d -p 443:443 --name local.hub -v /home/localhub/certs:/certs
-v /home/localhub/registry:/var/lib/registry -v /home/localhub/auth:/auth
-e "REGISTRY_AUTH=htpasswd" -e "REGISTRY_AUTH_HTPASSWD_REALM=Registry Realm"
-e REGISTRY_AUTH_HTPASSWD_PATH=/auth/htpasswd -e REGISTRY_HTTP_ADDR=0.0.0.0:443
-e REGISTRY_HTTP_TLS_CERTIFICATE=/certs/localhub.crt
-e REGISTRY_HTTP_TLS_KEY=/certs/localhub.key registry
- Ensure your registry is up and running:
Windows/Linux:
docker container ls
- Now, if you try to push/pull a package from the private registry, it will throw an error as connection refused:
Windows/Linux:
docker pull hub.docker.local/alpine
- To fix the above error, you need to log in with
hub.docker.local
:
Windows/Linux:
docker login hub.docker.local
- Now, if you try the same command again, it will work like a charm:
- When you try to access catalog URL https://hub.docker.local/v2/_catalog, it will also prompt you for login:
Conclusion
In this article, we have covered how to secure our private registry with SSL and user authentication. Thanks for reading this article and I hope you find something useful. Please share your valuable comments below. In the next article, I plan to write about "how to register your registry as a service?".
History
- 17th October, 2018: Initial version