A private registry can be useful for storing Linux container images for your applications in an internal, controlled (and potentially more secure) infrastructure.

Linux containers are technologies that allow you to package and isolate applications with their entire runtime environment—all of the files—necessary to run. This makes it easy to move the contained application between environments (dev, test, production, etc.).

In this article, I will show you how to create a simple SSL/TLS-ready private registry with a stronger security posture that can be used to store containers in general, as well as how to integrate it with Red Hat OpenShift, to be able to perform OCP disconnected deployments. It can also be used for cases where the OperatorHub does not have internet access.

Requisites

We will need the following requisites:

  • FQDN: registry.rhbrlabs.com
  • OS: Red Hat Enterprise Linux 8.6+
  • SELinux: Enforcing
  • Firewalld: Enabled
  • Registry: Podman
  • Apache Tools
  • Volume: 100Gb mounted on /data

This registry fully supports disconnected installations of OpenShift.

Installation

An installation to maximize system security consists of using cryptography, in addition to the security features already available in Linux.

Create the required directories:

[root@registry ~]# mkdir -p /data/registry/{auth,certs,data}

Certificates

Generate certificates for the container registry. In this example, we are creating certificates that are valid for 10 years:

[root@registry ~]# openssl req -newkey rsa:4096 -nodes -sha256 \
-keyout /data/registry/certs/registry.rhbrlabs.com.key -x509 -days 3650 \
-out /data/registry/certs/registry.rhbrlabs.com.crt \
-subj "/C=US/ST=NorthCarolina/L=Raleigh/O=Red Hat/OU=Engineering/CN=registry.rhbrlabs.com" \
-addext "subjectAltName = DNS:registry.rhbrlabs.com"

The operating system needs to trust the certificates that were generated.

Copy the generated certificate to the anchors trusted directory, and run update-ca-trust:

[root@registry ~]# cp /data/registry/certs/registry.rhbrlabs.com.crt /etc/pki/ca-trust/source/anchors/

[root@registry ~]# update-ca-trust

User accounts

To control access to our registry, we will need to create user accounts. In the following example, we will create an account for the user registry.

Generate an authentication file for the image registry:

[root@registry ~]# dnf -y install httpd-tools

[root@registry ~]# htpasswd -bBc /data/registry/auth/htpasswd registry redhat12345678

HTTP secret

In addition to the user account, we will need a secret to increase the reliability of access.

Generate a random secret:

[root@registry ~]# date | md5sum

10f207a4cbba51bf00755b5a50718966

Registry software

With the necessary data in hand, it's time to create the registry.

Create the container registry using the image docker.io/library/registry:2:

[root@registry ~]# dnf -y install podman

[root@registry ~]# podman create --name ocp-registry --net host -p 5000:5000 \
   -v /data/registry/data:/var/lib/registry:z -v /data/registry/auth:/auth:z \
   -e "REGISTRY_AUTH=htpasswd" -e "REGISTRY_AUTH_HTPASSWD_REALM=Registry" \
   -e "REGISTRY_HTTP_SECRET=10f207a4cbba51bf00755b5a50718966" \
   -e REGISTRY_AUTH_HTPASSWD_PATH=/auth/htpasswd -v /data/registry/certs:/certs:z \
   -e REGISTRY_HTTP_TLS_CERTIFICATE=/certs/registry.rhbrlabs.com.crt \
   -e REGISTRY_HTTP_TLS_KEY=/certs/registry.rhbrlabs.com.key docker.io/library/registry:2

The above command will generate a message like this:

Trying to pull docker.io/library/registry:2...
Getting image source signatures
Copying blob fd4a5435f342 done 
Copying blob 213ec9aee27d done 
Copying blob 4583459ba037 done 
Copying blob b136d5c19b1d done 
Copying blob 6f6a6c5733af done 
Copying config dcb3d42c17 done 
Writing manifest to image destination
Storing signatures
Port mappings have been discarded as one of the Host, Container, Pod, and None network modes are in use
22633f37262a4ab2d64fc8beb44bb80618b11802974fb2f45d31d98db3cf14e8

The registry will now be ready for use. However, we need a way to control starting and stopping the service.

Startup control

Create a UNIT file for your registry to automatically start the container at boot:

[root@registry ~]# cat /etc/systemd/system/ocp-registry.service

[Unit]
Description=OCP Registry
[Service]
Restart=always
ExecStart=/usr/bin/podman start -a ocp-registry
ExecStop=/usr/bin/podman stop -t 10 ocp-registry
[Install]
WantedBy=network-online.target

Start the container:

[root@registry ~]# systemctl daemon-reload

[root@registry ~]# systemctl enable --now ocp-registry.service

Private registry running

Firewall

As we are using a local firewall, we will need to authorize the registry service port.

Allow TCP 5000 port on Firewalld:

[root@registry ~]# firewall-cmd --permanent --add-port=5000/tcp

[root@registry ~]# firewall-cmd --reload

Check that the registry is working

Now let's check access to our new registry.

Ensure authentication and SSL/TLS trusted is working:

[root@registry ~]# curl -u 'registry:redhat12345678' https://registry.rhbrlabs.com:5000/v2/_catalog

{"repositories":[]}

Red Hat OpenShift integration

If you are going to use this registry along with OCP, create a file in base64 format with the authentication information.

Generate a temporary file with the authentication information for OpenShift disconnected installs:

[root@registry ~]# cat <<EOF > ~/registry-secret.json
"registry.rhbrlabs.com:5000": {
   "email": "registry@redhat.com",
   "auth": "$(echo -n 'registry:redhat12345678' | base64 -w0)"
}
EOF

Final words

Your new private registry with additional security capabilities is now up and running. Having a private registry service is a good way to control access and meet stricter security standards, as public registry services are more susceptible to security issues.

In this post, I guided you in creating a security-enhanced registry from scratch. Despite being a functional solution, it lacks advanced features such as high availability, mirroring, caching and geo-replication, which is already present in more robust solutions.

All of these functions, plus container vulnerability scanning, object storage support and autoscaling are built into Red Hat Quay.

Red Hat Quay container registry platform provides security-enhanced storage, distribution and governance of containers and cloud-native artifacts on any infrastructure. It is available as a standalone component or it can run on top of Red Hat OpenShift.


About the author

Andre Rocha is a Consultant at Red Hat focused on OpenStack, OpenShift, RHEL and other Red Hat products. He has been at Red Hat since 2019, previously working as DevOps and SysAdmin for private companies.

Read full bio