TL;DR
Following up on our previous post about yum repository internals, this blog post will dive into the internals of APT repositories. Similarly, we’ll cover what each index file does and take a look at how a user can inspect and verify the metadata themselves.
What is an APT repository?
An APT repository is a collection of deb packages with metadata that is readable by the apt-*
family of tools, namely, apt-get
. Having an APT repository allows you to perform package install, removal, upgrade, and other operations on individual packages or groups of packages.
APT repositories are essential for storing, managing, and delivering software to Debian and Ubuntu systems.
Create an APT repository with reprepro
Generate GPG key for signing an APT repository
(Feel free to skip this section if you already have a GPG key you wish to use)
We’ll start by creating a GPG key to sign our repository metadata for a fuller, more illustrative example:
Since this is a throwaway blog example, we’ll just pick all the defaults without a passphrase.
NOTE: You’ll definitely want a passphrase for production deployments and ask-passphrase
in your apt/debian/conf/options
below.
Now when we gpg --list-keys
, we should see:
Installation of reprepro
Before taking a closer look at the repository metadata itself, let’s show how to get a repository set up by using the open source reprepro command line tool.
You can create an APT repository by using the command line tool reprepro
which you can install on Ubuntu and Debian systems by running:
Once installed, let’s create a directory for our APT repository and reprepro configuration.
Configuring reprepro
Let’s create the directory structure necessary for reprepro
and it’s configuration.
In the conf
directory, create a file named distributions
, here we will list all the distributions and architectures our repository will support. For this example, we’ll only support one distribution, debian squeeze:
The value of SignWith
being the subkey ID from the GPG key we wish to use (the one we generated above, in this case)
This defines a my_test_repo
for debian squeeze.
Now let’s download an example package to add to this repository:
Generate APT repository with reprepro
To add that package to this repository, we’lll call reprepro
with the desired distribution and path to debian package, from inside my_test_repo/apt/debian
directory, like so:
This will create and sign all the necessary repository metadata APT needs to install and verify this repository on another computer.
Hosting GPG key and APT repository over HTTP
Once the package has been added and repository indices have been generated, we’ll need to serve them up over HTTP so that APT can read it.
First, let’s export our GPG key and host it along with our repository, that way anyone installing this repository can also import our GPG public key.
Then, let’s serve up our repository using python’s built in HTTP server.
Navigate to my_test_repo
and run:
(Do this in a screen session if you’d like use the same terminal session for the rest of the tutorial)
Installing Package from APT repository
Finally, we can install a package from our configured and hosted repository!
Create an /etc/apt/sources.list.d/my_test_repo.list
on the computer you wish you install our package on and add the following line, substituted with the IP of the computer hosting the repository:
Let’s also import our GPG key into APT:
Now we can run apt-get update
to fetch the repository metadata and install our package:
On the server, you should see requests coming in for various repository metadata as APT tries install this package:
On the client, you can verify it successfully installed our package, by running:
Of course, using packagecloud is a much faster and simpler solution :) with SSL, GPG, authentication, collaboration, and everything else you need ready to go!
APT repository metadata
Now that we have verified our APT repository works by installing our package on another computer, let’s dive into the mechanics of how an APT repository works.
Let’s take a look at our reprepro
generated directory structure from the root of my_test_repo/apt/debian
and what each file does:
./dists/squeeze/Contents-<arch>.gz
: A gzipped index containing a directory listing of all packages for this architecture, across all components../dists/squeeze/Release
: The primary index which contains the locations and checksums of the architecture-specific Packages files../dists/squeeze/Release.gpg
: IfSignWith
was provided,reprepro
will generate a detached signature for the above Release index../dists/squeeze/InRelease
: Also only generated ifSignWith
was provided, it’s a version of Release with a clearsign signature, used by newer versions of APT../dists/squeeze/main/binary-<arch>/Packages
: Lists metadata about each package available for a given architecture<arch>
../dists/squeeze/main/Contents-<arch>.gz
: A gzipped index containing a directory listing of all packages for this architecture<arch>
, for themain
component../pool/main/*
: Directory where the actual package files reside.
Debugging
The examples below will show how you can view the index yourself to verify it contains what you expect.
GPG Verification of signed APT repository metadata
APT automatically verifies GPG signed metadata if it knows the public key (which we imported above), but we can also verify manually to be extra sure.
Let’s import the public key into our GPG keyring instead of APT’s:
Download the Release
file and its signature:
Verify it with GPG:
For more information on GPG signatures and APT packages, check out our post on gpg sign and verify deb packages.
Inspecting Release
metadata for APT repository
Let’s get the Release
for ubuntu precise for the packagecloud test packages repository:
It will return a huge list of all the architectures and their relevant Packages
files and checksums, so for binary-amd64
, for our example we have:
Inspecting Packages
metadata for APT repository
Let’s get the Packages
for ubuntu precise and binary-amd64
for the packagecloud test packages repository:
We can also verify the checksum (SHA256 in this case) for this Packages
file contained in Release
above:
This should return the expected checksum, which is:
Once the checksum is verified, we can look at the actual metadata, which looks like:
Inspecting Contents
metadata for APT repository
Lastly, let’s check out the Contents
file for the packagecloud test packages repository and amd64
:
This will list out all the files associated with each package:
Conclusion
APT repository metadata is comprised of a set of index files, checksums, and in some cases a GPG signature. The metadata describes which packages can be found in a repository, various attributes about each package, file and directory listings.
APT repository metadata can be manually examined and verified on the command line using a combination of curl
, less
/zless
, gpg
, and shasum
. This is useful if you need to debug some sort of issue with your repository (missing package, missing dependency, incorrect version, etc) or are curious about the inner workings of one of the most important pieces to your operating system.