This tutorial points dnf on Rocky Linux 9 at a Virtual Registry that caches Rocky’s BaseOS repository, and then enables the Artifact Firewall on that registry.
virtual_registry:
registries:
- name: rpm
remotes:
- url: https://dl.rockylinux.org
The examples below reach the registry as https://rpm.example.com, a host that the registry named rpm answers (see name). A path on the registry is the same path on the remote, so BaseOS, at https://dl.rockylinux.org/pub/rocky/9/BaseOS/, is at https://rpm.example.com/pub/rocky/9/BaseOS/. Package types describes how each file is cached.
Add the repository in /etc/yum.repos.d/rocky-baseos-vr.repo:
[baseos-vr]
name=Rocky Linux 9 BaseOS through the Virtual Registry
baseurl=https://rpm.example.com/pub/rocky/9/BaseOS/$basearch/os/
gpgcheck=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-Rocky-9
The repository has to be given by baseurl. Rocky’s own repositories, in /etc/yum.repos.d/rocky.repo, use mirrorlist, which hands dnf a list of mirrors that it then downloads from directly. Set enabled=0 on the baseos section there, or dnf can take a package from a mirror rather than from the registry. On a host that reaches only the registry, also set it on appstream in that file and on extras in rocky-extras.repo, or add them through the registry the same way, because dnf stops when it cannot fetch the metadata of an enabled repository.
Installs now go through the registry:
dnf install tree
The firewall is licensed separately, see enable_firewall. Turn it on for the registry and give it a ruleset:
virtual_registry:
registries:
- name: rpm
enable_firewall: true
remotes:
- url: https://dl.rockylinux.org
firewall:
rulesets:
- path: /etc/orca/rulesets
A rule names a package as pkg:rpm/<name>@<version>-<release>. This one, in /etc/orca/rulesets/rpm.yaml, denies every version of nano:
id: rpm-policy
rules:
- id: deny-nano
action: deny
reason: nano is not approved on build hosts
match:
- purl: pkg:rpm/nano
The firewall drops the package from primary.xml, so after the next metadata refresh dnf no longer finds it:
dnf --refresh install nano
ends with Unable to find a match: nano.
Dropping a package rewrites repomd.xml, which breaks the signature that the repository publishes over it. Leave repo_gpgcheck unset or at 0 on a repository that the firewall filters, as the file above does, and keep gpgcheck=1, which checks each package and still passes. RPM enforcement covers the alternative, which keeps the signature and gives up the filtering.