This article is a DRAFT, offered for preview only.
No claim is made as to the veracity, suitability,
or correctness of material contained herein.

Package Repositories

Aug 15 2016

This is the rest of the post

Docker Images

In support of this effort, I built a set of Docker images for Debian/Ubuntu platforms (debuild/*) and for RedHat / CentOS (rpmbuild/*) that provide environments with all the baseline tools and configuration for building native packages.

Running an APT Repository

Reprepro (formerly mirrorer), is a utility for managing all the little metadata files that make a Debian/Ubuntu APT repository go.

Setting up a GPG Key

GPG Agent

Signing RPM Packages

You will need to define some GPG-related RPM macros on whatever box you are going to use for package signing. Here's a copy of my ~/.rpmmacros file:

%_signature gpg
%_gpg_name  <<NAME OF GPG KEY>>
%__gpg_check_password_cmd /bin/true
%__gpg_sign_cmd %{__gpg} \
    gpg --batch --no-verbose --no-armor --use-agent --force-v3-sigs \
        %{?_gpg_digest_algo: --digest-algo=%{_gpg_digest_algo}} \
        -u "%{_gpg_name}" \
        -sbo %{__signature_filename} \
        %{__plaintext_filename}

The %__gpg_sign_cmd macro is a tweaked version of the default value, with a few additions. --use-agent tells GPG to contact our running gpg-agent instance, and --force-v3-sigs (unsurprisingly) forces V3 signatures of the signed RPM packages. Newer versions of RPM (4.7+, as near as I can tell) default to signing with V4 signatures, but prior versions of RPM cannot verify those signatures. This isn't a huge deal if you aren't building packages for CentOS 5 or older, but I've found no harm in running V3 signatures on later versions of RPM.

Signing RPM packages is fairly straightforward, if undocumented. If you've set up gpg-agent, and export the $GPGKEY environment variable, then this should work:

$ export GPGKEY=decafbad
$ rpm --addsign /path/to/package.rpm

You can verify packages as well:

$ rpm -K /path/to/package.rpm

This will fail if you don't have the public component of the GPG signing key imported into your RPM database, which you can do via rpm --import key.file

Interestingly, every time you import a GPG key into the RPM database, a new artificial package is created and installed. This makes it easy to see what public keys are installed in an RPM database:

$ rpm -q gpg-pubkey-\*

To see the details of a GPG key, including the ASCII-armored public key itself:

$ rpm -qi gpg-pubkey-c105b9de-4e0fd3a3
Name        : gpg-pubkey                   Relocations: (not relocatable)
Version     : c105b9de                          Vendor: (none)
Release     : 4e0fd3a3                      Build Date: Mon 08 Aug 2016 12:21:25 AM UTC
Install Date: Mon 08 Aug 2016 12:21:25 AM UTC      Build Host: localhost
Group       : Public Keys                   Source RPM: (none)
Size        : 0                                License: pubkey
Signature   : (none)
Summary     : gpg(CentOS-6 Key (CentOS 6 Official Signing Key) <centos-6-key@centos.org>)
Description :
-----BEGIN PGP PUBLIC KEY BLOCK-----
Version: rpm-4.8.0 (NSS-3)

mQINBE4P06MBEACqn48FZgYkG2QrtUAVDV58H6LpDYEcTcv4CIFSkgs6dJ9TavCW
NyPBZRpM2R+Rg5eVqlborp7TmktBP/sSsxc8eJ+3P2aQWSWc5ol74Y0OznJUCrBr
bIdypJllsD9Fe+h7gLBXTh3vdBEWr2lR+xA+Oou8UlO2gFbVFQqMafUgU1s0vqaE
/hHH0TzwD0/tJ6eqIbHwVR/Bu6kHFK4PwePovhfvyYD9Y+C0vOYd5Ict2vbLHz1f
QBDZObv4M6KN3j7nzme47hKtdMd+LwFqxM5cXfM6b5doDulWPmuGV78VoX6OR7el
x1tlfpuiFeuXYnImm5nTawArcQ1UkXUSYcTUKShJebRDLR3BycxR39Q9jtbOQ29R
FumHginovEhdUcinRr22eRXgcmzpR00zFIWoFCwHh/OCtG14nFhefuZ8Z80qbVhW
2J9+/O4tksv9HtQBmQNOK5S8C4HNF2M8AfOWNTr8esFSDc0YA5/cxzdfOOtWam/w
lBpNcUUSSgddRsBwijPuWhVA3NmA/uQlJtAo4Ji5vo8cj5MTPG3+U+rfNqRxu1Yc
ioXRo4LzggPscaTZX6V24n0fzw0J2k7TT4sX007k+7YXwEMqmHpcMYbDNzdCzUer
Zilh5hihJwvGfdi234W3GofttoO+jaAZjic7a3p6cO1ICMgfVqrbZCUQVQARAQAB
tEZDZW50T1MtNiBLZXkgKENlbnRPUyA2IE9mZmljaWFsIFNpZ25pbmcgS2V5KSA8
Y2VudG9zLTYta2V5QGNlbnRvcy5vcmc+iQI8BBMBAgAmBQJOD9OjAhsDBQkSzAMA
BgsJCAcDAgQVAggDBBYCAwECHgECF4AACgkQCUb8osEFud6ajRAAnb6d+w6Y/v/d
MSy7UEy4rNquArix8xhqBwwjoGXpa37OqTvvcJrftZ1XgtzmTbkqXc+9EFch0C+w
ST10f+H0SPTUGuPwqLkg27snUkDAv1B8laub+l2L9erzCaRriH8MnFyxt5v1rqWA
mVlRymzgXK+EQDr+XOgMm1CvxVY3OwdjdoHNox4TdVQWlZl83xdLXBxkd5IRciNm
sg5fJAzAMeg8YsoDee3m4khg9gEm+/Rj5io8Gfk0nhQpgGGeS1HEXl5jzTb44zQW
qudkfcLEdUMOECbu7IC5Z1wrcj559qcp9C94IwQQO+LxLwg4kHffvZjCaOXDRiya
h8KGsEDuiqwjU9HgGq9fa0Ceo3OyUazUi+WnOxBLVIQ8cUZJJ2Ia5PDnEsz59kCp
JmBZaYPxUEteMtG3yDTa8c8jUnJtMPpkwpSkeMBeNr/rEH4YcBoxuFjppHzQpJ7G
hZRbOfY8w97TgJbfDElwTX0/xX9ypsmBezgGoOvOkzP9iCy9YUBc9q/SNnflRWPO
sMVrjec0vc6ffthu2xBdigBXhL7x2bphWzTXf2T067k+JOdoh5EGney6LhQzcp8m
YCTENStCR+L/5XwrvNgRBnoXe4e0ZHet1CcCuBCBvSmsPHp5ml21ahsephnHx+rl
JNGtzulnNP07RyfzQcpCNFH7W4lXzqM=
=jrWY
-----END PGP PUBLIC KEY BLOCK-----

You can unsign a package via rpm --delsign <package.rpm>

You can see what keys a package was signed with using RPM's handy --qf flag:

$ rpm --qf '%{NAME}-%{VERSION}-%{RELEASE} %{SIGPGP:pgpsig} %{SIGGPG:pgpsig}\n' \
      -qp bolo-0.2.18-1.nifty1.x86_64.rpm
bolo-0.2.18-1.nifty1 RSA/SHA1, Sun 14 Aug 2016 05:01:32 PM UTC, Key ID 288e7c067b576eff (none)

Signing DEB Packages

I had to patch dpkg-sig to work with newer versions of debuild, which were popping out DEB package archives containing *.tar.xz files. Here's the patch (via bug #1156988) that I started with:

diff -ur dpkg-sig-0.13.1+nmu1/dpkg-sig dpkg-sig-0.13.1+nmu1.new/dpkg-sig
--- dpkg-sig-0.13.1+nmu1/dpkg-sig 2013-10-25 11:04:33.000000000 -0700
+++ dpkg-sig-0.13.1+nmu1.new/dpkg-sig 2014-07-16 13:03:15.103728779 -0700
@@ -634,7 +634,7 @@
  }

  return "FORCE_BAD" unless ($seen_files{"control.tar.gz"} &&
-                      $seen_files{"data.tar.gz"} &&
+                      ($seen_files{"data.tar.gz"} || $seen_files{"data.tar.xz"}) &&
                       $seen_files{"debian-binary"});

  return "GOOD";

I then had to add / to the end of each file name in the hash lookup. YMMV.

DEB packages are just ar archives, so you can use the ar utility to muck about with their internals.

List all the members:

$ ar t bolo_0.2.18-1.nifty1_amd64.deb
debian-binary
control.tar.gz
data.tar.gz
_gpgbuilder

Removing the _gpg* archive members essentially unsigns the DEB package file (which can be handy if you screw up the dpkg-sig call / script):

$ ar d bolo_0.2.18-1.nifty1_amd64.deb _gpgbuilder
$ ar t bolo_0.2.18-1.nifty1_amd64.deb
debian-binary
control.tar.gz
data.tar.gz
James Hunt (the avatar)

James works on the Internet, spends his weekends developing new and interesting bits of software and his nights trying to make sense of research papers.

Currently exploring just how much data you can shove though DuckDB before it explodes.