Setting up a personal secure apt repository

Posted by wijnen on Sun 24 May 2015 at 09:58

Packages under development aren't always ready to be in the main Debian archive. But that doesn't mean it should be hard for people to install them. When asking people to test programs, it is most convenient to present it in the way they are expecting: as a package. For this, a personal repository is useful. The tools for doing this are available in Debian, but the method is not well documented. This article attempts to do that.

Note that this article describes my setup only. In several cases, this is not the only good way to do it. But if you don't want to spend much time finding out what works, copying this setup may be a good idea. The host this is on is wijnen.dtdns.net. My username there is shevek. Replace those values with your own in the examples below.

Requirements

The packages must be as easy to install as official packages. That means adding a single line to /etc/apt/sources.list and nothing more. For this, the mini-dinstall package can be used. However, a signing key needs to be set up to avoid warnings about untrusted packages. Both these things are discussed below.

Apache

All this must run on a computer with a web server. I have Apache installed on my computer. My computer is behind a masquerading router (also called NAT). I have set up the router to forward http packets to my computer. How to do that depends on your router, and is outside the scope of this article.

All the files (except the private key) are stored in my home, under public_html/archive/. That way, everyone can read the source in http://wijnen.dtdns.net/~shevek/archive/, which is nice.

In /var/www/html/, I have added a symbolic link to /home/shevek/public_html/archive/, which makes the repository available in http://wijnen.dtdns.net/archive/.

Mini-dinstall

I'm running mini-dinstall from /home/shevek/public_html/archive as

mini-dinstall --config config --batch

The config file that is referenced there is /home/shevek/public_html/archive/config and it contains:

[DEFAULT] archivedir=/home/shevek/public_html/archive archive_style=simple-subdir architectures=all, amd64 generate_release=1 mail_on_success=0 release_signscript=/home/shevek/public_html/archive/sign [stable] release_codename=wheezy [unstable] release_codename=sid

Then sometimes files are referenced by suite (unstable) and sometimes by codename (sid). Therefore, both names must exist and be a directory. More specifically, both must be the same directory. So make directories and link them:

$ mkdir sid $ mkdir wheezy $ ln -s sid unstable $ ln -s wheezy stable

Using the codename as the real directory and the suite as the link makes it more clear what happens on release: the stable link is moved from wheezy to jessie (which I don't build for), while the packages in wheezy and jessie don't change.

An incoming directory is also required by mini-dinstall. That's where packages must be dropped to get them installed into the archive:

$ mkdir -p mini-dinstall/incoming

That's all for mini-dinstall. However, because it is set up to sign the release files, it doesn't work until that is set up as well.

Secure APT

To use signed repositories, I need a key to sign with. I want this to be without hassle, so without entering a passphrase. So I need to create a new key:

$ gpg --gen-key

I created type 4, which is sign only, used archive@wijnen.dtdns.net as e-mail (which I set up to redirect to myself) and I did not give it a passphrase. Now I need to use it for signing release files. For this, the config file specifies that a script called sign is used. It contains:

#!/bin/sh rm -f Release.gpg gpg --output Release.gpg --local-user archive@wijnen.dtdns.net --detach-sign "$1"

Now I need people testing my packages to get this key into their apt trusted keyring. The best way to do this, is by making it a package. Such packages are normally called *-archive-keyring, so I'll do that as well. I create the package directory in the archive directory. This means that the entire contents are public. That is not a problem, because only the public key will be in the package; the private key remains safely in my private keyring (in ~/.gnupg/secring.gpg).

$ mkdir wijnen-archive-keyring $ cd wijnen-archive-keyring $ gpg --export archive@wijnen.dtdns.net > wijnen-archive-keyring.gpg

Then I create a debian/ directory which installs this key in /etc/apt/trusted.gpg.d/. I shall not explain here how that is done, but feel free to read the package source.

Package building

After building a package, to get it into the archive, its changes file and everything referenced from it must be copied to the incoming directory. Then mini-dinstall must be run with the arguments described above. I have a script which does all that, which is described and linked here. Please read the security considerations before using it.

User instructions

With all this set up, the instructions for my users are:

Add ''deb http://wijnen.dtdns.net/archive sid/all/'' (and/or similar) to sources.list. apt-get update. apt-get --allow-unauthenticated install wijnen-archive-keyring apt-get install package-to-test Test the program and tell me about it.

Obviously, wijnen-archive-keyring only needs to be installed once, and they will automatically pull in updates when I publish them. My method of automatically publishing a package on every test build is perhaps not the best in that respect; it might be good to use a separate script for running mini-dinstall. Its man page describes such a method.