I have been playing around with building RPM packages today on CentOS because I needed to upgrade curl and the latest version available on CentOS didn’t have the features I needed to use. One of the things that had come h up during the RPM build process and the RPM package installation process using yum was the fact that your RPM packages should be signed. Signing RPM packages gives them some validity and will allow others to install them without having to modify their yum.conf file. Below I describe how to generate a GPG key to be used to sign RPM packages created using the rpmbuild command. First below is a message that will be received when attempting to install unsigned packages using yum with the default yum configuration.
Possible Error When Attempting To Install Unsigned Packages Using Yum Example:
Package curl-7.20.0-1.i386.rpm is not signed
You can get around the above message by disabling the GPG checking built into yum. The option in the yum.conf file that disables checking for GPG signatures in RPM packages that are being installed is called gpgcheck. If gpgcheck is set to 1 then yum will check for GPG signatures but if gpgcheck is set to 0 then yum will not check for GPG signatures in RPM packages installed using yum.
Generate GPG Signature To Use For Signing RPM Packages Built With rpmbuild:
- Verify GPG Installed: First you need to verify that GPG is installed on the computer where you are building RPM packages with rpmbuild by issuing the below command.
Use Which To Verify GPG Installed:
[root@dev ~]# rpm -qf `which gpg` gnupg-1.4.5-13
The output in the above example shows that gnupg is installed. If no results are returned then you can easily install gnupg using yum with the below command.
Install gnupg On CentOS Linux Using Yum Package Manager:
yum install gnupg
- Generate GPG Key: Now you need to issue the below command to generate the GPG key which might remind you of generating a SSL certificate.
Use GPG To Generate A GPG Key:
Below is an example output of using the gpg command to generate a GPG key that can be used to sign RPM packages built with the rpmbuild command. You should not issue the below command as root but instead you should issue the below command as the user that you also build RPM packages with.
Example GPG Signature Generation On CentOS Linux:
[alextest@dev ~]$ gpg --gen-key gpg (GnuPG) 1.4.5; Copyright (C) 2006 Free Software Foundation, Inc. This program comes with ABSOLUTELY NO WARRANTY. This is free software, and you are welcome to redistribute it under certain conditions. See the file COPYING for details. gpg: directory `/home/alextest/.gnupg' created gpg: new configuration file `/home/alextest/.gnupg/gpg.conf' created gpg: WARNING: options in `/home/alextest/.gnupg/gpg.conf' are not yet active during this run gpg: keyring `/home/alextest/.gnupg/secring.gpg' created gpg: keyring `/home/alextest/.gnupg/pubring.gpg' created Please select what kind of key you want: (1) DSA and Elgamal (default) (2) DSA (sign only) (5) RSA (sign only) Your selection? 1 DSA keypair will have 1024 bits. ELG-E keys may be between 1024 and 4096 bits long. What keysize do you want? (2048) 1024 Requested keysize is 1024 bits Please specify how long the key should be valid. 0 = key does not expire <n> = key expires in n days <n>w = key expires in n weeks <n>m = key expires in n months <n>y = key expires in n years Key is valid for? (0) 0 Key does not expire at all Is this correct? (y/N) y You need a user ID to identify your key; the software constructs the user ID from the Real Name, Comment and Email Address in this form: "Heinrich Heine (Der Dichter) <firstname.lastname@example.org>" Real name: Joe User Email address: email@example.com Comment: Example GPG Key Signature For RPM Packages You selected this USER-ID: "Joe User (Example GPG Key Signature For RPM Packages) <firstname.lastname@example.org>" Change (N)ame, (C)omment, (E)mail or (O)kay/(Q)uit? o You need a Passphrase to protect your secret key. We need to generate a lot of random bytes. It is a good idea to perform some other action (type on the keyboard, move the mouse, utilize the disks) during the prime generation; this gives the random number generator a better chance to gain enough entropy. ++++++++++++++++++++.++++++++++.++++++++++++++++++++++++++++++++++++++++.+++++.++++++++++.+++++++++++++++++++++++++++++++++++..++++++++++>++++++++++....>+++++..........+++++ Not enough random bytes available. Please do some other work to give the OS a chance to collect more entropy! (Need 278 more bytes) We need to generate a lot of random bytes. It is a good idea to perform some other action (type on the keyboard, move the mouse, utilize the disks) during the prime generation; this gives the random number generator a better chance to gain enough entropy. +++++++++++++++.++++++++++++++++++++++++++++++.+++++++++++++++++++++++++.+++++.+++++++++++++++.+++++++++++++++++++++++++..+++++++++++++++.................>+++++...............................+++++^^^ gpg: /home/alextest/.gnupg/trustdb.gpg: trustdb created gpg: key C169539E marked as ultimately trusted public and secret key created and signed. gpg: checking the trustdb gpg: 3 marginal(s) needed, 1 complete(s) needed, PGP trust model gpg: depth: 0 valid: 1 signed: 0 trust: 0-, 0q, 0n, 0m, 0f, 1u pub 1024D/C169539E 2010-03-04 Key fingerprint = 91D0 CFD2 4DE2 BA85 81AD 2319 F834 AF3B C169 539E uid Joe User (Example GPG Key Signature For RPM Packages) <email@example.com> sub 1024g/85369CDD 2010-03-04
During the process of key generation you will be required to select the type of key you want, the length of the GPG key itself, the GPG key expiration date, your name, your email address, a comment associated to the key, and a passphrase that you will need to remember as it is required each time you generate a signed RPM package. After entering in all of the information the computer will generate the GPG key and depending on the computer it may take awhile. In fact sometimes you might get a message as noted in the example above the computer may need to collect more entropy. You can read this article regarding what entropy means and how to generate more entropy for the OS. This process will create a .gnupg directory in the home directory of the user that issued the gpg command which will have numerous files in it after completing the GPG key generation.
- Configure RPM Macros: After generating the GPG key you should configure some RPM macros so the rpmbuild command knows where to locate the correct GPG key to use for signing RPM packages. The .rpmmacros may already exist but if it doesn’t create it with your favorite text file in the same user who builds the RPM files home directory and add the below lines to it. Make sure to replace each variable with the proper content.
Add RPM Macros To The .rpmmacros File In The Users Home Directory:
%_signature gpg %_gpg_path /home/alextest/.gnupg %_gpg_name Joe User (Example GPG Key Signature For RPM Packages) <firstname.lastname@example.org> %_gpgbin /usr/bin/gpg
If there are already other RPM macros in the .rpmmacros file just add the above four macros to the end of the file. Again make sure to update each value with the correct input for your scenario. You can locate the gpg location by typing “which gpg” from the command line of the computer but typically on CentOS gpg will be installed in the /usr/bin directory.
- rpmbuild Command To Sign Packages: Last but not least you will need to test this out by building a RPM package with the rpmbuild command. An example rpmbuild command is below and you will know that you are successful when you are asked for the passphrase you entered during the GPG key creation.
Generate A Signed RPM Package With The rpmbuild Command:
rpmbuild -v -ba --sign --clean SPECS/curl.spec
The above example command was issued from the rpmbuild directory located inside the users home directory. You will obviously need to have the proper source file(s) and have created a spec file already.
Once the package is built you can test if the signature was built in properly by attempting to install the RPM on your server. If the yum gpgcheck configuration setting is still the default setting (1) then the RPM installation will fail because you do not have the GPG key imported into RPM. Below is a command you can use to not only import the GPG key using rpm but also to generate the public ASCII GPG key version you will share for others to import using rpm before installing any packages you provide them.
Generate An ASCII Public Version Of Your GPG Key:
gpg --armor --output JOEUSER-GPG-KEY --export 'Joe User'
You will issue the above command while logged in as the same user you build RPM packages with and you generated the GPG key with. This will generate a ASCII version of your GPG key that can be imported using the rpm command as shown below.
Import A GPG Key Using RPM To Install Signed RPM Packages:
rpm --import JOEUSER-GPG-KEY
After importing the JOEUSER-GPG-KEY using the rpm command you will now be able to use yum to install the signed RPM package you created earlier.