How to secure your private docker registry?

How to secure your private docker registry?

Introduction

In my previous article, I explained how to set up your private Docker registry with Docker Registry. All works fine when you are consuming the private registry from the host machine but when you try to access from the remote machine then docker will throw an error about https connection. Also, it is mandatory to secure your private registry when it accessible through a public network. 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 Private Registry

We have three security options to secure your private registry and we are going to cover all three concepts in this articles. The available options are,

  • Enabling SSL with CA Certificate
  • Enabling SSL with Self-Signed Certificate
  • Basic Authentication

CA Certificate

To enable the https in a web server we need a SSL certificate againt our domain name(example hub.docker.local). There are lots CAs out there in the market to provide these certificates. For production environment, it is recommended to use the SSL certificate from CAs instead of creating your own. Docker registry supports to 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 are ready to configure into your private registry.

Do the following steps to configure SSL to your private registry,

  • Open a powershell console(teriminal 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 
  • As per previous article, repeat the same steps to push & pull a 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
  • 2018-10-17 10_14_02-OneNote.png

Self-Signed Certificate

It is strongly not recommended use self-signed certificate for production however, we can use this for testing purpose 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 registry

Configure a local DNS entry

Starting of the previous article we have seen how to configure the local dns entry for hub.docker.local. Please refer 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 available already. For windows we need to download and install manually from this links 64arch/86arch.

Windows:
Download the appropriate installer for your CPU architecture and it is recommend to choose bin folder to copy binary files instead of System 32 folder. Once instllation done add the openssl installed bin folder to PATH environment variables.

Do the following steps to generate the self-sgined certificate

  • Open a powershell console(teriminal 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
  • Type the following command to generate the self-signed certificate
  • Windows/Linux:
    openssl req -newkey rsa:4096 -nodes -sha256 -keyout certs/localhub.key -x509 
    -days 365 -out certs/localhub.crt
    
  • Once you hit enter, it will ask you a series of question. Answer them appropriatly for all question except Common Name. Common Name should match with your local dns, for our example it is hub.docker.local
    2018-10-17 10_46_40-Microsoft
  • Congratulation you have created self-signed certificate for your local domain

Apply the Self-Signed Certificate to Registry

Just repeat the same steps what you followed in applying CA certificate except certification file name change.

  • 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/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 saw how to share your private registry images securely across the networks but it is also important to consider who can access 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(teriminal 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 out put into file so 
    copy the console output without any space then open notepad and paste 
    the content then save file to C:\localhub\auth\htpasswd(without any extension). 
    Linux:
    docker run --entrypoint htpasswd registry -Bbn iniyan pass123 > auth/htpasswd
    
  • Stop the registry container that already running
  • Windows/Linux:
    docker container stop local.hub
    
  • Spin a new container for registry with 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 any the package from private registry it will throw an error like connection refushed
  • Windows/Linux:
    docker pull hub.docker.local/alpine
    
  • To fix the above error, you need to login with hub.docker.local
  •  Windows/Linux:
     docker login hub.docker.local
    

  • Now, If you try again the same comman, 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
  • 2018-10-17 12_28_55-https___hub.docker.local_v2__catalog.png

Conclusion

In this article, we have covered how to secure our private registry with SSL and user authentication. Thanks for reading this article. Please share your valuable comments below. In the next article, I have written about “how to register your registry as a service?”.

2 Replies to “How to secure your private docker registry?”

Leave a Reply

Your email address will not be published. Required fields are marked *