
Introduction
DNF is the default command-line package management utility for RPM-based Linux distributions. Primarily developed and maintained by Red Hat with contributions from the Fedora community, it was designed to improve upon the previously used YUM package manager, with better performance, memory usage, and dependency resolution. As the primary manager for Red Hat Enterprise Linux (RHEL), it handles the entire lifecycle of software, including installation, updates, and automatic removal dependencies. In this guide, we will show you How to Create a Local Repository on RHEL9.
DNF provides features for maintaining air-gapped environments by allowing system administrators to host entirely local package repositories. This works by creating a central server, acting as our package repository, and is disconnected from public internet.
There are several benefits to why do this:
- Faster data transfer times (data travels relatively shorter distances)
- Helps seperating between public and private internet zones
- Better version control for needed packages and dependencies
Procedure
Requirements
- RHEL9 machine with public internet access , acting as our repository server
- A RHEL9 machine with at least 4 cores CPU and 8 GiB RAM
- At least 256 GiB of disk storage space for the packages
- The repo-server must be on the same internet network as the client nodes wishing to pull packages from it, or configured with an additional network adapter
Configuring the repository server
Add the NGINX repository
[root@repository ~]# cat << EOF > /etc/yum.repos.d/nginx.repo
[nginx]
name=NGINX Repository
baseurl=http://nginx.org/packages/rhel/9/\$basearch/
gpgcheck=0
enabled=1
EOF
[root@repository ~]# dnf clean all
[root@repository ~]# dnf makecache
Download and start the nginx service
[root@repository ~]# dnf install -y nginx
[root@repository ~]# systemctl start nginx
[root@repository ~]# systemctl enable --now nginx
Allow http/s through the firewall
[root@repository ~]# firewall-cmd --zone=public --permanent --add-service=http
[root@repository ~]# firewall-cmd --zone=public --permanent --add-service=https
[root@repository ~]# firewall-cmd --reload
Edit ‘/etc/nginx/conf.d/default.conf’ with the following values:
server {
listen 80;
server_name _;
#access_log /var/log/nginx/host.access.log main;
location / {
root /var/www/html;
index index.html index.htm;
}
location /rhel9 {
alias /var/www/html/rhel9;
autoindex on;
}
#error_page 404 /404.html;
...
The rest keep as is.
Create the repository directories and allow NGINX to access the files in file permissions SELinux
[root@repository ~]# mkdir -p /var/www/html/rhel9/{baseOS,AppStream}
[root@repository ~]# chmod -R 755 /var/www/html
[root@repository ~]# chown -R nginx:nginx /var/www/html
[root@repository ~]# semanage fcontext -a -t httpd_sys_content_t "/var/www/html(/.*)?"
[root@repository ~]# restorecon -Rv /var/www/html
Restart the nginx server to load new config
[root@repository ~]# systemctl restart nginx
Install the required packages
[root@repository ~]# dnf install -y yum-utils createrepo_c httpd
Download the packages locally
NOTE: This takes several hours to complete. Adding the ‘–newest-only’ option will result in a significant faster process, but might pose future dependencies issues that will have to be addresses manually.
Important remark:
It is recommended to set the repository server with 2 disks; one for the RHEL9 OS, and one for the package storage. That way, it will be easier to migrate the packages onto another node that might need physical packages on the system, or in an event of repo server failure.
To achieve this, you’ll to mount the disk onto the system, download the packages there, and either create a soft link from the mountpoint to ‘/var/www/html/’, or serve entierly from that mountpoint (with considerations to SELinux permissions).
[root@repository ~]# reposync --gpgcheck --download-metadata --repoid=rhel-9-for-x86_64-baseos-rpms -p /var/www/html/rhel9/baseOS --download-path=/var/www/html/rhel9/baseOS
[root@repository ~]# mv -rf /var/www/html/rhel9/AppStream/rhel-9-for-x86_64-baseos-rpms/* /var/www/html/rhel9/baseOS
[root@repository ~]# rmdir /var/www/html/rhel9/baseOS/rhel-9-for-x86_64-baseOS-rpms/
[root@repository ~]# reposync --gpgcheck --download-metadata --repoid=rhel-9-for-x86_64-appstream-rpms -p /var/www/html/rhel9/AppStream --download-path=/var/www/html/rhel9/AppStream
[root@repository ~]# mv -rf /var/www/html/rhel9/AppStream/rhel-9-for-x86_64-appstream-rpms/* /var/www/html/rhel9/AppStream
[root@repository ~]# rmdir /var/www/html/rhel9/AppStream/rhel-9-for-x86_64-appstream-rpms/
Apply ownership and SELinux permissions
[root@repository ~]# chmod -R 755 /var/www/html
[root@repository ~]# chown -R nginx:nginx /var/www/html
[root@repository ~]# semanage fcontext -a -t httpd_sys_content_t "/var/www/html(/.*)?"
[root@repository ~]# restorecon -Rv /var/www/html
Create the repositories
[root@repository ~]# createrepo_c /var/www/html/rhel9/BaseOS/
[root@repository ~]# createrepo_c /var/www/html/rhel9/AppStream/
Configuring client nodes
To use the local repositories, we need to add the repositories to the client node. The next section shows you how.
Create a .repo file in ‘/etc/yum.repos.d/’
[root@client ~]# for REPO in AppStream BaseOS; do
cat << EOF > /etc/yum.repos.d/local-$REPO.repo
[local-$REPO]
name='My local $REPO repository'
baseurl=http://<repository-server-ip>/rhel9/$REPO/
enabled=1
gpgcheck=0
EOF
done
OPTIONAL: Disable other repositories with
dnf config-manager --disable <repo-id>
Clear and build new dnf metadata cache
[root@client ~]# dnf clean all
14 files removed
[root@client ~]# dnf makecache
My local AppStream repository 50 MB/s | 11 MB 00:00
My local BaseOS repository 55 MB/s | 104 MB 00:01
Metadata cache created.
Now, try and search/install a package, and it was part of BaseOS/AppStream repositories at the moment of creation, it will appear and download.
[root@client ~]# dnf search httpd
======== Name Exactly Matched: httpd ========
httpd.x86_64 : Apache HTTP Server
======== Name & Summary Matched: httpd ========
httpd-core.x86_64 : httpd minimal core
...
======== Name Matched: httpd ========
httpd-devel.x86_64 : Development interfaces for the Apache HTTP Server
httpd-filesystem.noarch : The basic directory layout for the Apache HTTP Server
...
[root@client ~]# dnf list httpd
Available Packages
httpd.x86_64 2.4.53-7.el9 local-AppStream
Summary
In this article, we’ve seen the benefits of setting up a local package repository server for your air-gapped environment. We’ve also showcased how to set up your own repository server.
In Octopus Computer Solutions, we provide cloud services security as a top priority. From Day-1 to Day-2 operations, we implement cutting-edge security practices that safeguard your data and infrastructure.
For more information regarding us, check out our website.
For more information regarding the ‘DNF’ utility, check out the Red Hat Docs.