Ubuntu: Customizing and repacking a deb file

ubuntuAlthough there are utilities such as dpkg-deb for managing .deb packages, they can also be manipulated by the standard set of archival utilities: tar, ar, and gzip.

This article will lead you through extracting the contents of a .deb file, making modifications to the installation scripts and default configuration files, then repackaging.

Overview

I think the legitimate use cases for unpackaging a .deb and repacking are few and far between.  An operator is more likely to put in hooks before the install or after the install using a configuration management tool, or to fork the source and repackage.  It is administratively difficult to maintain a set of modified .deb taken from upstream sources.

But…for anyone who does have a need to pre-configure app settings or control scripts of a .deb package before deploying out to a set of host, here is how that could be accomplished.

We will use the ntp client package as our test subject in this article.  It deploys a configuration file at “/etc/ntp.conf” that contains the time servers it should be using to synchronize the host.  By default these servers point to ubuntu.pool.ntp.org, but we will modify this .deb so that it by default points at time.google.com.  We will also hook into the pre-installation script to run our own command.

Download

The first step is to get the ntp client .deb file.   This can be done by either using apt or downloading it manually.   The easiest way is to have apt-get download it, then retrieve it from the apt cache.

$ sudo apt-get download ntp
$ ls -l /var/cache/apt/archives/ntp*.deb

Of course, this will grab the .deb appropriate for the architecture and version of the host – which may not necessarily be the same as your target machines.  So if you need to modify a specific .deb you can also manually download it.  The ntp client package for the Ubuntu repository can be found at this URL.  This has versions for trusty, xenial, etc. and their architectural flavors.

Extract

Once you have the .deb, then you can start the extraction process.  We will copy the .deb file into an separate directory to do this work.

$ mkdir /tmp/repkg; cd $_
$ cp /var/cache/apt/archives/ntp*.deb .

Now extract the .deb, you can see that I am using the Ubuntu trusty x64 bit package for this example.

$ ar xf ntp_1%3a4.2.6.p5+dfsg-3ubuntu2.14.04.13_amd64.deb
$ ls -l

control.tar.gz
debian-binary
data.tar.xz

You will see control and data archives along with a debian-binary text file which indicates the compatibility version of deb being used.  Extract the control and data archives.

$ mkdir DEBIAN; tar xfz control.tar.gz -C DEBIAN
$ ls DEBIAN
conffiles  control  md5sums  postinst  postrm  preinst  prerm

# for deb that contain xz archive
$ tar xf data.tar.xz
# for deb that contain gzip archive
$ tar xfz data.tar.gz

We unzipped the control files into a ‘DEBIAN’ subdirectory similar to dpkg-deb simply because it makes it clearer what files came from control package and which came from the data package.

As described in the documentation, the data archive can be in the xz or zip format.  For this ntp package, we had “data.tar.xz”, but this can also be “data.tar.gz”, extract accordingly.

Modify

Modifying package settings

First let’s modify the default time server used by the package, located at “etc/ntp.conf”.   Instead of the set of Ubuntu time servers:

server 0.ubuntu.pool.ntp.org
server 1.ubuntu.pool.ntp.org
server 2.ubuntu.pool.ntp.org
server 3.ubuntu.pool.ntp.org

Replace those lines with the Google time server:

server time.google.com

Modifying control files

We can also hook into the control process with pre and post installation scripts.  For example, let’s modify the pre-installation script so that it writes a line of output to “/tmp/myntp.log”.

Append the following text to the end of the “DEBIAN/preinst” file.

echo "ran preinst of ntp client at $(date)." >> /tmp/myntp.log

Recalculate MD5 sums

The control package has an md5sums file that has contains the md5 calculation of files within the package.  This sum is not enforced during installation.  Rather, it is used to determine if an already existing local file is different from what is found in the package for “dpkg -verify“.

For our example with ntp, the /etc/ntp.conf file is not included in the md5sums file, so there is no need to make any changes.  But if it was, then you should run the md5 calculation on that specific file and copy that new result into “DEBIAN/md5sums”.

md5sum /etc/ntp.conf

Repackage control files

With the modifications complete, repackage the control files.

tar -C DEBIAN -cvf control.tar . && gzip -f control.tar

Repackage data files

If you started with a .xz data file, you should first check what directories you need to archive, then use that list when repacking.

# determine which directories are contained
tar tf data.tar.xz

# make sure to use 'J' for .xz or you get lzma errors
tar cJf data.tar.xz etc usr var

If you started with a .gz data file, you should first check what directories you need to archive, then use that list when repacking.

tar tf data.tar.gz
tar cfz data.tar.gz etc usr var

Repackage .deb

The final step is to repackage the .deb in its entirety.

ar rcs ntp_1%3a4.2.6.p5+dfsg-3ubuntu2.14.04.13_amd64.deb debian-binary control.tar.gz data.tar.xz

It is important that you list debian-binary as the first file, this is how it is expected and you can get errors during the apt-get installation if you do not follow this order.

If you are packaging a data.tar.gz file, then list that as the last parameter instead of data.tar.xz.  Either .xz or .gz formats are valid for .deb packages.

Testing

Unless you have a local or remote repository ready to host this new .deb package, the easiest way to test this new package is to first use “apt-get install” to install the package from its original repository.  This will install all the dependencies (which is not done when using dpkg).

sudo apt-get install ntp

Then run “dkpg -i” to install your custom .deb on top of it.

sudo dpkg -i ntp_1%3a4.2.6.p5+dfsg-3ubuntu2.14.04.13_amd64.deb

Verify that “/etc/ntp.conf” is pointing to Google time servers.

grep "time.google" /etc/ntp.conf

And that our pre-installation scripts created a debug line in “/tmp/myntp.log”

cat /tmp/myntp.log

 

REFERENCES

https://debian-handbook.info/browse/stable/packaging-system.html (description of deb contents)

https://blog.packagecloud.io/eng/2015/10/13/inspect-extract-contents-debian-packages/

https://ubuntuforums.org/archive/index.php/t-1481153.html

https://www.ostechnix.com/download-packages-dependencies-locally-ubuntu/ (shows how to download dependencies)

https://www.addictivetips.com/ubuntu-linux-tips/install-a-debian-package-on-any-linux-distribution/ (cat control to see dependencies)

https://coderwall.com/p/hes3ha/change-the-dependencies-of-a-deb-package

https://askubuntu.com/questions/462946/how-to-modify-the-details-of-a-debian-package

https://www.linuxquestions.org/questions/linux-software-2/xz-compression-with-tar-726007/ (xzutils)

https://askubuntu.com/questions/40779/how-do-i-install-a-deb-file-via-the-command-line (various commands for dpkg)

https://blog.heckel.xyz/2015/10/18/how-to-create-debian-package-and-debian-repository/ (creating an Ubuntu repo, packages.gz contains list)

https://ubuntuforums.org/showthread.php?t=910717 (make a basic helloworld .deb)

https://packages.ubuntu.com/search?keywords=ntp (download for ntp deb from ubuntu)

https://unix.stackexchange.com/questions/251466/significance-of-md5sum-file-in-debian-package-source (md5 sums explanation)

https://debian-handbook.info/browse/stable/sect.package-meta-information.html#sect.conffiles (checksum and dpkg –verify)

NOTES

dpkg-deb commands

dpkg-deb -c my.deb (show data)

dpkg –control my.deb (extract control to ‘DEBIAN’ directory)

dpkg –fsys-tarfile my.deb > data.tar.gz

List only first level directory of archive

tar tf data.tar.xz –exclude=”*/*/*”

tar tfz data.tar.gzip –exclude=”*/*/*”

tar tfz data.tar.gzip –exclude=”*/*”

List package dependencies

cat DEBIAN/control | grep -i ^depends

Depends: adduser, lsb-base (>= 3.2-13), netbase, libc6 (>= 2.17), libcap2 (>= 2.10), libedit2 (>= 2.11-20080614), libopts25 (>= 1:5.18), libssl1.0.0 (>= 1.0.1d)

Alternate syntax for creating control.tar.gz

tar c postinst control prerm md5sums preinst conffiles | gzip -c > control.tar.gz