Installing Linux Packages Offline
1. Introduction
Hi there 😊. Another day, another post. Today, I thought it would be useful to share some tips and tricks when installing new software on a standalone linux machine / VM.
For cybersecurity researchers that have to adhere to company policy to disconnect research machines from the internet, this post will be useful for your future workflows.
Before I begin the walkthrough, it is important to have 1 internet-connected machine that is of a similar OS Version to the offline machine so as to minimize incompatibilities between systems.
For now, this post will only be going through the steps to install packages offline for Ubuntu and CentOS machines. In the future, I may revist and update this post again if I find more workarounds.
2. Ubuntu
2.1 Editing Apt Source
The first thing you want to do is to edit /etc/apt/sources.list and uncomment the lines that start with deb-src.
Once you are done, your /etc/apt/sources.list should look something like this:
(base) gerald@nexus:~$ cat /etc/apt/sources.list
#deb cdrom:[Ubuntu 22.04.1 LTS _Jammy Jellyfish_ - Release amd64 (20220809.1)]/ jammy main restricted
# See http://help.ubuntu.com/community/UpgradeNotes for how to upgrade to
# newer versions of the distribution.
deb http://sg.archive.ubuntu.com/ubuntu/ jammy main restricted
deb-src http://sg.archive.ubuntu.com/ubuntu/ jammy main restricted
....
2.2 Downloading Main Package with Dependencies
-
Make a new directory to save your packages
user@internet-connected:~$ mkdir $HOME/Downloads/xfer -
Change directory
user@internet-connected:~$ cd $HOME/Downloads/xfer -
Download package with its dependencies
user@internet-connected:~/Downloads/xfer$ apt-get download \ $(apt-cache depends --recurse --no-recommends \ --no-suggests --no-conflicts --no-breaks \ --no-replaces --no-enhances \ $PACKAGE_NAME | grep "^\w")
2.3 Transfer and Install on Offline Machine
Now that you have the main package with its dependencies, use whichever method you prefer to transfer these packages over to the offline machine.
Then, just run the following command to install all packages. Do not that this is an extremely lazy way of doing things and it does not regard the order in which the packages should be installed.
user@standalone:~/Downloads/xfer$ sudo dpkg -i *.deb
If the above command does not install everything the first time due to the wrong order of dependencies being installed, just run it a few more times until you see that there’s no error. It’s abit stupid…I know. But if it works, it works.

2.4 ⭐ BONUS - Extracting Libraries and Binaries
Assuming you just want some libraries from the .deb package, you can make use of dpkg-deb extraction.
# SYSROOT_PATH refers to the directory to extract to.
$ dpkg-deb -x $PACKAGE_NAME.deb $SYSROOT_PATH
Here’s also a one liner to extract all .deb packages in the same directory for the lazy people out there like myself.
$ DEBS=($(ls | grep ".deb")); \
for package in "${DEBS[@]}"; \
do dpkg-deb -x $package $SYSROOT_PATH; \
done
3. CentOS
If your CentOS Version has reached EOL (End of Life), you will need to update the remote yum repository URLs. Otherwise, you can skip the steps in sub section 3.1.
3.1 Editing Yum Source
For CentOS Versions that have reached EOL, you may find all archived packages in the following 2 URLs:
For this example, I used CentOS 8.5.2111 which has already reached EOL.
For the following 3 repository lists, comment out mirrorlist, and edit the baseurl accordingly:
-
Edit /etc/yum.repos.d/CentOS-Linux-AppStream.repo:
... [appstream] name=CentOS Linux $releasever - AppStream #mirrorlist=http://mirrorlist.centos.org/?release=$releasever&arch=$basearch&repo=AppStream&infra=$infra baseurl=http://archive.kernel.org/centos-vault/8.5.2111/AppStream/$basearch/os/ ... -
Edit /etc/yum.repos.d/CentOS-Linux-BaseOS.repo
... [baseos] name=CentOS Linux $releasever - BaseOS #mirrorlist=http://mirrorlist.centos.org/?release=$releasever&arch=$basearch&repo=BaseOS&infra=$infra baseurl=http://archive.kernel.org/centos-vault/8.5.2111/BaseOS/$basearch/os/ ... -
Edit /etc/yum.repos.d/CentOS-Linux-Extras.repo
... [extras] name=CentOS Linux $releasever - Extras #mirrorlist=http://mirrorlist.centos.org/?release=$releasever&arch=$basearch&repo=extras&infra=$infra baseurl=http://archive.kernel.org/centos-vault/8.5.2111/extras/$basearch/os/ ...
Once you are done, do a dnf update / yum update to check that the remote reposiotry is working properly.
3.2 Downloading Main Package with Dependencies
You can use either dnf or yum to download your packages.
3.2.1 Using dnf
- Install dnf-plugins-core (if not already installed)
[user@internet-connected ~]$ sudo dnf install dnf-plugins-core - Download the package together with its dependencies
[user@internet-connected ~]$ dnf download --resolve \ --destdir $HOME/Downloads/xfer \ $PACKAGE_NAME
3.2.2 Using yum
- Install yum-utils (if not already installed)
[user@internet-connected ~]$ sudo yum install yum-utils - Download the package together with its dependencies
[user@internet-connected ~]$ yumdownloader --resolve \ --destdir $HOME/Downloads/xfer \ $PACKAGE_NAME
3.3 Transfer and Install on Offline Machine
You can use either dnf or yum to install your packages.
3.3.1 Using dnf
[user@standalone ~]$ sudo dnf localinstall *.rpm
3.3.2 Using yum
[user@standalone ~]$ sudo yum localinstall *.rpm
3.4 ⭐ BONUS - Extracting Libraries and Binaries
Assuming you just want some libraries from the .rpm package, you can make use of
rpm2cpio and cpio for extraction.
# SYSROOT_PATH refers to the directory to extract to.
[user@localhost ~]$ rpm2cpio $PACKAGE_NAME.rpm \
| (cd $SYSROOT_PATH && cpio -idmv)
Here’s also a one liner to extract all .rpm packages in the same directory for the lazy people out there like myself.
$ RPMS=($(ls | grep ".rpm")); \
for package in "${RPMS[@]}"; \
do rpm2cpio $package \
| (cd $SYSROOT_PATH && cpio -idmv); \
done
4. Conclusion
If you have made it this far, congratulations!

I hope you learnt something useful today and if this works like a charm for you, you are always welcome to come back to reference these set of instructions for your future use. Cheers and have a nice day!