Packagecloud logo

HOWTO: Create debian repositories with reprepro

TL;DR

This blog post will explain the steps needed for creating a Debian APT repository using command line tools.

 

Quick start

The fastest, easiest, and most secure way to create a Debian repository is to sign up at packagecloud.io. You will take advantage of numerous features like SSL and consistent APT repositories without needing to build any of these features yourself.

If you are determined to do it yourself with command line tools, follow the guide below. Note that, unfortuantely, you cannot generate consistent APT repositories with reprepro.

 

Required prerequisite information

It’s important to understand that APT repositories as generated by reprepro are essentially a carefully constructed series of directories. The exact directory path (and thus the URL) that is generated is determined largely by a few important parts: the codename, the component, and the architecture.

For example, if your repository is setup with the codename “trusty”, the component “main”, and the “amd64” architecture, a series of directories will be created with these names for storing your repository metadata.

We’ll see where these are configured shortly.

 

Install necessary tools

Start by installing the command line tool reprepro which will be used to generate the repository metadata:

$ sudo apt-get install reprepro

Create directory structure and config files

First, create a top level directory for your debian repository:

% mkdir repo

Next, create a directory called conf and a file in that directory called distributions:

% mkdir repo/conf
% touch repo/conf/distributions

Open the distributions file with your favorite editor. You’ll need the following configuration:

Origin: repo.example.com
Label: repo.example.com
Codename: trusty
Architectures: i386 amd64 source
Components: main
Description: example repo
SignWith: D69C3E54

What do these reprepro configuration options do? Check the man page (man reprepro) for a detailed explanation. A short description of the minimum options provided above:

  • Origin: This field is copied directly into the generated metadata. This usually an identifier explaining where this repository came from. A URL is a good bet for this field. Folks using APT pinning may attempt to setup their pinning using a combination of this field and others, so choose wisely.
  • Label: This field is copied directly into the generated metadata, as well. Folks using APT pinning may attempt to setup their pinning using a combination of this field and others, so choose wisely.
  • Codename: This field is used to determine the directory structure of where the generated metadata will live. Usually, you’ll want to choose an Ubuntu or Debian codename for this, like: “trusty” or “xenial” or “jessie”. When a user configures a repository for installation on their system, they will need to specify their codename in their configuration. Technically, you can choose any value for this, if you like.
  • Architectures: The architectures to update. Most folks will want at least amd64. source is useful if you plan on having source packages, but is not mandatory.
  • Components: The names of the components that packages can be imported into. You can think of components as a way of segementing packages in a repository. You can use any identifier you want for this. You’ll need to let the user know which component they should use so the user can correctly configure their apt client. In our example, we chose a commonly used component name: main.
  • Description: This field is optional, but useful for end users. This field will copied directly to the generated metadata.
  • SignWith: This field can be either “yes”, “default”, or have the GPG key ID of a GPG key that should be used to sign the repository metadata. If “yes” or “default” are specified, reprepro will use the default GPG key available when signing repository metadata. You can get your GPG key id by running gpg --list-keys.

Using SignWith is one important component of generating a secure APT repository. Please continue reading through the Notes on security section below to understand all of the important requirements for a secure debian repository.

 

Run reprepro to create the repository

Once you have the directories and configuration file setup, you can now import a package to generate the repository.

In this example, we’re going to import a package named jake_1.0-7_amd64.deb to the repository for the trusty distribution:

% reprepro -b repo/ includedeb trusty jake_1.0-7_amd64.deb
Exporting indices...

Done! The repository has been generated. You can now add more packages if needed and start using your repository. Before showing how to use the repository, let’s take a look at some important security notes.

 

Notes on debian repository security

Debian repositories are tricky to operate in a secure manner. There are two major points that should be mentioned here:

  1. If you are distributing your repository over the internet, you must do so via SSL. Debian repositories (even those with GPG signatures) are vulnerable to replay attacks if not served over SSL. In addition, there is a remote code execution vulnerability when verifying GPG signatures over HTTP. Always use SSL when distributing APT repositories over the internet.

  2. GPG signatures are a confusing part of creating and configuring Debian repositories. There are two types of GPG signatures: signatures on the Debian packages themselves and signatures on the repository metadata. Signatures on Debian packages are not used or verified by default on Ubuntu systems. This means that if you sign your package with debsign, users installing your package will not be verifying the signatures. Signatures on the repository metadata, however, are verified automatically by clients. Using the SignWith option described above is the simplest way to generate GPG signatures for your repository metadata.

Read our detailed blog post about how to sign and verify debian packages and APT repositories if you’d like to learn more about GPG and APT.

 

Consistent Debian repositories (fix Hash sum mismatch)

Unfortunately, the APT metadata format is inherently racy. This means that if you run reprepro to regenerate your repository while a user is running apt-get update against your reopsitory, the user can get an error and end up with stale or inconsistent metadata.

This is the primary cause of the confusing Hash sum mismatch error many APT users run into in the wild.

At the time of this writing, the reprepro commandline tool does not support generating APT metadata that allows clients to avoid this issue. The easiest way to avoid this issue is to create a free debian repository on packagecloud.

 

Secure Debian repository access

In order to get access to secure debian repositories distributed over SSL with GPG signed metadata, the end user will need to a few simple tasks:

  1. Run sudo apt-get install apt-transport-https. This will install a helper program that apt-get will use to download repository metadata over SSL.
  2. Import the repository signing key. If you provide the GPG public key for your repository over the internet, the user can run wget -qO - https://your-url-here.com/archive.key | sudo apt-key add - to add the public key to the APT keyring.

 

Accessing the Debian repository

Once the user has installed apt-transport-https and imported the public GPG key, they will need to construct a simple repository configuration file in /etc/apt/sources.list.d/. It is required that this filename ends in .list.

In order to construct the file correctly, the user will need to know the component and codename of the repository to add:

deb https://your-url-here.com/repo CODENAME COMPONENT 
deb-src https://your-url-here.com/repo CODENAME COMPONENT 

The first line of the sample configuration above adds a binary repository. The second line starts with deb-src because it adds the repository so that source packages can be downloaded. If you didn’t add “source” to the Architectures option, clients do not need to specify a deb-src line.

Once the configuration file is setup, the client must run apt-get update and then they can install packages from your repository!

Conclusion

You can use the reprepro command line tool to create and update debian repositories. It’s a useful tool and has a wide range of options explained in the man page. It is only one piece of the software distribution puzzle. Users still need to deal with SSL, backups, access control. Clients can sometimes receive the dreaded “hash sum mismatch” error if the repository is updated on the server while the client is refreshing its metadata cache on the client side.

You might also like other posts...