How to audit a Debian package
Debian packages do not have to be inherently less safe than standalone scripts, in fact the opposite can be the case. A package has a very clear structure and is easy to navigate. For packages that contain no compiled tools, everything is plain in the open to read - such is the case of the free-pmx-no-subscription auto-configuration tool package, which we take for an example:
In the package
The content of a Debian package can be explored easily:
mkdir CONTENTS
ar x free-pmx-no-subscription_0.1.0.deb --output CONTENTS
tree CONTENTS
CONTENTS
├── control.tar.xz
├── data.tar.xz
└── debian-binary
We can see we got hold of an archive that contains two archives. We will unpack them further yet.
Note
The debian-binary
is actually a text file that contains nothing more than 2.0
within.
cd CONTENTS
mkdir CONTROL DATA
tar -xf control.tar.xz -C CONTROL
tar -xf data.tar.xz -C DATA
tree
.
├── CONTROL
│ ├── conffiles
│ ├── control
│ ├── postinst
│ └── triggers
├── control.tar.xz
├── DATA
│ ├── bin
│ │ ├── free-pmx-no-nag
│ │ └── free-pmx-no-subscription
│ ├── etc
│ │ └── free-pmx
│ │ └── no-subscription.conf
│ └── usr
│ ├── lib
│ │ └── free-pmx
│ │ ├── no-nag-patch
│ │ ├── repo-key-check
│ │ └── repo-list-replace
│ └── share
│ ├── doc
│ │ └── free-pmx-no-subscription
│ │ ├── changelog.gz
│ │ └── copyright
│ └── man
│ └── man1
│ ├── free-pmx-no-nag.1.gz
│ └── free-pmx-no-subscription.1.gz
├── data.tar.xz
└── debian-binary
DATA - the filesystem
The unpacked DATA
directory contains the filesystem structure as will be installed onto the target system, i.e. relative to its root:
/bin
- executables available to the user from command-line/etc
- a config file/usr/lib/free-pmx
- internal tooling not exposed to the user/usr/share/doc
- mandatory information for any Debian package/usr/share/man
- manual pages
You can (and should) explore each and every file with whichever favourite tool of yours, e.g.:
less usr/share/doc/free-pmx-no-subscription/copyright
A manual page can be directly displayed with:
man usr/share/man/man1/free-pmx-no-subscription.1.gz
And if you suspect shenanings with the changelog, it really is just that:
zcat usr/share/doc/free-pmx-no-subscription/changelog.gz
free-pmx-no-subscription (0.1.0) stable; urgency=medium
* Initial release.
- free-pmx-no-subscription (PVE & PBS support)
- free-pmx-no-nag
-- free-pmx <179050296@users.noreply.github.com> Wed, 26 Mar 2025 20:00:00 +0000
Tip
You can see the same after the package gets installed with apt changelog free-pmx-no-subscription
CONTROL - the metadata
Particularly enlightening are the files unpacked into the CONTROL
directory, however - they are all regular text files:
Tip
Installed packages can be queried for this information with: apt show free-pmx-no-subscription
conffiles
lists paths to our single configuration file which is then NOT removed by the system upon regular uninstall;postinst
is a package configuration script which will be invoked after installation and when triggered, it is the most important one to audit before installing when given a package from unknown sources;triggers
lists all the files that will be triggering the post-installation script.
interest-noawait /etc/apt/sources.list.d/pve-enterprise.list
interest-noawait /etc/apt/sources.list.d/pbs-enterprise.list
interest-noawait /usr/share/javascript/proxmox-widget-toolkit/proxmoxlib.js
Course of audit
It would be prudent to check all executable files in the package, starting from those triggered by the installation itself - which in this case are also regularly available user commands. Particularly of interest are any potentially unsafe operations or files being written to that influence core system functions. Check for system command calls and for dubious payload written into unusual locations. A package structure should be easy to navigate, commands self-explanatory, crucial values configurable or assigned to variables exposed at the top of each script.
Tip
User commands
free-pmx-no-subscription
There are two internal sub-commands that are called to perform the actual list replacement (repo-list-replace
) and to ensure that Proxmox release keys are trusted on the system (repo-key-check
). You are at will to explore each on your own.
free-pmx-no-nag
The actual patch of the “No valid subscription” notice is the search’n’replace method which will at worst fail gracefully, i.e. NOT disrupt the UI - this is the only other internal script it calls (no-nag-patch
).
And more
For this particular package, you can also explore its GitHub repository, but always keep in mind that what has been packaged by someone else might contain something other than they had shared in their sources. Therefore auditing the actual .deb
file is crucial unless you are going to build from sources.
Excuse limited formatting, absent referencing and missing media content.
Your feedback is welcome in comments therein.