Air-Gapped Mirrors and a Private CA
RHEL: HTTPS internal repositories and update-ca-trust
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
- Copy the tree rpm from
/opt/localrepoto/srv/rpmrepoand create a repository withcreaterepo_c. - In
/root/pki, create a root (ca.crtandca.key, CNAirgap Internal Root CA) and arepo.airgap.internalcertificate (repo.crtandrepo.key, with a SAN), and add the name to/etc/hosts. - With
/root/pki/serve.py, serve/srv/rpmrepoathttps://repo.airgap.internal:8443/. - In
/etc/yum.repos.d/airgap.repo, write the repositoryairgap(signature checking on, the distribution key/etc/pki/rpm-gpg/RPM-GPG-KEY-Rocky-9). - Turn off the other repositories, run
dnf makecachewithairgapalone, and save the failing output in/root/rhel/tls-fail.txt. - Put the root into the system trust as
airgap-root.crtand extract again. - Install tree with the
airgaprepository alone. - Issue a
team.airgap.internalcertificate with the partner CA (/root/pki/team-ca.crt, CNPartner Team CA), serve the same repository on 9443, and throughsslcacertin/etc/yum.repos.d/airgap-team.repomake only that repository trust this CA. Do not put the partner CA into the system trust.
Notes
- With a single repository only:
dnf --disablerepo='*' --enablerepo=airgap makecache - Viewing the system trust:
trust list | grep -A3 Airgap· extracting:update-ca-trust extract - Where it was installed from: the
From repoofdnf info --installed tree - Common mistake 1: getting past it with
sslverify=0. The grader rejects this setting. - Common mistake 2: putting even the partner CA in anchors. The moment you do, every program on the server trusts that CA.
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.