TT Lab
Get started
Learn Learning paths Courses

Air-Gapped Mirrors and a Private CA

RHEL: HTTPS internal repositories and update-ca-trust

Continue in TT Lab

Goal

On a RHEL-family system, stand up an internal dnf repository over HTTPS and install by putting the private CA into the system trust. You also use sslcacert, which narrows the scope of trust to a single repository.

Why it matters

When you switch the internal repository to HTTPS, dnf stops at certificate verification, and the most common response is sslverify=0. Repository metadata is the document that decides what to install, so origin checking must not be turned off. If you can choose between system-wide trust (update-ca-trust) and per-repository trust (sslcacert), you solve it without patches. This Pod cannot reach the outside (DNS only). Packages are taken from /opt/localrepo inside the image.

Steps

  1. Copy the tree rpm from /opt/localrepo to /srv/rpmrepo and create a repository with createrepo_c.
  2. In /root/pki, create a root (ca.crt and ca.key, CN Airgap Internal Root CA) and a repo.airgap.internal certificate (repo.crt and repo.key, with a SAN), and add the name to /etc/hosts.
  3. With /root/pki/serve.py, serve /srv/rpmrepo at https://repo.airgap.internal:8443/.
  4. In /etc/yum.repos.d/airgap.repo, write the repository airgap (signature checking on, the distribution key /etc/pki/rpm-gpg/RPM-GPG-KEY-Rocky-9).
  5. Turn off the other repositories, run dnf makecache with airgap alone, and save the failing output in /root/rhel/tls-fail.txt.
  6. Put the root into the system trust as airgap-root.crt and extract again.
  7. Install tree with the airgap repository alone.
  8. Issue a team.airgap.internal certificate with the partner CA (/root/pki/team-ca.crt, CN Partner Team CA), serve the same repository on 9443, and through sslcacert in /etc/yum.repos.d/airgap-team.repo make only that repository trust this CA. Do not put the partner CA into the system trust.

Notes

Create the internal repository with createrepo_c

Copy the tree rpm from /opt/localrepo to /srv/rpmrepo and create a repository with createrepo_c.

A repository is the rpm files plus a repodata directory that describes them. If you give createrepo_c a directory, it creates repomd.xml and the list files.

Private CA and the repository certificate

In /root/pki, create a root (ca.crt and ca.key) and a repo.airgap.internal certificate (repo.crt and repo.key, with a SAN), and add the name to /etc/hosts.

The root is self-signed with CA:TRUE, and the server certificate is signed with the root while giving the SAN through an extension file. It is the same procedure as in the private CA module.

Serve the repository over HTTPS

With /root/pki/serve.py, serve /srv/rpmrepo at https://repo.airgap.internal:8443/.

Wrap the http.server of the Python standard library in an ssl context. The Python in this image is 3.9. Start it in the background and download repomd.xml with curl given --cacert.

Write the .repo file

In /etc/yum.repos.d/airgap.repo, write the repository airgap (signature checking on, the distribution key specified).

The section name is the repository id. baseurl is the address of the directory that has repodata, and you write signature checking and the public key file path along with it. Do not write a line that turns off certificate verification.

Record the certificate verification failure

Turn off the other repositories, run dnf makecache with airgap alone, and save the failing output in /root/rhel/tls-fail.txt.

If you use --disablerepo and --enablerepo together, you can look at a single repository. Save the whole output (including standard error).

Put the root into the system trust

Put the root into the system trust as airgap-root.crt and extract again.

On RHEL-family systems, you place it in the anchors directory and run the extract command. Check the label and the kind of trust with trust list.

Install from the internal repository

Install tree with the airgap repository alone.

If you install with only one repository enabled, it cannot come from anywhere else. After installing, look with dnf info --installed at which repository it came from.

Only one repository with a different CA

Issue a team.airgap.internal certificate with the partner CA (/root/pki/team-ca.crt, CN Partner Team CA), serve the same repository on 9443, and through sslcacert in /etc/yum.repos.d/airgap-team.repo make only that repository trust it.

Do not put the partner CA in anchors. A .repo has an option to specify the CA file per repository. Check with a makecache of only that repository, and by whether the system curl still rejects it.