TL;DR
GPG can be used to create a digital signature for both Debian package files and for APT repository metadata.
Many Debian-based Linux distributions (e.g., Ubuntu) have GPG signature verification of Debian package files (.deb) disabled by default and instead choose to verify GPG signatures of repository metadata and source packages (.dsc). The setting which enables GPG signature checking of the individual .deb packages can be found in /etc/dpkg/dpkg.cfg
and is set to no-debsig
, but there are important caveats to enabling this option explained below.
Further, most official Debian package files from the publicly accessible repositories do not have GPG signatures. The official repository metadata is GPG signed, as are the source packages, but the .deb packages themselves are not.
If you publish a Debian package and GPG sign the package yourself before distributing it to users, those users’ systems will, in most cases, not verify the signature of the package unless they have done a considerable amount of configuration. However, their system will, in most cases, automatically verify repository metadata.
This post explains how Debian package GPG signatures are implemented, how to enable GPG signature checking of packages on your system, and how to GPG sign packages you create.
This post will also explain how APT repository GPG signatures are implemented and how to sign your APT repository metadata.
Debian package GPG signatures
Signing data with a GPG key enables the recipient of the data to verify that no modifications occurred after the data was signed (assuming the recipient has a copy of the sender’s public GPG key).
Debian package files (.deb files), Debian source packages (.dsc files), and Debian changes files (.changes files) can all be signed with GPG.
GPG signing Debian source packages (.dsc files) and changes files
Debian source packages and Debian changes files are text-based files which can be used to rebuild a Debian package from source code. Theses files can be signed with a GPG key by using a program called debsign
.
debsign
will add a GPG signature to .dsc and .changes files themselves. You can use debsign
like this:
This command specifies the GPG key ID to use when signing the Debian source file test_1.0-7.dsc
. The signature is embedded in the file test_1.0-7.dsc
and can be verified by running:
The Debian source package file and changes file both contain SHA1, SHA256, and MD5 checksums of all source files that comprise the source package. Since this data is signed, any modifications to the source file checksums, file size, or other data in the dsc or changes files would cause signature verification to fail.
As long as a recipient who wishes to build the deb package from a dsc file verifies the checksums of each file in the source package and verifies the signature of the source package itself, the recipient knows their build uses precisely the same files that the packager used when building.
apt-get source packagename
will automatically check the GPG signature of the source package file and the checksums of the source files listed in the source package.
GPG signing Debian package files (.deb files)
A Debian package file itself is actually an AR archive that contains at least three entries:
debian-binary
: a file describing the deb format versioncontrol
: an archive containing package metadata such as pre-install or post-install scriptsdata
: an archive containing the actual installable files
The control
and data
archives are typically tar
, tar.gz
, tar.bz2
, tar.xz
, tar.lzma
, or another archive format.
When a Debian package is signed with a GPG key, the signature is also included in the archive and is named based on its type.
Debian package signatures are typically associated with a role. Some commonly used roles include:
origin
: the signature of the organization which distributes the .deb filemaint
: the signature of the package maintainerarchive
: the signature of the archive providing the package to reassure users that the package is the actually provided by the archive
In order to sign a Debian package, you can use the program debsigs
:
In the above example, the Debian file is signed using the GPG key on my system with the ID E732A79A. The signature type is origin
and thus the deb package will be modified to include a file called _gpgorigin
that contains the GPG signature of the debian-binary
file, control
archive, and data
archive from the deb package concatenated together.
I used the type origin because I am person distributing the deb package test_1.0-7_amd64.deb.
Verifying signatures on Debian .deb package files is a bit more involved than the other verification methods.
Verifying GPG signatures of .deb package files
In order to verify .deb package files, you must have the program debsig-verify
installed, import the public GPG keys you will use to verify packages to the debsig-verify
keyrings, and you must also create an XML policy document for signature verification.
First, create a keyring directory for the public key and import the public key to the debsig-verify
GPG keyring:
In the above example, the keyring subdirectory, DDDF2F4CE732A79A, is the fingerprint of the GPG key which will be imported. Note that the name of the keyring debsig.gpg
will be used in the XML policy document created next. You can use any filename you like.
Now that the public key is imported, the XML policy document can be constructed.
First, create a directory for the policy document. It must have the GPG key fingerprint in the path:
Next create the XML document. The debsig-verify
man page indicates that the filename is irrelevant so long as the filename ends with .pol
and resides in a directory named after the GPG key fingerpint.
You can find more information regarding how the build the policy document in /usr/share/doc/debsig-verify/policy-syntax.txt
and some examples in /usr/share/doc/debsig-verify/examples
.
Here’s an example XML policy document:
Once this document is constructed, you can verify the GPG signature of the Debian .deb package:
dpkg
support for debsig-verify
dpkg has support for verifying GPG signatures of Debian package files, but this verification is disabled by default. This means that when a package is installed on a Debian-based system, the signature checking for individual packages is disabled.
In order to enable it, the file /etc/dpkg/dpkg.cfg
will need to be modified to remove the no-debsig
option from the config file.
CAUTION: Doing this may cause dpkg to reject installation of unsigned Debian files. If you plan to enable this, it is strongly recommended you try this first in a testing environment. You’ll also need to ensure you have the correct XML policy files created, as explained above.
Another Debian package signing tool: dpkg-sig
There is a another tool available for signing and verifying Debian package files called dpkg-sig
. Signatures created by this tool are not compatible with debsigs and the tools cannot understand or verify each other signatures.
dpkg-sig
generates a Debian control file with several userful fields:
- Version of dpkg-sig which generated the signature
- Gpg key signer information
- Role
- Files section with checksums, file sizes, and filenames of the control, data, and debian-binary files in the Debian package
This file is named based on the role selected, which is defaulted to builder if none is specified. So, signing a Debian package file with no role would result in a file named _gpgbuilder
being created and added to the package file. This file is signed with GPG and the signature is embedded as plain text (a “clearsign” GPG signature).
The result of this scheme is that the GPG signature can be verified using commonly available software. The Debian package can be extracted with ar
and the signature of the control file can be checked with just gpg --verify
.
Signing a Debian file with dpkg-sig
is straight forward:
The signature can also be checked by using dpkg-sig
directly, if desired:
Additionally, no XML policy document is required for signature verification, which makes signature verification much simpler to integrate into a workflow.
dpkg
support for dpkg-sig
Unfortunately, dpkg
does not have built-in support for dpkg-sig
, but the discussion appears to have been moved to a bug ticket with Debian (last updated in 2012): https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=340306.
GPG signatures for APT repository metadata
It is also possible to generate GPG signatures for APT repositories in addition to generating signatures for Debian packages themselves.
Generating signatures of the repository metadata allows you to verify that the repository metadata has not been tampered with since it was generated by the repository host.
This is critical to preventing a Man-in-the-Middle attack attack where a malicious actor plants repository metadata causing a user’s package manager to install potentially malicious packages.
Luckily, generating GPG sigantures for APT repositories is straightforward with reprepro
.
Assuming you have a GPG key you’d like to use to sign the repository metadata, you can simply modify your reprepro
repository config to add your GPG key.
Using the same GPG key ID used in the earlier examples, the conf/distributions
config file can be modified to add the field:
SignWith: E732A79A
This will cause reprepro
to generate GPG signatures of the repository metadata. reprepro
will generate a signature of the apt Release
file and store the signature in the file Release.gpg
. This is called a “detached GPG signature.”
Newer version of reprepro
will generate an embedded text GPG signature (a “clearsign” GPG signature) in a file named InRelease
.
The apt
client will download the GPG Release file(s) it understands and will automatically attempt to verify the GPG signature of the repository.
Users of the repository will need to have the GPG key installed on the system. This can be done by end users running the command: apt-key
:
The above command downloads a GPG key and adds the GPG key to the system using apt-key
.
Conclusion
GPG signing of Debian package files, source packages, and repository metadata is critical to establishing the authenticity of the package objects and repository metadata.
Knowing that a package being installed on your system is the same package that was generated by a vendor, and that you were able to retrieve that package from the repository generated by the vendor is the only way to ensure that you are safely installing software in your infrastructure.
Unfortunately, signing and checking the signatures of Debian packages is not as streamlined and integrated as it could be, so vendors currently signing their Debian package files may be surprised to learn that the majority of their customers are not automatically checking the GPG signature of their packages. At the very least, vendors should be signing their repository metadata. Also signing their Debian package files and providing instructions for how users can verify those signatures would be a great way to help improve their end user’s security.
packagecloud.io signs repository metadata it generates using a GPG key so that users of our repositories know, without a doubt, that the repository metadata their package manager downloaded was generated by packagecloud.io.