TT Lab
Get started
Learn Learning paths Courses

RHEL-Family Administration

Completing an Air-Gap Transfer

Continue in TT Lab

Goal

You build an import bundle, verify it with the manifest, pack it into an archive and unpack it, set up a repository, and install from it alone. You pass through the entire air-gapped network procedure in one go.

Why it matters

An import medium must not hold only rpms. It needs all six: rpm, repodata, GPG key, manifest, checksums, and an install procedure document, and the ones most often missing in practice are the manifest and the GPG key.

And verification must be two-way. Is every file in the manifest on the medium (the missing check), and is there a file on the medium that is not in the manifest (the added check). A missing file shows up quickly as an install failure, but an added file passes without anyone knowing — from the viewpoint of import review, this one is more dangerous.

Steps

  1. Create the /root/airgap/rpms directory and download tree and nano into that directory with all their dependencies (including those already installed).
  2. Create /root/airgap/MANIFEST.tsv. The first line is the header NAME EPOCH VERSION RELEASE ARCH SHA256 FILE (tab-separated), and you must fill in those values one line per rpm. Fill in 0 for a package with no epoch.
  3. Bundle the rpms directory and the manifest into /root/airgap/bundle.tar.gz, and save that archive's sha256 to /root/airgap/bundle.sha256.
  4. Unpack the archive into /root/airgap/unpacked/, and save the result of comparing the manifest's checksums against the actual files to /root/airgap/verify.txt. And write the number of files that are in the directory but not in the manifest as a single numeric line in /root/airgap/extra.txt (it must be 0).
  5. Build metadata in /root/airgap/unpacked/rpms and write /etc/yum.repos.d/airgap.repo. The repository ID is airgap-local, and it must include snapshot and a date in name, baseurl=file:///root/airgap/unpacked/rpms, enabled=1, gpgcheck=0, and metadata_expire=-1.
  6. With all other repositories turned off and only airgap-local on, reinstall tree, and save the output to /root/airgap/install.txt.
  7. Leave state records. Save the module list to /root/airgap/state-modules.txt and the user-installed list to /root/airgap/state-userinstalled.txt.
  8. Make /root/airgap/report.txt with the following 6 lines. BUNDLE_ID=airgap-<오늘 날짜 YYYY-MM-DD> / PACKAGES=<rpms 안 .rpm 개수> / MANIFEST_LINES=<매니페스트의 헤더 제외 줄 수> / VERIFY=OK / EXTRA=0 / INSTALLED_FROM=airgap-local (that is, today's date in YYYY-MM-DD, the number of .rpm files in rpms, and the number of manifest lines excluding the header)

Notes

Collecting the import bundle

Create the /root/airgap/rpms directory and download tree and nano into that directory with all their dependencies (including those already installed).

You need an option combination that downloads the dependencies but does not skip those already installed.

Generating the manifest

Create /root/airgap/MANIFEST.tsv. The first line is the header NAME EPOCH VERSION RELEASE ARCH SHA256 FILE (tab-separated), and you must fill in those values one line per rpm. Fill in 0 for a package with no epoch.

It holds the NEVRA and the checksum together. There is a notation that fills in 0 for a package with no epoch.

Packing into an archive

Bundle the rpms directory and the manifest into /root/airgap/bundle.tar.gz, and save that archive's sha256 to /root/airgap/bundle.sha256.

You make a single object to put on the medium. Leave the checksum of the archive itself as well.

Unpack and verify

Unpack the archive into /root/airgap/unpacked/, and save the result of comparing the manifest's checksums against the actual files to /root/airgap/verify.txt. And write the number of files that are in the directory but not in the manifest as a single numeric line in /root/airgap/extra.txt (it must be 0).

Unpack to a different path and compare the checksums. Also check for files not in the manifest.

Configuring the repository

Build metadata in /root/airgap/unpacked/rpms and write /etc/yum.repos.d/airgap.repo. The repository ID is airgap-local, and it must include snapshot and a date in name, baseurl=file:///root/airgap/unpacked/rpms, enabled=1, gpgcheck=0, and metadata_expire=-1.

Build the metadata and write the .repo file. It is an air-gapped network, so adjust the expiry setting.

Installing from that repository alone

With all other repositories turned off and only airgap-local on, reinstall tree, and save the output to /root/airgap/install.txt.

Install with all the other repositories turned off and only the import repository turned on.

Recording the module state

Leave state records. Save the module list to /root/airgap/state-modules.txt and the user-installed list to /root/airgap/state-userinstalled.txt.

Leave the module list and the user-installed list. They are part of the import record.

Import report

Make /root/airgap/report.txt with the following 6 lines. BUNDLE_ID=airgap-<오늘 날짜 YYYY-MM-DD> / PACKAGES=<rpms 안 .rpm 개수> / MANIFEST_LINES=<매니페스트의 헤더 제외 줄 수> / VERIFY=OK / EXTRA=0 / INSTALLED_FROM=airgap-local (that is, today's date in YYYY-MM-DD, the number of .rpm files in rpms, and the number of manifest lines excluding the header)

Gather the bundle information and the verification result. The values must be actual check results.