Simple Guide To Signing RPMs with FPM



I’ve been using the excellent fpm (Effing package manager!) tool for automatically generating rpms from source (for example, creating a custom compiled php-fpm binary and then wrapping it for install in an rpm for distribution from our own repository). FPM also creates .debs and other binaries as you need them.

To ensure we have a secure infrastructure we wanted to make sure that the rpms are correctly signed so that the gpg check can be completed on them when installed.

First, generate the gpg public/private key pair:

1
gpg --gen-key

Fill out the required information. The entropy generation step may take a long time to complete.

Export a text version of the public key with this command, for later use in your repository:

1
gpg --export -a 'Dave Drager' > ~/RPM-GPG-KEY-reponame

fpm docs state that you just need to add the –rpm-sign to your fpm command. However, this generated the following error for me:

1
2
error: You must set "%_gpg_name" in your macro file {:level=>:error}
Pass phrase check failed {:level=>:error}

The reason for this is that it uses the settings located in your ~/.rpmmacros file. Find your key ID:

1
2
3
4
5
6
# gpg --list-keys
/user/.gnupg/pubring.gpg
------------------------
pub   2048R/94E8C1F6 2013-04-24
uid                  Dave Drager <ddrager@xxx>
sub   2048R/94E8C1F6 2013-04-24

In this sample, the KEY_ID would be “94E8C1F6”

1
2
3
4
%_signature gpg
%_gpg_path /path/to/.gnupg
%_gpg_name KEY_ID
%_gpgbin /usr/bin/gpg

From here, the fpm command runs without issue.

1
2
3
4
# fpm -s dir -t rpm -n php-fpm-xda -v 5.2.23 -C /tmp/installdir -p php-fpm-xda_VERSION_ARCH.rpm -d openssl -d pcre -d bzip2 -d curl -d libjpeg -d libpng -d freetype -d gmp -d libmcrypt -d libmhash -d libxml2 --rpm-sign usr/bin usr/share/man/man1 usr/sbin etc usr/share/man/man8 usr/share/fpm usr/lib/build usr/include/php
Enter pass phrase:
Pass phrase is good. {:level=>:error}
Created rpm {:path=>"php-fpm-xda_5.2.23_x86_64.rpm"}

This is an alias of the rpm --addsign command.

Now let’s check the signature on this rpm.

1
2
# rpm --checksig php-fpm-xda_5.2.23_x86_64.rpm
php-fpm-xda_5.2.23_x86_64.rpm: RSA sha1 ((MD5) PGP) md5 NOT OK (MISSING KEYS: (MD5) PGP#94E8C1F6)

Whoops, it doesn’t seem to be signed properly. Well, that is because the rpm system doesn’t know to trust this GPG key yet. Import with the following command:

1
rpm --import ~/RPM-GPG-KEY-reponame

Note that this is the plain text file from before. Your RPM system knows to trust this key, and now if you verify the file:

1
2
# rpm --checksig php-fpm-xda_5.2.23_x86_64.rpm
php-fpm-xda_5.2.23_x86_64.rpm: rsa sha1 (md5) pgp md5 OK

This RPM is now ready for use in a repo. In the .repo file, use the following to ensure it follows the correct signature:

1
2
gpgcheck=1
gpgkey=http://repo.xxxx.com/RPM-GPG-KEY-reponame

All key names have been changed to protect the innocent.